Initial Commit
This commit is contained in:
1 parent
377b32db6e
commit
2d9a5eecba
14134 files changed
+1160982
No files matched your search
+162
@@ -0,0 +1,162 @@
|
||||
package net.minecraft;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntStack;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class BlockUtil {
|
||||
/**
|
||||
* Finds the rectangle with the largest area containing centerPos within the blocks specified by the predicate
|
||||
*/
|
||||
public static BlockUtil.FoundRectangle getLargestRectangleAround(BlockPos pCenterPos, Direction.Axis pAxis1, int pMax1, Direction.Axis pAxis2, int pMax2, Predicate<BlockPos> pPosPredicate) {
|
||||
BlockPos.MutableBlockPos blockpos$mutableblockpos = pCenterPos.mutable();
|
||||
Direction direction = Direction.get(Direction.AxisDirection.NEGATIVE, pAxis1);
|
||||
Direction direction1 = direction.getOpposite();
|
||||
Direction direction2 = Direction.get(Direction.AxisDirection.NEGATIVE, pAxis2);
|
||||
Direction direction3 = direction2.getOpposite();
|
||||
int i = getLimit(pPosPredicate, blockpos$mutableblockpos.set(pCenterPos), direction, pMax1);
|
||||
int j = getLimit(pPosPredicate, blockpos$mutableblockpos.set(pCenterPos), direction1, pMax1);
|
||||
int k = i;
|
||||
BlockUtil.IntBounds[] ablockutil$intbounds = new BlockUtil.IntBounds[i + 1 + j];
|
||||
ablockutil$intbounds[i] = new BlockUtil.IntBounds(getLimit(pPosPredicate, blockpos$mutableblockpos.set(pCenterPos), direction2, pMax2), getLimit(pPosPredicate, blockpos$mutableblockpos.set(pCenterPos), direction3, pMax2));
|
||||
int l = ablockutil$intbounds[i].min;
|
||||
|
||||
for(int i1 = 1; i1 <= i; ++i1) {
|
||||
BlockUtil.IntBounds blockutil$intbounds = ablockutil$intbounds[k - (i1 - 1)];
|
||||
ablockutil$intbounds[k - i1] = new BlockUtil.IntBounds(getLimit(pPosPredicate, blockpos$mutableblockpos.set(pCenterPos).move(direction, i1), direction2, blockutil$intbounds.min), getLimit(pPosPredicate, blockpos$mutableblockpos.set(pCenterPos).move(direction, i1), direction3, blockutil$intbounds.max));
|
||||
}
|
||||
|
||||
for(int l2 = 1; l2 <= j; ++l2) {
|
||||
BlockUtil.IntBounds blockutil$intbounds2 = ablockutil$intbounds[k + l2 - 1];
|
||||
ablockutil$intbounds[k + l2] = new BlockUtil.IntBounds(getLimit(pPosPredicate, blockpos$mutableblockpos.set(pCenterPos).move(direction1, l2), direction2, blockutil$intbounds2.min), getLimit(pPosPredicate, blockpos$mutableblockpos.set(pCenterPos).move(direction1, l2), direction3, blockutil$intbounds2.max));
|
||||
}
|
||||
|
||||
int i3 = 0;
|
||||
int j3 = 0;
|
||||
int j1 = 0;
|
||||
int k1 = 0;
|
||||
int[] aint = new int[ablockutil$intbounds.length];
|
||||
|
||||
for(int l1 = l; l1 >= 0; --l1) {
|
||||
for(int i2 = 0; i2 < ablockutil$intbounds.length; ++i2) {
|
||||
BlockUtil.IntBounds blockutil$intbounds1 = ablockutil$intbounds[i2];
|
||||
int j2 = l - blockutil$intbounds1.min;
|
||||
int k2 = l + blockutil$intbounds1.max;
|
||||
aint[i2] = l1 >= j2 && l1 <= k2 ? k2 + 1 - l1 : 0;
|
||||
}
|
||||
|
||||
Pair<BlockUtil.IntBounds, Integer> pair = getMaxRectangleLocation(aint);
|
||||
BlockUtil.IntBounds blockutil$intbounds3 = pair.getFirst();
|
||||
int k3 = 1 + blockutil$intbounds3.max - blockutil$intbounds3.min;
|
||||
int l3 = pair.getSecond();
|
||||
if (k3 * l3 > j1 * k1) {
|
||||
i3 = blockutil$intbounds3.min;
|
||||
j3 = l1;
|
||||
j1 = k3;
|
||||
k1 = l3;
|
||||
}
|
||||
}
|
||||
|
||||
return new BlockUtil.FoundRectangle(pCenterPos.relative(pAxis1, i3 - k).relative(pAxis2, j3 - l), j1, k1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the distance we can travel in the given direction while the predicate returns true
|
||||
*/
|
||||
private static int getLimit(Predicate<BlockPos> pPosPredicate, BlockPos.MutableBlockPos pCenterPos, Direction pDirection, int pMax) {
|
||||
int i;
|
||||
for(i = 0; i < pMax && pPosPredicate.test(pCenterPos.move(pDirection)); ++i) {
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the largest rectangle within the array of heights
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static Pair<BlockUtil.IntBounds, Integer> getMaxRectangleLocation(int[] pHeights) {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
IntStack intstack = new IntArrayList();
|
||||
intstack.push(0);
|
||||
|
||||
for(int l = 1; l <= pHeights.length; ++l) {
|
||||
int i1 = l == pHeights.length ? 0 : pHeights[l];
|
||||
|
||||
while(!intstack.isEmpty()) {
|
||||
int j1 = pHeights[intstack.topInt()];
|
||||
if (i1 >= j1) {
|
||||
intstack.push(l);
|
||||
break;
|
||||
}
|
||||
|
||||
intstack.popInt();
|
||||
int k1 = intstack.isEmpty() ? 0 : intstack.topInt() + 1;
|
||||
if (j1 * (l - k1) > k * (j - i)) {
|
||||
j = l;
|
||||
i = k1;
|
||||
k = j1;
|
||||
}
|
||||
}
|
||||
|
||||
if (intstack.isEmpty()) {
|
||||
intstack.push(l);
|
||||
}
|
||||
}
|
||||
|
||||
return new Pair<>(new BlockUtil.IntBounds(i, j - 1), k);
|
||||
}
|
||||
|
||||
public static Optional<BlockPos> getTopConnectedBlock(BlockGetter pGetter, BlockPos pPos, Block pBaseBlock, Direction pDirection, Block pEndBlock) {
|
||||
BlockPos.MutableBlockPos blockpos$mutableblockpos = pPos.mutable();
|
||||
|
||||
BlockState blockstate;
|
||||
do {
|
||||
blockpos$mutableblockpos.move(pDirection);
|
||||
blockstate = pGetter.getBlockState(blockpos$mutableblockpos);
|
||||
} while(blockstate.is(pBaseBlock));
|
||||
|
||||
return blockstate.is(pEndBlock) ? Optional.of(blockpos$mutableblockpos) : Optional.empty();
|
||||
}
|
||||
|
||||
public static class FoundRectangle {
|
||||
/** Starting position of the rectangle represented by this result */
|
||||
public final BlockPos minCorner;
|
||||
/** Distance between minimum and maximum values on the first axis argument */
|
||||
public final int axis1Size;
|
||||
/** Distance between minimum and maximum values on the second axis argument */
|
||||
public final int axis2Size;
|
||||
|
||||
public FoundRectangle(BlockPos pMinCorner, int pAxis1Size, int pAxis2Size) {
|
||||
this.minCorner = pMinCorner;
|
||||
this.axis1Size = pAxis1Size;
|
||||
this.axis2Size = pAxis2Size;
|
||||
}
|
||||
}
|
||||
|
||||
public static class IntBounds {
|
||||
/** The minimum bound */
|
||||
public final int min;
|
||||
/** The maximum bound */
|
||||
public final int max;
|
||||
|
||||
public IntBounds(int pMin, int pMax) {
|
||||
this.min = pMin;
|
||||
this.max = pMax;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "IntBounds{min=" + this.min + ", max=" + this.max + "}";
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package net.minecraft;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CharPredicate {
|
||||
boolean test(char pValue);
|
||||
|
||||
default CharPredicate and(CharPredicate pPredicate) {
|
||||
Objects.requireNonNull(pPredicate);
|
||||
return (p_178295_) -> {
|
||||
return this.test(p_178295_) && pPredicate.test(p_178295_);
|
||||
};
|
||||
}
|
||||
|
||||
default CharPredicate negate() {
|
||||
return (p_178285_) -> {
|
||||
return !this.test(p_178285_);
|
||||
};
|
||||
}
|
||||
|
||||
default CharPredicate or(CharPredicate pPredicate) {
|
||||
Objects.requireNonNull(pPredicate);
|
||||
return (p_178290_) -> {
|
||||
return this.test(p_178290_) || pPredicate.test(p_178290_);
|
||||
};
|
||||
}
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
package net.minecraft;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.serialization.Codec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
|
||||
public enum ChatFormatting implements StringRepresentable {
|
||||
BLACK("BLACK", '0', 0, 0),
|
||||
DARK_BLUE("DARK_BLUE", '1', 1, 170),
|
||||
DARK_GREEN("DARK_GREEN", '2', 2, 43520),
|
||||
DARK_AQUA("DARK_AQUA", '3', 3, 43690),
|
||||
DARK_RED("DARK_RED", '4', 4, 11141120),
|
||||
DARK_PURPLE("DARK_PURPLE", '5', 5, 11141290),
|
||||
GOLD("GOLD", '6', 6, 16755200),
|
||||
GRAY("GRAY", '7', 7, 11184810),
|
||||
DARK_GRAY("DARK_GRAY", '8', 8, 5592405),
|
||||
BLUE("BLUE", '9', 9, 5592575),
|
||||
GREEN("GREEN", 'a', 10, 5635925),
|
||||
AQUA("AQUA", 'b', 11, 5636095),
|
||||
RED("RED", 'c', 12, 16733525),
|
||||
LIGHT_PURPLE("LIGHT_PURPLE", 'd', 13, 16733695),
|
||||
YELLOW("YELLOW", 'e', 14, 16777045),
|
||||
WHITE("WHITE", 'f', 15, 16777215),
|
||||
OBFUSCATED("OBFUSCATED", 'k', true),
|
||||
BOLD("BOLD", 'l', true),
|
||||
STRIKETHROUGH("STRIKETHROUGH", 'm', true),
|
||||
UNDERLINE("UNDERLINE", 'n', true),
|
||||
ITALIC("ITALIC", 'o', true),
|
||||
RESET("RESET", 'r', -1, (Integer)null);
|
||||
|
||||
public static final Codec<ChatFormatting> CODEC = StringRepresentable.fromEnum(ChatFormatting::values);
|
||||
public static final char PREFIX_CODE = '\u00a7';
|
||||
private static final Map<String, ChatFormatting> FORMATTING_BY_NAME = Arrays.stream(values()).collect(Collectors.toMap((p_126660_) -> {
|
||||
return cleanName(p_126660_.name);
|
||||
}, (p_126652_) -> {
|
||||
return p_126652_;
|
||||
}));
|
||||
private static final Pattern STRIP_FORMATTING_PATTERN = Pattern.compile("(?i)\u00a7[0-9A-FK-OR]");
|
||||
/** The name of this color/formatting */
|
||||
private final String name;
|
||||
private final char code;
|
||||
private final boolean isFormat;
|
||||
private final String toString;
|
||||
/** The numerical index that represents this color */
|
||||
private final int id;
|
||||
@Nullable
|
||||
private final Integer color;
|
||||
|
||||
private static String cleanName(String pString) {
|
||||
return pString.toLowerCase(Locale.ROOT).replaceAll("[^a-z]", "");
|
||||
}
|
||||
|
||||
private ChatFormatting(String pName, char pCode, int pId, @Nullable Integer pColor) {
|
||||
this(pName, pCode, false, pId, pColor);
|
||||
}
|
||||
|
||||
private ChatFormatting(String pName, char pCode, boolean pIsFormat) {
|
||||
this(pName, pCode, pIsFormat, -1, (Integer)null);
|
||||
}
|
||||
|
||||
private ChatFormatting(String pName, char pCode, boolean pIsFormat, int pId, @Nullable Integer pColor) {
|
||||
this.name = pName;
|
||||
this.code = pCode;
|
||||
this.isFormat = pIsFormat;
|
||||
this.id = pId;
|
||||
this.color = pColor;
|
||||
this.toString = "\u00a7" + pCode;
|
||||
}
|
||||
|
||||
public char getChar() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numerical color index that represents this formatting
|
||||
*/
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* False if this is just changing the color or resetting true otherwise.
|
||||
*/
|
||||
public boolean isFormat() {
|
||||
return this.isFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a color code.
|
||||
*/
|
||||
public boolean isColor() {
|
||||
return !this.isFormat && this != RESET;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the friendly name of this value.
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.toString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the given string, with formatting codes stripped away.
|
||||
*/
|
||||
@Nullable
|
||||
public static String stripFormatting(@Nullable String pText) {
|
||||
return pText == null ? null : STRIP_FORMATTING_PATTERN.matcher(pText).replaceAll("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value by its friendly name null if the given name does not map to a defined value.
|
||||
*/
|
||||
@Nullable
|
||||
public static ChatFormatting getByName(@Nullable String pFriendlyName) {
|
||||
return pFriendlyName == null ? null : FORMATTING_BY_NAME.get(cleanName(pFriendlyName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a TextFormatting from its color index
|
||||
*/
|
||||
@Nullable
|
||||
public static ChatFormatting getById(int pIndex) {
|
||||
if (pIndex < 0) {
|
||||
return RESET;
|
||||
} else {
|
||||
for(ChatFormatting chatformatting : values()) {
|
||||
if (chatformatting.getId() == pIndex) {
|
||||
return chatformatting;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ChatFormatting getByCode(char pFormattingCode) {
|
||||
char c0 = Character.toString(pFormattingCode).toLowerCase(Locale.ROOT).charAt(0);
|
||||
|
||||
for(ChatFormatting chatformatting : values()) {
|
||||
if (chatformatting.code == c0) {
|
||||
return chatformatting;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the valid values.
|
||||
*/
|
||||
public static Collection<String> getNames(boolean pGetColor, boolean pGetFancyStyling) {
|
||||
List<String> list = Lists.newArrayList();
|
||||
|
||||
for(ChatFormatting chatformatting : values()) {
|
||||
if ((!chatformatting.isColor() || pGetColor) && (!chatformatting.isFormat() || pGetFancyStyling)) {
|
||||
list.add(chatformatting.getName());
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public String getSerializedName() {
|
||||
return this.getName();
|
||||
}
|
||||
}
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
package net.minecraft;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import net.minecraft.util.MemoryReserve;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CrashReport {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
|
||||
private final String title;
|
||||
private final Throwable exception;
|
||||
private final List<CrashReportCategory> details = Lists.newArrayList();
|
||||
private File saveFile;
|
||||
private boolean trackingStackTrace = true;
|
||||
private StackTraceElement[] uncategorizedStackTrace = new StackTraceElement[0];
|
||||
private final SystemReport systemReport = new SystemReport();
|
||||
|
||||
public CrashReport(String pTitle, Throwable pException) {
|
||||
this.title = pTitle;
|
||||
this.exception = pException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description of the Crash Report.
|
||||
*/
|
||||
public String getTitle() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Throwable object that is the cause for the crash and Crash Report.
|
||||
*/
|
||||
public Throwable getException() {
|
||||
return this.exception;
|
||||
}
|
||||
|
||||
public String getDetails() {
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
this.getDetails(stringbuilder);
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the various sections of the crash report into the given StringBuilder
|
||||
*/
|
||||
public void getDetails(StringBuilder pBuilder) {
|
||||
if ((this.uncategorizedStackTrace == null || this.uncategorizedStackTrace.length <= 0) && !this.details.isEmpty()) {
|
||||
this.uncategorizedStackTrace = ArrayUtils.subarray((StackTraceElement[])this.details.get(0).getStacktrace(), 0, 1);
|
||||
}
|
||||
|
||||
if (this.uncategorizedStackTrace != null && this.uncategorizedStackTrace.length > 0) {
|
||||
pBuilder.append("-- Head --\n");
|
||||
pBuilder.append("Thread: ").append(Thread.currentThread().getName()).append("\n");
|
||||
pBuilder.append(net.minecraftforge.logging.CrashReportAnalyser.appendSuspectedMods(this.exception, this.uncategorizedStackTrace));
|
||||
pBuilder.append("Stacktrace:");
|
||||
pBuilder.append(net.minecraftforge.logging.CrashReportExtender.generateEnhancedStackTrace(this.uncategorizedStackTrace));
|
||||
}
|
||||
|
||||
for(CrashReportCategory crashreportcategory : this.details) {
|
||||
crashreportcategory.getDetails(pBuilder);
|
||||
pBuilder.append("\n\n");
|
||||
}
|
||||
|
||||
net.minecraftforge.logging.CrashReportExtender.extendSystemReport(systemReport);
|
||||
this.systemReport.appendToCrashReportString(pBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stack trace of the Throwable that caused this crash report, or if that fails, the cause {@code
|
||||
* .toString()}.
|
||||
*/
|
||||
public String getExceptionMessage() {
|
||||
StringWriter stringwriter = null;
|
||||
PrintWriter printwriter = null;
|
||||
Throwable throwable = this.exception;
|
||||
if (throwable.getMessage() == null) {
|
||||
if (throwable instanceof NullPointerException) {
|
||||
throwable = new NullPointerException(this.title);
|
||||
} else if (throwable instanceof StackOverflowError) {
|
||||
throwable = new StackOverflowError(this.title);
|
||||
} else if (throwable instanceof OutOfMemoryError) {
|
||||
throwable = new OutOfMemoryError(this.title);
|
||||
}
|
||||
|
||||
throwable.setStackTrace(this.exception.getStackTrace());
|
||||
}
|
||||
|
||||
return net.minecraftforge.logging.CrashReportExtender.generateEnhancedStackTrace(throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the complete report with headers, stack trace, and different sections as a string.
|
||||
*/
|
||||
public String getFriendlyReport() {
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
stringbuilder.append("---- Minecraft Crash Report ----\n");
|
||||
net.minecraftforge.logging.CrashReportExtender.addCrashReportHeader(stringbuilder, this);
|
||||
stringbuilder.append("// ");
|
||||
stringbuilder.append(getErrorComment());
|
||||
stringbuilder.append("\n\n");
|
||||
stringbuilder.append("Time: ");
|
||||
stringbuilder.append(DATE_TIME_FORMATTER.format(ZonedDateTime.now()));
|
||||
stringbuilder.append("\n");
|
||||
stringbuilder.append("Description: ");
|
||||
stringbuilder.append(this.title);
|
||||
stringbuilder.append("\n\n");
|
||||
stringbuilder.append(this.getExceptionMessage());
|
||||
stringbuilder.append("\n\nA detailed walkthrough of the error, its code path and all known details is as follows:\n");
|
||||
|
||||
for(int i = 0; i < 87; ++i) {
|
||||
stringbuilder.append("-");
|
||||
}
|
||||
|
||||
stringbuilder.append("\n\n");
|
||||
this.getDetails(stringbuilder);
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file this crash report is saved into.
|
||||
*/
|
||||
public File getSaveFile() {
|
||||
return this.saveFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this CrashReport to the given file and returns a value indicating whether we were successful at doing so.
|
||||
*/
|
||||
public boolean saveToFile(File pToFile) {
|
||||
if (this.saveFile != null) {
|
||||
return false;
|
||||
} else {
|
||||
if (pToFile.getParentFile() != null) {
|
||||
pToFile.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
Writer writer = null;
|
||||
|
||||
boolean flag;
|
||||
try {
|
||||
writer = new OutputStreamWriter(new FileOutputStream(pToFile), StandardCharsets.UTF_8);
|
||||
writer.write(this.getFriendlyReport());
|
||||
this.saveFile = pToFile;
|
||||
return true;
|
||||
} catch (Throwable throwable) {
|
||||
LOGGER.error("Could not save crash report to {}", pToFile, throwable);
|
||||
flag = false;
|
||||
} finally {
|
||||
IOUtils.closeQuietly(writer);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
|
||||
public SystemReport getSystemReport() {
|
||||
return this.systemReport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CrashReportCategory
|
||||
*/
|
||||
public CrashReportCategory addCategory(String pName) {
|
||||
return this.addCategory(pName, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CrashReportCategory for the given stack trace depth
|
||||
*/
|
||||
public CrashReportCategory addCategory(String pCategoryName, int pStacktraceLength) {
|
||||
CrashReportCategory crashreportcategory = new CrashReportCategory(pCategoryName);
|
||||
if (this.trackingStackTrace) {
|
||||
int i = crashreportcategory.fillInStackTrace(pStacktraceLength);
|
||||
StackTraceElement[] astacktraceelement = this.exception.getStackTrace();
|
||||
StackTraceElement stacktraceelement = null;
|
||||
StackTraceElement stacktraceelement1 = null;
|
||||
int j = astacktraceelement.length - i;
|
||||
if (j < 0) {
|
||||
System.out.println("Negative index in crash report handler (" + astacktraceelement.length + "/" + i + ")");
|
||||
}
|
||||
|
||||
if (astacktraceelement != null && 0 <= j && j < astacktraceelement.length) {
|
||||
stacktraceelement = astacktraceelement[j];
|
||||
if (astacktraceelement.length + 1 - i < astacktraceelement.length) {
|
||||
stacktraceelement1 = astacktraceelement[astacktraceelement.length + 1 - i];
|
||||
}
|
||||
}
|
||||
|
||||
this.trackingStackTrace = crashreportcategory.validateStackTrace(stacktraceelement, stacktraceelement1);
|
||||
if (astacktraceelement != null && astacktraceelement.length >= i && 0 <= j && j < astacktraceelement.length) {
|
||||
this.uncategorizedStackTrace = new StackTraceElement[j];
|
||||
System.arraycopy(astacktraceelement, 0, this.uncategorizedStackTrace, 0, this.uncategorizedStackTrace.length);
|
||||
} else {
|
||||
this.trackingStackTrace = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.details.add(crashreportcategory);
|
||||
return crashreportcategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random witty comment for inclusion in this CrashReport
|
||||
*/
|
||||
private static String getErrorComment() {
|
||||
String[] astring = new String[]{"Who set us up the TNT?", "Everything's going to plan. No, really, that was supposed to happen.", "Uh... Did I do that?", "Oops.", "Why did you do that?", "I feel sad now :(", "My bad.", "I'm sorry, Dave.", "I let you down. Sorry :(", "On the bright side, I bought you a teddy bear!", "Daisy, daisy...", "Oh - I know what I did wrong!", "Hey, that tickles! Hehehe!", "I blame Dinnerbone.", "You should try our sister game, Minceraft!", "Don't be sad. I'll do better next time, I promise!", "Don't be sad, have a hug! <3", "I just don't know what went wrong :(", "Shall we play a game?", "Quite honestly, I wouldn't worry myself about that.", "I bet Cylons wouldn't have this problem.", "Sorry :(", "Surprise! Haha. Well, this is awkward.", "Would you like a cupcake?", "Hi. I'm Minecraft, and I'm a crashaholic.", "Ooh. Shiny.", "This doesn't make any sense!", "Why is it breaking :(", "Don't do that.", "Ouch. That hurt :(", "You're mean.", "This is a token for 1 free hug. Redeem at your nearest Mojangsta: [~~HUG~~]", "There are four lights!", "But it works on my machine."};
|
||||
|
||||
try {
|
||||
return astring[(int)(Util.getNanos() % (long)astring.length)];
|
||||
} catch (Throwable throwable) {
|
||||
return "Witty comment unavailable :(";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a crash report for the exception
|
||||
*/
|
||||
public static CrashReport forThrowable(Throwable pCause, String pDescription) {
|
||||
while(pCause instanceof CompletionException && pCause.getCause() != null) {
|
||||
pCause = pCause.getCause();
|
||||
}
|
||||
|
||||
CrashReport crashreport;
|
||||
if (pCause instanceof ReportedException) {
|
||||
crashreport = ((ReportedException)pCause).getReport();
|
||||
} else {
|
||||
crashreport = new CrashReport(pDescription, pCause);
|
||||
}
|
||||
|
||||
return crashreport;
|
||||
}
|
||||
|
||||
public static void preload() {
|
||||
MemoryReserve.allocate();
|
||||
(new CrashReport("Don't panic!", new Throwable())).getFriendlyReport();
|
||||
}
|
||||
}
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
package net.minecraft;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class CrashReportCategory {
|
||||
private final String title;
|
||||
private final List<CrashReportCategory.Entry> entries = Lists.newArrayList();
|
||||
private StackTraceElement[] stackTrace = new StackTraceElement[0];
|
||||
|
||||
public CrashReportCategory(String pTitle) {
|
||||
this.title = pTitle;
|
||||
}
|
||||
|
||||
public static String formatLocation(LevelHeightAccessor pLevelHeightAccess, double pX, double pY, double pZ) {
|
||||
return String.format(Locale.ROOT, "%.2f,%.2f,%.2f - %s", pX, pY, pZ, formatLocation(pLevelHeightAccess, BlockPos.containing(pX, pY, pZ)));
|
||||
}
|
||||
|
||||
public static String formatLocation(LevelHeightAccessor pLevelHeightAccess, BlockPos pPos) {
|
||||
return formatLocation(pLevelHeightAccess, pPos.getX(), pPos.getY(), pPos.getZ());
|
||||
}
|
||||
|
||||
public static String formatLocation(LevelHeightAccessor pLevelHeightAccess, int pX, int pY, int pZ) {
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
|
||||
try {
|
||||
stringbuilder.append(String.format(Locale.ROOT, "World: (%d,%d,%d)", pX, pY, pZ));
|
||||
} catch (Throwable throwable2) {
|
||||
stringbuilder.append("(Error finding world loc)");
|
||||
}
|
||||
|
||||
stringbuilder.append(", ");
|
||||
|
||||
try {
|
||||
int i = SectionPos.blockToSectionCoord(pX);
|
||||
int j = SectionPos.blockToSectionCoord(pY);
|
||||
int k = SectionPos.blockToSectionCoord(pZ);
|
||||
int l = pX & 15;
|
||||
int i1 = pY & 15;
|
||||
int j1 = pZ & 15;
|
||||
int k1 = SectionPos.sectionToBlockCoord(i);
|
||||
int l1 = pLevelHeightAccess.getMinBuildHeight();
|
||||
int i2 = SectionPos.sectionToBlockCoord(k);
|
||||
int j2 = SectionPos.sectionToBlockCoord(i + 1) - 1;
|
||||
int k2 = pLevelHeightAccess.getMaxBuildHeight() - 1;
|
||||
int l2 = SectionPos.sectionToBlockCoord(k + 1) - 1;
|
||||
stringbuilder.append(String.format(Locale.ROOT, "Section: (at %d,%d,%d in %d,%d,%d; chunk contains blocks %d,%d,%d to %d,%d,%d)", l, i1, j1, i, j, k, k1, l1, i2, j2, k2, l2));
|
||||
} catch (Throwable throwable1) {
|
||||
stringbuilder.append("(Error finding chunk loc)");
|
||||
}
|
||||
|
||||
stringbuilder.append(", ");
|
||||
|
||||
try {
|
||||
int i3 = pX >> 9;
|
||||
int j3 = pZ >> 9;
|
||||
int k3 = i3 << 5;
|
||||
int l3 = j3 << 5;
|
||||
int i4 = (i3 + 1 << 5) - 1;
|
||||
int j4 = (j3 + 1 << 5) - 1;
|
||||
int k4 = i3 << 9;
|
||||
int l4 = pLevelHeightAccess.getMinBuildHeight();
|
||||
int i5 = j3 << 9;
|
||||
int j5 = (i3 + 1 << 9) - 1;
|
||||
int k5 = pLevelHeightAccess.getMaxBuildHeight() - 1;
|
||||
int l5 = (j3 + 1 << 9) - 1;
|
||||
stringbuilder.append(String.format(Locale.ROOT, "Region: (%d,%d; contains chunks %d,%d to %d,%d, blocks %d,%d,%d to %d,%d,%d)", i3, j3, k3, l3, i4, j4, k4, l4, i5, j5, k5, l5));
|
||||
} catch (Throwable throwable) {
|
||||
stringbuilder.append("(Error finding world loc)");
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a section to this crash report category, resolved by calling the given callable.
|
||||
*
|
||||
* If the given callable throws an exception, a detail containing that exception will be created instead.
|
||||
*/
|
||||
public CrashReportCategory setDetail(String pName, CrashReportDetail<String> pDetail) {
|
||||
try {
|
||||
this.setDetail(pName, pDetail.call());
|
||||
} catch (Throwable throwable) {
|
||||
this.setDetailError(pName, throwable);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Crashreport section with the given name with the given value (converted {@code .toString()})
|
||||
*/
|
||||
public CrashReportCategory setDetail(String pSectionName, Object pValue) {
|
||||
this.entries.add(new CrashReportCategory.Entry(pSectionName, pValue));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Crashreport section with the given name with the given Throwable
|
||||
*/
|
||||
public void setDetailError(String pSectionName, Throwable pThrowable) {
|
||||
this.setDetail(pSectionName, pThrowable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets our stack trace according to the current trace, pruning the deepest 3 entries. The parameter indicates how
|
||||
* many additional deepest entries to prune. Returns the number of entries in the resulting pruned stack trace.
|
||||
*/
|
||||
public int fillInStackTrace(int pSize) {
|
||||
StackTraceElement[] astacktraceelement = Thread.currentThread().getStackTrace();
|
||||
if (astacktraceelement.length <= 0) {
|
||||
return 0;
|
||||
} else {
|
||||
int len = astacktraceelement.length - 3 - pSize;
|
||||
if (len <= 0) len = astacktraceelement.length;
|
||||
this.stackTrace = new StackTraceElement[len];
|
||||
System.arraycopy(astacktraceelement, astacktraceelement.length - len, this.stackTrace, 0, this.stackTrace.length);
|
||||
return this.stackTrace.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the deepest two elements of our saved stack trace match the given elements, in order from the deepest?
|
||||
*/
|
||||
public boolean validateStackTrace(StackTraceElement pS1, StackTraceElement pS2) {
|
||||
if (this.stackTrace.length != 0 && pS1 != null) {
|
||||
StackTraceElement stacktraceelement = this.stackTrace[0];
|
||||
if (stacktraceelement.isNativeMethod() == pS1.isNativeMethod() && stacktraceelement.getClassName().equals(pS1.getClassName()) && stacktraceelement.getFileName().equals(pS1.getFileName()) && stacktraceelement.getMethodName().equals(pS1.getMethodName())) {
|
||||
if (pS2 != null != this.stackTrace.length > 1) {
|
||||
return false;
|
||||
} else if (pS2 != null && !this.stackTrace[1].equals(pS2)) {
|
||||
return false;
|
||||
} else {
|
||||
this.stackTrace[0] = pS1;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given number entries from the bottom of the stack trace.
|
||||
*/
|
||||
public void trimStacktrace(int pAmount) {
|
||||
StackTraceElement[] astacktraceelement = new StackTraceElement[this.stackTrace.length - pAmount];
|
||||
System.arraycopy(this.stackTrace, 0, astacktraceelement, 0, astacktraceelement.length);
|
||||
this.stackTrace = astacktraceelement;
|
||||
}
|
||||
|
||||
public void getDetails(StringBuilder pBuilder) {
|
||||
pBuilder.append("-- ").append(this.title).append(" --\n");
|
||||
pBuilder.append("Details:");
|
||||
|
||||
for(CrashReportCategory.Entry crashreportcategory$entry : this.entries) {
|
||||
pBuilder.append("\n\t");
|
||||
pBuilder.append(crashreportcategory$entry.getKey());
|
||||
pBuilder.append(": ");
|
||||
pBuilder.append(crashreportcategory$entry.getValue());
|
||||
}
|
||||
|
||||
if (this.stackTrace != null && this.stackTrace.length > 0) {
|
||||
pBuilder.append("\nStacktrace:");
|
||||
pBuilder.append(net.minecraftforge.logging.CrashReportExtender.generateEnhancedStackTrace(this.stackTrace));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public StackTraceElement[] getStacktrace() {
|
||||
return this.stackTrace;
|
||||
}
|
||||
|
||||
public void applyStackTrace(Throwable t) {
|
||||
this.stackTrace = t.getStackTrace();
|
||||
}
|
||||
|
||||
public static void populateBlockDetails(CrashReportCategory pCategory, LevelHeightAccessor pLevelHeightAccessor, BlockPos pPos, @Nullable BlockState pState) {
|
||||
if (pState != null) {
|
||||
pCategory.setDetail("Block", pState::toString);
|
||||
}
|
||||
|
||||
pCategory.setDetail("Block location", () -> {
|
||||
return formatLocation(pLevelHeightAccessor, pPos);
|
||||
});
|
||||
}
|
||||
|
||||
static class Entry {
|
||||
private final String key;
|
||||
private final String value;
|
||||
|
||||
public Entry(String pKey, @Nullable Object pValue) {
|
||||
this.key = pKey;
|
||||
if (pValue == null) {
|
||||
this.value = "~~NULL~~";
|
||||
} else if (pValue instanceof Throwable) {
|
||||
Throwable throwable = (Throwable)pValue;
|
||||
this.value = "~~ERROR~~ " + throwable.getClass().getSimpleName() + ": " + throwable.getMessage();
|
||||
} else {
|
||||
this.value = pValue.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package net.minecraft;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public interface CrashReportDetail<V> extends Callable<V> {
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package net.minecraft;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class DefaultUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
|
||||
private final Logger logger;
|
||||
|
||||
public DefaultUncaughtExceptionHandler(Logger pLogger) {
|
||||
this.logger = pLogger;
|
||||
}
|
||||
|
||||
public void uncaughtException(Thread pThread, Throwable pException) {
|
||||
this.logger.error("Caught previously unhandled exception :", pException);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package net.minecraft;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class DefaultUncaughtExceptionHandlerWithName implements Thread.UncaughtExceptionHandler {
|
||||
private final Logger logger;
|
||||
|
||||
public DefaultUncaughtExceptionHandlerWithName(Logger pLogger) {
|
||||
this.logger = pLogger;
|
||||
}
|
||||
|
||||
public void uncaughtException(Thread pThread, Throwable pException) {
|
||||
this.logger.error("Caught previously unhandled exception :");
|
||||
this.logger.error(pThread.getName(), pException);
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
package net.minecraft;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.storage.DataVersion;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class DetectedVersion implements WorldVersion {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final WorldVersion BUILT_IN = new DetectedVersion();
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final boolean stable;
|
||||
private final DataVersion worldVersion;
|
||||
private final int protocolVersion;
|
||||
private final int resourcePackVersion;
|
||||
private final int dataPackVersion;
|
||||
private final Date buildTime;
|
||||
|
||||
private DetectedVersion() {
|
||||
this.id = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
this.name = "1.20.1";
|
||||
this.stable = true;
|
||||
this.worldVersion = new DataVersion(3465, "main");
|
||||
this.protocolVersion = SharedConstants.getProtocolVersion();
|
||||
this.resourcePackVersion = 15;
|
||||
this.dataPackVersion = 15;
|
||||
this.buildTime = new Date();
|
||||
}
|
||||
|
||||
private DetectedVersion(JsonObject pJson) {
|
||||
this.id = GsonHelper.getAsString(pJson, "id");
|
||||
this.name = GsonHelper.getAsString(pJson, "name");
|
||||
this.stable = GsonHelper.getAsBoolean(pJson, "stable");
|
||||
this.worldVersion = new DataVersion(GsonHelper.getAsInt(pJson, "world_version"), GsonHelper.getAsString(pJson, "series_id", DataVersion.MAIN_SERIES));
|
||||
this.protocolVersion = GsonHelper.getAsInt(pJson, "protocol_version");
|
||||
JsonObject jsonobject = GsonHelper.getAsJsonObject(pJson, "pack_version");
|
||||
this.resourcePackVersion = GsonHelper.getAsInt(jsonobject, "resource");
|
||||
this.dataPackVersion = GsonHelper.getAsInt(jsonobject, "data");
|
||||
this.buildTime = Date.from(ZonedDateTime.parse(GsonHelper.getAsString(pJson, "build_time")).toInstant());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance containing world version data from version.json (or fallback data if necessary).
|
||||
*
|
||||
* For getting data, use {@link SharedConstants#getCurrentVersion} instead, as that is cached.
|
||||
*/
|
||||
public static WorldVersion tryDetectVersion() {
|
||||
try (InputStream inputstream = DetectedVersion.class.getResourceAsStream("/version.json")) {
|
||||
if (inputstream == null) {
|
||||
LOGGER.warn("Missing version information!");
|
||||
return BUILT_IN;
|
||||
} else {
|
||||
try (InputStreamReader inputstreamreader = new InputStreamReader(inputstream)) {
|
||||
return new DetectedVersion(GsonHelper.parse(inputstreamreader));
|
||||
}
|
||||
}
|
||||
} catch (JsonParseException | IOException ioexception) {
|
||||
throw new IllegalStateException("Game version information is corrupt", ioexception);
|
||||
}
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public DataVersion getDataVersion() {
|
||||
return this.worldVersion;
|
||||
}
|
||||
|
||||
public int getProtocolVersion() {
|
||||
return this.protocolVersion;
|
||||
}
|
||||
|
||||
public int getPackVersion(PackType pPackType) {
|
||||
return pPackType == PackType.SERVER_DATA ? this.dataPackVersion : this.resourcePackVersion;
|
||||
}
|
||||
|
||||
public Date getBuildTime() {
|
||||
return this.buildTime;
|
||||
}
|
||||
|
||||
public boolean isStable() {
|
||||
return this.stable;
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package net.minecraft;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface FieldsAreNonnullByDefault {
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
package net.minecraft;
|
||||
|
||||
import com.mojang.serialization.DataResult;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
public class FileUtil {
|
||||
private static final Pattern COPY_COUNTER_PATTERN = Pattern.compile("(<name>.*) \\((<count>\\d*)\\)", 66);
|
||||
private static final int MAX_FILE_NAME = 255;
|
||||
private static final Pattern RESERVED_WINDOWS_FILENAMES = Pattern.compile(".*\\.|(?:COM|CLOCK\\$|CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\\..*)?", 2);
|
||||
private static final Pattern STRICT_PATH_SEGMENT_CHECK = Pattern.compile("[-._a-z0-9]+");
|
||||
|
||||
public static String findAvailableName(Path pDirPath, String pFileName, String pFileFormat) throws IOException {
|
||||
for(char c0 : SharedConstants.ILLEGAL_FILE_CHARACTERS) {
|
||||
pFileName = pFileName.replace(c0, '_');
|
||||
}
|
||||
|
||||
pFileName = pFileName.replaceAll("[./\"]", "_");
|
||||
if (RESERVED_WINDOWS_FILENAMES.matcher(pFileName).matches()) {
|
||||
pFileName = "_" + pFileName + "_";
|
||||
}
|
||||
|
||||
Matcher matcher = COPY_COUNTER_PATTERN.matcher(pFileName);
|
||||
int j = 0;
|
||||
if (matcher.matches()) {
|
||||
pFileName = matcher.group("name");
|
||||
j = Integer.parseInt(matcher.group("count"));
|
||||
}
|
||||
|
||||
if (pFileName.length() > 255 - pFileFormat.length()) {
|
||||
pFileName = pFileName.substring(0, 255 - pFileFormat.length());
|
||||
}
|
||||
|
||||
while(true) {
|
||||
String s = pFileName;
|
||||
if (j != 0) {
|
||||
String s1 = " (" + j + ")";
|
||||
int i = 255 - s1.length();
|
||||
if (pFileName.length() > i) {
|
||||
s = pFileName.substring(0, i);
|
||||
}
|
||||
|
||||
s = s + s1;
|
||||
}
|
||||
|
||||
s = s + pFileFormat;
|
||||
Path path = pDirPath.resolve(s);
|
||||
|
||||
try {
|
||||
Path path1 = Files.createDirectory(path);
|
||||
Files.deleteIfExists(path1);
|
||||
return pDirPath.relativize(path1).toString();
|
||||
} catch (FileAlreadyExistsException filealreadyexistsexception) {
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPathNormalized(Path pPath) {
|
||||
Path path = pPath.normalize();
|
||||
return path.equals(pPath);
|
||||
}
|
||||
|
||||
public static boolean isPathPortable(Path pPath) {
|
||||
for(Path path : pPath) {
|
||||
if (RESERVED_WINDOWS_FILENAMES.matcher(path.toString()).matches()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Path createPathToResource(Path pDirPath, String pLocationPath, String pFileFormat) {
|
||||
String s = pLocationPath + pFileFormat;
|
||||
Path path = Paths.get(s);
|
||||
if (path.endsWith(pFileFormat)) {
|
||||
throw new InvalidPathException(s, "empty resource name");
|
||||
} else {
|
||||
return pDirPath.resolve(path);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFullResourcePath(String pPath) {
|
||||
return FilenameUtils.getFullPath(pPath).replace(File.separator, "/");
|
||||
}
|
||||
|
||||
public static String normalizeResourcePath(String pPath) {
|
||||
return FilenameUtils.normalize(pPath).replace(File.separator, "/");
|
||||
}
|
||||
|
||||
public static DataResult<List<String>> decomposePath(String pPath) {
|
||||
int i = pPath.indexOf(47);
|
||||
if (i == -1) {
|
||||
DataResult dataresult;
|
||||
switch (pPath) {
|
||||
case "":
|
||||
case ".":
|
||||
case "..":
|
||||
dataresult = DataResult.error(() -> {
|
||||
return "Invalid path '" + pPath + "'";
|
||||
});
|
||||
break;
|
||||
default:
|
||||
dataresult = !isValidStrictPathSegment(pPath) ? DataResult.error(() -> {
|
||||
return "Invalid path '" + pPath + "'";
|
||||
}) : DataResult.success(List.of(pPath));
|
||||
}
|
||||
|
||||
return dataresult;
|
||||
} else {
|
||||
List<String> list = new ArrayList<>();
|
||||
int j = 0;
|
||||
boolean flag = false;
|
||||
|
||||
while(true) {
|
||||
String s = pPath.substring(j, i);
|
||||
switch (pPath.substring(j, i)) {
|
||||
case "":
|
||||
case ".":
|
||||
case "..":
|
||||
return DataResult.error(() -> {
|
||||
return "Invalid segment '" + s + "' in path '" + pPath + "'";
|
||||
});
|
||||
}
|
||||
|
||||
if (!isValidStrictPathSegment(s)) {
|
||||
return DataResult.error(() -> {
|
||||
return "Invalid segment '" + s + "' in path '" + pPath + "'";
|
||||
});
|
||||
}
|
||||
|
||||
list.add(s);
|
||||
if (flag) {
|
||||
return DataResult.success(list);
|
||||
}
|
||||
|
||||
j = i + 1;
|
||||
i = pPath.indexOf(47, j);
|
||||
if (i == -1) {
|
||||
i = pPath.length();
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Path resolvePath(Path pPath, List<String> p_251495_) {
|
||||
int i = p_251495_.size();
|
||||
Path path;
|
||||
switch (i) {
|
||||
case 0:
|
||||
path = pPath;
|
||||
break;
|
||||
case 1:
|
||||
path = pPath.resolve(p_251495_.get(0));
|
||||
break;
|
||||
default:
|
||||
String[] astring = new String[i - 1];
|
||||
|
||||
for(int j = 1; j < i; ++j) {
|
||||
astring[j - 1] = p_251495_.get(j);
|
||||
}
|
||||
|
||||
path = pPath.resolve(pPath.getFileSystem().getPath(p_251495_.get(0), astring));
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public static boolean isValidStrictPathSegment(String p_249814_) {
|
||||
return STRICT_PATH_SEGMENT_CHECK.matcher(p_249814_).matches();
|
||||
}
|
||||
|
||||
public static void validatePath(String... pElements) {
|
||||
if (pElements.length == 0) {
|
||||
throw new IllegalArgumentException("Path must have at least one element");
|
||||
} else {
|
||||
for(String s : pElements) {
|
||||
if (s.equals("..") || s.equals(".") || !isValidStrictPathSegment(s)) {
|
||||
throw new IllegalArgumentException("Illegal segment " + s + " in path " + Arrays.toString((Object[])pElements));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void createDirectoriesSafe(Path pPath) throws IOException {
|
||||
Files.createDirectories(Files.exists(pPath) ? pPath.toRealPath() : pPath);
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package net.minecraft;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MethodsReturnNonnullByDefault {
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package net.minecraft;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class Optionull {
|
||||
@Nullable
|
||||
public static <T, R> R map(@Nullable T pValue, Function<T, R> pMapper) {
|
||||
return (R)(pValue == null ? null : pMapper.apply(pValue));
|
||||
}
|
||||
|
||||
public static <T, R> R mapOrDefault(@Nullable T pValue, Function<T, R> pMapper, R pDefaultValue) {
|
||||
return (R)(pValue == null ? pDefaultValue : pMapper.apply(pValue));
|
||||
}
|
||||
|
||||
public static <T, R> R mapOrElse(@Nullable T pValue, Function<T, R> pMapper, Supplier<R> pSupplier) {
|
||||
return (R)(pValue == null ? pSupplier.get() : pMapper.apply(pValue));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <T> T first(Collection<T> pCollection) {
|
||||
Iterator<T> iterator = pCollection.iterator();
|
||||
return (T)(iterator.hasNext() ? iterator.next() : null);
|
||||
}
|
||||
|
||||
public static <T> T firstOrDefault(Collection<T> pCollection, T pDefaultValue) {
|
||||
Iterator<T> iterator = pCollection.iterator();
|
||||
return (T)(iterator.hasNext() ? iterator.next() : pDefaultValue);
|
||||
}
|
||||
|
||||
public static <T> T firstOrElse(Collection<T> pCollection, Supplier<T> pSupplier) {
|
||||
Iterator<T> iterator = pCollection.iterator();
|
||||
return (T)(iterator.hasNext() ? iterator.next() : pSupplier.get());
|
||||
}
|
||||
|
||||
public static <T> boolean isNullOrEmpty(@Nullable T[] pArray) {
|
||||
return pArray == null || pArray.length == 0;
|
||||
}
|
||||
|
||||
public static boolean isNullOrEmpty(@Nullable boolean[] pArray) {
|
||||
return pArray == null || pArray.length == 0;
|
||||
}
|
||||
|
||||
public static boolean isNullOrEmpty(@Nullable byte[] pArray) {
|
||||
return pArray == null || pArray.length == 0;
|
||||
}
|
||||
|
||||
public static boolean isNullOrEmpty(@Nullable char[] pArray) {
|
||||
return pArray == null || pArray.length == 0;
|
||||
}
|
||||
|
||||
public static boolean isNullOrEmpty(@Nullable short[] pArray) {
|
||||
return pArray == null || pArray.length == 0;
|
||||
}
|
||||
|
||||
public static boolean isNullOrEmpty(@Nullable int[] pArray) {
|
||||
return pArray == null || pArray.length == 0;
|
||||
}
|
||||
|
||||
public static boolean isNullOrEmpty(@Nullable long[] pArray) {
|
||||
return pArray == null || pArray.length == 0;
|
||||
}
|
||||
|
||||
public static boolean isNullOrEmpty(@Nullable float[] pArray) {
|
||||
return pArray == null || pArray.length == 0;
|
||||
}
|
||||
|
||||
public static boolean isNullOrEmpty(@Nullable double[] pArray) {
|
||||
return pArray == null || pArray.length == 0;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package net.minecraft;
|
||||
|
||||
public class ReportedException extends RuntimeException {
|
||||
private final CrashReport report;
|
||||
|
||||
public ReportedException(CrashReport pReport) {
|
||||
this.report = pReport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CrashReport wrapped by this exception.
|
||||
*/
|
||||
public CrashReport getReport() {
|
||||
return this.report;
|
||||
}
|
||||
|
||||
public Throwable getCause() {
|
||||
return this.report.getException();
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.report.getTitle();
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package net.minecraft;
|
||||
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
|
||||
public class ResourceLocationException extends RuntimeException {
|
||||
public ResourceLocationException(String pMessage) {
|
||||
super(StringEscapeUtils.escapeJava(pMessage));
|
||||
}
|
||||
|
||||
public ResourceLocationException(String pMessage, Throwable pCause) {
|
||||
super(StringEscapeUtils.escapeJava(pMessage), pCause);
|
||||
}
|
||||
}
|
||||
+376
@@ -0,0 +1,376 @@
|
||||
package net.minecraft;
|
||||
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.datafixers.DSL;
|
||||
import io.netty.util.ResourceLeakDetector;
|
||||
import io.netty.util.ResourceLeakDetector.Level;
|
||||
import java.time.Duration;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.commands.BrigadierExceptions;
|
||||
import net.minecraft.util.datafix.DataFixTypes;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
|
||||
/**
|
||||
* Shared global constants.
|
||||
*
|
||||
* <p><strong>Note:</strong> The majority of the fields within this class are {@code public static final} with constant
|
||||
* expressions (constants), and are inlined by the Java compiler at all places which reference these constant fields.
|
||||
* Therefore, changing the value of these constant fields will have no effect on already compiled code.</p>
|
||||
*
|
||||
* <p>In addition, it is presumed that a large portion of these constant fields (such as those prefixed with {@code
|
||||
* DEBUG_} are used as 'flags', for manually toggling code meant for use by Mojang developers in debugging. Therefore,
|
||||
* optimizing compilers (which include the Java compiler) may omit the code hidden behind disabled flags, and will
|
||||
* result in these flags having no apparent use in the code (when in reality, the optimizing compiler has removed the
|
||||
* code which uses them).</p>
|
||||
*
|
||||
* @see <a href="https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-15.29">The Java® Language
|
||||
* Specification, Java SE 16 Edition, § 15.29. "Constant Expressions"</a>
|
||||
* @see <a href="https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-14.22">The Java® Language
|
||||
* Specification, Java SE 16 Edition, § 14.22. "Unreachable Statements"</a>
|
||||
*/
|
||||
public class SharedConstants {
|
||||
/** @deprecated */
|
||||
/**
|
||||
* Indicates whether the currently running game version is a snapshot version.
|
||||
*
|
||||
* @see com.mojang.bridge.game.GameVersion#isStable()
|
||||
* @deprecated Use {@link #getCurrentVersion()} and {@link com.mojang.bridge.game.GameVersion#isStable()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final boolean SNAPSHOT = false;
|
||||
/** @deprecated */
|
||||
/**
|
||||
* The numeric format number for worlds used by this game version.
|
||||
*
|
||||
* @see com.mojang.bridge.game.GameVersion#getWorldVersion()
|
||||
* @deprecated Use {@link #getCurrentVersion()} and {@link com.mojang.bridge.game.GameVersion#getWorldVersion()}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int WORLD_VERSION = 3465;
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
public static final String SERIES = "main";
|
||||
/** @deprecated */
|
||||
/**
|
||||
* The human readable name of this game version.
|
||||
*
|
||||
* @see com.mojang.bridge.game.GameVersion#getName()
|
||||
* @deprecated Use {@link #getCurrentVersion()} and {@link com.mojang.bridge.game.GameVersion#getName()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String VERSION_STRING = "1.20.1";
|
||||
/** @deprecated */
|
||||
/**
|
||||
* The numeric format number for the networking protocol used by the release target of this game version.
|
||||
*
|
||||
* <p>This protocol version is used when this game version is a release version, not a {@linkplain #SNAPSHOT
|
||||
* snapshots}. For snapshots, see {@link #SNAPSHOT_NETWORK_PROTOCOL_VERSION}.</p>
|
||||
*
|
||||
* @see #getProtocolVersion()
|
||||
* @deprecated Use {@link #getProtocolVersion()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int RELEASE_NETWORK_PROTOCOL_VERSION = 763;
|
||||
/** @deprecated */
|
||||
/**
|
||||
* The numeric format number for the networking protocol used by the snapshot of this game version.
|
||||
*
|
||||
* <p>This protocol version is used when this game version is a {@linkplain #SNAPSHOT snapshot version}. For
|
||||
* releases, see {@link #RELEASE_NETWORK_PROTOCOL_VERSION}.</p>
|
||||
*
|
||||
* <p>The actual networking protocol version used in snapshot versions is the combination (bitwise OR) of this number
|
||||
* and the bit at the position marked by {@link #SNAPSHOT_PROTOCOL_BIT}.</p>
|
||||
*
|
||||
* @see #getProtocolVersion()
|
||||
* @deprecated Use {@link #getProtocolVersion()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int SNAPSHOT_NETWORK_PROTOCOL_VERSION = 142;
|
||||
public static final int SNBT_NAG_VERSION = 3437;
|
||||
/**
|
||||
* The bit in the networking protocol version for denoting {@linkplain #SNAPSHOT snapshot versions}.
|
||||
*
|
||||
* @see #SNAPSHOT_NETWORK_PROTOCOL_VERSION
|
||||
*/
|
||||
private static final int SNAPSHOT_PROTOCOL_BIT = 30;
|
||||
public static final boolean THROW_ON_TASK_FAILURE = false;
|
||||
/** @deprecated */
|
||||
/**
|
||||
* The format of the resource packs used by this game version. Resource packs contain client-side assets, such as
|
||||
* translation files, models, and textures.
|
||||
*
|
||||
* @see com.mojang.bridge.game.GameVersion#getPackVersion(com.mojang.bridge.game.PackType)
|
||||
* @deprecated Use {@link #getCurrentVersion()}, {@link
|
||||
* com.mojang.bridge.game.GameVersion#com.mojang.bridge.game.GameVersion#getPackVersion(com.mojang.bridge.game.PackType)},
|
||||
* and com.mojang.bridge.game.PackType#RESOURCE instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int RESOURCE_PACK_FORMAT = 15;
|
||||
/** @deprecated */
|
||||
/**
|
||||
* The format of the data packs used by this game version. Data packs contain server-side data such as recipes, loot
|
||||
* tables, and tags.
|
||||
*
|
||||
* @see com.mojang.bridge.game.GameVersion#getPackVersion(com.mojang.bridge.game.PackType)
|
||||
* @deprecated Use {@link #getCurrentVersion()}, {@link
|
||||
* com.mojang.bridge.game.GameVersion#com.mojang.bridge.game.GameVersion#getPackVersion(com.mojang.bridge.game.PackType)},
|
||||
* and com.mojang.bridge.game.PackType#DATA instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int DATA_PACK_FORMAT = 15;
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
public static final int LANGUAGE_FORMAT = 1;
|
||||
public static final int REPORT_FORMAT_VERSION = 1;
|
||||
/**
|
||||
* The key for the NBT tag which contains the data version of some data, for use in datafixing.
|
||||
*
|
||||
* <p>For various objects, their stored data in a {@link net.minecraft.nbt.CompoundTag} will usually contain a {@link
|
||||
* net.minecraft.nbt.IntTag} indexed with this key, which stores the data version when the data for that object was
|
||||
* written out. This is used by the datafixer system to determine which fixers needs to be applied to the data.</p>
|
||||
*
|
||||
* @see com.mojang.bridge.game.GameVersion#getWorldVersion()
|
||||
*/
|
||||
public static final String DATA_VERSION_TAG = "DataVersion";
|
||||
public static final boolean USE_NEW_RENDERSYSTEM = false;
|
||||
public static final boolean MULTITHREADED_RENDERING = false;
|
||||
public static final boolean FIX_TNT_DUPE = false;
|
||||
public static final boolean FIX_SAND_DUPE = false;
|
||||
public static final boolean USE_DEBUG_FEATURES = false;
|
||||
public static final boolean DEBUG_OPEN_INCOMPATIBLE_WORLDS = false;
|
||||
public static final boolean DEBUG_ALLOW_LOW_SIM_DISTANCE = false;
|
||||
public static final boolean DEBUG_HOTKEYS = false;
|
||||
public static final boolean DEBUG_UI_NARRATION = false;
|
||||
public static final boolean DEBUG_RENDER = false;
|
||||
public static final boolean DEBUG_PATHFINDING = false;
|
||||
public static final boolean DEBUG_WATER = false;
|
||||
public static final boolean DEBUG_HEIGHTMAP = false;
|
||||
public static final boolean DEBUG_COLLISION = false;
|
||||
public static final boolean DEBUG_SUPPORT_BLOCKS = false;
|
||||
public static final boolean DEBUG_SHAPES = false;
|
||||
public static final boolean DEBUG_NEIGHBORSUPDATE = false;
|
||||
public static final boolean DEBUG_STRUCTURES = false;
|
||||
public static final boolean DEBUG_LIGHT = false;
|
||||
public static final boolean DEBUG_SKY_LIGHT_SECTIONS = false;
|
||||
public static final boolean DEBUG_WORLDGENATTEMPT = false;
|
||||
public static final boolean DEBUG_SOLID_FACE = false;
|
||||
public static final boolean DEBUG_CHUNKS = false;
|
||||
public static final boolean DEBUG_GAME_EVENT_LISTENERS = false;
|
||||
public static final boolean DEBUG_DUMP_TEXTURE_ATLAS = false;
|
||||
public static final boolean DEBUG_DUMP_INTERPOLATED_TEXTURE_FRAMES = false;
|
||||
public static final boolean DEBUG_STRUCTURE_EDIT_MODE = false;
|
||||
public static final boolean DEBUG_SAVE_STRUCTURES_AS_SNBT = false;
|
||||
public static final boolean DEBUG_SYNCHRONOUS_GL_LOGS = false;
|
||||
public static final boolean DEBUG_VERBOSE_SERVER_EVENTS = false;
|
||||
public static final boolean DEBUG_NAMED_RUNNABLES = false;
|
||||
public static final boolean DEBUG_GOAL_SELECTOR = false;
|
||||
public static final boolean DEBUG_VILLAGE_SECTIONS = false;
|
||||
public static final boolean DEBUG_BRAIN = false;
|
||||
public static final boolean DEBUG_BEES = false;
|
||||
public static final boolean DEBUG_RAIDS = false;
|
||||
public static final boolean DEBUG_BLOCK_BREAK = false;
|
||||
public static final boolean DEBUG_RESOURCE_LOAD_TIMES = false;
|
||||
public static final boolean DEBUG_MONITOR_TICK_TIMES = false;
|
||||
public static final boolean DEBUG_KEEP_JIGSAW_BLOCKS_DURING_STRUCTURE_GEN = false;
|
||||
public static final boolean DEBUG_DONT_SAVE_WORLD = false;
|
||||
public static final boolean DEBUG_LARGE_DRIPSTONE = false;
|
||||
public static final boolean DEBUG_PACKET_SERIALIZATION = false;
|
||||
public static final boolean DEBUG_CARVERS = false;
|
||||
public static final boolean DEBUG_ORE_VEINS = false;
|
||||
public static final boolean DEBUG_SCULK_CATALYST = false;
|
||||
public static final boolean DEBUG_BYPASS_REALMS_VERSION_CHECK = false;
|
||||
public static final boolean DEBUG_SOCIAL_INTERACTIONS = false;
|
||||
public static final boolean DEBUG_VALIDATE_RESOURCE_PATH_CASE = false;
|
||||
public static final boolean DEBUG_IGNORE_LOCAL_MOB_CAP = false;
|
||||
public static final boolean DEBUG_SMALL_SPAWN = false;
|
||||
public static final boolean DEBUG_DISABLE_LIQUID_SPREADING = false;
|
||||
public static final boolean DEBUG_AQUIFERS = false;
|
||||
public static final boolean DEBUG_JFR_PROFILING_ENABLE_LEVEL_LOADING = false;
|
||||
public static boolean debugGenerateSquareTerrainWithoutNoise = false;
|
||||
public static boolean debugGenerateStripedTerrainWithoutNoise = false;
|
||||
public static final boolean DEBUG_ONLY_GENERATE_HALF_THE_WORLD = false;
|
||||
public static final boolean DEBUG_DISABLE_FLUID_GENERATION = false;
|
||||
public static final boolean DEBUG_DISABLE_AQUIFERS = false;
|
||||
public static final boolean DEBUG_DISABLE_SURFACE = false;
|
||||
public static final boolean DEBUG_DISABLE_CARVERS = false;
|
||||
public static final boolean DEBUG_DISABLE_STRUCTURES = false;
|
||||
public static final boolean DEBUG_DISABLE_FEATURES = false;
|
||||
public static final boolean DEBUG_DISABLE_ORE_VEINS = false;
|
||||
public static final boolean DEBUG_DISABLE_BLENDING = false;
|
||||
public static final boolean DEBUG_DISABLE_BELOW_ZERO_RETROGENERATION = false;
|
||||
/**
|
||||
* The default port used by Minecraft for communication between servers and clients.
|
||||
*
|
||||
* <p>This is not a registered port at the Internet Assigned Numbers Authority, and therefore may conflict with
|
||||
* existing applications. Minecraft servers may be hosted at other ports, in which case the clients must supply the
|
||||
* correct port when connecting to the server.</p>
|
||||
*
|
||||
* @see https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?&page=128
|
||||
* Internet Assigned Numbers Authority, Internet Service Name and Transport Protocol Port Number Registry
|
||||
*/
|
||||
public static final int DEFAULT_MINECRAFT_PORT = 25565;
|
||||
public static final boolean INGAME_DEBUG_OUTPUT = false;
|
||||
public static final boolean DEBUG_SUBTITLES = false;
|
||||
public static final int FAKE_MS_LATENCY = 0;
|
||||
public static final int FAKE_MS_JITTER = 0;
|
||||
public static final ResourceLeakDetector.Level NETTY_LEAK_DETECTION = Level.DISABLED;
|
||||
public static final boolean COMMAND_STACK_TRACES = false;
|
||||
public static final boolean DEBUG_WORLD_RECREATE = false;
|
||||
public static final boolean DEBUG_SHOW_SERVER_DEBUG_VALUES = false;
|
||||
public static final boolean DEBUG_STORE_CHUNK_STACKTRACES = false;
|
||||
public static final boolean DEBUG_FEATURE_COUNT = false;
|
||||
public static final boolean DEBUG_RESOURCE_GENERATION_OVERRIDE = false;
|
||||
public static final boolean DEBUG_FORCE_TELEMETRY = false;
|
||||
public static final boolean DEBUG_DONT_SEND_TELEMETRY_TO_BACKEND = false;
|
||||
public static final long MAXIMUM_TICK_TIME_NANOS = Duration.ofMillis(300L).toNanos();
|
||||
public static final boolean USE_WORKFLOWS_HOOKS = false;
|
||||
public static boolean CHECK_DATA_FIXER_SCHEMA = true;
|
||||
public static boolean IS_RUNNING_IN_IDE;
|
||||
public static Set<DSL.TypeReference> DATA_FIX_TYPES_TO_OPTIMIZE = Set.of();
|
||||
public static final int WORLD_RESOLUTION = 16;
|
||||
/** The maximum length of a chat message that can be typed by a player. */
|
||||
public static final int MAX_CHAT_LENGTH = 256;
|
||||
/** The maximum length of a command that can be typed in a command block by a player. */
|
||||
public static final int MAX_COMMAND_LENGTH = 32500;
|
||||
public static final int MAX_CHAINED_NEIGHBOR_UPDATES = 1000000;
|
||||
public static final int MAX_RENDER_DISTANCE = 32;
|
||||
/**
|
||||
* The characters which may not form part of a file's name. Used in various file processing methods to replace these
|
||||
* illegal characters with valid characters, such as the underscore "{@code _}".
|
||||
*
|
||||
* <p>This collection of characters is a subset of the forbidden characters listed in the documentation for Microsoft
|
||||
* Windows, with the addition of the backtick ({@code `}).
|
||||
*
|
||||
* @see <a href="https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file">Microsoft Corporation, "Naming
|
||||
* Files, Paths, and Namespaces", § Naming Conventions</a>
|
||||
*/
|
||||
public static final char[] ILLEGAL_FILE_CHARACTERS = new char[]{'/', '\n', '\r', '\t', '\u0000', '\f', '`', '?', '*', '\\', '<', '>', '|', '"', ':'};
|
||||
/**
|
||||
* The amount of game ticks within a real-life second.
|
||||
*
|
||||
* <p>This is not guaranteed by a running server to be an accurate measurement of real-life seconds. Heavy load on
|
||||
* the server may cause the actual tick-to-second ratio to go below this defined ratio.</p>
|
||||
*/
|
||||
public static final int TICKS_PER_SECOND = 20;
|
||||
/**
|
||||
* The amount of game ticks within a real-life minute. This is equal to {@code TICKS_PER_SECOND * 60}, and falls
|
||||
* under the same guarantees and restrictions as {@link #TICKS_PER_SECOND}.
|
||||
*
|
||||
* @see #TICKS_PER_SECOND
|
||||
*/
|
||||
public static final int TICKS_PER_MINUTE = 1200;
|
||||
/**
|
||||
* The amount of game ticks within a game day. A game day is defined as 20 real-life minutes, so this is equal to
|
||||
* {@code TICKS_PER_MINUTE * 20}. This falls under the same guarantees and restrictions as {@link #TICKS_PER_SECOND}.
|
||||
*/
|
||||
public static final int TICKS_PER_GAME_DAY = 24000;
|
||||
public static final float AVERAGE_GAME_TICKS_PER_RANDOM_TICK_PER_BLOCK = 1365.3334F;
|
||||
public static final float AVERAGE_RANDOM_TICKS_PER_BLOCK_PER_MINUTE = 0.87890625F;
|
||||
public static final float AVERAGE_RANDOM_TICKS_PER_BLOCK_PER_GAME_DAY = 17.578125F;
|
||||
public static final int WORLD_ICON_SIZE = 64;
|
||||
@Nullable
|
||||
private static WorldVersion CURRENT_VERSION;
|
||||
|
||||
/**
|
||||
* Checks if the given character is allowed to be put into chat.
|
||||
*/
|
||||
public static boolean isAllowedChatCharacter(char pCharacter) {
|
||||
return pCharacter != 167 && pCharacter >= ' ' && pCharacter != 127;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the string, keeping only characters for which {@link #isAllowedCharacter(char)} returns {@code true}.
|
||||
*
|
||||
* <p>Note that this method strips line breaks, as {@link #isAllowedCharacter(char)} returns {@code false} for
|
||||
* those.</p>
|
||||
*
|
||||
* @return a filtered version of the input string
|
||||
* @param pInput the input string
|
||||
*/
|
||||
public static String filterText(String pInput) {
|
||||
return filterText(pInput, false);
|
||||
}
|
||||
|
||||
public static String filterText(String pInput, boolean pAllowLineBreaks) {
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
|
||||
for(char c0 : pInput.toCharArray()) {
|
||||
if (isAllowedChatCharacter(c0)) {
|
||||
stringbuilder.append(c0);
|
||||
} else if (pAllowLineBreaks && c0 == '\n') {
|
||||
stringbuilder.append(c0);
|
||||
}
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the world version, failing if a different world version is already present.
|
||||
*
|
||||
* @throws IllegalStateException if a different world version has already been set previously
|
||||
* @param pVersion the world version to set
|
||||
*/
|
||||
public static void setVersion(WorldVersion pVersion) {
|
||||
if (CURRENT_VERSION == null) {
|
||||
CURRENT_VERSION = pVersion;
|
||||
} else if (pVersion != CURRENT_VERSION) {
|
||||
throw new IllegalStateException("Cannot override the current game version!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void tryDetectVersion() {
|
||||
if (CURRENT_VERSION == null) {
|
||||
CURRENT_VERSION = DetectedVersion.tryDetectVersion();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the {@link WorldVersion world version}}
|
||||
*
|
||||
* @throws IllegalStateException if a world version has not been set previously
|
||||
*/
|
||||
public static WorldVersion getCurrentVersion() {
|
||||
if (CURRENT_VERSION == null) {
|
||||
throw new IllegalStateException("Game version not set");
|
||||
} else {
|
||||
return CURRENT_VERSION;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the networking protocol version in use by this game version}
|
||||
*
|
||||
* <p>For releases, this will be equivalent to {@link #RELEASE_NETWORK_PROTOCOL_VERSION}. For snapshot versions, this
|
||||
* will be the combination (bitwise OR) of {@link #SNAPSHOT_NETWORK_PROTOCOL_VERSION} and the bit marked by {@link
|
||||
* #SNAPSHOT_PROTOCOL_BIT}.</p>
|
||||
*/
|
||||
public static int getProtocolVersion() {
|
||||
return 763;
|
||||
}
|
||||
|
||||
public static boolean debugVoidTerrain(ChunkPos pChunkPos) {
|
||||
int i = pChunkPos.getMinBlockX();
|
||||
int j = pChunkPos.getMinBlockZ();
|
||||
if (!debugGenerateSquareTerrainWithoutNoise) {
|
||||
return false;
|
||||
} else {
|
||||
return i > 8192 || i < 0 || j > 1024 || j < 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static void enableDataFixerOptimizations() {
|
||||
DATA_FIX_TYPES_TO_OPTIMIZE = DataFixTypes.TYPES_FOR_LEVEL_LIST;
|
||||
}
|
||||
|
||||
static {
|
||||
if (System.getProperty("io.netty.leakDetection.level") == null) // Forge: allow level to be manually specified
|
||||
ResourceLeakDetector.setLevel(NETTY_LEAK_DETECTION);
|
||||
CommandSyntaxException.ENABLE_COMMAND_STACK_TRACES = false;
|
||||
CommandSyntaxException.BUILT_IN_EXCEPTIONS = new BrigadierExceptions();
|
||||
}
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
package net.minecraft;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import oshi.SystemInfo;
|
||||
import oshi.hardware.CentralProcessor;
|
||||
import oshi.hardware.GlobalMemory;
|
||||
import oshi.hardware.GraphicsCard;
|
||||
import oshi.hardware.HardwareAbstractionLayer;
|
||||
import oshi.hardware.PhysicalMemory;
|
||||
import oshi.hardware.VirtualMemory;
|
||||
|
||||
public class SystemReport {
|
||||
public static final long BYTES_PER_MEBIBYTE = 1048576L;
|
||||
private static final long ONE_GIGA = 1000000000L;
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final String OPERATING_SYSTEM = System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ") version " + System.getProperty("os.version");
|
||||
private static final String JAVA_VERSION = System.getProperty("java.version") + ", " + System.getProperty("java.vendor");
|
||||
private static final String JAVA_VM_VERSION = System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor");
|
||||
private final Map<String, String> entries = Maps.newLinkedHashMap();
|
||||
|
||||
public SystemReport() {
|
||||
this.setDetail("Minecraft Version", SharedConstants.getCurrentVersion().getName());
|
||||
this.setDetail("Minecraft Version ID", SharedConstants.getCurrentVersion().getId());
|
||||
this.setDetail("Operating System", OPERATING_SYSTEM);
|
||||
this.setDetail("Java Version", JAVA_VERSION);
|
||||
this.setDetail("Java VM Version", JAVA_VM_VERSION);
|
||||
this.setDetail("Memory", () -> {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
long i = runtime.maxMemory();
|
||||
long j = runtime.totalMemory();
|
||||
long k = runtime.freeMemory();
|
||||
long l = i / 1048576L;
|
||||
long i1 = j / 1048576L;
|
||||
long j1 = k / 1048576L;
|
||||
return k + " bytes (" + j1 + " MiB) / " + j + " bytes (" + i1 + " MiB) up to " + i + " bytes (" + l + " MiB)";
|
||||
});
|
||||
this.setDetail("CPUs", () -> {
|
||||
return String.valueOf(Runtime.getRuntime().availableProcessors());
|
||||
});
|
||||
this.ignoreErrors("hardware", () -> {
|
||||
this.putHardware(new SystemInfo());
|
||||
});
|
||||
this.setDetail("JVM Flags", () -> {
|
||||
List<String> list = Util.getVmArguments().collect(Collectors.toList());
|
||||
return String.format(Locale.ROOT, "%d total; %s", list.size(), String.join(" ", list));
|
||||
});
|
||||
}
|
||||
|
||||
public void setDetail(String pIdentifier, String pValue) {
|
||||
this.entries.put(pIdentifier, pValue);
|
||||
}
|
||||
|
||||
public void setDetail(String pIdentifier, Supplier<String> pValueSupplier) {
|
||||
try {
|
||||
this.setDetail(pIdentifier, pValueSupplier.get());
|
||||
} catch (Exception exception) {
|
||||
LOGGER.warn("Failed to get system info for {}", pIdentifier, exception);
|
||||
this.setDetail(pIdentifier, "ERR");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void putHardware(SystemInfo pInfo) {
|
||||
HardwareAbstractionLayer hardwareabstractionlayer = pInfo.getHardware();
|
||||
this.ignoreErrors("processor", () -> {
|
||||
this.putProcessor(hardwareabstractionlayer.getProcessor());
|
||||
});
|
||||
this.ignoreErrors("graphics", () -> {
|
||||
this.putGraphics(hardwareabstractionlayer.getGraphicsCards());
|
||||
});
|
||||
this.ignoreErrors("memory", () -> {
|
||||
this.putMemory(hardwareabstractionlayer.getMemory());
|
||||
});
|
||||
}
|
||||
|
||||
private void ignoreErrors(String pGroupIdentifier, Runnable pExecutor) {
|
||||
try {
|
||||
pExecutor.run();
|
||||
} catch (Throwable throwable) {
|
||||
LOGGER.warn("Failed retrieving info for group {}", pGroupIdentifier, throwable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void putPhysicalMemory(List<PhysicalMemory> pMemorySlots) {
|
||||
int i = 0;
|
||||
|
||||
for(PhysicalMemory physicalmemory : pMemorySlots) {
|
||||
String s = String.format(Locale.ROOT, "Memory slot #%d ", i++);
|
||||
this.setDetail(s + "capacity (MB)", () -> {
|
||||
return String.format(Locale.ROOT, "%.2f", (float)physicalmemory.getCapacity() / 1048576.0F);
|
||||
});
|
||||
this.setDetail(s + "clockSpeed (GHz)", () -> {
|
||||
return String.format(Locale.ROOT, "%.2f", (float)physicalmemory.getClockSpeed() / 1.0E9F);
|
||||
});
|
||||
this.setDetail(s + "type", physicalmemory::getMemoryType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void putVirtualMemory(VirtualMemory pMemory) {
|
||||
this.setDetail("Virtual memory max (MB)", () -> {
|
||||
return String.format(Locale.ROOT, "%.2f", (float)pMemory.getVirtualMax() / 1048576.0F);
|
||||
});
|
||||
this.setDetail("Virtual memory used (MB)", () -> {
|
||||
return String.format(Locale.ROOT, "%.2f", (float)pMemory.getVirtualInUse() / 1048576.0F);
|
||||
});
|
||||
this.setDetail("Swap memory total (MB)", () -> {
|
||||
return String.format(Locale.ROOT, "%.2f", (float)pMemory.getSwapTotal() / 1048576.0F);
|
||||
});
|
||||
this.setDetail("Swap memory used (MB)", () -> {
|
||||
return String.format(Locale.ROOT, "%.2f", (float)pMemory.getSwapUsed() / 1048576.0F);
|
||||
});
|
||||
}
|
||||
|
||||
private void putMemory(GlobalMemory pMemory) {
|
||||
this.ignoreErrors("physical memory", () -> {
|
||||
this.putPhysicalMemory(pMemory.getPhysicalMemory());
|
||||
});
|
||||
this.ignoreErrors("virtual memory", () -> {
|
||||
this.putVirtualMemory(pMemory.getVirtualMemory());
|
||||
});
|
||||
}
|
||||
|
||||
private void putGraphics(List<GraphicsCard> pGpus) {
|
||||
int i = 0;
|
||||
|
||||
for(GraphicsCard graphicscard : pGpus) {
|
||||
String s = String.format(Locale.ROOT, "Graphics card #%d ", i++);
|
||||
this.setDetail(s + "name", graphicscard::getName);
|
||||
this.setDetail(s + "vendor", graphicscard::getVendor);
|
||||
this.setDetail(s + "VRAM (MB)", () -> {
|
||||
return String.format(Locale.ROOT, "%.2f", (float)graphicscard.getVRam() / 1048576.0F);
|
||||
});
|
||||
this.setDetail(s + "deviceId", graphicscard::getDeviceId);
|
||||
this.setDetail(s + "versionInfo", graphicscard::getVersionInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void putProcessor(CentralProcessor pCpu) {
|
||||
CentralProcessor.ProcessorIdentifier processoridentifier = pCpu.getProcessorIdentifier();
|
||||
this.setDetail("Processor Vendor", processoridentifier::getVendor);
|
||||
this.setDetail("Processor Name", processoridentifier::getName);
|
||||
this.setDetail("Identifier", processoridentifier::getIdentifier);
|
||||
this.setDetail("Microarchitecture", processoridentifier::getMicroarchitecture);
|
||||
this.setDetail("Frequency (GHz)", () -> {
|
||||
return String.format(Locale.ROOT, "%.2f", (float)processoridentifier.getVendorFreq() / 1.0E9F);
|
||||
});
|
||||
this.setDetail("Number of physical packages", () -> {
|
||||
return String.valueOf(pCpu.getPhysicalPackageCount());
|
||||
});
|
||||
this.setDetail("Number of physical CPUs", () -> {
|
||||
return String.valueOf(pCpu.getPhysicalProcessorCount());
|
||||
});
|
||||
this.setDetail("Number of logical CPUs", () -> {
|
||||
return String.valueOf(pCpu.getLogicalProcessorCount());
|
||||
});
|
||||
}
|
||||
|
||||
public void appendToCrashReportString(StringBuilder pReportAppender) {
|
||||
pReportAppender.append("-- ").append("System Details").append(" --\n");
|
||||
pReportAppender.append("Details:");
|
||||
this.entries.forEach((p_143529_, p_143530_) -> {
|
||||
pReportAppender.append("\n\t");
|
||||
pReportAppender.append(p_143529_);
|
||||
pReportAppender.append(": ");
|
||||
pReportAppender.append(p_143530_);
|
||||
});
|
||||
}
|
||||
|
||||
public String toLineSeparatedString() {
|
||||
return this.entries.entrySet().stream().map((p_143534_) -> {
|
||||
return (String)p_143534_.getKey() + ": " + (String)p_143534_.getValue();
|
||||
}).collect(Collectors.joining(System.lineSeparator()));
|
||||
}
|
||||
}
|
||||
+920
@@ -0,0 +1,920 @@
|
||||
package net.minecraft;
|
||||
|
||||
import com.google.common.base.Ticker;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.mojang.datafixers.DSL;
|
||||
import com.mojang.datafixers.DataFixUtils;
|
||||
import com.mojang.datafixers.types.Type;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import it.unimi.dsi.fastutil.Hash;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.spi.FileSystemProvider;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinWorkerThread;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.SingleKeyCache;
|
||||
import net.minecraft.util.TimeSource;
|
||||
import net.minecraft.util.datafix.DataFixers;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class Util {
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int DEFAULT_MAX_THREADS = 255;
|
||||
private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads";
|
||||
private static final AtomicInteger WORKER_COUNT = new AtomicInteger(1);
|
||||
private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main");
|
||||
private static final ExecutorService IO_POOL = makeIoExecutor();
|
||||
private static final DateTimeFormatter FILENAME_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss", Locale.ROOT);
|
||||
public static TimeSource.NanoTimeSource timeSource = System::nanoTime;
|
||||
public static final Ticker TICKER = new Ticker() {
|
||||
public long read() {
|
||||
return Util.timeSource.getAsLong();
|
||||
}
|
||||
};
|
||||
public static final UUID NIL_UUID = new UUID(0L, 0L);
|
||||
public static final FileSystemProvider ZIP_FILE_SYSTEM_PROVIDER = FileSystemProvider.installedProviders().stream().filter((p_201865_) -> {
|
||||
return p_201865_.getScheme().equalsIgnoreCase("jar");
|
||||
}).findFirst().orElseThrow(() -> {
|
||||
return new IllegalStateException("No jar file system provider found");
|
||||
});
|
||||
private static Consumer<String> thePauser = (p_201905_) -> {
|
||||
};
|
||||
|
||||
public static <K, V> Collector<Map.Entry<? extends K, ? extends V>, ?, Map<K, V>> toMap() {
|
||||
return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue);
|
||||
}
|
||||
|
||||
public static <T extends Comparable<T>> String getPropertyName(Property<T> pProperty, Object pValue) {
|
||||
return pProperty.getName((T)(pValue));
|
||||
}
|
||||
|
||||
public static String makeDescriptionId(String pType, @Nullable ResourceLocation pId) {
|
||||
return pId == null ? pType + ".unregistered_sadface" : pType + "." + pId.getNamespace() + "." + pId.getPath().replace('/', '.');
|
||||
}
|
||||
|
||||
public static long getMillis() {
|
||||
return getNanos() / 1000000L;
|
||||
}
|
||||
|
||||
public static long getNanos() {
|
||||
return timeSource.getAsLong();
|
||||
}
|
||||
|
||||
public static long getEpochMillis() {
|
||||
return Instant.now().toEpochMilli();
|
||||
}
|
||||
|
||||
public static String getFilenameFormattedDateTime() {
|
||||
return FILENAME_DATE_TIME_FORMATTER.format(ZonedDateTime.now());
|
||||
}
|
||||
|
||||
private static ExecutorService makeExecutor(String pServiceName) {
|
||||
int i = Mth.clamp(Runtime.getRuntime().availableProcessors() - 1, 1, getMaxThreads());
|
||||
ExecutorService executorservice;
|
||||
if (i <= 0) {
|
||||
executorservice = MoreExecutors.newDirectExecutorService();
|
||||
} else {
|
||||
executorservice = new ForkJoinPool(i, (p_201863_) -> {
|
||||
ForkJoinWorkerThread forkjoinworkerthread = new ForkJoinWorkerThread(p_201863_) {
|
||||
protected void onTermination(Throwable p_211561_) {
|
||||
if (p_211561_ != null) {
|
||||
Util.LOGGER.warn("{} died", this.getName(), p_211561_);
|
||||
} else {
|
||||
Util.LOGGER.debug("{} shutdown", (Object)this.getName());
|
||||
}
|
||||
|
||||
super.onTermination(p_211561_);
|
||||
}
|
||||
};
|
||||
forkjoinworkerthread.setName("Worker-" + pServiceName + "-" + WORKER_COUNT.getAndIncrement());
|
||||
return forkjoinworkerthread;
|
||||
}, Util::onThreadException, true);
|
||||
}
|
||||
|
||||
return executorservice;
|
||||
}
|
||||
|
||||
private static int getMaxThreads() {
|
||||
String s = System.getProperty("max.bg.threads");
|
||||
if (s != null) {
|
||||
try {
|
||||
int i = Integer.parseInt(s);
|
||||
if (i >= 1 && i <= 255) {
|
||||
return i;
|
||||
}
|
||||
|
||||
LOGGER.error("Wrong {} property value '{}'. Should be an integer value between 1 and {}.", "max.bg.threads", s, 255);
|
||||
} catch (NumberFormatException numberformatexception) {
|
||||
LOGGER.error("Could not parse {} property value '{}'. Should be an integer value between 1 and {}.", "max.bg.threads", s, 255);
|
||||
}
|
||||
}
|
||||
|
||||
return 255;
|
||||
}
|
||||
|
||||
// We add these inner classes to compensate for Mojang's missing inner classes and shift the anonymous class index.
|
||||
// This allows us to obfuscate subsequent anonymous inner classes correctly.
|
||||
@SuppressWarnings("unused") private static java.util.function.LongSupplier INNER_CLASS_SHIFT1 = new java.util.function.LongSupplier() { public long getAsLong() { return 0; } };
|
||||
@SuppressWarnings("unused") private static java.util.function.LongSupplier INNER_CLASS_SHIFT2 = new java.util.function.LongSupplier() { public long getAsLong() { return 0; } };
|
||||
|
||||
public static ExecutorService backgroundExecutor() {
|
||||
return BACKGROUND_EXECUTOR;
|
||||
}
|
||||
|
||||
public static ExecutorService ioPool() {
|
||||
return IO_POOL;
|
||||
}
|
||||
|
||||
public static void shutdownExecutors() {
|
||||
shutdownExecutor(BACKGROUND_EXECUTOR);
|
||||
shutdownExecutor(IO_POOL);
|
||||
}
|
||||
|
||||
private static void shutdownExecutor(ExecutorService pService) {
|
||||
pService.shutdown();
|
||||
|
||||
boolean flag;
|
||||
try {
|
||||
flag = pService.awaitTermination(3L, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException interruptedexception) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
pService.shutdownNow();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static ExecutorService makeIoExecutor() {
|
||||
return Executors.newCachedThreadPool((p_201860_) -> {
|
||||
Thread thread = new Thread(p_201860_);
|
||||
thread.setName("IO-Worker-" + WORKER_COUNT.getAndIncrement());
|
||||
thread.setUncaughtExceptionHandler(Util::onThreadException);
|
||||
return thread;
|
||||
});
|
||||
}
|
||||
|
||||
public static void throwAsRuntime(Throwable pThrowable) {
|
||||
throw pThrowable instanceof RuntimeException ? (RuntimeException)pThrowable : new RuntimeException(pThrowable);
|
||||
}
|
||||
|
||||
private static void onThreadException(Thread p_137496_, Throwable p_137497_) {
|
||||
pauseInIde(p_137497_);
|
||||
if (p_137497_ instanceof CompletionException) {
|
||||
p_137497_ = p_137497_.getCause();
|
||||
}
|
||||
|
||||
if (p_137497_ instanceof ReportedException) {
|
||||
Bootstrap.realStdoutPrintln(((ReportedException)p_137497_).getReport().getFriendlyReport());
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
LOGGER.error(String.format(Locale.ROOT, "Caught exception in thread %s", p_137496_), p_137497_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Type<?> fetchChoiceType(DSL.TypeReference pType, String pChoiceName) {
|
||||
return !SharedConstants.CHECK_DATA_FIXER_SCHEMA ? null : doFetchChoiceType(pType, pChoiceName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Type<?> doFetchChoiceType(DSL.TypeReference pType, String pChoiceName) {
|
||||
Type<?> type = null;
|
||||
|
||||
try {
|
||||
type = DataFixers.getDataFixer().getSchema(DataFixUtils.makeKey(SharedConstants.getCurrentVersion().getDataVersion().getVersion())).getChoiceType(pType, pChoiceName);
|
||||
} catch (IllegalArgumentException illegalargumentexception) {
|
||||
LOGGER.debug("No data fixer registered for {}", (Object)pChoiceName);
|
||||
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
||||
throw illegalargumentexception;
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
public static Runnable wrapThreadWithTaskName(String pName, Runnable pTask) {
|
||||
return SharedConstants.IS_RUNNING_IN_IDE ? () -> {
|
||||
Thread thread = Thread.currentThread();
|
||||
String s = thread.getName();
|
||||
thread.setName(pName);
|
||||
|
||||
try {
|
||||
pTask.run();
|
||||
} finally {
|
||||
thread.setName(s);
|
||||
}
|
||||
|
||||
} : pTask;
|
||||
}
|
||||
|
||||
public static <V> Supplier<V> wrapThreadWithTaskName(String pName, Supplier<V> pTask) {
|
||||
return SharedConstants.IS_RUNNING_IN_IDE ? () -> {
|
||||
Thread thread = Thread.currentThread();
|
||||
String s = thread.getName();
|
||||
thread.setName(pName);
|
||||
|
||||
Object object;
|
||||
try {
|
||||
object = pTask.get();
|
||||
} finally {
|
||||
thread.setName(s);
|
||||
}
|
||||
|
||||
return (V)object;
|
||||
} : pTask;
|
||||
}
|
||||
|
||||
public static Util.OS getPlatform() {
|
||||
String s = System.getProperty("os.name").toLowerCase(Locale.ROOT);
|
||||
if (s.contains("win")) {
|
||||
return Util.OS.WINDOWS;
|
||||
} else if (s.contains("mac")) {
|
||||
return Util.OS.OSX;
|
||||
} else if (s.contains("solaris")) {
|
||||
return Util.OS.SOLARIS;
|
||||
} else if (s.contains("sunos")) {
|
||||
return Util.OS.SOLARIS;
|
||||
} else if (s.contains("linux")) {
|
||||
return Util.OS.LINUX;
|
||||
} else {
|
||||
return s.contains("unix") ? Util.OS.LINUX : Util.OS.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public static Stream<String> getVmArguments() {
|
||||
RuntimeMXBean runtimemxbean = ManagementFactory.getRuntimeMXBean();
|
||||
return runtimemxbean.getInputArguments().stream().filter((p_201903_) -> {
|
||||
return p_201903_.startsWith("-X");
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> T lastOf(List<T> pList) {
|
||||
return pList.get(pList.size() - 1);
|
||||
}
|
||||
|
||||
public static <T> T findNextInIterable(Iterable<T> pIterable, @Nullable T pElement) {
|
||||
Iterator<T> iterator = pIterable.iterator();
|
||||
T t = iterator.next();
|
||||
if (pElement != null) {
|
||||
T t1 = t;
|
||||
|
||||
while(t1 != pElement) {
|
||||
if (iterator.hasNext()) {
|
||||
t1 = iterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
if (iterator.hasNext()) {
|
||||
return iterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
public static <T> T findPreviousInIterable(Iterable<T> pIterable, @Nullable T pCurrent) {
|
||||
Iterator<T> iterator = pIterable.iterator();
|
||||
|
||||
T t;
|
||||
T t1;
|
||||
for(t = null; iterator.hasNext(); t = t1) {
|
||||
t1 = iterator.next();
|
||||
if (t1 == pCurrent) {
|
||||
if (t == null) {
|
||||
t = (T)(iterator.hasNext() ? Iterators.getLast(iterator) : pCurrent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
public static <T> T make(Supplier<T> pSupplier) {
|
||||
return pSupplier.get();
|
||||
}
|
||||
|
||||
public static <T> T make(T pObject, Consumer<T> pConsumer) {
|
||||
pConsumer.accept(pObject);
|
||||
return pObject;
|
||||
}
|
||||
|
||||
public static <K> Hash.Strategy<K> identityStrategy() {
|
||||
return (Hash.Strategy<K>) Util.IdentityStrategy.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a list of futures and returns a future of list that completes when all of them succeed or any of them error,
|
||||
*/
|
||||
public static <V> CompletableFuture<List<V>> sequence(List<? extends CompletableFuture<V>> pFutures) {
|
||||
if (pFutures.isEmpty()) {
|
||||
return CompletableFuture.completedFuture(List.of());
|
||||
} else if (pFutures.size() == 1) {
|
||||
return pFutures.get(0).thenApply(List::of);
|
||||
} else {
|
||||
CompletableFuture<Void> completablefuture = CompletableFuture.allOf(pFutures.toArray(new CompletableFuture[0]));
|
||||
return completablefuture.thenApply((p_203746_) -> {
|
||||
return pFutures.stream().map(CompletableFuture::join).toList();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static <V> CompletableFuture<List<V>> sequenceFailFast(List<? extends CompletableFuture<? extends V>> pCompletableFutures) {
|
||||
CompletableFuture<List<V>> completablefuture = new CompletableFuture<>();
|
||||
return fallibleSequence(pCompletableFutures, completablefuture::completeExceptionally).applyToEither(completablefuture, Function.identity());
|
||||
}
|
||||
|
||||
public static <V> CompletableFuture<List<V>> sequenceFailFastAndCancel(List<? extends CompletableFuture<? extends V>> pCompletableFutures) {
|
||||
CompletableFuture<List<V>> completablefuture = new CompletableFuture<>();
|
||||
return fallibleSequence(pCompletableFutures, (p_274642_) -> {
|
||||
if (completablefuture.completeExceptionally(p_274642_)) {
|
||||
for(CompletableFuture<? extends V> completablefuture1 : pCompletableFutures) {
|
||||
completablefuture1.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
}).applyToEither(completablefuture, Function.identity());
|
||||
}
|
||||
|
||||
private static <V> CompletableFuture<List<V>> fallibleSequence(List<? extends CompletableFuture<? extends V>> pCompletableFutures, Consumer<Throwable> pThrowableConsumer) {
|
||||
List<V> list = Lists.newArrayListWithCapacity(pCompletableFutures.size());
|
||||
CompletableFuture<?>[] completablefuture = new CompletableFuture[pCompletableFutures.size()];
|
||||
pCompletableFutures.forEach((p_214641_) -> {
|
||||
int i = list.size();
|
||||
list.add((V)null);
|
||||
completablefuture[i] = p_214641_.whenComplete((p_214650_, p_214651_) -> {
|
||||
if (p_214651_ != null) {
|
||||
pThrowableConsumer.accept(p_214651_);
|
||||
} else {
|
||||
list.set(i, p_214650_);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
return CompletableFuture.allOf(completablefuture).thenApply((p_214626_) -> {
|
||||
return list;
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> Optional<T> ifElse(Optional<T> pOpt, Consumer<T> pConsumer, Runnable pOrElse) {
|
||||
if (pOpt.isPresent()) {
|
||||
pConsumer.accept(pOpt.get());
|
||||
} else {
|
||||
pOrElse.run();
|
||||
}
|
||||
|
||||
return pOpt;
|
||||
}
|
||||
|
||||
public static <T> Supplier<T> name(Supplier<T> p_214656_, Supplier<String> p_214657_) {
|
||||
return p_214656_;
|
||||
}
|
||||
|
||||
public static Runnable name(Runnable pRunnable, Supplier<String> pSupplier) {
|
||||
return pRunnable;
|
||||
}
|
||||
|
||||
public static void logAndPauseIfInIde(String pError) {
|
||||
LOGGER.error(pError);
|
||||
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
||||
doPause(pError);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void logAndPauseIfInIde(String pMsg, Throwable pErr) {
|
||||
LOGGER.error(pMsg, pErr);
|
||||
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
||||
doPause(pMsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static <T extends Throwable> T pauseInIde(T pThrowable) {
|
||||
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
||||
LOGGER.error("Trying to throw a fatal exception, pausing in IDE", pThrowable);
|
||||
doPause(pThrowable.getMessage());
|
||||
}
|
||||
|
||||
return pThrowable;
|
||||
}
|
||||
|
||||
public static void setPause(Consumer<String> pThePauser) {
|
||||
thePauser = pThePauser;
|
||||
}
|
||||
|
||||
private static void doPause(String pMsg) {
|
||||
Instant instant = Instant.now();
|
||||
LOGGER.warn("Did you remember to set a breakpoint here?");
|
||||
boolean flag = Duration.between(instant, Instant.now()).toMillis() > 500L;
|
||||
if (!flag) {
|
||||
thePauser.accept(pMsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String describeError(Throwable pThrowable) {
|
||||
if (pThrowable.getCause() != null) {
|
||||
return describeError(pThrowable.getCause());
|
||||
} else {
|
||||
return pThrowable.getMessage() != null ? pThrowable.getMessage() : pThrowable.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T getRandom(T[] pSelections, RandomSource pRandom) {
|
||||
return pSelections[pRandom.nextInt(pSelections.length)];
|
||||
}
|
||||
|
||||
public static int getRandom(int[] pSelections, RandomSource pRandom) {
|
||||
return pSelections[pRandom.nextInt(pSelections.length)];
|
||||
}
|
||||
|
||||
public static <T> T getRandom(List<T> pSelections, RandomSource pRandom) {
|
||||
return pSelections.get(pRandom.nextInt(pSelections.size()));
|
||||
}
|
||||
|
||||
public static <T> Optional<T> getRandomSafe(List<T> pSelections, RandomSource pRandom) {
|
||||
return pSelections.isEmpty() ? Optional.empty() : Optional.of(getRandom(pSelections, pRandom));
|
||||
}
|
||||
|
||||
private static BooleanSupplier createRenamer(final Path pFilePath, final Path pNewName) {
|
||||
return new BooleanSupplier() {
|
||||
public boolean getAsBoolean() {
|
||||
try {
|
||||
Files.move(pFilePath, pNewName);
|
||||
return true;
|
||||
} catch (IOException ioexception) {
|
||||
Util.LOGGER.error("Failed to rename", (Throwable)ioexception);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "rename " + pFilePath + " to " + pNewName;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static BooleanSupplier createDeleter(final Path pFilePath) {
|
||||
return new BooleanSupplier() {
|
||||
public boolean getAsBoolean() {
|
||||
try {
|
||||
Files.deleteIfExists(pFilePath);
|
||||
return true;
|
||||
} catch (IOException ioexception) {
|
||||
Util.LOGGER.warn("Failed to delete", (Throwable)ioexception);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "delete old " + pFilePath;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static BooleanSupplier createFileDeletedCheck(final Path pFilePath) {
|
||||
return new BooleanSupplier() {
|
||||
public boolean getAsBoolean() {
|
||||
return !Files.exists(pFilePath);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "verify that " + pFilePath + " is deleted";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static BooleanSupplier createFileCreatedCheck(final Path pFilePath) {
|
||||
return new BooleanSupplier() {
|
||||
public boolean getAsBoolean() {
|
||||
return Files.isRegularFile(pFilePath);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "verify that " + pFilePath + " is present";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean executeInSequence(BooleanSupplier... pSuppliers) {
|
||||
for(BooleanSupplier booleansupplier : pSuppliers) {
|
||||
if (!booleansupplier.getAsBoolean()) {
|
||||
LOGGER.warn("Failed to execute {}", (Object)booleansupplier);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean runWithRetries(int pMaxTries, String pActionName, BooleanSupplier... pSuppliers) {
|
||||
for(int i = 0; i < pMaxTries; ++i) {
|
||||
if (executeInSequence(pSuppliers)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LOGGER.error("Failed to {}, retrying {}/{}", pActionName, i, pMaxTries);
|
||||
}
|
||||
|
||||
LOGGER.error("Failed to {}, aborting, progress might be lost", (Object)pActionName);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void safeReplaceFile(File pCurrent, File pLatest, File pOldBackup) {
|
||||
safeReplaceFile(pCurrent.toPath(), pLatest.toPath(), pOldBackup.toPath());
|
||||
}
|
||||
|
||||
public static void safeReplaceFile(Path pCurrent, Path pLatest, Path pOldBackup) {
|
||||
safeReplaceOrMoveFile(pCurrent, pLatest, pOldBackup, false);
|
||||
}
|
||||
|
||||
public static void safeReplaceOrMoveFile(File pCurrent, File pLatest, File pOldBackup, boolean pMove) {
|
||||
safeReplaceOrMoveFile(pCurrent.toPath(), pLatest.toPath(), pOldBackup.toPath(), pMove);
|
||||
}
|
||||
|
||||
public static void safeReplaceOrMoveFile(Path pCurrent, Path pLatest, Path pOldBackup, boolean pMove) {
|
||||
int i = 10;
|
||||
if (!Files.exists(pCurrent) || runWithRetries(10, "create backup " + pOldBackup, createDeleter(pOldBackup), createRenamer(pCurrent, pOldBackup), createFileCreatedCheck(pOldBackup))) {
|
||||
if (runWithRetries(10, "remove old " + pCurrent, createDeleter(pCurrent), createFileDeletedCheck(pCurrent))) {
|
||||
if (!runWithRetries(10, "replace " + pCurrent + " with " + pLatest, createRenamer(pLatest, pCurrent), createFileCreatedCheck(pCurrent)) && !pMove) {
|
||||
runWithRetries(10, "restore " + pCurrent + " from " + pOldBackup, createRenamer(pOldBackup, pCurrent), createFileCreatedCheck(pCurrent));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int offsetByCodepoints(String pText, int pCursorPos, int pDirection) {
|
||||
int i = pText.length();
|
||||
if (pDirection >= 0) {
|
||||
for(int j = 0; pCursorPos < i && j < pDirection; ++j) {
|
||||
if (Character.isHighSurrogate(pText.charAt(pCursorPos++)) && pCursorPos < i && Character.isLowSurrogate(pText.charAt(pCursorPos))) {
|
||||
++pCursorPos;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int k = pDirection; pCursorPos > 0 && k < 0; ++k) {
|
||||
--pCursorPos;
|
||||
if (Character.isLowSurrogate(pText.charAt(pCursorPos)) && pCursorPos > 0 && Character.isHighSurrogate(pText.charAt(pCursorPos - 1))) {
|
||||
--pCursorPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pCursorPos;
|
||||
}
|
||||
|
||||
public static Consumer<String> prefix(String pPrefix, Consumer<String> pExpectedSize) {
|
||||
return (p_214645_) -> {
|
||||
pExpectedSize.accept(pPrefix + p_214645_);
|
||||
};
|
||||
}
|
||||
|
||||
public static DataResult<int[]> fixedSize(IntStream pStream, int pSize) {
|
||||
int[] aint = pStream.limit((long)(pSize + 1)).toArray();
|
||||
if (aint.length != pSize) {
|
||||
Supplier<String> supplier = () -> {
|
||||
return "Input is not a list of " + pSize + " ints";
|
||||
};
|
||||
return aint.length >= pSize ? DataResult.error(supplier, Arrays.copyOf(aint, pSize)) : DataResult.error(supplier);
|
||||
} else {
|
||||
return DataResult.success(aint);
|
||||
}
|
||||
}
|
||||
|
||||
public static DataResult<long[]> fixedSize(LongStream pStream, int pExpectedSize) {
|
||||
long[] along = pStream.limit((long)(pExpectedSize + 1)).toArray();
|
||||
if (along.length != pExpectedSize) {
|
||||
Supplier<String> supplier = () -> {
|
||||
return "Input is not a list of " + pExpectedSize + " longs";
|
||||
};
|
||||
return along.length >= pExpectedSize ? DataResult.error(supplier, Arrays.copyOf(along, pExpectedSize)) : DataResult.error(supplier);
|
||||
} else {
|
||||
return DataResult.success(along);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> DataResult<List<T>> fixedSize(List<T> pList, int pExpectedSize) {
|
||||
if (pList.size() != pExpectedSize) {
|
||||
Supplier<String> supplier = () -> {
|
||||
return "Input is not a list of " + pExpectedSize + " elements";
|
||||
};
|
||||
return pList.size() >= pExpectedSize ? DataResult.error(supplier, pList.subList(0, pExpectedSize)) : DataResult.error(supplier);
|
||||
} else {
|
||||
return DataResult.success(pList);
|
||||
}
|
||||
}
|
||||
|
||||
public static void startTimerHackThread() {
|
||||
Thread thread = new Thread("Timer hack thread") {
|
||||
public void run() {
|
||||
while(true) {
|
||||
try {
|
||||
Thread.sleep(2147483647L);
|
||||
} catch (InterruptedException interruptedexception) {
|
||||
Util.LOGGER.warn("Timer hack thread interrupted, that really should not happen");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
thread.setDaemon(true);
|
||||
thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public static void copyBetweenDirs(Path pFromDirectory, Path pToDirectory, Path pFilePath) throws IOException {
|
||||
Path path = pFromDirectory.relativize(pFilePath);
|
||||
Path path1 = pToDirectory.resolve(path);
|
||||
Files.copy(pFilePath, path1);
|
||||
}
|
||||
|
||||
public static String sanitizeName(String pFileName, CharPredicate pCharacterValidator) {
|
||||
return pFileName.toLowerCase(Locale.ROOT).chars().mapToObj((p_214666_) -> {
|
||||
return pCharacterValidator.test((char)p_214666_) ? Character.toString((char)p_214666_) : "_";
|
||||
}).collect(Collectors.joining());
|
||||
}
|
||||
|
||||
public static <K, V> SingleKeyCache<K, V> singleKeyCache(Function<K, V> pComputeValue) {
|
||||
return new SingleKeyCache<>(pComputeValue);
|
||||
}
|
||||
|
||||
public static <T, R> Function<T, R> memoize(final Function<T, R> pMemoFunction) {
|
||||
return new Function<T, R>() {
|
||||
private final Map<T, R> cache = new ConcurrentHashMap<>();
|
||||
|
||||
public R apply(T p_214691_) {
|
||||
return this.cache.computeIfAbsent(p_214691_, pMemoFunction);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "memoize/1[function=" + pMemoFunction + ", size=" + this.cache.size() + "]";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T, U, R> BiFunction<T, U, R> memoize(final BiFunction<T, U, R> pMemoBiFunction) {
|
||||
return new BiFunction<T, U, R>() {
|
||||
private final Map<Pair<T, U>, R> cache = new ConcurrentHashMap<>();
|
||||
|
||||
public R apply(T p_214700_, U p_214701_) {
|
||||
return this.cache.computeIfAbsent(Pair.of(p_214700_, p_214701_), (p_214698_) -> {
|
||||
return pMemoBiFunction.apply(p_214698_.getFirst(), p_214698_.getSecond());
|
||||
});
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "memoize/2[function=" + pMemoBiFunction + ", size=" + this.cache.size() + "]";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> List<T> toShuffledList(Stream<T> pStream, RandomSource pRandom) {
|
||||
ObjectArrayList<T> objectarraylist = pStream.collect(ObjectArrayList.toList());
|
||||
shuffle(objectarraylist, pRandom);
|
||||
return objectarraylist;
|
||||
}
|
||||
|
||||
public static IntArrayList toShuffledList(IntStream pStream, RandomSource pRandom) {
|
||||
IntArrayList intarraylist = IntArrayList.wrap(pStream.toArray());
|
||||
int i = intarraylist.size();
|
||||
|
||||
for(int j = i; j > 1; --j) {
|
||||
int k = pRandom.nextInt(j);
|
||||
intarraylist.set(j - 1, intarraylist.set(k, intarraylist.getInt(j - 1)));
|
||||
}
|
||||
|
||||
return intarraylist;
|
||||
}
|
||||
|
||||
public static <T> List<T> shuffledCopy(T[] pArray, RandomSource pRandom) {
|
||||
ObjectArrayList<T> objectarraylist = new ObjectArrayList<>(pArray);
|
||||
shuffle(objectarraylist, pRandom);
|
||||
return objectarraylist;
|
||||
}
|
||||
|
||||
public static <T> List<T> shuffledCopy(ObjectArrayList<T> pList, RandomSource pRandom) {
|
||||
ObjectArrayList<T> objectarraylist = new ObjectArrayList<>(pList);
|
||||
shuffle(objectarraylist, pRandom);
|
||||
return objectarraylist;
|
||||
}
|
||||
|
||||
public static <T> void shuffle(ObjectArrayList<T> pList, RandomSource pRandom) {
|
||||
int i = pList.size();
|
||||
|
||||
for(int j = i; j > 1; --j) {
|
||||
int k = pRandom.nextInt(j);
|
||||
pList.set(j - 1, pList.set(k, pList.get(j - 1)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static <T> CompletableFuture<T> blockUntilDone(Function<Executor, CompletableFuture<T>> p_214680_) {
|
||||
return blockUntilDone(p_214680_, CompletableFuture::isDone);
|
||||
}
|
||||
|
||||
public static <T> T blockUntilDone(Function<Executor, T> p_214653_, Predicate<T> pDonePredicate) {
|
||||
BlockingQueue<Runnable> blockingqueue = new LinkedBlockingQueue<>();
|
||||
T t = p_214653_.apply(blockingqueue::add);
|
||||
|
||||
while(!pDonePredicate.test(t)) {
|
||||
try {
|
||||
Runnable runnable = blockingqueue.poll(100L, TimeUnit.MILLISECONDS);
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
} catch (InterruptedException interruptedexception) {
|
||||
LOGGER.warn("Interrupted wait");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int i = blockingqueue.size();
|
||||
if (i > 0) {
|
||||
LOGGER.warn("Tasks left in queue: {}", (int)i);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
public static <T> ToIntFunction<T> createIndexLookup(List<T> pList) {
|
||||
return createIndexLookup(pList, Object2IntOpenHashMap::new);
|
||||
}
|
||||
|
||||
public static <T> ToIntFunction<T> createIndexLookup(List<T> pList, IntFunction<Object2IntMap<T>> p_214636_) {
|
||||
Object2IntMap<T> object2intmap = p_214636_.apply(pList.size());
|
||||
|
||||
for(int i = 0; i < pList.size(); ++i) {
|
||||
object2intmap.put(pList.get(i), i);
|
||||
}
|
||||
|
||||
return object2intmap;
|
||||
}
|
||||
|
||||
public static <T, E extends Exception> T getOrThrow(DataResult<T> pDataResult, Function<String, E> pExceptionGetter) throws E {
|
||||
Optional<DataResult.PartialResult<T>> optional = pDataResult.error();
|
||||
if (optional.isPresent()) {
|
||||
throw pExceptionGetter.apply(optional.get().message());
|
||||
} else {
|
||||
return pDataResult.result().orElseThrow();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWhitespace(int p_289004_) {
|
||||
return Character.isWhitespace(p_289004_) || Character.isSpaceChar(p_289004_);
|
||||
}
|
||||
|
||||
public static boolean isBlank(@Nullable String pString) {
|
||||
return pString != null && pString.length() != 0 ? pString.chars().allMatch(Util::isWhitespace) : true;
|
||||
}
|
||||
|
||||
static enum IdentityStrategy implements Hash.Strategy<Object> {
|
||||
INSTANCE;
|
||||
|
||||
public int hashCode(Object pObject) {
|
||||
return System.identityHashCode(pObject);
|
||||
}
|
||||
|
||||
public boolean equals(Object pThiz, Object pOther) {
|
||||
return pThiz == pOther;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum OS {
|
||||
LINUX("linux"),
|
||||
SOLARIS("solaris"),
|
||||
WINDOWS("windows") {
|
||||
protected String[] getOpenUrlArguments(URL p_137662_) {
|
||||
return new String[]{"rundll32", "url.dll,FileProtocolHandler", p_137662_.toString()};
|
||||
}
|
||||
},
|
||||
OSX("mac") {
|
||||
protected String[] getOpenUrlArguments(URL p_137667_) {
|
||||
return new String[]{"open", p_137667_.toString()};
|
||||
}
|
||||
},
|
||||
UNKNOWN("unknown");
|
||||
|
||||
private final String telemetryName;
|
||||
|
||||
OS(String pTelemetryName) {
|
||||
this.telemetryName = pTelemetryName;
|
||||
}
|
||||
|
||||
public void openUrl(URL pUrl) {
|
||||
try {
|
||||
Process process = AccessController.doPrivileged((PrivilegedExceptionAction<Process>)(() -> {
|
||||
return Runtime.getRuntime().exec(this.getOpenUrlArguments(pUrl));
|
||||
}));
|
||||
process.getInputStream().close();
|
||||
process.getErrorStream().close();
|
||||
process.getOutputStream().close();
|
||||
} catch (IOException | PrivilegedActionException privilegedactionexception) {
|
||||
Util.LOGGER.error("Couldn't open url '{}'", pUrl, privilegedactionexception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void openUri(URI pUri) {
|
||||
try {
|
||||
this.openUrl(pUri.toURL());
|
||||
} catch (MalformedURLException malformedurlexception) {
|
||||
Util.LOGGER.error("Couldn't open uri '{}'", pUri, malformedurlexception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void openFile(File pFile) {
|
||||
try {
|
||||
this.openUrl(pFile.toURI().toURL());
|
||||
} catch (MalformedURLException malformedurlexception) {
|
||||
Util.LOGGER.error("Couldn't open file '{}'", pFile, malformedurlexception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String[] getOpenUrlArguments(URL pUrl) {
|
||||
String s = pUrl.toString();
|
||||
if ("file".equals(pUrl.getProtocol())) {
|
||||
s = s.replace("file:", "file://");
|
||||
}
|
||||
|
||||
return new String[]{"xdg-open", s};
|
||||
}
|
||||
|
||||
public void openUri(String pUri) {
|
||||
try {
|
||||
this.openUrl((new URI(pUri)).toURL());
|
||||
} catch (MalformedURLException | IllegalArgumentException | URISyntaxException urisyntaxexception) {
|
||||
Util.LOGGER.error("Couldn't open uri '{}'", pUri, urisyntaxexception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String telemetryName() {
|
||||
return this.telemetryName;
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package net.minecraft;
|
||||
|
||||
import java.util.Date;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.world.level.storage.DataVersion;
|
||||
|
||||
public interface WorldVersion {
|
||||
DataVersion getDataVersion();
|
||||
|
||||
String getId();
|
||||
|
||||
String getName();
|
||||
|
||||
int getProtocolVersion();
|
||||
|
||||
int getPackVersion(PackType pPackType);
|
||||
|
||||
Date getBuildTime();
|
||||
|
||||
boolean isStable();
|
||||
}
|
||||
+466
@@ -0,0 +1,466 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.advancements.critereon.DeserializationContext;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.ComponentUtils;
|
||||
import net.minecraft.network.chat.HoverEvent;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
public class Advancement {
|
||||
@Nullable
|
||||
private final Advancement parent;
|
||||
@Nullable
|
||||
private final DisplayInfo display;
|
||||
private final AdvancementRewards rewards;
|
||||
private final ResourceLocation id;
|
||||
private final Map<String, Criterion> criteria;
|
||||
private final String[][] requirements;
|
||||
private final Set<Advancement> children = Sets.newLinkedHashSet();
|
||||
private final Component chatComponent;
|
||||
private final boolean sendsTelemetryEvent;
|
||||
|
||||
public Advancement(ResourceLocation pId, @Nullable Advancement pParent, @Nullable DisplayInfo pDisplay, AdvancementRewards pRewards, Map<String, Criterion> pCriteria, String[][] pRequirements, boolean pSendsTelemetryEvent) {
|
||||
this.id = pId;
|
||||
this.display = pDisplay;
|
||||
this.criteria = ImmutableMap.copyOf(pCriteria);
|
||||
this.parent = pParent;
|
||||
this.rewards = pRewards;
|
||||
this.requirements = pRequirements;
|
||||
this.sendsTelemetryEvent = pSendsTelemetryEvent;
|
||||
if (pParent != null) {
|
||||
pParent.addChild(this);
|
||||
}
|
||||
|
||||
if (pDisplay == null) {
|
||||
this.chatComponent = Component.literal(pId.toString());
|
||||
} else {
|
||||
Component component = pDisplay.getTitle();
|
||||
ChatFormatting chatformatting = pDisplay.getFrame().getChatColor();
|
||||
Component component1 = ComponentUtils.mergeStyles(component.copy(), Style.EMPTY.withColor(chatformatting)).append("\n").append(pDisplay.getDescription());
|
||||
Component component2 = component.copy().withStyle((p_138316_) -> {
|
||||
return p_138316_.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, component1));
|
||||
});
|
||||
this.chatComponent = ComponentUtils.wrapInSquareBrackets(component2).withStyle(chatformatting);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deconstructs this advancement into a {@link net.minecraft.advancements.Advancement#Builder}.
|
||||
*/
|
||||
public Advancement.Builder deconstruct() {
|
||||
return new Advancement.Builder(this.parent == null ? null : this.parent.getId(), this.display, this.rewards, this.criteria, this.requirements, this.sendsTelemetryEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The parent advancement to display in the advancements screen or {@code null} to signify this is a root
|
||||
* advancement.
|
||||
*/
|
||||
@Nullable
|
||||
public Advancement getParent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
public Advancement getRoot() {
|
||||
return getRoot(this);
|
||||
}
|
||||
|
||||
public static Advancement getRoot(Advancement pAdvancement) {
|
||||
Advancement advancement = pAdvancement;
|
||||
|
||||
while(true) {
|
||||
Advancement advancement1 = advancement.getParent();
|
||||
if (advancement1 == null) {
|
||||
return advancement;
|
||||
}
|
||||
|
||||
advancement = advancement1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Display information for this advancement, or {@code null} if this advancement is invisible.
|
||||
*/
|
||||
@Nullable
|
||||
public DisplayInfo getDisplay() {
|
||||
return this.display;
|
||||
}
|
||||
|
||||
public boolean sendsTelemetryEvent() {
|
||||
return this.sendsTelemetryEvent;
|
||||
}
|
||||
|
||||
public AdvancementRewards getRewards() {
|
||||
return this.rewards;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "SimpleAdvancement{id=" + this.getId() + ", parent=" + (this.parent == null ? "null" : this.parent.getId()) + ", display=" + this.display + ", rewards=" + this.rewards + ", criteria=" + this.criteria + ", requirements=" + Arrays.deepToString(this.requirements) + ", sendsTelemetryEvent=" + this.sendsTelemetryEvent + "}";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An iterable through this advancement's children.
|
||||
*/
|
||||
public Iterable<Advancement> getChildren() {
|
||||
return this.children;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A map of criteria required to complete this advancement. Keys represent the criteria names and values are
|
||||
* the {@link net.minecraft.advancements.Criterion} instances.
|
||||
*/
|
||||
public Map<String, Criterion> getCriteria() {
|
||||
return this.criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return How many requirements this advancement has.
|
||||
*/
|
||||
public int getMaxCriteraRequired() {
|
||||
return this.requirements.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the provided {@code child} as a child of this advancement.
|
||||
*/
|
||||
public void addChild(Advancement pChild) {
|
||||
this.children.add(pChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ID of this advancement.
|
||||
*/
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else if (!(pOther instanceof Advancement)) {
|
||||
return false;
|
||||
} else {
|
||||
Advancement advancement = (Advancement)pOther;
|
||||
return this.id.equals(advancement.id);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.id.hashCode();
|
||||
}
|
||||
|
||||
public String[][] getRequirements() {
|
||||
return this.requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The {@link net.minecraft.network.chat.Component} that is shown in the chat message sent after this
|
||||
* advancement is completed.
|
||||
*/
|
||||
public Component getChatComponent() {
|
||||
return this.chatComponent;
|
||||
}
|
||||
|
||||
public static class Builder implements net.minecraftforge.common.extensions.IForgeAdvancementBuilder {
|
||||
@Nullable
|
||||
private ResourceLocation parentId;
|
||||
@Nullable
|
||||
private Advancement parent;
|
||||
@Nullable
|
||||
private DisplayInfo display;
|
||||
private AdvancementRewards rewards = AdvancementRewards.EMPTY;
|
||||
private Map<String, Criterion> criteria = Maps.newLinkedHashMap();
|
||||
@Nullable
|
||||
private String[][] requirements;
|
||||
private RequirementsStrategy requirementsStrategy = RequirementsStrategy.AND;
|
||||
private final boolean sendsTelemetryEvent;
|
||||
|
||||
Builder(@Nullable ResourceLocation pParentId, @Nullable DisplayInfo pDisplay, AdvancementRewards pRewards, Map<String, Criterion> pCriteria, String[][] pRequirements, boolean pSendsTelemetryEvent) {
|
||||
this.parentId = pParentId;
|
||||
this.display = pDisplay;
|
||||
this.rewards = pRewards;
|
||||
this.criteria = pCriteria;
|
||||
this.requirements = pRequirements;
|
||||
this.sendsTelemetryEvent = pSendsTelemetryEvent;
|
||||
}
|
||||
|
||||
private Builder(boolean pSendsTelemetryEvent) {
|
||||
this.sendsTelemetryEvent = pSendsTelemetryEvent;
|
||||
}
|
||||
|
||||
public static Advancement.Builder advancement() {
|
||||
return new Advancement.Builder(true);
|
||||
}
|
||||
|
||||
public static Advancement.Builder recipeAdvancement() {
|
||||
return new Advancement.Builder(false);
|
||||
}
|
||||
|
||||
public Advancement.Builder parent(Advancement pParent) {
|
||||
this.parent = pParent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Advancement.Builder parent(ResourceLocation pParentId) {
|
||||
this.parentId = pParentId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Advancement.Builder display(ItemStack pStack, Component pTitle, Component pDescription, @Nullable ResourceLocation pBackground, FrameType pFrame, boolean pShowToast, boolean pAnnounceToChat, boolean pHidden) {
|
||||
return this.display(new DisplayInfo(pStack, pTitle, pDescription, pBackground, pFrame, pShowToast, pAnnounceToChat, pHidden));
|
||||
}
|
||||
|
||||
public Advancement.Builder display(ItemLike pItem, Component pTitle, Component pDescription, @Nullable ResourceLocation pBackground, FrameType pFrame, boolean pShowToast, boolean pAnnounceToChat, boolean pHidden) {
|
||||
return this.display(new DisplayInfo(new ItemStack(pItem.asItem()), pTitle, pDescription, pBackground, pFrame, pShowToast, pAnnounceToChat, pHidden));
|
||||
}
|
||||
|
||||
public Advancement.Builder display(DisplayInfo pDisplay) {
|
||||
this.display = pDisplay;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Advancement.Builder rewards(AdvancementRewards.Builder pRewardsBuilder) {
|
||||
return this.rewards(pRewardsBuilder.build());
|
||||
}
|
||||
|
||||
public Advancement.Builder rewards(AdvancementRewards pRewards) {
|
||||
this.rewards = pRewards;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Advancement.Builder addCriterion(String pKey, CriterionTriggerInstance pCriterion) {
|
||||
return this.addCriterion(pKey, new Criterion(pCriterion));
|
||||
}
|
||||
|
||||
public Advancement.Builder addCriterion(String pKey, Criterion pCriterion) {
|
||||
if (this.criteria.containsKey(pKey)) {
|
||||
throw new IllegalArgumentException("Duplicate criterion " + pKey);
|
||||
} else {
|
||||
this.criteria.put(pKey, pCriterion);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Advancement.Builder requirements(RequirementsStrategy pStrategy) {
|
||||
this.requirementsStrategy = pStrategy;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Advancement.Builder requirements(String[][] pRequirements) {
|
||||
this.requirements = pRequirements;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to resolve the parent of this advancement, if possible. Returns {@code true} on success.
|
||||
*/
|
||||
public boolean canBuild(Function<ResourceLocation, Advancement> pParentLookup) {
|
||||
if (this.parentId == null) {
|
||||
return true;
|
||||
} else {
|
||||
if (this.parent == null) {
|
||||
this.parent = pParentLookup.apply(this.parentId);
|
||||
}
|
||||
|
||||
return this.parent != null;
|
||||
}
|
||||
}
|
||||
|
||||
public Advancement build(ResourceLocation pId) {
|
||||
if (!this.canBuild((p_138407_) -> {
|
||||
return null;
|
||||
})) {
|
||||
throw new IllegalStateException("Tried to build incomplete advancement!");
|
||||
} else {
|
||||
if (this.requirements == null) {
|
||||
this.requirements = this.requirementsStrategy.createRequirements(this.criteria.keySet());
|
||||
}
|
||||
|
||||
return new Advancement(pId, this.parent, this.display, this.rewards, this.criteria, this.requirements, this.sendsTelemetryEvent);
|
||||
}
|
||||
}
|
||||
|
||||
public Advancement save(Consumer<Advancement> pConsumer, String pId) {
|
||||
Advancement advancement = this.build(new ResourceLocation(pId));
|
||||
pConsumer.accept(advancement);
|
||||
return advancement;
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson() {
|
||||
if (this.requirements == null) {
|
||||
this.requirements = this.requirementsStrategy.createRequirements(this.criteria.keySet());
|
||||
}
|
||||
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (this.parent != null) {
|
||||
jsonobject.addProperty("parent", this.parent.getId().toString());
|
||||
} else if (this.parentId != null) {
|
||||
jsonobject.addProperty("parent", this.parentId.toString());
|
||||
}
|
||||
|
||||
if (this.display != null) {
|
||||
jsonobject.add("display", this.display.serializeToJson());
|
||||
}
|
||||
|
||||
jsonobject.add("rewards", this.rewards.serializeToJson());
|
||||
JsonObject jsonobject1 = new JsonObject();
|
||||
|
||||
for(Map.Entry<String, Criterion> entry : this.criteria.entrySet()) {
|
||||
jsonobject1.add(entry.getKey(), entry.getValue().serializeToJson());
|
||||
}
|
||||
|
||||
jsonobject.add("criteria", jsonobject1);
|
||||
JsonArray jsonarray1 = new JsonArray();
|
||||
|
||||
for(String[] astring : this.requirements) {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
for(String s : astring) {
|
||||
jsonarray.add(s);
|
||||
}
|
||||
|
||||
jsonarray1.add(jsonarray);
|
||||
}
|
||||
|
||||
jsonobject.add("requirements", jsonarray1);
|
||||
jsonobject.addProperty("sends_telemetry_event", this.sendsTelemetryEvent);
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public void serializeToNetwork(FriendlyByteBuf pBuffer) {
|
||||
if (this.requirements == null) {
|
||||
this.requirements = this.requirementsStrategy.createRequirements(this.criteria.keySet());
|
||||
}
|
||||
|
||||
pBuffer.writeNullable(this.parentId, FriendlyByteBuf::writeResourceLocation);
|
||||
pBuffer.writeNullable(this.display, (p_214831_, p_214832_) -> {
|
||||
p_214832_.serializeToNetwork(p_214831_);
|
||||
});
|
||||
Criterion.serializeToNetwork(this.criteria, pBuffer);
|
||||
pBuffer.writeVarInt(this.requirements.length);
|
||||
|
||||
for(String[] astring : this.requirements) {
|
||||
pBuffer.writeVarInt(astring.length);
|
||||
|
||||
for(String s : astring) {
|
||||
pBuffer.writeUtf(s);
|
||||
}
|
||||
}
|
||||
|
||||
pBuffer.writeBoolean(this.sendsTelemetryEvent);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Task Advancement{parentId=" + this.parentId + ", display=" + this.display + ", rewards=" + this.rewards + ", criteria=" + this.criteria + ", requirements=" + Arrays.deepToString(this.requirements) + ", sends_telemetry_event=" + this.sendsTelemetryEvent + "}";
|
||||
}
|
||||
|
||||
/** @deprecated Forge: use {@linkplain #fromJson(JsonObject, DeserializationContext, net.minecraftforge.common.crafting.conditions.ICondition.IContext) overload with context}. */
|
||||
@Deprecated
|
||||
public static Advancement.Builder fromJson(JsonObject pJson, DeserializationContext pContext) {
|
||||
return fromJson(pJson, pContext, net.minecraftforge.common.crafting.conditions.ICondition.IContext.EMPTY);
|
||||
}
|
||||
|
||||
public static Advancement.Builder fromJson(JsonObject pJson, DeserializationContext pContext, net.minecraftforge.common.crafting.conditions.ICondition.IContext context) {
|
||||
if ((pJson = net.minecraftforge.common.crafting.ConditionalAdvancement.processConditional(pJson, context)) == null) return null;
|
||||
ResourceLocation resourcelocation = pJson.has("parent") ? new ResourceLocation(GsonHelper.getAsString(pJson, "parent")) : null;
|
||||
DisplayInfo displayinfo = pJson.has("display") ? DisplayInfo.fromJson(GsonHelper.getAsJsonObject(pJson, "display")) : null;
|
||||
AdvancementRewards advancementrewards = pJson.has("rewards") ? AdvancementRewards.deserialize(GsonHelper.getAsJsonObject(pJson, "rewards")) : AdvancementRewards.EMPTY;
|
||||
Map<String, Criterion> map = Criterion.criteriaFromJson(GsonHelper.getAsJsonObject(pJson, "criteria"), pContext);
|
||||
if (map.isEmpty()) {
|
||||
throw new JsonSyntaxException("Advancement criteria cannot be empty");
|
||||
} else {
|
||||
JsonArray jsonarray = GsonHelper.getAsJsonArray(pJson, "requirements", new JsonArray());
|
||||
String[][] astring = new String[jsonarray.size()][];
|
||||
|
||||
for(int i = 0; i < jsonarray.size(); ++i) {
|
||||
JsonArray jsonarray1 = GsonHelper.convertToJsonArray(jsonarray.get(i), "requirements[" + i + "]");
|
||||
astring[i] = new String[jsonarray1.size()];
|
||||
|
||||
for(int j = 0; j < jsonarray1.size(); ++j) {
|
||||
astring[i][j] = GsonHelper.convertToString(jsonarray1.get(j), "requirements[" + i + "][" + j + "]");
|
||||
}
|
||||
}
|
||||
|
||||
if (astring.length == 0) {
|
||||
astring = new String[map.size()][];
|
||||
int k = 0;
|
||||
|
||||
for(String s2 : map.keySet()) {
|
||||
astring[k++] = new String[]{s2};
|
||||
}
|
||||
}
|
||||
|
||||
for(String[] astring1 : astring) {
|
||||
if (astring1.length == 0 && map.isEmpty()) {
|
||||
throw new JsonSyntaxException("Requirement entry cannot be empty");
|
||||
}
|
||||
|
||||
for(String s : astring1) {
|
||||
if (!map.containsKey(s)) {
|
||||
throw new JsonSyntaxException("Unknown required criterion '" + s + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(String s1 : map.keySet()) {
|
||||
boolean flag1 = false;
|
||||
|
||||
for(String[] astring2 : astring) {
|
||||
if (ArrayUtils.contains(astring2, s1)) {
|
||||
flag1 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag1) {
|
||||
throw new JsonSyntaxException("Criterion '" + s1 + "' isn't a requirement for completion. This isn't supported behaviour, all criteria must be required.");
|
||||
}
|
||||
}
|
||||
|
||||
boolean flag = GsonHelper.getAsBoolean(pJson, "sends_telemetry_event", false);
|
||||
return new Advancement.Builder(resourcelocation, displayinfo, advancementrewards, map, astring, flag);
|
||||
}
|
||||
}
|
||||
|
||||
public static Advancement.Builder fromNetwork(FriendlyByteBuf pBuffer) {
|
||||
ResourceLocation resourcelocation = pBuffer.readNullable(FriendlyByteBuf::readResourceLocation);
|
||||
DisplayInfo displayinfo = pBuffer.readNullable(DisplayInfo::fromNetwork);
|
||||
Map<String, Criterion> map = Criterion.criteriaFromNetwork(pBuffer);
|
||||
String[][] astring = new String[pBuffer.readVarInt()][];
|
||||
|
||||
for(int i = 0; i < astring.length; ++i) {
|
||||
astring[i] = new String[pBuffer.readVarInt()];
|
||||
|
||||
for(int j = 0; j < astring[i].length; ++j) {
|
||||
astring[i][j] = pBuffer.readUtf();
|
||||
}
|
||||
}
|
||||
|
||||
boolean flag = pBuffer.readBoolean();
|
||||
return new Advancement.Builder(resourcelocation, displayinfo, AdvancementRewards.EMPTY, map, astring, flag);
|
||||
}
|
||||
|
||||
public Map<String, Criterion> getCriteria() {
|
||||
return this.criteria;
|
||||
}
|
||||
}
|
||||
}
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class AdvancementList {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final Map<ResourceLocation, Advancement> advancements = Maps.newHashMap();
|
||||
private final Set<Advancement> roots = Sets.newLinkedHashSet();
|
||||
private final Set<Advancement> tasks = Sets.newLinkedHashSet();
|
||||
@Nullable
|
||||
private AdvancementList.Listener listener;
|
||||
|
||||
private void remove(Advancement pAdvancement) {
|
||||
for(Advancement advancement : pAdvancement.getChildren()) {
|
||||
this.remove(advancement);
|
||||
}
|
||||
|
||||
LOGGER.info("Forgot about advancement {}", (Object)pAdvancement.getId());
|
||||
this.advancements.remove(pAdvancement.getId());
|
||||
if (pAdvancement.getParent() == null) {
|
||||
this.roots.remove(pAdvancement);
|
||||
if (this.listener != null) {
|
||||
this.listener.onRemoveAdvancementRoot(pAdvancement);
|
||||
}
|
||||
} else {
|
||||
this.tasks.remove(pAdvancement);
|
||||
if (this.listener != null) {
|
||||
this.listener.onRemoveAdvancementTask(pAdvancement);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void remove(Set<ResourceLocation> pIds) {
|
||||
for(ResourceLocation resourcelocation : pIds) {
|
||||
Advancement advancement = this.advancements.get(resourcelocation);
|
||||
if (advancement == null) {
|
||||
LOGGER.warn("Told to remove advancement {} but I don't know what that is", (Object)resourcelocation);
|
||||
} else {
|
||||
this.remove(advancement);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void add(Map<ResourceLocation, Advancement.Builder> pAdvancements) {
|
||||
Map<ResourceLocation, Advancement.Builder> map = Maps.newHashMap(pAdvancements);
|
||||
|
||||
while(!map.isEmpty()) {
|
||||
boolean flag = false;
|
||||
Iterator<Map.Entry<ResourceLocation, Advancement.Builder>> iterator = map.entrySet().iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
Map.Entry<ResourceLocation, Advancement.Builder> entry = iterator.next();
|
||||
ResourceLocation resourcelocation = entry.getKey();
|
||||
Advancement.Builder advancement$builder = entry.getValue();
|
||||
if (advancement$builder.canBuild(this.advancements::get)) {
|
||||
Advancement advancement = advancement$builder.build(resourcelocation);
|
||||
this.advancements.put(resourcelocation, advancement);
|
||||
flag = true;
|
||||
iterator.remove();
|
||||
if (advancement.getParent() == null) {
|
||||
this.roots.add(advancement);
|
||||
if (this.listener != null) {
|
||||
this.listener.onAddAdvancementRoot(advancement);
|
||||
}
|
||||
} else {
|
||||
this.tasks.add(advancement);
|
||||
if (this.listener != null) {
|
||||
this.listener.onAddAdvancementTask(advancement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
for(Map.Entry<ResourceLocation, Advancement.Builder> entry1 : map.entrySet()) {
|
||||
LOGGER.error("Couldn't load advancement {}: {}", entry1.getKey(), entry1.getValue());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.info("Loaded {} advancements", (int)this.advancements.size());
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.advancements.clear();
|
||||
this.roots.clear();
|
||||
this.tasks.clear();
|
||||
if (this.listener != null) {
|
||||
this.listener.onAdvancementsCleared();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Iterable<Advancement> getRoots() {
|
||||
return this.roots;
|
||||
}
|
||||
|
||||
public Collection<Advancement> getAllAdvancements() {
|
||||
return this.advancements.values();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Advancement get(ResourceLocation pId) {
|
||||
return this.advancements.get(pId);
|
||||
}
|
||||
|
||||
public void setListener(@Nullable AdvancementList.Listener pListener) {
|
||||
this.listener = pListener;
|
||||
if (pListener != null) {
|
||||
for(Advancement advancement : this.roots) {
|
||||
pListener.onAddAdvancementRoot(advancement);
|
||||
}
|
||||
|
||||
for(Advancement advancement1 : this.tasks) {
|
||||
pListener.onAddAdvancementTask(advancement1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
void onAddAdvancementRoot(Advancement pAdvancement);
|
||||
|
||||
void onRemoveAdvancementRoot(Advancement pAdvancement);
|
||||
|
||||
void onAddAdvancementTask(Advancement pAdvancement);
|
||||
|
||||
void onRemoveAdvancementTask(Advancement pAdvancement);
|
||||
|
||||
void onAdvancementsCleared();
|
||||
}
|
||||
}
|
||||
+255
@@ -0,0 +1,255 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
|
||||
public class AdvancementProgress implements Comparable<AdvancementProgress> {
|
||||
final Map<String, CriterionProgress> criteria;
|
||||
private String[][] requirements = new String[0][];
|
||||
|
||||
private AdvancementProgress(Map<String, CriterionProgress> pCriteria) {
|
||||
this.criteria = pCriteria;
|
||||
}
|
||||
|
||||
public AdvancementProgress() {
|
||||
this.criteria = Maps.newHashMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this AdvancementProgress' criteria and requirements
|
||||
*/
|
||||
public void update(Map<String, Criterion> pCriteria, String[][] pRequirements) {
|
||||
Set<String> set = pCriteria.keySet();
|
||||
this.criteria.entrySet().removeIf((p_8203_) -> {
|
||||
return !set.contains(p_8203_.getKey());
|
||||
});
|
||||
|
||||
for(String s : set) {
|
||||
if (!this.criteria.containsKey(s)) {
|
||||
this.criteria.put(s, new CriterionProgress());
|
||||
}
|
||||
}
|
||||
|
||||
this.requirements = pRequirements;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
if (this.requirements.length == 0) {
|
||||
return false;
|
||||
} else {
|
||||
for(String[] astring : this.requirements) {
|
||||
boolean flag = false;
|
||||
|
||||
for(String s : astring) {
|
||||
CriterionProgress criterionprogress = this.getCriterion(s);
|
||||
if (criterionprogress != null && criterionprogress.isDone()) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasProgress() {
|
||||
for(CriterionProgress criterionprogress : this.criteria.values()) {
|
||||
if (criterionprogress.isDone()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean grantProgress(String pCriterionName) {
|
||||
CriterionProgress criterionprogress = this.criteria.get(pCriterionName);
|
||||
if (criterionprogress != null && !criterionprogress.isDone()) {
|
||||
criterionprogress.grant();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean revokeProgress(String pCriterionName) {
|
||||
CriterionProgress criterionprogress = this.criteria.get(pCriterionName);
|
||||
if (criterionprogress != null && criterionprogress.isDone()) {
|
||||
criterionprogress.revoke();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "AdvancementProgress{criteria=" + this.criteria + ", requirements=" + Arrays.deepToString(this.requirements) + "}";
|
||||
}
|
||||
|
||||
public void serializeToNetwork(FriendlyByteBuf pBuffer) {
|
||||
pBuffer.writeMap(this.criteria, FriendlyByteBuf::writeUtf, (p_144360_, p_144361_) -> {
|
||||
p_144361_.serializeToNetwork(p_144360_);
|
||||
});
|
||||
}
|
||||
|
||||
public static AdvancementProgress fromNetwork(FriendlyByteBuf pBuffer) {
|
||||
Map<String, CriterionProgress> map = pBuffer.readMap(FriendlyByteBuf::readUtf, CriterionProgress::fromNetwork);
|
||||
return new AdvancementProgress(map);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CriterionProgress getCriterion(String pCriterionName) {
|
||||
return this.criteria.get(pCriterionName);
|
||||
}
|
||||
|
||||
public float getPercent() {
|
||||
if (this.criteria.isEmpty()) {
|
||||
return 0.0F;
|
||||
} else {
|
||||
float f = (float)this.requirements.length;
|
||||
float f1 = (float)this.countCompletedRequirements();
|
||||
return f1 / f;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getProgressText() {
|
||||
if (this.criteria.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
int i = this.requirements.length;
|
||||
if (i <= 1) {
|
||||
return null;
|
||||
} else {
|
||||
int j = this.countCompletedRequirements();
|
||||
return j + "/" + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int countCompletedRequirements() {
|
||||
int i = 0;
|
||||
|
||||
for(String[] astring : this.requirements) {
|
||||
boolean flag = false;
|
||||
|
||||
for(String s : astring) {
|
||||
CriterionProgress criterionprogress = this.getCriterion(s);
|
||||
if (criterionprogress != null && criterionprogress.isDone()) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public Iterable<String> getRemainingCriteria() {
|
||||
List<String> list = Lists.newArrayList();
|
||||
|
||||
for(Map.Entry<String, CriterionProgress> entry : this.criteria.entrySet()) {
|
||||
if (!entry.getValue().isDone()) {
|
||||
list.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public Iterable<String> getCompletedCriteria() {
|
||||
List<String> list = Lists.newArrayList();
|
||||
|
||||
for(Map.Entry<String, CriterionProgress> entry : this.criteria.entrySet()) {
|
||||
if (entry.getValue().isDone()) {
|
||||
list.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Date getFirstProgressDate() {
|
||||
Date date = null;
|
||||
|
||||
for(CriterionProgress criterionprogress : this.criteria.values()) {
|
||||
if (criterionprogress.isDone() && (date == null || criterionprogress.getObtained().before(date))) {
|
||||
date = criterionprogress.getObtained();
|
||||
}
|
||||
}
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
public int compareTo(AdvancementProgress p_8195_) {
|
||||
Date date = this.getFirstProgressDate();
|
||||
Date date1 = p_8195_.getFirstProgressDate();
|
||||
if (date == null && date1 != null) {
|
||||
return 1;
|
||||
} else if (date != null && date1 == null) {
|
||||
return -1;
|
||||
} else {
|
||||
return date == null && date1 == null ? 0 : date.compareTo(date1);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Serializer implements JsonDeserializer<AdvancementProgress>, JsonSerializer<AdvancementProgress> {
|
||||
public JsonElement serialize(AdvancementProgress pSrc, Type pTypeOfSrc, JsonSerializationContext pContext) {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
JsonObject jsonobject1 = new JsonObject();
|
||||
|
||||
for(Map.Entry<String, CriterionProgress> entry : pSrc.criteria.entrySet()) {
|
||||
CriterionProgress criterionprogress = entry.getValue();
|
||||
if (criterionprogress.isDone()) {
|
||||
jsonobject1.add(entry.getKey(), criterionprogress.serializeToJson());
|
||||
}
|
||||
}
|
||||
|
||||
if (!jsonobject1.entrySet().isEmpty()) {
|
||||
jsonobject.add("criteria", jsonobject1);
|
||||
}
|
||||
|
||||
jsonobject.addProperty("done", pSrc.isDone());
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public AdvancementProgress deserialize(JsonElement pJson, Type pTypeOfT, JsonDeserializationContext pContext) throws JsonParseException {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "advancement");
|
||||
JsonObject jsonobject1 = GsonHelper.getAsJsonObject(jsonobject, "criteria", new JsonObject());
|
||||
AdvancementProgress advancementprogress = new AdvancementProgress();
|
||||
|
||||
for(Map.Entry<String, JsonElement> entry : jsonobject1.entrySet()) {
|
||||
String s = entry.getKey();
|
||||
advancementprogress.criteria.put(s, CriterionProgress.fromJson(GsonHelper.convertToString(entry.getValue(), s)));
|
||||
}
|
||||
|
||||
return advancementprogress;
|
||||
}
|
||||
}
|
||||
}
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.commands.CommandFunction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.storage.loot.LootParams;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
|
||||
public class AdvancementRewards {
|
||||
public static final AdvancementRewards EMPTY = new AdvancementRewards(0, new ResourceLocation[0], new ResourceLocation[0], CommandFunction.CacheableFunction.NONE);
|
||||
private final int experience;
|
||||
private final ResourceLocation[] loot;
|
||||
private final ResourceLocation[] recipes;
|
||||
private final CommandFunction.CacheableFunction function;
|
||||
|
||||
public AdvancementRewards(int pExperience, ResourceLocation[] pLoot, ResourceLocation[] pRecipes, CommandFunction.CacheableFunction pFunction) {
|
||||
this.experience = pExperience;
|
||||
this.loot = pLoot;
|
||||
this.recipes = pRecipes;
|
||||
this.function = pFunction;
|
||||
}
|
||||
|
||||
public ResourceLocation[] getRecipes() {
|
||||
return this.recipes;
|
||||
}
|
||||
|
||||
public void grant(ServerPlayer pPlayer) {
|
||||
pPlayer.giveExperiencePoints(this.experience);
|
||||
LootParams lootparams = (new LootParams.Builder(pPlayer.serverLevel())).withParameter(LootContextParams.THIS_ENTITY, pPlayer).withParameter(LootContextParams.ORIGIN, pPlayer.position()).withLuck(pPlayer.getLuck()).create(LootContextParamSets.ADVANCEMENT_REWARD); // Forge: Add luck to LootContext
|
||||
boolean flag = false;
|
||||
|
||||
for(ResourceLocation resourcelocation : this.loot) {
|
||||
for(ItemStack itemstack : pPlayer.server.getLootData().getLootTable(resourcelocation).getRandomItems(lootparams)) {
|
||||
if (pPlayer.addItem(itemstack)) {
|
||||
pPlayer.level().playSound((Player)null, pPlayer.getX(), pPlayer.getY(), pPlayer.getZ(), SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, 0.2F, ((pPlayer.getRandom().nextFloat() - pPlayer.getRandom().nextFloat()) * 0.7F + 1.0F) * 2.0F);
|
||||
flag = true;
|
||||
} else {
|
||||
ItemEntity itementity = pPlayer.drop(itemstack, false);
|
||||
if (itementity != null) {
|
||||
itementity.setNoPickUpDelay();
|
||||
itementity.setTarget(pPlayer.getUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
pPlayer.containerMenu.broadcastChanges();
|
||||
}
|
||||
|
||||
if (this.recipes.length > 0) {
|
||||
pPlayer.awardRecipesByKey(this.recipes);
|
||||
}
|
||||
|
||||
MinecraftServer minecraftserver = pPlayer.server;
|
||||
this.function.get(minecraftserver.getFunctions()).ifPresent((p_289236_) -> {
|
||||
minecraftserver.getFunctions().execute(p_289236_, pPlayer.createCommandSourceStack().withSuppressedOutput().withPermission(2));
|
||||
});
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "AdvancementRewards{experience=" + this.experience + ", loot=" + Arrays.toString((Object[])this.loot) + ", recipes=" + Arrays.toString((Object[])this.recipes) + ", function=" + this.function + "}";
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == EMPTY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (this.experience != 0) {
|
||||
jsonobject.addProperty("experience", this.experience);
|
||||
}
|
||||
|
||||
if (this.loot.length > 0) {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
for(ResourceLocation resourcelocation : this.loot) {
|
||||
jsonarray.add(resourcelocation.toString());
|
||||
}
|
||||
|
||||
jsonobject.add("loot", jsonarray);
|
||||
}
|
||||
|
||||
if (this.recipes.length > 0) {
|
||||
JsonArray jsonarray1 = new JsonArray();
|
||||
|
||||
for(ResourceLocation resourcelocation1 : this.recipes) {
|
||||
jsonarray1.add(resourcelocation1.toString());
|
||||
}
|
||||
|
||||
jsonobject.add("recipes", jsonarray1);
|
||||
}
|
||||
|
||||
if (this.function.getId() != null) {
|
||||
jsonobject.addProperty("function", this.function.getId().toString());
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static AdvancementRewards deserialize(JsonObject pJson) throws JsonParseException {
|
||||
int i = GsonHelper.getAsInt(pJson, "experience", 0);
|
||||
JsonArray jsonarray = GsonHelper.getAsJsonArray(pJson, "loot", new JsonArray());
|
||||
ResourceLocation[] aresourcelocation = new ResourceLocation[jsonarray.size()];
|
||||
|
||||
for(int j = 0; j < aresourcelocation.length; ++j) {
|
||||
aresourcelocation[j] = new ResourceLocation(GsonHelper.convertToString(jsonarray.get(j), "loot[" + j + "]"));
|
||||
}
|
||||
|
||||
JsonArray jsonarray1 = GsonHelper.getAsJsonArray(pJson, "recipes", new JsonArray());
|
||||
ResourceLocation[] aresourcelocation1 = new ResourceLocation[jsonarray1.size()];
|
||||
|
||||
for(int k = 0; k < aresourcelocation1.length; ++k) {
|
||||
aresourcelocation1[k] = new ResourceLocation(GsonHelper.convertToString(jsonarray1.get(k), "recipes[" + k + "]"));
|
||||
}
|
||||
|
||||
CommandFunction.CacheableFunction commandfunction$cacheablefunction;
|
||||
if (pJson.has("function")) {
|
||||
commandfunction$cacheablefunction = new CommandFunction.CacheableFunction(new ResourceLocation(GsonHelper.getAsString(pJson, "function")));
|
||||
} else {
|
||||
commandfunction$cacheablefunction = CommandFunction.CacheableFunction.NONE;
|
||||
}
|
||||
|
||||
return new AdvancementRewards(i, aresourcelocation, aresourcelocation1, commandfunction$cacheablefunction);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private int experience;
|
||||
private final List<ResourceLocation> loot = Lists.newArrayList();
|
||||
private final List<ResourceLocation> recipes = Lists.newArrayList();
|
||||
@Nullable
|
||||
private ResourceLocation function;
|
||||
|
||||
/**
|
||||
* Creates a new builder with the given amount of experience as a reward
|
||||
*/
|
||||
public static AdvancementRewards.Builder experience(int pExperience) {
|
||||
return (new AdvancementRewards.Builder()).addExperience(pExperience);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given amount of experience. (Not a direct setter)
|
||||
*/
|
||||
public AdvancementRewards.Builder addExperience(int pExperience) {
|
||||
this.experience += pExperience;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static AdvancementRewards.Builder loot(ResourceLocation pLootTableId) {
|
||||
return (new AdvancementRewards.Builder()).addLootTable(pLootTableId);
|
||||
}
|
||||
|
||||
public AdvancementRewards.Builder addLootTable(ResourceLocation pLootTableId) {
|
||||
this.loot.add(pLootTableId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new builder with the given recipe as a reward.
|
||||
*/
|
||||
public static AdvancementRewards.Builder recipe(ResourceLocation pRecipeId) {
|
||||
return (new AdvancementRewards.Builder()).addRecipe(pRecipeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given recipe to the rewards.
|
||||
*/
|
||||
public AdvancementRewards.Builder addRecipe(ResourceLocation pRecipeId) {
|
||||
this.recipes.add(pRecipeId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static AdvancementRewards.Builder function(ResourceLocation pFunctionId) {
|
||||
return (new AdvancementRewards.Builder()).runs(pFunctionId);
|
||||
}
|
||||
|
||||
public AdvancementRewards.Builder runs(ResourceLocation pFunctionId) {
|
||||
this.function = pFunctionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AdvancementRewards build() {
|
||||
return new AdvancementRewards(this.experience, this.loot.toArray(new ResourceLocation[0]), this.recipes.toArray(new ResourceLocation[0]), this.function == null ? CommandFunction.CacheableFunction.NONE : new CommandFunction.CacheableFunction(this.function));
|
||||
}
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.advancements.critereon.BeeNestDestroyedTrigger;
|
||||
import net.minecraft.advancements.critereon.BredAnimalsTrigger;
|
||||
import net.minecraft.advancements.critereon.BrewedPotionTrigger;
|
||||
import net.minecraft.advancements.critereon.ChangeDimensionTrigger;
|
||||
import net.minecraft.advancements.critereon.ChanneledLightningTrigger;
|
||||
import net.minecraft.advancements.critereon.ConstructBeaconTrigger;
|
||||
import net.minecraft.advancements.critereon.ConsumeItemTrigger;
|
||||
import net.minecraft.advancements.critereon.CuredZombieVillagerTrigger;
|
||||
import net.minecraft.advancements.critereon.DistanceTrigger;
|
||||
import net.minecraft.advancements.critereon.EffectsChangedTrigger;
|
||||
import net.minecraft.advancements.critereon.EnchantedItemTrigger;
|
||||
import net.minecraft.advancements.critereon.EnterBlockTrigger;
|
||||
import net.minecraft.advancements.critereon.EntityHurtPlayerTrigger;
|
||||
import net.minecraft.advancements.critereon.FilledBucketTrigger;
|
||||
import net.minecraft.advancements.critereon.FishingRodHookedTrigger;
|
||||
import net.minecraft.advancements.critereon.ImpossibleTrigger;
|
||||
import net.minecraft.advancements.critereon.InventoryChangeTrigger;
|
||||
import net.minecraft.advancements.critereon.ItemDurabilityTrigger;
|
||||
import net.minecraft.advancements.critereon.ItemUsedOnLocationTrigger;
|
||||
import net.minecraft.advancements.critereon.KilledByCrossbowTrigger;
|
||||
import net.minecraft.advancements.critereon.KilledTrigger;
|
||||
import net.minecraft.advancements.critereon.LevitationTrigger;
|
||||
import net.minecraft.advancements.critereon.LightningStrikeTrigger;
|
||||
import net.minecraft.advancements.critereon.LootTableTrigger;
|
||||
import net.minecraft.advancements.critereon.PickedUpItemTrigger;
|
||||
import net.minecraft.advancements.critereon.PlayerHurtEntityTrigger;
|
||||
import net.minecraft.advancements.critereon.PlayerInteractTrigger;
|
||||
import net.minecraft.advancements.critereon.PlayerTrigger;
|
||||
import net.minecraft.advancements.critereon.RecipeCraftedTrigger;
|
||||
import net.minecraft.advancements.critereon.RecipeUnlockedTrigger;
|
||||
import net.minecraft.advancements.critereon.ShotCrossbowTrigger;
|
||||
import net.minecraft.advancements.critereon.SlideDownBlockTrigger;
|
||||
import net.minecraft.advancements.critereon.StartRidingTrigger;
|
||||
import net.minecraft.advancements.critereon.SummonedEntityTrigger;
|
||||
import net.minecraft.advancements.critereon.TameAnimalTrigger;
|
||||
import net.minecraft.advancements.critereon.TargetBlockTrigger;
|
||||
import net.minecraft.advancements.critereon.TradeTrigger;
|
||||
import net.minecraft.advancements.critereon.UsedEnderEyeTrigger;
|
||||
import net.minecraft.advancements.critereon.UsedTotemTrigger;
|
||||
import net.minecraft.advancements.critereon.UsingItemTrigger;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class CriteriaTriggers {
|
||||
private static final Map<ResourceLocation, CriterionTrigger<?>> CRITERIA = Maps.newHashMap();
|
||||
public static final ImpossibleTrigger IMPOSSIBLE = register(new ImpossibleTrigger());
|
||||
public static final KilledTrigger PLAYER_KILLED_ENTITY = register(new KilledTrigger(new ResourceLocation("player_killed_entity")));
|
||||
public static final KilledTrigger ENTITY_KILLED_PLAYER = register(new KilledTrigger(new ResourceLocation("entity_killed_player")));
|
||||
public static final EnterBlockTrigger ENTER_BLOCK = register(new EnterBlockTrigger());
|
||||
public static final InventoryChangeTrigger INVENTORY_CHANGED = register(new InventoryChangeTrigger());
|
||||
public static final RecipeUnlockedTrigger RECIPE_UNLOCKED = register(new RecipeUnlockedTrigger());
|
||||
public static final PlayerHurtEntityTrigger PLAYER_HURT_ENTITY = register(new PlayerHurtEntityTrigger());
|
||||
public static final EntityHurtPlayerTrigger ENTITY_HURT_PLAYER = register(new EntityHurtPlayerTrigger());
|
||||
public static final EnchantedItemTrigger ENCHANTED_ITEM = register(new EnchantedItemTrigger());
|
||||
public static final FilledBucketTrigger FILLED_BUCKET = register(new FilledBucketTrigger());
|
||||
public static final BrewedPotionTrigger BREWED_POTION = register(new BrewedPotionTrigger());
|
||||
public static final ConstructBeaconTrigger CONSTRUCT_BEACON = register(new ConstructBeaconTrigger());
|
||||
public static final UsedEnderEyeTrigger USED_ENDER_EYE = register(new UsedEnderEyeTrigger());
|
||||
public static final SummonedEntityTrigger SUMMONED_ENTITY = register(new SummonedEntityTrigger());
|
||||
public static final BredAnimalsTrigger BRED_ANIMALS = register(new BredAnimalsTrigger());
|
||||
public static final PlayerTrigger LOCATION = register(new PlayerTrigger(new ResourceLocation("location")));
|
||||
public static final PlayerTrigger SLEPT_IN_BED = register(new PlayerTrigger(new ResourceLocation("slept_in_bed")));
|
||||
public static final CuredZombieVillagerTrigger CURED_ZOMBIE_VILLAGER = register(new CuredZombieVillagerTrigger());
|
||||
public static final TradeTrigger TRADE = register(new TradeTrigger());
|
||||
public static final ItemDurabilityTrigger ITEM_DURABILITY_CHANGED = register(new ItemDurabilityTrigger());
|
||||
public static final LevitationTrigger LEVITATION = register(new LevitationTrigger());
|
||||
public static final ChangeDimensionTrigger CHANGED_DIMENSION = register(new ChangeDimensionTrigger());
|
||||
public static final PlayerTrigger TICK = register(new PlayerTrigger(new ResourceLocation("tick")));
|
||||
public static final TameAnimalTrigger TAME_ANIMAL = register(new TameAnimalTrigger());
|
||||
public static final ItemUsedOnLocationTrigger PLACED_BLOCK = register(new ItemUsedOnLocationTrigger(new ResourceLocation("placed_block")));
|
||||
public static final ConsumeItemTrigger CONSUME_ITEM = register(new ConsumeItemTrigger());
|
||||
public static final EffectsChangedTrigger EFFECTS_CHANGED = register(new EffectsChangedTrigger());
|
||||
public static final UsedTotemTrigger USED_TOTEM = register(new UsedTotemTrigger());
|
||||
public static final DistanceTrigger NETHER_TRAVEL = register(new DistanceTrigger(new ResourceLocation("nether_travel")));
|
||||
public static final FishingRodHookedTrigger FISHING_ROD_HOOKED = register(new FishingRodHookedTrigger());
|
||||
public static final ChanneledLightningTrigger CHANNELED_LIGHTNING = register(new ChanneledLightningTrigger());
|
||||
public static final ShotCrossbowTrigger SHOT_CROSSBOW = register(new ShotCrossbowTrigger());
|
||||
public static final KilledByCrossbowTrigger KILLED_BY_CROSSBOW = register(new KilledByCrossbowTrigger());
|
||||
public static final PlayerTrigger RAID_WIN = register(new PlayerTrigger(new ResourceLocation("hero_of_the_village")));
|
||||
public static final PlayerTrigger BAD_OMEN = register(new PlayerTrigger(new ResourceLocation("voluntary_exile")));
|
||||
public static final SlideDownBlockTrigger HONEY_BLOCK_SLIDE = register(new SlideDownBlockTrigger());
|
||||
public static final BeeNestDestroyedTrigger BEE_NEST_DESTROYED = register(new BeeNestDestroyedTrigger());
|
||||
public static final TargetBlockTrigger TARGET_BLOCK_HIT = register(new TargetBlockTrigger());
|
||||
public static final ItemUsedOnLocationTrigger ITEM_USED_ON_BLOCK = register(new ItemUsedOnLocationTrigger(new ResourceLocation("item_used_on_block")));
|
||||
public static final LootTableTrigger GENERATE_LOOT = register(new LootTableTrigger());
|
||||
public static final PickedUpItemTrigger THROWN_ITEM_PICKED_UP_BY_ENTITY = register(new PickedUpItemTrigger(new ResourceLocation("thrown_item_picked_up_by_entity")));
|
||||
public static final PickedUpItemTrigger THROWN_ITEM_PICKED_UP_BY_PLAYER = register(new PickedUpItemTrigger(new ResourceLocation("thrown_item_picked_up_by_player")));
|
||||
public static final PlayerInteractTrigger PLAYER_INTERACTED_WITH_ENTITY = register(new PlayerInteractTrigger());
|
||||
public static final StartRidingTrigger START_RIDING_TRIGGER = register(new StartRidingTrigger());
|
||||
public static final LightningStrikeTrigger LIGHTNING_STRIKE = register(new LightningStrikeTrigger());
|
||||
public static final UsingItemTrigger USING_ITEM = register(new UsingItemTrigger());
|
||||
public static final DistanceTrigger FALL_FROM_HEIGHT = register(new DistanceTrigger(new ResourceLocation("fall_from_height")));
|
||||
public static final DistanceTrigger RIDE_ENTITY_IN_LAVA_TRIGGER = register(new DistanceTrigger(new ResourceLocation("ride_entity_in_lava")));
|
||||
public static final KilledTrigger KILL_MOB_NEAR_SCULK_CATALYST = register(new KilledTrigger(new ResourceLocation("kill_mob_near_sculk_catalyst")));
|
||||
public static final ItemUsedOnLocationTrigger ALLAY_DROP_ITEM_ON_BLOCK = register(new ItemUsedOnLocationTrigger(new ResourceLocation("allay_drop_item_on_block")));
|
||||
public static final PlayerTrigger AVOID_VIBRATION = register(new PlayerTrigger(new ResourceLocation("avoid_vibration")));
|
||||
public static final RecipeCraftedTrigger RECIPE_CRAFTED = register(new RecipeCraftedTrigger());
|
||||
|
||||
public static <T extends CriterionTrigger<?>> T register(T pCriterion) {
|
||||
if (CRITERIA.containsKey(pCriterion.getId())) {
|
||||
throw new IllegalArgumentException("Duplicate criterion id " + pCriterion.getId());
|
||||
} else {
|
||||
CRITERIA.put(pCriterion.getId(), pCriterion);
|
||||
return pCriterion;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <T extends CriterionTriggerInstance> CriterionTrigger<T> getCriterion(ResourceLocation pId) {
|
||||
return (CriterionTrigger<T>)CRITERIA.get(pId);
|
||||
}
|
||||
|
||||
public static Iterable<? extends CriterionTrigger<?>> all() {
|
||||
return CRITERIA.values();
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.advancements.critereon.DeserializationContext;
|
||||
import net.minecraft.advancements.critereon.SerializationContext;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
|
||||
public class Criterion {
|
||||
@Nullable
|
||||
private final CriterionTriggerInstance trigger;
|
||||
|
||||
public Criterion(CriterionTriggerInstance pTrigger) {
|
||||
this.trigger = pTrigger;
|
||||
}
|
||||
|
||||
public Criterion() {
|
||||
this.trigger = null;
|
||||
}
|
||||
|
||||
public void serializeToNetwork(FriendlyByteBuf pBuffer) {
|
||||
}
|
||||
|
||||
public static Criterion criterionFromJson(JsonObject pJson, DeserializationContext pContext) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(pJson, "trigger"));
|
||||
CriterionTrigger<?> criteriontrigger = CriteriaTriggers.getCriterion(resourcelocation);
|
||||
if (criteriontrigger == null) {
|
||||
throw new JsonSyntaxException("Invalid criterion trigger: " + resourcelocation);
|
||||
} else {
|
||||
CriterionTriggerInstance criteriontriggerinstance = criteriontrigger.createInstance(GsonHelper.getAsJsonObject(pJson, "conditions", new JsonObject()), pContext);
|
||||
return new Criterion(criteriontriggerinstance);
|
||||
}
|
||||
}
|
||||
|
||||
public static Criterion criterionFromNetwork(FriendlyByteBuf p_11430_) {
|
||||
return new Criterion();
|
||||
}
|
||||
|
||||
public static Map<String, Criterion> criteriaFromJson(JsonObject pJson, DeserializationContext pContext) {
|
||||
Map<String, Criterion> map = Maps.newHashMap();
|
||||
|
||||
for(Map.Entry<String, JsonElement> entry : pJson.entrySet()) {
|
||||
map.put(entry.getKey(), criterionFromJson(GsonHelper.convertToJsonObject(entry.getValue(), "criterion"), pContext));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Map<String, Criterion> criteriaFromNetwork(FriendlyByteBuf pBuffer) {
|
||||
return pBuffer.readMap(FriendlyByteBuf::readUtf, Criterion::criterionFromNetwork);
|
||||
}
|
||||
|
||||
public static void serializeToNetwork(Map<String, Criterion> pCriteria, FriendlyByteBuf pBuffer) {
|
||||
pBuffer.writeMap(pCriteria, FriendlyByteBuf::writeUtf, (p_145258_, p_145259_) -> {
|
||||
p_145259_.serializeToNetwork(p_145258_);
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CriterionTriggerInstance getTrigger() {
|
||||
return this.trigger;
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this.trigger == null) {
|
||||
throw new JsonSyntaxException("Missing trigger");
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.addProperty("trigger", this.trigger.getCriterion().toString());
|
||||
JsonObject jsonobject1 = this.trigger.serializeToJson(SerializationContext.INSTANCE);
|
||||
if (jsonobject1.size() != 0) {
|
||||
jsonobject.add("conditions", jsonobject1);
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
|
||||
public class CriterionProgress {
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.ROOT);
|
||||
@Nullable
|
||||
private Date obtained;
|
||||
|
||||
public boolean isDone() {
|
||||
return this.obtained != null;
|
||||
}
|
||||
|
||||
public void grant() {
|
||||
this.obtained = new Date();
|
||||
}
|
||||
|
||||
public void revoke() {
|
||||
this.obtained = null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Date getObtained() {
|
||||
return this.obtained;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "CriterionProgress{obtained=" + (this.obtained == null ? "false" : this.obtained) + "}";
|
||||
}
|
||||
|
||||
public void serializeToNetwork(FriendlyByteBuf pBuffer) {
|
||||
pBuffer.writeNullable(this.obtained, FriendlyByteBuf::writeDate);
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
return (JsonElement)(this.obtained != null ? new JsonPrimitive(DATE_FORMAT.format(this.obtained)) : JsonNull.INSTANCE);
|
||||
}
|
||||
|
||||
public static CriterionProgress fromNetwork(FriendlyByteBuf pBuffer) {
|
||||
CriterionProgress criterionprogress = new CriterionProgress();
|
||||
criterionprogress.obtained = pBuffer.readNullable(FriendlyByteBuf::readDate);
|
||||
return criterionprogress;
|
||||
}
|
||||
|
||||
public static CriterionProgress fromJson(String pDateTime) {
|
||||
CriterionProgress criterionprogress = new CriterionProgress();
|
||||
|
||||
try {
|
||||
criterionprogress.obtained = DATE_FORMAT.parse(pDateTime);
|
||||
return criterionprogress;
|
||||
} catch (ParseException parseexception) {
|
||||
throw new JsonSyntaxException("Invalid datetime: " + pDateTime, parseexception);
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.advancements.critereon.DeserializationContext;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.PlayerAdvancements;
|
||||
|
||||
public interface CriterionTrigger<T extends CriterionTriggerInstance> {
|
||||
ResourceLocation getId();
|
||||
|
||||
void addPlayerListener(PlayerAdvancements pPlayerAdvancements, CriterionTrigger.Listener<T> pListener);
|
||||
|
||||
void removePlayerListener(PlayerAdvancements pPlayerAdvancements, CriterionTrigger.Listener<T> pListener);
|
||||
|
||||
void removePlayerListeners(PlayerAdvancements pPlayerAdvancements);
|
||||
|
||||
T createInstance(JsonObject pJson, DeserializationContext pContext);
|
||||
|
||||
public static class Listener<T extends CriterionTriggerInstance> {
|
||||
private final T trigger;
|
||||
private final Advancement advancement;
|
||||
private final String criterion;
|
||||
|
||||
public Listener(T pTrigger, Advancement pAdvancement, String pCriterion) {
|
||||
this.trigger = pTrigger;
|
||||
this.advancement = pAdvancement;
|
||||
this.criterion = pCriterion;
|
||||
}
|
||||
|
||||
public T getTriggerInstance() {
|
||||
return this.trigger;
|
||||
}
|
||||
|
||||
public void run(PlayerAdvancements pPlayerAdvancements) {
|
||||
pPlayerAdvancements.award(this.advancement, this.criterion);
|
||||
}
|
||||
|
||||
public boolean equals(Object pOther) {
|
||||
if (this == pOther) {
|
||||
return true;
|
||||
} else if (pOther != null && this.getClass() == pOther.getClass()) {
|
||||
CriterionTrigger.Listener<?> listener = (CriterionTrigger.Listener)pOther;
|
||||
if (!this.trigger.equals(listener.trigger)) {
|
||||
return false;
|
||||
} else {
|
||||
return !this.advancement.equals(listener.advancement) ? false : this.criterion.equals(listener.criterion);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int i = this.trigger.hashCode();
|
||||
i = 31 * i + this.advancement.hashCode();
|
||||
return 31 * i + this.criterion.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.advancements.critereon.SerializationContext;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public interface CriterionTriggerInstance {
|
||||
ResourceLocation getCriterion();
|
||||
|
||||
JsonObject serializeToJson(SerializationContext pContext);
|
||||
}
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class DisplayInfo {
|
||||
private final Component title;
|
||||
private final Component description;
|
||||
private final ItemStack icon;
|
||||
@Nullable
|
||||
private final ResourceLocation background;
|
||||
private final FrameType frame;
|
||||
private final boolean showToast;
|
||||
private final boolean announceChat;
|
||||
private final boolean hidden;
|
||||
private float x;
|
||||
private float y;
|
||||
|
||||
public DisplayInfo(ItemStack pIcon, Component pTitle, Component pDescription, @Nullable ResourceLocation pBackground, FrameType pFrame, boolean pShowToast, boolean pAnnounceChat, boolean pHidden) {
|
||||
this.title = pTitle;
|
||||
this.description = pDescription;
|
||||
this.icon = pIcon;
|
||||
this.background = pBackground;
|
||||
this.frame = pFrame;
|
||||
this.showToast = pShowToast;
|
||||
this.announceChat = pAnnounceChat;
|
||||
this.hidden = pHidden;
|
||||
}
|
||||
|
||||
public void setLocation(float pX, float pY) {
|
||||
this.x = pX;
|
||||
this.y = pY;
|
||||
}
|
||||
|
||||
public Component getTitle() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
public Component getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public ItemStack getIcon() {
|
||||
return this.icon;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ResourceLocation getBackground() {
|
||||
return this.background;
|
||||
}
|
||||
|
||||
public FrameType getFrame() {
|
||||
return this.frame;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public boolean shouldShowToast() {
|
||||
return this.showToast;
|
||||
}
|
||||
|
||||
public boolean shouldAnnounceChat() {
|
||||
return this.announceChat;
|
||||
}
|
||||
|
||||
public boolean isHidden() {
|
||||
return this.hidden;
|
||||
}
|
||||
|
||||
public static DisplayInfo fromJson(JsonObject pJson) {
|
||||
Component component = Component.Serializer.fromJson(pJson.get("title"));
|
||||
Component component1 = Component.Serializer.fromJson(pJson.get("description"));
|
||||
if (component != null && component1 != null) {
|
||||
ItemStack itemstack = getIcon(GsonHelper.getAsJsonObject(pJson, "icon"));
|
||||
ResourceLocation resourcelocation = pJson.has("background") ? new ResourceLocation(GsonHelper.getAsString(pJson, "background")) : null;
|
||||
FrameType frametype = pJson.has("frame") ? FrameType.byName(GsonHelper.getAsString(pJson, "frame")) : FrameType.TASK;
|
||||
boolean flag = GsonHelper.getAsBoolean(pJson, "show_toast", true);
|
||||
boolean flag1 = GsonHelper.getAsBoolean(pJson, "announce_to_chat", true);
|
||||
boolean flag2 = GsonHelper.getAsBoolean(pJson, "hidden", false);
|
||||
return new DisplayInfo(itemstack, component, component1, resourcelocation, frametype, flag, flag1, flag2);
|
||||
} else {
|
||||
throw new JsonSyntaxException("Both title and description must be set");
|
||||
}
|
||||
}
|
||||
|
||||
private static ItemStack getIcon(JsonObject pJson) {
|
||||
if (!pJson.has("item")) {
|
||||
throw new JsonSyntaxException("Unsupported icon type, currently only items are supported (add 'item' key)");
|
||||
} else {
|
||||
Item item = GsonHelper.getAsItem(pJson, "item");
|
||||
if (pJson.has("data")) {
|
||||
throw new JsonParseException("Disallowed data tag found");
|
||||
} else {
|
||||
ItemStack itemstack = new ItemStack(item);
|
||||
if (pJson.has("nbt")) {
|
||||
try {
|
||||
CompoundTag compoundtag = TagParser.parseTag(GsonHelper.convertToString(pJson.get("nbt"), "nbt"));
|
||||
itemstack.setTag(compoundtag);
|
||||
} catch (CommandSyntaxException commandsyntaxexception) {
|
||||
throw new JsonSyntaxException("Invalid nbt tag: " + commandsyntaxexception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return itemstack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void serializeToNetwork(FriendlyByteBuf pBuffer) {
|
||||
pBuffer.writeComponent(this.title);
|
||||
pBuffer.writeComponent(this.description);
|
||||
pBuffer.writeItem(this.icon);
|
||||
pBuffer.writeEnum(this.frame);
|
||||
int i = 0;
|
||||
if (this.background != null) {
|
||||
i |= 1;
|
||||
}
|
||||
|
||||
if (this.showToast) {
|
||||
i |= 2;
|
||||
}
|
||||
|
||||
if (this.hidden) {
|
||||
i |= 4;
|
||||
}
|
||||
|
||||
pBuffer.writeInt(i);
|
||||
if (this.background != null) {
|
||||
pBuffer.writeResourceLocation(this.background);
|
||||
}
|
||||
|
||||
pBuffer.writeFloat(this.x);
|
||||
pBuffer.writeFloat(this.y);
|
||||
}
|
||||
|
||||
public static DisplayInfo fromNetwork(FriendlyByteBuf pBuffer) {
|
||||
Component component = pBuffer.readComponent();
|
||||
Component component1 = pBuffer.readComponent();
|
||||
ItemStack itemstack = pBuffer.readItem();
|
||||
FrameType frametype = pBuffer.readEnum(FrameType.class);
|
||||
int i = pBuffer.readInt();
|
||||
ResourceLocation resourcelocation = (i & 1) != 0 ? pBuffer.readResourceLocation() : null;
|
||||
boolean flag = (i & 2) != 0;
|
||||
boolean flag1 = (i & 4) != 0;
|
||||
DisplayInfo displayinfo = new DisplayInfo(itemstack, component, component1, resourcelocation, frametype, flag, false, flag1);
|
||||
displayinfo.setLocation(pBuffer.readFloat(), pBuffer.readFloat());
|
||||
return displayinfo;
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("icon", this.serializeIcon());
|
||||
jsonobject.add("title", Component.Serializer.toJsonTree(this.title));
|
||||
jsonobject.add("description", Component.Serializer.toJsonTree(this.description));
|
||||
jsonobject.addProperty("frame", this.frame.getName());
|
||||
jsonobject.addProperty("show_toast", this.showToast);
|
||||
jsonobject.addProperty("announce_to_chat", this.announceChat);
|
||||
jsonobject.addProperty("hidden", this.hidden);
|
||||
if (this.background != null) {
|
||||
jsonobject.addProperty("background", this.background.toString());
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
private JsonObject serializeIcon() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.addProperty("item", BuiltInRegistries.ITEM.getKey(this.icon.getItem()).toString());
|
||||
if (this.icon.hasTag()) {
|
||||
jsonobject.addProperty("nbt", this.icon.getTag().toString());
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public enum FrameType {
|
||||
TASK("task", 0, ChatFormatting.GREEN),
|
||||
CHALLENGE("challenge", 26, ChatFormatting.DARK_PURPLE),
|
||||
GOAL("goal", 52, ChatFormatting.GREEN);
|
||||
|
||||
private final String name;
|
||||
private final int texture;
|
||||
private final ChatFormatting chatColor;
|
||||
private final Component displayName;
|
||||
|
||||
private FrameType(String pName, int pTexture, ChatFormatting pChatColor) {
|
||||
this.name = pName;
|
||||
this.texture = pTexture;
|
||||
this.chatColor = pChatColor;
|
||||
this.displayName = Component.translatable("advancements.toast." + pName);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int getTexture() {
|
||||
return this.texture;
|
||||
}
|
||||
|
||||
public static FrameType byName(String pName) {
|
||||
for(FrameType frametype : values()) {
|
||||
if (frametype.name.equals(pName)) {
|
||||
return frametype;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown frame type '" + pName + "'");
|
||||
}
|
||||
|
||||
public ChatFormatting getChatColor() {
|
||||
return this.chatColor;
|
||||
}
|
||||
|
||||
public Component getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface RequirementsStrategy {
|
||||
RequirementsStrategy AND = (p_15984_) -> {
|
||||
String[][] astring = new String[p_15984_.size()][];
|
||||
int i = 0;
|
||||
|
||||
for(String s : p_15984_) {
|
||||
astring[i++] = new String[]{s};
|
||||
}
|
||||
|
||||
return astring;
|
||||
};
|
||||
RequirementsStrategy OR = (p_15982_) -> {
|
||||
return new String[][]{p_15982_.toArray(new String[0])};
|
||||
};
|
||||
|
||||
String[][] createRequirements(Collection<String> pRequirements);
|
||||
}
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
package net.minecraft.advancements;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class TreeNodePosition {
|
||||
private final Advancement advancement;
|
||||
@Nullable
|
||||
private final TreeNodePosition parent;
|
||||
@Nullable
|
||||
private final TreeNodePosition previousSibling;
|
||||
private final int childIndex;
|
||||
private final List<TreeNodePosition> children = Lists.newArrayList();
|
||||
private TreeNodePosition ancestor;
|
||||
@Nullable
|
||||
private TreeNodePosition thread;
|
||||
private int x;
|
||||
private float y;
|
||||
private float mod;
|
||||
private float change;
|
||||
private float shift;
|
||||
|
||||
public TreeNodePosition(Advancement pAdvancement, @Nullable TreeNodePosition pParent, @Nullable TreeNodePosition pPreviousSibling, int pChildIndex, int pX) {
|
||||
if (pAdvancement.getDisplay() == null) {
|
||||
throw new IllegalArgumentException("Can't position an invisible advancement!");
|
||||
} else {
|
||||
this.advancement = pAdvancement;
|
||||
this.parent = pParent;
|
||||
this.previousSibling = pPreviousSibling;
|
||||
this.childIndex = pChildIndex;
|
||||
this.ancestor = this;
|
||||
this.x = pX;
|
||||
this.y = -1.0F;
|
||||
TreeNodePosition treenodeposition = null;
|
||||
|
||||
for(Advancement advancement : pAdvancement.getChildren()) {
|
||||
treenodeposition = this.addChild(advancement, treenodeposition);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TreeNodePosition addChild(Advancement pAdvancement, @Nullable TreeNodePosition pPrevious) {
|
||||
if (pAdvancement.getDisplay() != null) {
|
||||
pPrevious = new TreeNodePosition(pAdvancement, this, pPrevious, this.children.size() + 1, this.x + 1);
|
||||
this.children.add(pPrevious);
|
||||
} else {
|
||||
for(Advancement advancement : pAdvancement.getChildren()) {
|
||||
pPrevious = this.addChild(advancement, pPrevious);
|
||||
}
|
||||
}
|
||||
|
||||
return pPrevious;
|
||||
}
|
||||
|
||||
private void firstWalk() {
|
||||
if (this.children.isEmpty()) {
|
||||
if (this.previousSibling != null) {
|
||||
this.y = this.previousSibling.y + 1.0F;
|
||||
} else {
|
||||
this.y = 0.0F;
|
||||
}
|
||||
|
||||
} else {
|
||||
TreeNodePosition treenodeposition = null;
|
||||
|
||||
for(TreeNodePosition treenodeposition1 : this.children) {
|
||||
treenodeposition1.firstWalk();
|
||||
treenodeposition = treenodeposition1.apportion(treenodeposition == null ? treenodeposition1 : treenodeposition);
|
||||
}
|
||||
|
||||
this.executeShifts();
|
||||
float f = ((this.children.get(0)).y + (this.children.get(this.children.size() - 1)).y) / 2.0F;
|
||||
if (this.previousSibling != null) {
|
||||
this.y = this.previousSibling.y + 1.0F;
|
||||
this.mod = this.y - f;
|
||||
} else {
|
||||
this.y = f;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private float secondWalk(float pOffsetY, int pColumnX, float pSubtreeTopY) {
|
||||
this.y += pOffsetY;
|
||||
this.x = pColumnX;
|
||||
if (this.y < pSubtreeTopY) {
|
||||
pSubtreeTopY = this.y;
|
||||
}
|
||||
|
||||
for(TreeNodePosition treenodeposition : this.children) {
|
||||
pSubtreeTopY = treenodeposition.secondWalk(pOffsetY + this.mod, pColumnX + 1, pSubtreeTopY);
|
||||
}
|
||||
|
||||
return pSubtreeTopY;
|
||||
}
|
||||
|
||||
private void thirdWalk(float pY) {
|
||||
this.y += pY;
|
||||
|
||||
for(TreeNodePosition treenodeposition : this.children) {
|
||||
treenodeposition.thirdWalk(pY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void executeShifts() {
|
||||
float f = 0.0F;
|
||||
float f1 = 0.0F;
|
||||
|
||||
for(int i = this.children.size() - 1; i >= 0; --i) {
|
||||
TreeNodePosition treenodeposition = this.children.get(i);
|
||||
treenodeposition.y += f;
|
||||
treenodeposition.mod += f;
|
||||
f1 += treenodeposition.change;
|
||||
f += treenodeposition.shift + f1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TreeNodePosition previousOrThread() {
|
||||
if (this.thread != null) {
|
||||
return this.thread;
|
||||
} else {
|
||||
return !this.children.isEmpty() ? this.children.get(0) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TreeNodePosition nextOrThread() {
|
||||
if (this.thread != null) {
|
||||
return this.thread;
|
||||
} else {
|
||||
return !this.children.isEmpty() ? this.children.get(this.children.size() - 1) : null;
|
||||
}
|
||||
}
|
||||
|
||||
private TreeNodePosition apportion(TreeNodePosition pNode) {
|
||||
if (this.previousSibling == null) {
|
||||
return pNode;
|
||||
} else {
|
||||
TreeNodePosition treenodeposition = this;
|
||||
TreeNodePosition treenodeposition1 = this;
|
||||
TreeNodePosition treenodeposition2 = this.previousSibling;
|
||||
TreeNodePosition treenodeposition3 = this.parent.children.get(0);
|
||||
float f = this.mod;
|
||||
float f1 = this.mod;
|
||||
float f2 = treenodeposition2.mod;
|
||||
|
||||
float f3;
|
||||
for(f3 = treenodeposition3.mod; treenodeposition2.nextOrThread() != null && treenodeposition.previousOrThread() != null; f1 += treenodeposition1.mod) {
|
||||
treenodeposition2 = treenodeposition2.nextOrThread();
|
||||
treenodeposition = treenodeposition.previousOrThread();
|
||||
treenodeposition3 = treenodeposition3.previousOrThread();
|
||||
treenodeposition1 = treenodeposition1.nextOrThread();
|
||||
treenodeposition1.ancestor = this;
|
||||
float f4 = treenodeposition2.y + f2 - (treenodeposition.y + f) + 1.0F;
|
||||
if (f4 > 0.0F) {
|
||||
treenodeposition2.getAncestor(this, pNode).moveSubtree(this, f4);
|
||||
f += f4;
|
||||
f1 += f4;
|
||||
}
|
||||
|
||||
f2 += treenodeposition2.mod;
|
||||
f += treenodeposition.mod;
|
||||
f3 += treenodeposition3.mod;
|
||||
}
|
||||
|
||||
if (treenodeposition2.nextOrThread() != null && treenodeposition1.nextOrThread() == null) {
|
||||
treenodeposition1.thread = treenodeposition2.nextOrThread();
|
||||
treenodeposition1.mod += f2 - f1;
|
||||
} else {
|
||||
if (treenodeposition.previousOrThread() != null && treenodeposition3.previousOrThread() == null) {
|
||||
treenodeposition3.thread = treenodeposition.previousOrThread();
|
||||
treenodeposition3.mod += f - f3;
|
||||
}
|
||||
|
||||
pNode = this;
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
}
|
||||
|
||||
private void moveSubtree(TreeNodePosition pNode, float pShift) {
|
||||
float f = (float)(pNode.childIndex - this.childIndex);
|
||||
if (f != 0.0F) {
|
||||
pNode.change -= pShift / f;
|
||||
this.change += pShift / f;
|
||||
}
|
||||
|
||||
pNode.shift += pShift;
|
||||
pNode.y += pShift;
|
||||
pNode.mod += pShift;
|
||||
}
|
||||
|
||||
private TreeNodePosition getAncestor(TreeNodePosition pSelf, TreeNodePosition pOther) {
|
||||
return this.ancestor != null && pSelf.parent.children.contains(this.ancestor) ? this.ancestor : pOther;
|
||||
}
|
||||
|
||||
private void finalizePosition() {
|
||||
if (this.advancement.getDisplay() != null) {
|
||||
this.advancement.getDisplay().setLocation((float)this.x, this.y);
|
||||
}
|
||||
|
||||
if (!this.children.isEmpty()) {
|
||||
for(TreeNodePosition treenodeposition : this.children) {
|
||||
treenodeposition.finalizePosition();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void run(Advancement pRoot) {
|
||||
if (pRoot.getDisplay() == null) {
|
||||
throw new IllegalArgumentException("Can't position children of an invisible root!");
|
||||
} else {
|
||||
TreeNodePosition treenodeposition = new TreeNodePosition(pRoot, (TreeNodePosition)null, (TreeNodePosition)null, 1, 0);
|
||||
treenodeposition.firstWalk();
|
||||
float f = treenodeposition.secondWalk(0.0F, 0, treenodeposition.y);
|
||||
if (f < 0.0F) {
|
||||
treenodeposition.thirdWalk(-f);
|
||||
}
|
||||
|
||||
treenodeposition.finalizePosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.advancements.CriterionTriggerInstance;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public abstract class AbstractCriterionTriggerInstance implements CriterionTriggerInstance {
|
||||
private final ResourceLocation criterion;
|
||||
private final ContextAwarePredicate player;
|
||||
|
||||
public AbstractCriterionTriggerInstance(ResourceLocation pCriterion, ContextAwarePredicate pPlayer) {
|
||||
this.criterion = pCriterion;
|
||||
this.player = pPlayer;
|
||||
}
|
||||
|
||||
public ResourceLocation getCriterion() {
|
||||
return this.criterion;
|
||||
}
|
||||
|
||||
protected ContextAwarePredicate getPlayerPredicate() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("player", this.player.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "AbstractCriterionInstance{criterion=" + this.criterion + "}";
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class BeeNestDestroyedTrigger extends SimpleCriterionTrigger<BeeNestDestroyedTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("bee_nest_destroyed");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public BeeNestDestroyedTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
Block block = deserializeBlock(pJson);
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(pJson.get("item"));
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(pJson.get("num_bees_inside"));
|
||||
return new BeeNestDestroyedTrigger.TriggerInstance(pPredicate, block, itempredicate, minmaxbounds$ints);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Block deserializeBlock(JsonObject pJson) {
|
||||
if (pJson.has("block")) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(pJson, "block"));
|
||||
return BuiltInRegistries.BLOCK.getOptional(resourcelocation).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown block type '" + resourcelocation + "'");
|
||||
});
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, BlockState pState, ItemStack pStack, int pNumBees) {
|
||||
this.trigger(pPlayer, (p_146660_) -> {
|
||||
return p_146660_.matches(pState, pStack, pNumBees);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
@Nullable
|
||||
private final Block block;
|
||||
private final ItemPredicate item;
|
||||
private final MinMaxBounds.Ints numBees;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, @Nullable Block pBlock, ItemPredicate pItem, MinMaxBounds.Ints pNumBees) {
|
||||
super(BeeNestDestroyedTrigger.ID, pPlayer);
|
||||
this.block = pBlock;
|
||||
this.item = pItem;
|
||||
this.numBees = pNumBees;
|
||||
}
|
||||
|
||||
public static BeeNestDestroyedTrigger.TriggerInstance destroyedBeeNest(Block pBlock, ItemPredicate.Builder pItemPredicateBuilder, MinMaxBounds.Ints pBeesContained) {
|
||||
return new BeeNestDestroyedTrigger.TriggerInstance(ContextAwarePredicate.ANY, pBlock, pItemPredicateBuilder.build(), pBeesContained);
|
||||
}
|
||||
|
||||
public boolean matches(BlockState pState, ItemStack pStack, int pNumBees) {
|
||||
if (this.block != null && !pState.is(this.block)) {
|
||||
return false;
|
||||
} else {
|
||||
return !this.item.matches(pStack) ? false : this.numBees.matches(pNumBees);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
if (this.block != null) {
|
||||
jsonobject.addProperty("block", BuiltInRegistries.BLOCK.getKey(this.block).toString());
|
||||
}
|
||||
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
jsonobject.add("num_bees_inside", this.numBees.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class BlockPredicate {
|
||||
public static final BlockPredicate ANY = new BlockPredicate((TagKey<Block>)null, (Set<Block>)null, StatePropertiesPredicate.ANY, NbtPredicate.ANY);
|
||||
@Nullable
|
||||
private final TagKey<Block> tag;
|
||||
@Nullable
|
||||
private final Set<Block> blocks;
|
||||
private final StatePropertiesPredicate properties;
|
||||
private final NbtPredicate nbt;
|
||||
|
||||
public BlockPredicate(@Nullable TagKey<Block> pTag, @Nullable Set<Block> pBlocks, StatePropertiesPredicate pProperties, NbtPredicate pNbt) {
|
||||
this.tag = pTag;
|
||||
this.blocks = pBlocks;
|
||||
this.properties = pProperties;
|
||||
this.nbt = pNbt;
|
||||
}
|
||||
|
||||
public boolean matches(ServerLevel pLevel, BlockPos pPos) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else if (!pLevel.isLoaded(pPos)) {
|
||||
return false;
|
||||
} else {
|
||||
BlockState blockstate = pLevel.getBlockState(pPos);
|
||||
if (this.tag != null && !blockstate.is(this.tag)) {
|
||||
return false;
|
||||
} else if (this.blocks != null && !this.blocks.contains(blockstate.getBlock())) {
|
||||
return false;
|
||||
} else if (!this.properties.matches(blockstate)) {
|
||||
return false;
|
||||
} else {
|
||||
if (this.nbt != NbtPredicate.ANY) {
|
||||
BlockEntity blockentity = pLevel.getBlockEntity(pPos);
|
||||
if (blockentity == null || !this.nbt.matches(blockentity.saveWithFullMetadata())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static BlockPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "block");
|
||||
NbtPredicate nbtpredicate = NbtPredicate.fromJson(jsonobject.get("nbt"));
|
||||
Set<Block> set = null;
|
||||
JsonArray jsonarray = GsonHelper.getAsJsonArray(jsonobject, "blocks", (JsonArray)null);
|
||||
if (jsonarray != null) {
|
||||
ImmutableSet.Builder<Block> builder = ImmutableSet.builder();
|
||||
|
||||
for(JsonElement jsonelement : jsonarray) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.convertToString(jsonelement, "block"));
|
||||
builder.add(BuiltInRegistries.BLOCK.getOptional(resourcelocation).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown block id '" + resourcelocation + "'");
|
||||
}));
|
||||
}
|
||||
|
||||
set = builder.build();
|
||||
}
|
||||
|
||||
TagKey<Block> tagkey = null;
|
||||
if (jsonobject.has("tag")) {
|
||||
ResourceLocation resourcelocation1 = new ResourceLocation(GsonHelper.getAsString(jsonobject, "tag"));
|
||||
tagkey = TagKey.create(Registries.BLOCK, resourcelocation1);
|
||||
}
|
||||
|
||||
StatePropertiesPredicate statepropertiespredicate = StatePropertiesPredicate.fromJson(jsonobject.get("state"));
|
||||
return new BlockPredicate(tagkey, set, statepropertiespredicate, nbtpredicate);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (this.blocks != null) {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
for(Block block : this.blocks) {
|
||||
jsonarray.add(BuiltInRegistries.BLOCK.getKey(block).toString());
|
||||
}
|
||||
|
||||
jsonobject.add("blocks", jsonarray);
|
||||
}
|
||||
|
||||
if (this.tag != null) {
|
||||
jsonobject.addProperty("tag", this.tag.location().toString());
|
||||
}
|
||||
|
||||
jsonobject.add("nbt", this.nbt.serializeToJson());
|
||||
jsonobject.add("state", this.properties.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@Nullable
|
||||
private Set<Block> blocks;
|
||||
@Nullable
|
||||
private TagKey<Block> tag;
|
||||
private StatePropertiesPredicate properties = StatePropertiesPredicate.ANY;
|
||||
private NbtPredicate nbt = NbtPredicate.ANY;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
public static BlockPredicate.Builder block() {
|
||||
return new BlockPredicate.Builder();
|
||||
}
|
||||
|
||||
public BlockPredicate.Builder of(Block... pBlocks) {
|
||||
this.blocks = ImmutableSet.copyOf(pBlocks);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockPredicate.Builder of(Iterable<Block> pBlocks) {
|
||||
this.blocks = ImmutableSet.copyOf(pBlocks);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockPredicate.Builder of(TagKey<Block> pTag) {
|
||||
this.tag = pTag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockPredicate.Builder hasNbt(CompoundTag pNbt) {
|
||||
this.nbt = new NbtPredicate(pNbt);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockPredicate.Builder setProperties(StatePropertiesPredicate pProperties) {
|
||||
this.properties = pProperties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockPredicate build() {
|
||||
return new BlockPredicate(this.tag, this.blocks, this.properties, this.nbt);
|
||||
}
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.AgeableMob;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class BredAnimalsTrigger extends SimpleCriterionTrigger<BredAnimalsTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("bred_animals");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public BredAnimalsTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "parent", pDeserializationContext);
|
||||
ContextAwarePredicate contextawarepredicate1 = EntityPredicate.fromJson(pJson, "partner", pDeserializationContext);
|
||||
ContextAwarePredicate contextawarepredicate2 = EntityPredicate.fromJson(pJson, "child", pDeserializationContext);
|
||||
return new BredAnimalsTrigger.TriggerInstance(pPredicate, contextawarepredicate, contextawarepredicate1, contextawarepredicate2);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Animal pParent, Animal pPartner, @Nullable AgeableMob pChild) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pParent);
|
||||
LootContext lootcontext1 = EntityPredicate.createContext(pPlayer, pPartner);
|
||||
LootContext lootcontext2 = pChild != null ? EntityPredicate.createContext(pPlayer, pChild) : null;
|
||||
this.trigger(pPlayer, (p_18653_) -> {
|
||||
return p_18653_.matches(lootcontext, lootcontext1, lootcontext2);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ContextAwarePredicate parent;
|
||||
private final ContextAwarePredicate partner;
|
||||
private final ContextAwarePredicate child;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ContextAwarePredicate pParent, ContextAwarePredicate pPartner, ContextAwarePredicate pChild) {
|
||||
super(BredAnimalsTrigger.ID, pPlayer);
|
||||
this.parent = pParent;
|
||||
this.partner = pPartner;
|
||||
this.child = pChild;
|
||||
}
|
||||
|
||||
public static BredAnimalsTrigger.TriggerInstance bredAnimals() {
|
||||
return new BredAnimalsTrigger.TriggerInstance(ContextAwarePredicate.ANY, ContextAwarePredicate.ANY, ContextAwarePredicate.ANY, ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public static BredAnimalsTrigger.TriggerInstance bredAnimals(EntityPredicate.Builder pChildBuilder) {
|
||||
return new BredAnimalsTrigger.TriggerInstance(ContextAwarePredicate.ANY, ContextAwarePredicate.ANY, ContextAwarePredicate.ANY, EntityPredicate.wrap(pChildBuilder.build()));
|
||||
}
|
||||
|
||||
public static BredAnimalsTrigger.TriggerInstance bredAnimals(EntityPredicate pParent, EntityPredicate pPartner, EntityPredicate pChild) {
|
||||
return new BredAnimalsTrigger.TriggerInstance(ContextAwarePredicate.ANY, EntityPredicate.wrap(pParent), EntityPredicate.wrap(pPartner), EntityPredicate.wrap(pChild));
|
||||
}
|
||||
|
||||
public boolean matches(LootContext pParentContext, LootContext pPartnerContext, @Nullable LootContext pChildContext) {
|
||||
if (this.child == ContextAwarePredicate.ANY || pChildContext != null && this.child.matches(pChildContext)) {
|
||||
return this.parent.matches(pParentContext) && this.partner.matches(pPartnerContext) || this.parent.matches(pPartnerContext) && this.partner.matches(pParentContext);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("parent", this.parent.toJson(pConditions));
|
||||
jsonobject.add("partner", this.partner.toJson(pConditions));
|
||||
jsonobject.add("child", this.child.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.alchemy.Potion;
|
||||
|
||||
public class BrewedPotionTrigger extends SimpleCriterionTrigger<BrewedPotionTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("brewed_potion");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public BrewedPotionTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
Potion potion = null;
|
||||
if (pJson.has("potion")) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(pJson, "potion"));
|
||||
potion = BuiltInRegistries.POTION.getOptional(resourcelocation).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown potion '" + resourcelocation + "'");
|
||||
});
|
||||
}
|
||||
|
||||
return new BrewedPotionTrigger.TriggerInstance(pPredicate, potion);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Potion pPotion) {
|
||||
this.trigger(pPlayer, (p_19125_) -> {
|
||||
return p_19125_.matches(pPotion);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
@Nullable
|
||||
private final Potion potion;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, @Nullable Potion pPotion) {
|
||||
super(BrewedPotionTrigger.ID, pPlayer);
|
||||
this.potion = pPotion;
|
||||
}
|
||||
|
||||
public static BrewedPotionTrigger.TriggerInstance brewedPotion() {
|
||||
return new BrewedPotionTrigger.TriggerInstance(ContextAwarePredicate.ANY, (Potion)null);
|
||||
}
|
||||
|
||||
public boolean matches(Potion pPotion) {
|
||||
return this.potion == null || this.potion == pPotion;
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
if (this.potion != null) {
|
||||
jsonobject.addProperty("potion", BuiltInRegistries.POTION.getKey(this.potion).toString());
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
public class ChangeDimensionTrigger extends SimpleCriterionTrigger<ChangeDimensionTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("changed_dimension");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public ChangeDimensionTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ResourceKey<Level> resourcekey = pJson.has("from") ? ResourceKey.create(Registries.DIMENSION, new ResourceLocation(GsonHelper.getAsString(pJson, "from"))) : null;
|
||||
ResourceKey<Level> resourcekey1 = pJson.has("to") ? ResourceKey.create(Registries.DIMENSION, new ResourceLocation(GsonHelper.getAsString(pJson, "to"))) : null;
|
||||
return new ChangeDimensionTrigger.TriggerInstance(pPredicate, resourcekey, resourcekey1);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ResourceKey<Level> pFromLevel, ResourceKey<Level> pToLevel) {
|
||||
this.trigger(pPlayer, (p_19768_) -> {
|
||||
return p_19768_.matches(pFromLevel, pToLevel);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
@Nullable
|
||||
private final ResourceKey<Level> from;
|
||||
@Nullable
|
||||
private final ResourceKey<Level> to;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, @Nullable ResourceKey<Level> pFrom, @Nullable ResourceKey<Level> pTo) {
|
||||
super(ChangeDimensionTrigger.ID, pPlayer);
|
||||
this.from = pFrom;
|
||||
this.to = pTo;
|
||||
}
|
||||
|
||||
public static ChangeDimensionTrigger.TriggerInstance changedDimension() {
|
||||
return new ChangeDimensionTrigger.TriggerInstance(ContextAwarePredicate.ANY, (ResourceKey<Level>)null, (ResourceKey<Level>)null);
|
||||
}
|
||||
|
||||
public static ChangeDimensionTrigger.TriggerInstance changedDimension(ResourceKey<Level> pFrom, ResourceKey<Level> pTo) {
|
||||
return new ChangeDimensionTrigger.TriggerInstance(ContextAwarePredicate.ANY, pFrom, pTo);
|
||||
}
|
||||
|
||||
public static ChangeDimensionTrigger.TriggerInstance changedDimensionTo(ResourceKey<Level> pTo) {
|
||||
return new ChangeDimensionTrigger.TriggerInstance(ContextAwarePredicate.ANY, (ResourceKey<Level>)null, pTo);
|
||||
}
|
||||
|
||||
public static ChangeDimensionTrigger.TriggerInstance changedDimensionFrom(ResourceKey<Level> pFrom) {
|
||||
return new ChangeDimensionTrigger.TriggerInstance(ContextAwarePredicate.ANY, pFrom, (ResourceKey<Level>)null);
|
||||
}
|
||||
|
||||
public boolean matches(ResourceKey<Level> pFromLevel, ResourceKey<Level> pToLevel) {
|
||||
if (this.from != null && this.from != pFromLevel) {
|
||||
return false;
|
||||
} else {
|
||||
return this.to == null || this.to == pToLevel;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
if (this.from != null) {
|
||||
jsonobject.addProperty("from", this.from.location().toString());
|
||||
}
|
||||
|
||||
if (this.to != null) {
|
||||
jsonobject.addProperty("to", this.to.location().toString());
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class ChanneledLightningTrigger extends SimpleCriterionTrigger<ChanneledLightningTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("channeled_lightning");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public ChanneledLightningTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ContextAwarePredicate[] acontextawarepredicate = EntityPredicate.fromJsonArray(pJson, "victims", pDeserializationContext);
|
||||
return new ChanneledLightningTrigger.TriggerInstance(pPredicate, acontextawarepredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Collection<? extends Entity> pEntityTriggered) {
|
||||
List<LootContext> list = pEntityTriggered.stream().map((p_21720_) -> {
|
||||
return EntityPredicate.createContext(pPlayer, p_21720_);
|
||||
}).collect(Collectors.toList());
|
||||
this.trigger(pPlayer, (p_21730_) -> {
|
||||
return p_21730_.matches(list);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ContextAwarePredicate[] victims;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ContextAwarePredicate[] pVictims) {
|
||||
super(ChanneledLightningTrigger.ID, pPlayer);
|
||||
this.victims = pVictims;
|
||||
}
|
||||
|
||||
public static ChanneledLightningTrigger.TriggerInstance channeledLightning(EntityPredicate... pVictims) {
|
||||
return new ChanneledLightningTrigger.TriggerInstance(ContextAwarePredicate.ANY, Stream.of(pVictims).map(EntityPredicate::wrap).toArray((p_286116_) -> {
|
||||
return new ContextAwarePredicate[p_286116_];
|
||||
}));
|
||||
}
|
||||
|
||||
public boolean matches(Collection<? extends LootContext> pVictims) {
|
||||
for(ContextAwarePredicate contextawarepredicate : this.victims) {
|
||||
boolean flag = false;
|
||||
|
||||
for(LootContext lootcontext : pVictims) {
|
||||
if (contextawarepredicate.matches(lootcontext)) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("victims", ContextAwarePredicate.toJson(this.victims, pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
public class ConstructBeaconTrigger extends SimpleCriterionTrigger<ConstructBeaconTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("construct_beacon");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public ConstructBeaconTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(pJson.get("level"));
|
||||
return new ConstructBeaconTrigger.TriggerInstance(pPredicate, minmaxbounds$ints);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, int pLevel) {
|
||||
this.trigger(pPlayer, (p_148028_) -> {
|
||||
return p_148028_.matches(pLevel);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final MinMaxBounds.Ints level;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, MinMaxBounds.Ints pLevel) {
|
||||
super(ConstructBeaconTrigger.ID, pPlayer);
|
||||
this.level = pLevel;
|
||||
}
|
||||
|
||||
public static ConstructBeaconTrigger.TriggerInstance constructedBeacon() {
|
||||
return new ConstructBeaconTrigger.TriggerInstance(ContextAwarePredicate.ANY, MinMaxBounds.Ints.ANY);
|
||||
}
|
||||
|
||||
public static ConstructBeaconTrigger.TriggerInstance constructedBeacon(MinMaxBounds.Ints pLevel) {
|
||||
return new ConstructBeaconTrigger.TriggerInstance(ContextAwarePredicate.ANY, pLevel);
|
||||
}
|
||||
|
||||
public boolean matches(int pLevel) {
|
||||
return this.level.matches(pLevel);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("level", this.level.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.alchemy.Potion;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
|
||||
public class ConsumeItemTrigger extends SimpleCriterionTrigger<ConsumeItemTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("consume_item");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public ConsumeItemTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
return new ConsumeItemTrigger.TriggerInstance(pPredicate, ItemPredicate.fromJson(pJson.get("item")));
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ItemStack pItem) {
|
||||
this.trigger(pPlayer, (p_23687_) -> {
|
||||
return p_23687_.matches(pItem);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ItemPredicate item;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ItemPredicate pItem) {
|
||||
super(ConsumeItemTrigger.ID, pPlayer);
|
||||
this.item = pItem;
|
||||
}
|
||||
|
||||
public static ConsumeItemTrigger.TriggerInstance usedItem() {
|
||||
return new ConsumeItemTrigger.TriggerInstance(ContextAwarePredicate.ANY, ItemPredicate.ANY);
|
||||
}
|
||||
|
||||
public static ConsumeItemTrigger.TriggerInstance usedItem(ItemPredicate pItem) {
|
||||
return new ConsumeItemTrigger.TriggerInstance(ContextAwarePredicate.ANY, pItem);
|
||||
}
|
||||
|
||||
public static ConsumeItemTrigger.TriggerInstance usedItem(ItemLike pItem) {
|
||||
return new ConsumeItemTrigger.TriggerInstance(ContextAwarePredicate.ANY, new ItemPredicate((TagKey<Item>)null, ImmutableSet.of(pItem.asItem()), MinMaxBounds.Ints.ANY, MinMaxBounds.Ints.ANY, EnchantmentPredicate.NONE, EnchantmentPredicate.NONE, (Potion)null, NbtPredicate.ANY));
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack pItem) {
|
||||
return this.item.matches(pItem);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import java.util.function.Predicate;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemConditions;
|
||||
|
||||
public class ContextAwarePredicate {
|
||||
public static final ContextAwarePredicate ANY = new ContextAwarePredicate(new LootItemCondition[0]);
|
||||
private final LootItemCondition[] conditions;
|
||||
private final Predicate<LootContext> compositePredicates;
|
||||
|
||||
ContextAwarePredicate(LootItemCondition[] pConditons) {
|
||||
this.conditions = pConditons;
|
||||
this.compositePredicates = LootItemConditions.andConditions(pConditons);
|
||||
}
|
||||
|
||||
public static ContextAwarePredicate create(LootItemCondition... pConditions) {
|
||||
return new ContextAwarePredicate(pConditions);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ContextAwarePredicate fromElement(String pId, DeserializationContext pContext, @Nullable JsonElement pElement, LootContextParamSet pParamSet) {
|
||||
if (pElement != null && pElement.isJsonArray()) {
|
||||
LootItemCondition[] alootitemcondition = pContext.deserializeConditions(pElement.getAsJsonArray(), pContext.getAdvancementId() + "/" + pId, pParamSet);
|
||||
return new ContextAwarePredicate(alootitemcondition);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matches(LootContext pContext) {
|
||||
return this.compositePredicates.test(pContext);
|
||||
}
|
||||
|
||||
public JsonElement toJson(SerializationContext pContext) {
|
||||
return (JsonElement)(this.conditions.length == 0 ? JsonNull.INSTANCE : pContext.serializeConditions(this.conditions));
|
||||
}
|
||||
|
||||
public static JsonElement toJson(ContextAwarePredicate[] pPredicates, SerializationContext pContext) {
|
||||
if (pPredicates.length == 0) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
for(ContextAwarePredicate contextawarepredicate : pPredicates) {
|
||||
jsonarray.add(contextawarepredicate.toJson(pContext));
|
||||
}
|
||||
|
||||
return jsonarray;
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.monster.Zombie;
|
||||
import net.minecraft.world.entity.npc.Villager;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class CuredZombieVillagerTrigger extends SimpleCriterionTrigger<CuredZombieVillagerTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("cured_zombie_villager");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public CuredZombieVillagerTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "zombie", pDeserializationContext);
|
||||
ContextAwarePredicate contextawarepredicate1 = EntityPredicate.fromJson(pJson, "villager", pDeserializationContext);
|
||||
return new CuredZombieVillagerTrigger.TriggerInstance(pPredicate, contextawarepredicate, contextawarepredicate1);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Zombie pZombie, Villager pVillager) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pZombie);
|
||||
LootContext lootcontext1 = EntityPredicate.createContext(pPlayer, pVillager);
|
||||
this.trigger(pPlayer, (p_24285_) -> {
|
||||
return p_24285_.matches(lootcontext, lootcontext1);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ContextAwarePredicate zombie;
|
||||
private final ContextAwarePredicate villager;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ContextAwarePredicate pZombie, ContextAwarePredicate pVillager) {
|
||||
super(CuredZombieVillagerTrigger.ID, pPlayer);
|
||||
this.zombie = pZombie;
|
||||
this.villager = pVillager;
|
||||
}
|
||||
|
||||
public static CuredZombieVillagerTrigger.TriggerInstance curedZombieVillager() {
|
||||
return new CuredZombieVillagerTrigger.TriggerInstance(ContextAwarePredicate.ANY, ContextAwarePredicate.ANY, ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public boolean matches(LootContext pZombie, LootContext pVillager) {
|
||||
if (!this.zombie.matches(pZombie)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.villager.matches(pVillager);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("zombie", this.zombie.toJson(pConditions));
|
||||
jsonobject.add("villager", this.villager.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
|
||||
public class DamagePredicate {
|
||||
public static final DamagePredicate ANY = DamagePredicate.Builder.damageInstance().build();
|
||||
private final MinMaxBounds.Doubles dealtDamage;
|
||||
private final MinMaxBounds.Doubles takenDamage;
|
||||
private final EntityPredicate sourceEntity;
|
||||
@Nullable
|
||||
private final Boolean blocked;
|
||||
private final DamageSourcePredicate type;
|
||||
|
||||
public DamagePredicate() {
|
||||
this.dealtDamage = MinMaxBounds.Doubles.ANY;
|
||||
this.takenDamage = MinMaxBounds.Doubles.ANY;
|
||||
this.sourceEntity = EntityPredicate.ANY;
|
||||
this.blocked = null;
|
||||
this.type = DamageSourcePredicate.ANY;
|
||||
}
|
||||
|
||||
public DamagePredicate(MinMaxBounds.Doubles pDealtDamage, MinMaxBounds.Doubles pTakenDamage, EntityPredicate pSourceEntity, @Nullable Boolean pBlocked, DamageSourcePredicate pType) {
|
||||
this.dealtDamage = pDealtDamage;
|
||||
this.takenDamage = pTakenDamage;
|
||||
this.sourceEntity = pSourceEntity;
|
||||
this.blocked = pBlocked;
|
||||
this.type = pType;
|
||||
}
|
||||
|
||||
public boolean matches(ServerPlayer pPlayer, DamageSource pSource, float pDealtDamage, float pTakenDamage, boolean pBlocked) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else if (!this.dealtDamage.matches((double)pDealtDamage)) {
|
||||
return false;
|
||||
} else if (!this.takenDamage.matches((double)pTakenDamage)) {
|
||||
return false;
|
||||
} else if (!this.sourceEntity.matches(pPlayer, pSource.getEntity())) {
|
||||
return false;
|
||||
} else if (this.blocked != null && this.blocked != pBlocked) {
|
||||
return false;
|
||||
} else {
|
||||
return this.type.matches(pPlayer, pSource);
|
||||
}
|
||||
}
|
||||
|
||||
public static DamagePredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "damage");
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles = MinMaxBounds.Doubles.fromJson(jsonobject.get("dealt"));
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles1 = MinMaxBounds.Doubles.fromJson(jsonobject.get("taken"));
|
||||
Boolean obool = jsonobject.has("blocked") ? GsonHelper.getAsBoolean(jsonobject, "blocked") : null;
|
||||
EntityPredicate entitypredicate = EntityPredicate.fromJson(jsonobject.get("source_entity"));
|
||||
DamageSourcePredicate damagesourcepredicate = DamageSourcePredicate.fromJson(jsonobject.get("type"));
|
||||
return new DamagePredicate(minmaxbounds$doubles, minmaxbounds$doubles1, entitypredicate, obool, damagesourcepredicate);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("dealt", this.dealtDamage.serializeToJson());
|
||||
jsonobject.add("taken", this.takenDamage.serializeToJson());
|
||||
jsonobject.add("source_entity", this.sourceEntity.serializeToJson());
|
||||
jsonobject.add("type", this.type.serializeToJson());
|
||||
if (this.blocked != null) {
|
||||
jsonobject.addProperty("blocked", this.blocked);
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private MinMaxBounds.Doubles dealtDamage = MinMaxBounds.Doubles.ANY;
|
||||
private MinMaxBounds.Doubles takenDamage = MinMaxBounds.Doubles.ANY;
|
||||
private EntityPredicate sourceEntity = EntityPredicate.ANY;
|
||||
@Nullable
|
||||
private Boolean blocked;
|
||||
private DamageSourcePredicate type = DamageSourcePredicate.ANY;
|
||||
|
||||
public static DamagePredicate.Builder damageInstance() {
|
||||
return new DamagePredicate.Builder();
|
||||
}
|
||||
|
||||
public DamagePredicate.Builder dealtDamage(MinMaxBounds.Doubles pDealtDamage) {
|
||||
this.dealtDamage = pDealtDamage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamagePredicate.Builder takenDamage(MinMaxBounds.Doubles pTakenDamage) {
|
||||
this.takenDamage = pTakenDamage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamagePredicate.Builder sourceEntity(EntityPredicate pSourceEntity) {
|
||||
this.sourceEntity = pSourceEntity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamagePredicate.Builder blocked(Boolean pBlocked) {
|
||||
this.blocked = pBlocked;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamagePredicate.Builder type(DamageSourcePredicate pType) {
|
||||
this.type = pType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamagePredicate.Builder type(DamageSourcePredicate.Builder pTypeBuilder) {
|
||||
this.type = pTypeBuilder.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamagePredicate build() {
|
||||
return new DamagePredicate(this.dealtDamage, this.takenDamage, this.sourceEntity, this.blocked, this.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.damagesource.DamageType;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class DamageSourcePredicate {
|
||||
public static final DamageSourcePredicate ANY = DamageSourcePredicate.Builder.damageType().build();
|
||||
private final List<TagPredicate<DamageType>> tags;
|
||||
private final EntityPredicate directEntity;
|
||||
private final EntityPredicate sourceEntity;
|
||||
|
||||
public DamageSourcePredicate(List<TagPredicate<DamageType>> pTags, EntityPredicate pDirectEntity, EntityPredicate pSourceEntity) {
|
||||
this.tags = pTags;
|
||||
this.directEntity = pDirectEntity;
|
||||
this.sourceEntity = pSourceEntity;
|
||||
}
|
||||
|
||||
public boolean matches(ServerPlayer pPlayer, DamageSource pSource) {
|
||||
return this.matches(pPlayer.serverLevel(), pPlayer.position(), pSource);
|
||||
}
|
||||
|
||||
public boolean matches(ServerLevel pLevel, Vec3 pPosition, DamageSource pSource) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else {
|
||||
for(TagPredicate<DamageType> tagpredicate : this.tags) {
|
||||
if (!tagpredicate.matches(pSource.typeHolder())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.directEntity.matches(pLevel, pPosition, pSource.getDirectEntity())) {
|
||||
return false;
|
||||
} else {
|
||||
return this.sourceEntity.matches(pLevel, pPosition, pSource.getEntity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static DamageSourcePredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "damage type");
|
||||
JsonArray jsonarray = GsonHelper.getAsJsonArray(jsonobject, "tags", (JsonArray)null);
|
||||
List<TagPredicate<DamageType>> list;
|
||||
if (jsonarray != null) {
|
||||
list = new ArrayList<>(jsonarray.size());
|
||||
|
||||
for(JsonElement jsonelement : jsonarray) {
|
||||
list.add(TagPredicate.fromJson(jsonelement, Registries.DAMAGE_TYPE));
|
||||
}
|
||||
} else {
|
||||
list = List.of();
|
||||
}
|
||||
|
||||
EntityPredicate entitypredicate = EntityPredicate.fromJson(jsonobject.get("direct_entity"));
|
||||
EntityPredicate entitypredicate1 = EntityPredicate.fromJson(jsonobject.get("source_entity"));
|
||||
return new DamageSourcePredicate(list, entitypredicate, entitypredicate1);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (!this.tags.isEmpty()) {
|
||||
JsonArray jsonarray = new JsonArray(this.tags.size());
|
||||
|
||||
for(int i = 0; i < this.tags.size(); ++i) {
|
||||
jsonarray.add(this.tags.get(i).serializeToJson());
|
||||
}
|
||||
|
||||
jsonobject.add("tags", jsonarray);
|
||||
}
|
||||
|
||||
jsonobject.add("direct_entity", this.directEntity.serializeToJson());
|
||||
jsonobject.add("source_entity", this.sourceEntity.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final ImmutableList.Builder<TagPredicate<DamageType>> tags = ImmutableList.builder();
|
||||
private EntityPredicate directEntity = EntityPredicate.ANY;
|
||||
private EntityPredicate sourceEntity = EntityPredicate.ANY;
|
||||
|
||||
public static DamageSourcePredicate.Builder damageType() {
|
||||
return new DamageSourcePredicate.Builder();
|
||||
}
|
||||
|
||||
public DamageSourcePredicate.Builder tag(TagPredicate<DamageType> pTag) {
|
||||
this.tags.add(pTag);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamageSourcePredicate.Builder direct(EntityPredicate pDirectEntity) {
|
||||
this.directEntity = pDirectEntity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamageSourcePredicate.Builder direct(EntityPredicate.Builder pDirectEntity) {
|
||||
this.directEntity = pDirectEntity.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamageSourcePredicate.Builder source(EntityPredicate pSourceEntity) {
|
||||
this.sourceEntity = pSourceEntity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamageSourcePredicate.Builder source(EntityPredicate.Builder pSourceEntity) {
|
||||
this.sourceEntity = pSourceEntity.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
public DamageSourcePredicate build() {
|
||||
return new DamageSourcePredicate(this.tags.build(), this.directEntity, this.sourceEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.storage.loot.Deserializers;
|
||||
import net.minecraft.world.level.storage.loot.LootDataManager;
|
||||
import net.minecraft.world.level.storage.loot.ValidationContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class DeserializationContext {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final ResourceLocation id;
|
||||
private final LootDataManager lootData;
|
||||
private final Gson predicateGson = Deserializers.createConditionSerializer().create();
|
||||
|
||||
public DeserializationContext(ResourceLocation pId, LootDataManager pLootData) {
|
||||
this.id = pId;
|
||||
this.lootData = pLootData;
|
||||
}
|
||||
|
||||
public final LootItemCondition[] deserializeConditions(JsonArray pJson, String pId, LootContextParamSet pParameterSet) {
|
||||
LootItemCondition[] alootitemcondition = this.predicateGson.fromJson(pJson, LootItemCondition[].class);
|
||||
ValidationContext validationcontext = new ValidationContext(pParameterSet, this.lootData);
|
||||
|
||||
for(LootItemCondition lootitemcondition : alootitemcondition) {
|
||||
lootitemcondition.validate(validationcontext);
|
||||
validationcontext.getProblems().forEach((p_25880_, p_25881_) -> {
|
||||
LOGGER.warn("Found validation problem in advancement trigger {}/{}: {}", pId, p_25880_, p_25881_);
|
||||
});
|
||||
}
|
||||
|
||||
return alootitemcondition;
|
||||
}
|
||||
|
||||
public ResourceLocation getAdvancementId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
public class DistancePredicate {
|
||||
public static final DistancePredicate ANY = new DistancePredicate(MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY);
|
||||
private final MinMaxBounds.Doubles x;
|
||||
private final MinMaxBounds.Doubles y;
|
||||
private final MinMaxBounds.Doubles z;
|
||||
private final MinMaxBounds.Doubles horizontal;
|
||||
private final MinMaxBounds.Doubles absolute;
|
||||
|
||||
public DistancePredicate(MinMaxBounds.Doubles pX, MinMaxBounds.Doubles pY, MinMaxBounds.Doubles pZ, MinMaxBounds.Doubles pHorizontal, MinMaxBounds.Doubles pAbsolute) {
|
||||
this.x = pX;
|
||||
this.y = pY;
|
||||
this.z = pZ;
|
||||
this.horizontal = pHorizontal;
|
||||
this.absolute = pAbsolute;
|
||||
}
|
||||
|
||||
public static DistancePredicate horizontal(MinMaxBounds.Doubles pHorizontal) {
|
||||
return new DistancePredicate(MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, pHorizontal, MinMaxBounds.Doubles.ANY);
|
||||
}
|
||||
|
||||
public static DistancePredicate vertical(MinMaxBounds.Doubles pVertical) {
|
||||
return new DistancePredicate(MinMaxBounds.Doubles.ANY, pVertical, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY);
|
||||
}
|
||||
|
||||
public static DistancePredicate absolute(MinMaxBounds.Doubles pAbsolute) {
|
||||
return new DistancePredicate(MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, pAbsolute);
|
||||
}
|
||||
|
||||
public boolean matches(double pX1, double pY1, double pZ1, double pX2, double pY2, double pZ2) {
|
||||
float f = (float)(pX1 - pX2);
|
||||
float f1 = (float)(pY1 - pY2);
|
||||
float f2 = (float)(pZ1 - pZ2);
|
||||
if (this.x.matches((double)Mth.abs(f)) && this.y.matches((double)Mth.abs(f1)) && this.z.matches((double)Mth.abs(f2))) {
|
||||
if (!this.horizontal.matchesSqr((double)(f * f + f2 * f2))) {
|
||||
return false;
|
||||
} else {
|
||||
return this.absolute.matchesSqr((double)(f * f + f1 * f1 + f2 * f2));
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static DistancePredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "distance");
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles = MinMaxBounds.Doubles.fromJson(jsonobject.get("x"));
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles1 = MinMaxBounds.Doubles.fromJson(jsonobject.get("y"));
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles2 = MinMaxBounds.Doubles.fromJson(jsonobject.get("z"));
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles3 = MinMaxBounds.Doubles.fromJson(jsonobject.get("horizontal"));
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles4 = MinMaxBounds.Doubles.fromJson(jsonobject.get("absolute"));
|
||||
return new DistancePredicate(minmaxbounds$doubles, minmaxbounds$doubles1, minmaxbounds$doubles2, minmaxbounds$doubles3, minmaxbounds$doubles4);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("x", this.x.serializeToJson());
|
||||
jsonobject.add("y", this.y.serializeToJson());
|
||||
jsonobject.add("z", this.z.serializeToJson());
|
||||
jsonobject.add("horizontal", this.horizontal.serializeToJson());
|
||||
jsonobject.add("absolute", this.absolute.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class DistanceTrigger extends SimpleCriterionTrigger<DistanceTrigger.TriggerInstance> {
|
||||
final ResourceLocation id;
|
||||
|
||||
public DistanceTrigger(ResourceLocation pId) {
|
||||
this.id = pId;
|
||||
}
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public DistanceTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
LocationPredicate locationpredicate = LocationPredicate.fromJson(pJson.get("start_position"));
|
||||
DistancePredicate distancepredicate = DistancePredicate.fromJson(pJson.get("distance"));
|
||||
return new DistanceTrigger.TriggerInstance(this.id, pPredicate, locationpredicate, distancepredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Vec3 pPosition) {
|
||||
Vec3 vec3 = pPlayer.position();
|
||||
this.trigger(pPlayer, (p_284572_) -> {
|
||||
return p_284572_.matches(pPlayer.serverLevel(), pPosition, vec3);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final LocationPredicate startPosition;
|
||||
private final DistancePredicate distance;
|
||||
|
||||
public TriggerInstance(ResourceLocation pCriterion, ContextAwarePredicate pPlayer, LocationPredicate pStartPosition, DistancePredicate pDistance) {
|
||||
super(pCriterion, pPlayer);
|
||||
this.startPosition = pStartPosition;
|
||||
this.distance = pDistance;
|
||||
}
|
||||
|
||||
public static DistanceTrigger.TriggerInstance fallFromHeight(EntityPredicate.Builder pPlayer, DistancePredicate pDistance, LocationPredicate pStartPosition) {
|
||||
return new DistanceTrigger.TriggerInstance(CriteriaTriggers.FALL_FROM_HEIGHT.id, EntityPredicate.wrap(pPlayer.build()), pStartPosition, pDistance);
|
||||
}
|
||||
|
||||
public static DistanceTrigger.TriggerInstance rideEntityInLava(EntityPredicate.Builder pPlayer, DistancePredicate pDistance) {
|
||||
return new DistanceTrigger.TriggerInstance(CriteriaTriggers.RIDE_ENTITY_IN_LAVA_TRIGGER.id, EntityPredicate.wrap(pPlayer.build()), LocationPredicate.ANY, pDistance);
|
||||
}
|
||||
|
||||
public static DistanceTrigger.TriggerInstance travelledThroughNether(DistancePredicate pDistance) {
|
||||
return new DistanceTrigger.TriggerInstance(CriteriaTriggers.NETHER_TRAVEL.id, ContextAwarePredicate.ANY, LocationPredicate.ANY, pDistance);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("start_position", this.startPosition.serializeToJson());
|
||||
jsonobject.add("distance", this.distance.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public boolean matches(ServerLevel pLevel, Vec3 pStartPosition, Vec3 pCurrentPosition) {
|
||||
if (!this.startPosition.matches(pLevel, pStartPosition.x, pStartPosition.y, pStartPosition.z)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.distance.matches(pStartPosition.x, pStartPosition.y, pStartPosition.z, pCurrentPosition.x, pCurrentPosition.y, pCurrentPosition.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class EffectsChangedTrigger extends SimpleCriterionTrigger<EffectsChangedTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("effects_changed");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public EffectsChangedTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
MobEffectsPredicate mobeffectspredicate = MobEffectsPredicate.fromJson(pJson.get("effects"));
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "source", pDeserializationContext);
|
||||
return new EffectsChangedTrigger.TriggerInstance(pPredicate, mobeffectspredicate, contextawarepredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, @Nullable Entity pSource) {
|
||||
LootContext lootcontext = pSource != null ? EntityPredicate.createContext(pPlayer, pSource) : null;
|
||||
this.trigger(pPlayer, (p_149268_) -> {
|
||||
return p_149268_.matches(pPlayer, lootcontext);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final MobEffectsPredicate effects;
|
||||
private final ContextAwarePredicate source;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, MobEffectsPredicate pEffects, ContextAwarePredicate pSource) {
|
||||
super(EffectsChangedTrigger.ID, pPlayer);
|
||||
this.effects = pEffects;
|
||||
this.source = pSource;
|
||||
}
|
||||
|
||||
public static EffectsChangedTrigger.TriggerInstance hasEffects(MobEffectsPredicate pEffects) {
|
||||
return new EffectsChangedTrigger.TriggerInstance(ContextAwarePredicate.ANY, pEffects, ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public static EffectsChangedTrigger.TriggerInstance gotEffectsFrom(EntityPredicate pSource) {
|
||||
return new EffectsChangedTrigger.TriggerInstance(ContextAwarePredicate.ANY, MobEffectsPredicate.ANY, EntityPredicate.wrap(pSource));
|
||||
}
|
||||
|
||||
public boolean matches(ServerPlayer pPlayer, @Nullable LootContext pLootContext) {
|
||||
if (!this.effects.matches(pPlayer)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.source == ContextAwarePredicate.ANY || pLootContext != null && this.source.matches(pLootContext);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("effects", this.effects.serializeToJson());
|
||||
jsonobject.add("source", this.source.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class EnchantedItemTrigger extends SimpleCriterionTrigger<EnchantedItemTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("enchanted_item");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public EnchantedItemTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(pJson.get("item"));
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(pJson.get("levels"));
|
||||
return new EnchantedItemTrigger.TriggerInstance(pPredicate, itempredicate, minmaxbounds$ints);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ItemStack pItem, int pLevelsSpent) {
|
||||
this.trigger(pPlayer, (p_27675_) -> {
|
||||
return p_27675_.matches(pItem, pLevelsSpent);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ItemPredicate item;
|
||||
private final MinMaxBounds.Ints levels;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ItemPredicate pItem, MinMaxBounds.Ints pLevels) {
|
||||
super(EnchantedItemTrigger.ID, pPlayer);
|
||||
this.item = pItem;
|
||||
this.levels = pLevels;
|
||||
}
|
||||
|
||||
public static EnchantedItemTrigger.TriggerInstance enchantedItem() {
|
||||
return new EnchantedItemTrigger.TriggerInstance(ContextAwarePredicate.ANY, ItemPredicate.ANY, MinMaxBounds.Ints.ANY);
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack pItem, int pLevels) {
|
||||
if (!this.item.matches(pItem)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.levels.matches(pLevels);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
jsonobject.add("levels", this.levels.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantment;
|
||||
|
||||
public class EnchantmentPredicate {
|
||||
public static final EnchantmentPredicate ANY = new EnchantmentPredicate();
|
||||
public static final EnchantmentPredicate[] NONE = new EnchantmentPredicate[0];
|
||||
@Nullable
|
||||
private final Enchantment enchantment;
|
||||
private final MinMaxBounds.Ints level;
|
||||
|
||||
public EnchantmentPredicate() {
|
||||
this.enchantment = null;
|
||||
this.level = MinMaxBounds.Ints.ANY;
|
||||
}
|
||||
|
||||
public EnchantmentPredicate(@Nullable Enchantment pEnchantment, MinMaxBounds.Ints pLevel) {
|
||||
this.enchantment = pEnchantment;
|
||||
this.level = pLevel;
|
||||
}
|
||||
|
||||
public boolean containedIn(Map<Enchantment, Integer> pEnchantments) {
|
||||
if (this.enchantment != null) {
|
||||
if (!pEnchantments.containsKey(this.enchantment)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int i = pEnchantments.get(this.enchantment);
|
||||
if (this.level != MinMaxBounds.Ints.ANY && !this.level.matches(i)) {
|
||||
return false;
|
||||
}
|
||||
} else if (this.level != MinMaxBounds.Ints.ANY) {
|
||||
for(Integer integer : pEnchantments.values()) {
|
||||
if (this.level.matches(integer)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (this.enchantment != null) {
|
||||
jsonobject.addProperty("enchantment", BuiltInRegistries.ENCHANTMENT.getKey(this.enchantment).toString());
|
||||
}
|
||||
|
||||
jsonobject.add("levels", this.level.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static EnchantmentPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "enchantment");
|
||||
Enchantment enchantment = null;
|
||||
if (jsonobject.has("enchantment")) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(jsonobject, "enchantment"));
|
||||
enchantment = BuiltInRegistries.ENCHANTMENT.getOptional(resourcelocation).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown enchantment '" + resourcelocation + "'");
|
||||
});
|
||||
}
|
||||
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(jsonobject.get("levels"));
|
||||
return new EnchantmentPredicate(enchantment, minmaxbounds$ints);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public static EnchantmentPredicate[] fromJsonArray(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonArray jsonarray = GsonHelper.convertToJsonArray(pJson, "enchantments");
|
||||
EnchantmentPredicate[] aenchantmentpredicate = new EnchantmentPredicate[jsonarray.size()];
|
||||
|
||||
for(int i = 0; i < aenchantmentpredicate.length; ++i) {
|
||||
aenchantmentpredicate[i] = fromJson(jsonarray.get(i));
|
||||
}
|
||||
|
||||
return aenchantmentpredicate;
|
||||
} else {
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class EnterBlockTrigger extends SimpleCriterionTrigger<EnterBlockTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("enter_block");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public EnterBlockTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
Block block = deserializeBlock(pJson);
|
||||
StatePropertiesPredicate statepropertiespredicate = StatePropertiesPredicate.fromJson(pJson.get("state"));
|
||||
if (block != null) {
|
||||
statepropertiespredicate.checkState(block.getStateDefinition(), (p_31274_) -> {
|
||||
throw new JsonSyntaxException("Block " + block + " has no property " + p_31274_);
|
||||
});
|
||||
}
|
||||
|
||||
return new EnterBlockTrigger.TriggerInstance(pPredicate, block, statepropertiespredicate);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Block deserializeBlock(JsonObject pJson) {
|
||||
if (pJson.has("block")) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(pJson, "block"));
|
||||
return BuiltInRegistries.BLOCK.getOptional(resourcelocation).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown block type '" + resourcelocation + "'");
|
||||
});
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, BlockState pState) {
|
||||
this.trigger(pPlayer, (p_31277_) -> {
|
||||
return p_31277_.matches(pState);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
@Nullable
|
||||
private final Block block;
|
||||
private final StatePropertiesPredicate state;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, @Nullable Block pBlock, StatePropertiesPredicate pState) {
|
||||
super(EnterBlockTrigger.ID, pPlayer);
|
||||
this.block = pBlock;
|
||||
this.state = pState;
|
||||
}
|
||||
|
||||
public static EnterBlockTrigger.TriggerInstance entersBlock(Block pBlock) {
|
||||
return new EnterBlockTrigger.TriggerInstance(ContextAwarePredicate.ANY, pBlock, StatePropertiesPredicate.ANY);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
if (this.block != null) {
|
||||
jsonobject.addProperty("block", BuiltInRegistries.BLOCK.getKey(this.block).toString());
|
||||
}
|
||||
|
||||
jsonobject.add("state", this.state.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public boolean matches(BlockState pState) {
|
||||
if (this.block != null && !pState.is(this.block)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.state.matches(pState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.raid.Raid;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
public class EntityEquipmentPredicate {
|
||||
public static final EntityEquipmentPredicate ANY = new EntityEquipmentPredicate(ItemPredicate.ANY, ItemPredicate.ANY, ItemPredicate.ANY, ItemPredicate.ANY, ItemPredicate.ANY, ItemPredicate.ANY);
|
||||
public static final EntityEquipmentPredicate CAPTAIN = new EntityEquipmentPredicate(ItemPredicate.Builder.item().of(Items.WHITE_BANNER).hasNbt(Raid.getLeaderBannerInstance().getTag()).build(), ItemPredicate.ANY, ItemPredicate.ANY, ItemPredicate.ANY, ItemPredicate.ANY, ItemPredicate.ANY);
|
||||
private final ItemPredicate head;
|
||||
private final ItemPredicate chest;
|
||||
private final ItemPredicate legs;
|
||||
private final ItemPredicate feet;
|
||||
private final ItemPredicate mainhand;
|
||||
private final ItemPredicate offhand;
|
||||
|
||||
public EntityEquipmentPredicate(ItemPredicate pHead, ItemPredicate pChest, ItemPredicate pLegs, ItemPredicate pFeet, ItemPredicate pMainhand, ItemPredicate pOffhand) {
|
||||
this.head = pHead;
|
||||
this.chest = pChest;
|
||||
this.legs = pLegs;
|
||||
this.feet = pFeet;
|
||||
this.mainhand = pMainhand;
|
||||
this.offhand = pOffhand;
|
||||
}
|
||||
|
||||
public boolean matches(@Nullable Entity pEntity) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else if (!(pEntity instanceof LivingEntity)) {
|
||||
return false;
|
||||
} else {
|
||||
LivingEntity livingentity = (LivingEntity)pEntity;
|
||||
if (!this.head.matches(livingentity.getItemBySlot(EquipmentSlot.HEAD))) {
|
||||
return false;
|
||||
} else if (!this.chest.matches(livingentity.getItemBySlot(EquipmentSlot.CHEST))) {
|
||||
return false;
|
||||
} else if (!this.legs.matches(livingentity.getItemBySlot(EquipmentSlot.LEGS))) {
|
||||
return false;
|
||||
} else if (!this.feet.matches(livingentity.getItemBySlot(EquipmentSlot.FEET))) {
|
||||
return false;
|
||||
} else if (!this.mainhand.matches(livingentity.getItemBySlot(EquipmentSlot.MAINHAND))) {
|
||||
return false;
|
||||
} else {
|
||||
return this.offhand.matches(livingentity.getItemBySlot(EquipmentSlot.OFFHAND));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityEquipmentPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "equipment");
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(jsonobject.get("head"));
|
||||
ItemPredicate itempredicate1 = ItemPredicate.fromJson(jsonobject.get("chest"));
|
||||
ItemPredicate itempredicate2 = ItemPredicate.fromJson(jsonobject.get("legs"));
|
||||
ItemPredicate itempredicate3 = ItemPredicate.fromJson(jsonobject.get("feet"));
|
||||
ItemPredicate itempredicate4 = ItemPredicate.fromJson(jsonobject.get("mainhand"));
|
||||
ItemPredicate itempredicate5 = ItemPredicate.fromJson(jsonobject.get("offhand"));
|
||||
return new EntityEquipmentPredicate(itempredicate, itempredicate1, itempredicate2, itempredicate3, itempredicate4, itempredicate5);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("head", this.head.serializeToJson());
|
||||
jsonobject.add("chest", this.chest.serializeToJson());
|
||||
jsonobject.add("legs", this.legs.serializeToJson());
|
||||
jsonobject.add("feet", this.feet.serializeToJson());
|
||||
jsonobject.add("mainhand", this.mainhand.serializeToJson());
|
||||
jsonobject.add("offhand", this.offhand.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private ItemPredicate head = ItemPredicate.ANY;
|
||||
private ItemPredicate chest = ItemPredicate.ANY;
|
||||
private ItemPredicate legs = ItemPredicate.ANY;
|
||||
private ItemPredicate feet = ItemPredicate.ANY;
|
||||
private ItemPredicate mainhand = ItemPredicate.ANY;
|
||||
private ItemPredicate offhand = ItemPredicate.ANY;
|
||||
|
||||
public static EntityEquipmentPredicate.Builder equipment() {
|
||||
return new EntityEquipmentPredicate.Builder();
|
||||
}
|
||||
|
||||
public EntityEquipmentPredicate.Builder head(ItemPredicate pHead) {
|
||||
this.head = pHead;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityEquipmentPredicate.Builder chest(ItemPredicate pChest) {
|
||||
this.chest = pChest;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityEquipmentPredicate.Builder legs(ItemPredicate pLegs) {
|
||||
this.legs = pLegs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityEquipmentPredicate.Builder feet(ItemPredicate pFeet) {
|
||||
this.feet = pFeet;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityEquipmentPredicate.Builder mainhand(ItemPredicate pMainhand) {
|
||||
this.mainhand = pMainhand;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityEquipmentPredicate.Builder offhand(ItemPredicate pOffhand) {
|
||||
this.offhand = pOffhand;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityEquipmentPredicate build() {
|
||||
return new EntityEquipmentPredicate(this.head, this.chest, this.legs, this.feet, this.mainhand, this.offhand);
|
||||
}
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
|
||||
public class EntityFlagsPredicate {
|
||||
public static final EntityFlagsPredicate ANY = (new EntityFlagsPredicate.Builder()).build();
|
||||
@Nullable
|
||||
private final Boolean isOnFire;
|
||||
@Nullable
|
||||
private final Boolean isCrouching;
|
||||
@Nullable
|
||||
private final Boolean isSprinting;
|
||||
@Nullable
|
||||
private final Boolean isSwimming;
|
||||
@Nullable
|
||||
private final Boolean isBaby;
|
||||
|
||||
public EntityFlagsPredicate(@Nullable Boolean pIsOnFire, @Nullable Boolean pIsCouching, @Nullable Boolean pIsSprinting, @Nullable Boolean pIsSwimming, @Nullable Boolean pIsBaby) {
|
||||
this.isOnFire = pIsOnFire;
|
||||
this.isCrouching = pIsCouching;
|
||||
this.isSprinting = pIsSprinting;
|
||||
this.isSwimming = pIsSwimming;
|
||||
this.isBaby = pIsBaby;
|
||||
}
|
||||
|
||||
public boolean matches(Entity pEntity) {
|
||||
if (this.isOnFire != null && pEntity.isOnFire() != this.isOnFire) {
|
||||
return false;
|
||||
} else if (this.isCrouching != null && pEntity.isCrouching() != this.isCrouching) {
|
||||
return false;
|
||||
} else if (this.isSprinting != null && pEntity.isSprinting() != this.isSprinting) {
|
||||
return false;
|
||||
} else if (this.isSwimming != null && pEntity.isSwimming() != this.isSwimming) {
|
||||
return false;
|
||||
} else {
|
||||
return this.isBaby == null || !(pEntity instanceof LivingEntity) || ((LivingEntity)pEntity).isBaby() == this.isBaby;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Boolean getOptionalBoolean(JsonObject pJson, String pName) {
|
||||
return pJson.has(pName) ? GsonHelper.getAsBoolean(pJson, pName) : null;
|
||||
}
|
||||
|
||||
public static EntityFlagsPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "entity flags");
|
||||
Boolean obool = getOptionalBoolean(jsonobject, "is_on_fire");
|
||||
Boolean obool1 = getOptionalBoolean(jsonobject, "is_sneaking");
|
||||
Boolean obool2 = getOptionalBoolean(jsonobject, "is_sprinting");
|
||||
Boolean obool3 = getOptionalBoolean(jsonobject, "is_swimming");
|
||||
Boolean obool4 = getOptionalBoolean(jsonobject, "is_baby");
|
||||
return new EntityFlagsPredicate(obool, obool1, obool2, obool3, obool4);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
private void addOptionalBoolean(JsonObject pJson, String pName, @Nullable Boolean pValue) {
|
||||
if (pValue != null) {
|
||||
pJson.addProperty(pName, pValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
this.addOptionalBoolean(jsonobject, "is_on_fire", this.isOnFire);
|
||||
this.addOptionalBoolean(jsonobject, "is_sneaking", this.isCrouching);
|
||||
this.addOptionalBoolean(jsonobject, "is_sprinting", this.isSprinting);
|
||||
this.addOptionalBoolean(jsonobject, "is_swimming", this.isSwimming);
|
||||
this.addOptionalBoolean(jsonobject, "is_baby", this.isBaby);
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@Nullable
|
||||
private Boolean isOnFire;
|
||||
@Nullable
|
||||
private Boolean isCrouching;
|
||||
@Nullable
|
||||
private Boolean isSprinting;
|
||||
@Nullable
|
||||
private Boolean isSwimming;
|
||||
@Nullable
|
||||
private Boolean isBaby;
|
||||
|
||||
public static EntityFlagsPredicate.Builder flags() {
|
||||
return new EntityFlagsPredicate.Builder();
|
||||
}
|
||||
|
||||
public EntityFlagsPredicate.Builder setOnFire(@Nullable Boolean pOnFire) {
|
||||
this.isOnFire = pOnFire;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityFlagsPredicate.Builder setCrouching(@Nullable Boolean pIsCrouching) {
|
||||
this.isCrouching = pIsCrouching;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityFlagsPredicate.Builder setSprinting(@Nullable Boolean pIsSprinting) {
|
||||
this.isSprinting = pIsSprinting;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityFlagsPredicate.Builder setSwimming(@Nullable Boolean pIsSwimming) {
|
||||
this.isSwimming = pIsSwimming;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityFlagsPredicate.Builder setIsBaby(@Nullable Boolean pIsBaby) {
|
||||
this.isBaby = pIsBaby;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityFlagsPredicate build() {
|
||||
return new EntityFlagsPredicate(this.isOnFire, this.isCrouching, this.isSprinting, this.isSwimming, this.isBaby);
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
|
||||
public class EntityHurtPlayerTrigger extends SimpleCriterionTrigger<EntityHurtPlayerTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("entity_hurt_player");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public EntityHurtPlayerTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
DamagePredicate damagepredicate = DamagePredicate.fromJson(pJson.get("damage"));
|
||||
return new EntityHurtPlayerTrigger.TriggerInstance(pPredicate, damagepredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, DamageSource pSource, float pDealtDamage, float pTakenDamage, boolean pBlocked) {
|
||||
this.trigger(pPlayer, (p_35186_) -> {
|
||||
return p_35186_.matches(pPlayer, pSource, pDealtDamage, pTakenDamage, pBlocked);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final DamagePredicate damage;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, DamagePredicate pDamage) {
|
||||
super(EntityHurtPlayerTrigger.ID, pPlayer);
|
||||
this.damage = pDamage;
|
||||
}
|
||||
|
||||
public static EntityHurtPlayerTrigger.TriggerInstance entityHurtPlayer() {
|
||||
return new EntityHurtPlayerTrigger.TriggerInstance(ContextAwarePredicate.ANY, DamagePredicate.ANY);
|
||||
}
|
||||
|
||||
public static EntityHurtPlayerTrigger.TriggerInstance entityHurtPlayer(DamagePredicate pDamage) {
|
||||
return new EntityHurtPlayerTrigger.TriggerInstance(ContextAwarePredicate.ANY, pDamage);
|
||||
}
|
||||
|
||||
public static EntityHurtPlayerTrigger.TriggerInstance entityHurtPlayer(DamagePredicate.Builder pDamageConditionBuilder) {
|
||||
return new EntityHurtPlayerTrigger.TriggerInstance(ContextAwarePredicate.ANY, pDamageConditionBuilder.build());
|
||||
}
|
||||
|
||||
public boolean matches(ServerPlayer pPlayer, DamageSource pSource, float pDealtDamage, float pTakenDamage, boolean pBlocked) {
|
||||
return this.damage.matches(pPlayer, pSource, pDealtDamage, pTakenDamage, pBlocked);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("damage", this.damage.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+324
@@ -0,0 +1,324 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.LootParams;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemEntityPropertyCondition;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.scores.Team;
|
||||
|
||||
public class EntityPredicate {
|
||||
public static final EntityPredicate ANY = new EntityPredicate(EntityTypePredicate.ANY, DistancePredicate.ANY, LocationPredicate.ANY, LocationPredicate.ANY, MobEffectsPredicate.ANY, NbtPredicate.ANY, EntityFlagsPredicate.ANY, EntityEquipmentPredicate.ANY, EntitySubPredicate.ANY, (String)null);
|
||||
private final EntityTypePredicate entityType;
|
||||
private final DistancePredicate distanceToPlayer;
|
||||
private final LocationPredicate location;
|
||||
private final LocationPredicate steppingOnLocation;
|
||||
private final MobEffectsPredicate effects;
|
||||
private final NbtPredicate nbt;
|
||||
private final EntityFlagsPredicate flags;
|
||||
private final EntityEquipmentPredicate equipment;
|
||||
private final EntitySubPredicate subPredicate;
|
||||
private final EntityPredicate vehicle;
|
||||
private final EntityPredicate passenger;
|
||||
private final EntityPredicate targetedEntity;
|
||||
@Nullable
|
||||
private final String team;
|
||||
|
||||
private EntityPredicate(EntityTypePredicate pEntityType, DistancePredicate pDistanceToPlayer, LocationPredicate pLocation, LocationPredicate pSteppingOnLocation, MobEffectsPredicate pEffects, NbtPredicate pNbt, EntityFlagsPredicate pFlags, EntityEquipmentPredicate pEquipment, EntitySubPredicate pSubPredicate, @Nullable String pTeam) {
|
||||
this.entityType = pEntityType;
|
||||
this.distanceToPlayer = pDistanceToPlayer;
|
||||
this.location = pLocation;
|
||||
this.steppingOnLocation = pSteppingOnLocation;
|
||||
this.effects = pEffects;
|
||||
this.nbt = pNbt;
|
||||
this.flags = pFlags;
|
||||
this.equipment = pEquipment;
|
||||
this.subPredicate = pSubPredicate;
|
||||
this.passenger = this;
|
||||
this.vehicle = this;
|
||||
this.targetedEntity = this;
|
||||
this.team = pTeam;
|
||||
}
|
||||
|
||||
EntityPredicate(EntityTypePredicate pEntityType, DistancePredicate pDistanceToPlayer, LocationPredicate pLocation, LocationPredicate pSteppingOnLocation, MobEffectsPredicate pEffects, NbtPredicate pNbt, EntityFlagsPredicate pFlags, EntityEquipmentPredicate pEquipment, EntitySubPredicate pSubPredicate, EntityPredicate pVehicle, EntityPredicate pPassenger, EntityPredicate pTargetedEntity, @Nullable String pTeam) {
|
||||
this.entityType = pEntityType;
|
||||
this.distanceToPlayer = pDistanceToPlayer;
|
||||
this.location = pLocation;
|
||||
this.steppingOnLocation = pSteppingOnLocation;
|
||||
this.effects = pEffects;
|
||||
this.nbt = pNbt;
|
||||
this.flags = pFlags;
|
||||
this.equipment = pEquipment;
|
||||
this.subPredicate = pSubPredicate;
|
||||
this.vehicle = pVehicle;
|
||||
this.passenger = pPassenger;
|
||||
this.targetedEntity = pTargetedEntity;
|
||||
this.team = pTeam;
|
||||
}
|
||||
|
||||
public static ContextAwarePredicate fromJson(JsonObject pJson, String pId, DeserializationContext pContext) {
|
||||
JsonElement jsonelement = pJson.get(pId);
|
||||
return fromElement(pId, pContext, jsonelement);
|
||||
}
|
||||
|
||||
public static ContextAwarePredicate[] fromJsonArray(JsonObject pJson, String pId, DeserializationContext pContext) {
|
||||
JsonElement jsonelement = pJson.get(pId);
|
||||
if (jsonelement != null && !jsonelement.isJsonNull()) {
|
||||
JsonArray jsonarray = GsonHelper.convertToJsonArray(jsonelement, pId);
|
||||
ContextAwarePredicate[] acontextawarepredicate = new ContextAwarePredicate[jsonarray.size()];
|
||||
|
||||
for(int i = 0; i < jsonarray.size(); ++i) {
|
||||
acontextawarepredicate[i] = fromElement(pId + "[" + i + "]", pContext, jsonarray.get(i));
|
||||
}
|
||||
|
||||
return acontextawarepredicate;
|
||||
} else {
|
||||
return new ContextAwarePredicate[0];
|
||||
}
|
||||
}
|
||||
|
||||
private static ContextAwarePredicate fromElement(String pId, DeserializationContext pContext, @Nullable JsonElement pElement) {
|
||||
ContextAwarePredicate contextawarepredicate = ContextAwarePredicate.fromElement(pId, pContext, pElement, LootContextParamSets.ADVANCEMENT_ENTITY);
|
||||
if (contextawarepredicate != null) {
|
||||
return contextawarepredicate;
|
||||
} else {
|
||||
EntityPredicate entitypredicate = fromJson(pElement);
|
||||
return wrap(entitypredicate);
|
||||
}
|
||||
}
|
||||
|
||||
public static ContextAwarePredicate wrap(EntityPredicate pPredicate) {
|
||||
if (pPredicate == ANY) {
|
||||
return ContextAwarePredicate.ANY;
|
||||
} else {
|
||||
LootItemCondition lootitemcondition = LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, pPredicate).build();
|
||||
return new ContextAwarePredicate(new LootItemCondition[]{lootitemcondition});
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matches(ServerPlayer pPlayer, @Nullable Entity pEntity) {
|
||||
return this.matches(pPlayer.serverLevel(), pPlayer.position(), pEntity);
|
||||
}
|
||||
|
||||
public boolean matches(ServerLevel pLevel, @Nullable Vec3 pPosition, @Nullable Entity pEntity) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else if (pEntity == null) {
|
||||
return false;
|
||||
} else if (!this.entityType.matches(pEntity.getType())) {
|
||||
return false;
|
||||
} else {
|
||||
if (pPosition == null) {
|
||||
if (this.distanceToPlayer != DistancePredicate.ANY) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.distanceToPlayer.matches(pPosition.x, pPosition.y, pPosition.z, pEntity.getX(), pEntity.getY(), pEntity.getZ())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.location.matches(pLevel, pEntity.getX(), pEntity.getY(), pEntity.getZ())) {
|
||||
return false;
|
||||
} else {
|
||||
if (this.steppingOnLocation != LocationPredicate.ANY) {
|
||||
Vec3 vec3 = Vec3.atCenterOf(pEntity.getOnPos());
|
||||
if (!this.steppingOnLocation.matches(pLevel, vec3.x(), vec3.y(), vec3.z())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.effects.matches(pEntity)) {
|
||||
return false;
|
||||
} else if (!this.nbt.matches(pEntity)) {
|
||||
return false;
|
||||
} else if (!this.flags.matches(pEntity)) {
|
||||
return false;
|
||||
} else if (!this.equipment.matches(pEntity)) {
|
||||
return false;
|
||||
} else if (!this.subPredicate.matches(pEntity, pLevel, pPosition)) {
|
||||
return false;
|
||||
} else if (!this.vehicle.matches(pLevel, pPosition, pEntity.getVehicle())) {
|
||||
return false;
|
||||
} else if (this.passenger != ANY && pEntity.getPassengers().stream().noneMatch((p_150322_) -> {
|
||||
return this.passenger.matches(pLevel, pPosition, p_150322_);
|
||||
})) {
|
||||
return false;
|
||||
} else if (!this.targetedEntity.matches(pLevel, pPosition, pEntity instanceof Mob ? ((Mob)pEntity).getTarget() : null)) {
|
||||
return false;
|
||||
} else {
|
||||
if (this.team != null) {
|
||||
Team team = pEntity.getTeam();
|
||||
if (team == null || !this.team.equals(team.getName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "entity");
|
||||
EntityTypePredicate entitytypepredicate = EntityTypePredicate.fromJson(jsonobject.get("type"));
|
||||
DistancePredicate distancepredicate = DistancePredicate.fromJson(jsonobject.get("distance"));
|
||||
LocationPredicate locationpredicate = LocationPredicate.fromJson(jsonobject.get("location"));
|
||||
LocationPredicate locationpredicate1 = LocationPredicate.fromJson(jsonobject.get("stepping_on"));
|
||||
MobEffectsPredicate mobeffectspredicate = MobEffectsPredicate.fromJson(jsonobject.get("effects"));
|
||||
NbtPredicate nbtpredicate = NbtPredicate.fromJson(jsonobject.get("nbt"));
|
||||
EntityFlagsPredicate entityflagspredicate = EntityFlagsPredicate.fromJson(jsonobject.get("flags"));
|
||||
EntityEquipmentPredicate entityequipmentpredicate = EntityEquipmentPredicate.fromJson(jsonobject.get("equipment"));
|
||||
EntitySubPredicate entitysubpredicate = EntitySubPredicate.fromJson(jsonobject.get("type_specific"));
|
||||
EntityPredicate entitypredicate = fromJson(jsonobject.get("vehicle"));
|
||||
EntityPredicate entitypredicate1 = fromJson(jsonobject.get("passenger"));
|
||||
EntityPredicate entitypredicate2 = fromJson(jsonobject.get("targeted_entity"));
|
||||
String s = GsonHelper.getAsString(jsonobject, "team", (String)null);
|
||||
return (new EntityPredicate.Builder()).entityType(entitytypepredicate).distance(distancepredicate).located(locationpredicate).steppingOn(locationpredicate1).effects(mobeffectspredicate).nbt(nbtpredicate).flags(entityflagspredicate).equipment(entityequipmentpredicate).subPredicate(entitysubpredicate).team(s).vehicle(entitypredicate).passenger(entitypredicate1).targetedEntity(entitypredicate2).build();
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("type", this.entityType.serializeToJson());
|
||||
jsonobject.add("distance", this.distanceToPlayer.serializeToJson());
|
||||
jsonobject.add("location", this.location.serializeToJson());
|
||||
jsonobject.add("stepping_on", this.steppingOnLocation.serializeToJson());
|
||||
jsonobject.add("effects", this.effects.serializeToJson());
|
||||
jsonobject.add("nbt", this.nbt.serializeToJson());
|
||||
jsonobject.add("flags", this.flags.serializeToJson());
|
||||
jsonobject.add("equipment", this.equipment.serializeToJson());
|
||||
jsonobject.add("type_specific", this.subPredicate.serialize());
|
||||
jsonobject.add("vehicle", this.vehicle.serializeToJson());
|
||||
jsonobject.add("passenger", this.passenger.serializeToJson());
|
||||
jsonobject.add("targeted_entity", this.targetedEntity.serializeToJson());
|
||||
jsonobject.addProperty("team", this.team);
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static LootContext createContext(ServerPlayer pPlayer, Entity pEntity) {
|
||||
LootParams lootparams = (new LootParams.Builder(pPlayer.serverLevel())).withParameter(LootContextParams.THIS_ENTITY, pEntity).withParameter(LootContextParams.ORIGIN, pPlayer.position()).create(LootContextParamSets.ADVANCEMENT_ENTITY);
|
||||
return (new LootContext.Builder(lootparams)).create((ResourceLocation)null);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private EntityTypePredicate entityType = EntityTypePredicate.ANY;
|
||||
private DistancePredicate distanceToPlayer = DistancePredicate.ANY;
|
||||
private LocationPredicate location = LocationPredicate.ANY;
|
||||
private LocationPredicate steppingOnLocation = LocationPredicate.ANY;
|
||||
private MobEffectsPredicate effects = MobEffectsPredicate.ANY;
|
||||
private NbtPredicate nbt = NbtPredicate.ANY;
|
||||
private EntityFlagsPredicate flags = EntityFlagsPredicate.ANY;
|
||||
private EntityEquipmentPredicate equipment = EntityEquipmentPredicate.ANY;
|
||||
private EntitySubPredicate subPredicate = EntitySubPredicate.ANY;
|
||||
private EntityPredicate vehicle = EntityPredicate.ANY;
|
||||
private EntityPredicate passenger = EntityPredicate.ANY;
|
||||
private EntityPredicate targetedEntity = EntityPredicate.ANY;
|
||||
@Nullable
|
||||
private String team;
|
||||
|
||||
public static EntityPredicate.Builder entity() {
|
||||
return new EntityPredicate.Builder();
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder of(EntityType<?> pEntityType) {
|
||||
this.entityType = EntityTypePredicate.of(pEntityType);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder of(TagKey<EntityType<?>> pEntityTypeTag) {
|
||||
this.entityType = EntityTypePredicate.of(pEntityTypeTag);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder entityType(EntityTypePredicate pEntityType) {
|
||||
this.entityType = pEntityType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder distance(DistancePredicate pDistanceToPlayer) {
|
||||
this.distanceToPlayer = pDistanceToPlayer;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder located(LocationPredicate pLocation) {
|
||||
this.location = pLocation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder steppingOn(LocationPredicate pSteppingOnLocation) {
|
||||
this.steppingOnLocation = pSteppingOnLocation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder effects(MobEffectsPredicate pEffects) {
|
||||
this.effects = pEffects;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder nbt(NbtPredicate pNbt) {
|
||||
this.nbt = pNbt;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder flags(EntityFlagsPredicate pFlags) {
|
||||
this.flags = pFlags;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder equipment(EntityEquipmentPredicate pEquipment) {
|
||||
this.equipment = pEquipment;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder subPredicate(EntitySubPredicate pSubPredicate) {
|
||||
this.subPredicate = pSubPredicate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder vehicle(EntityPredicate pVehicle) {
|
||||
this.vehicle = pVehicle;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder passenger(EntityPredicate pPassenger) {
|
||||
this.passenger = pPassenger;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder targetedEntity(EntityPredicate pTargetedEntity) {
|
||||
this.targetedEntity = pTargetedEntity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate.Builder team(@Nullable String pTeam) {
|
||||
this.team = pTeam;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityPredicate build() {
|
||||
return new EntityPredicate(this.entityType, this.distanceToPlayer, this.location, this.steppingOnLocation, this.effects, this.nbt, this.flags, this.equipment, this.subPredicate, this.vehicle, this.passenger, this.targetedEntity, this.team);
|
||||
}
|
||||
}
|
||||
}
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.animal.Cat;
|
||||
import net.minecraft.world.entity.animal.CatVariant;
|
||||
import net.minecraft.world.entity.animal.Fox;
|
||||
import net.minecraft.world.entity.animal.FrogVariant;
|
||||
import net.minecraft.world.entity.animal.MushroomCow;
|
||||
import net.minecraft.world.entity.animal.Parrot;
|
||||
import net.minecraft.world.entity.animal.Rabbit;
|
||||
import net.minecraft.world.entity.animal.TropicalFish;
|
||||
import net.minecraft.world.entity.animal.axolotl.Axolotl;
|
||||
import net.minecraft.world.entity.animal.frog.Frog;
|
||||
import net.minecraft.world.entity.animal.horse.Horse;
|
||||
import net.minecraft.world.entity.animal.horse.Llama;
|
||||
import net.minecraft.world.entity.animal.horse.Variant;
|
||||
import net.minecraft.world.entity.decoration.Painting;
|
||||
import net.minecraft.world.entity.decoration.PaintingVariant;
|
||||
import net.minecraft.world.entity.npc.VillagerDataHolder;
|
||||
import net.minecraft.world.entity.npc.VillagerType;
|
||||
import net.minecraft.world.entity.vehicle.Boat;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public interface EntitySubPredicate {
|
||||
EntitySubPredicate ANY = new EntitySubPredicate() {
|
||||
public boolean matches(Entity p_218841_, ServerLevel p_218842_, @Nullable Vec3 p_218843_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public JsonObject serializeCustomData() {
|
||||
return new JsonObject();
|
||||
}
|
||||
|
||||
public EntitySubPredicate.Type type() {
|
||||
return EntitySubPredicate.Types.ANY;
|
||||
}
|
||||
};
|
||||
|
||||
static EntitySubPredicate fromJson(@Nullable JsonElement p_218836_) {
|
||||
if (p_218836_ != null && !p_218836_.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(p_218836_, "type_specific");
|
||||
String s = GsonHelper.getAsString(jsonobject, "type", (String)null);
|
||||
if (s == null) {
|
||||
return ANY;
|
||||
} else {
|
||||
EntitySubPredicate.Type entitysubpredicate$type = EntitySubPredicate.Types.TYPES.get(s);
|
||||
if (entitysubpredicate$type == null) {
|
||||
throw new JsonSyntaxException("Unknown sub-predicate type: " + s);
|
||||
} else {
|
||||
return entitysubpredicate$type.deserialize(jsonobject);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
boolean matches(Entity pEntity, ServerLevel pLevel, @Nullable Vec3 p_218830_);
|
||||
|
||||
JsonObject serializeCustomData();
|
||||
|
||||
default JsonElement serialize() {
|
||||
if (this.type() == EntitySubPredicate.Types.ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = this.serializeCustomData();
|
||||
String s = EntitySubPredicate.Types.TYPES.inverse().get(this.type());
|
||||
jsonobject.addProperty("type", s);
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
EntitySubPredicate.Type type();
|
||||
|
||||
static EntitySubPredicate variant(CatVariant p_218832_) {
|
||||
return EntitySubPredicate.Types.CAT.createPredicate(p_218832_);
|
||||
}
|
||||
|
||||
static EntitySubPredicate variant(FrogVariant p_218834_) {
|
||||
return EntitySubPredicate.Types.FROG.createPredicate(p_218834_);
|
||||
}
|
||||
|
||||
public interface Type {
|
||||
EntitySubPredicate deserialize(JsonObject p_218846_);
|
||||
}
|
||||
|
||||
public static final class Types {
|
||||
public static final EntitySubPredicate.Type ANY = (p_218860_) -> {
|
||||
return EntitySubPredicate.ANY;
|
||||
};
|
||||
public static final EntitySubPredicate.Type LIGHTNING = LighthingBoltPredicate::fromJson;
|
||||
public static final EntitySubPredicate.Type FISHING_HOOK = FishingHookPredicate::fromJson;
|
||||
public static final EntitySubPredicate.Type PLAYER = PlayerPredicate::fromJson;
|
||||
public static final EntitySubPredicate.Type SLIME = SlimePredicate::fromJson;
|
||||
public static final EntityVariantPredicate<CatVariant> CAT = EntityVariantPredicate.create(BuiltInRegistries.CAT_VARIANT, (p_218862_) -> {
|
||||
Optional optional;
|
||||
if (p_218862_ instanceof Cat cat) {
|
||||
optional = Optional.of(cat.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<FrogVariant> FROG = EntityVariantPredicate.create(BuiltInRegistries.FROG_VARIANT, (p_218858_) -> {
|
||||
Optional optional;
|
||||
if (p_218858_ instanceof Frog frog) {
|
||||
optional = Optional.of(frog.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<Axolotl.Variant> AXOLOTL = EntityVariantPredicate.create(Axolotl.Variant.CODEC, (p_262508_) -> {
|
||||
Optional optional;
|
||||
if (p_262508_ instanceof Axolotl axolotl) {
|
||||
optional = Optional.of(axolotl.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<Boat.Type> BOAT = EntityVariantPredicate.create(Boat.Type.CODEC, (p_262507_) -> {
|
||||
Optional optional;
|
||||
if (p_262507_ instanceof Boat boat) {
|
||||
optional = Optional.of(boat.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<Fox.Type> FOX = EntityVariantPredicate.create(Fox.Type.CODEC, (p_262510_) -> {
|
||||
Optional optional;
|
||||
if (p_262510_ instanceof Fox fox) {
|
||||
optional = Optional.of(fox.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<MushroomCow.MushroomType> MOOSHROOM = EntityVariantPredicate.create(MushroomCow.MushroomType.CODEC, (p_262513_) -> {
|
||||
Optional optional;
|
||||
if (p_262513_ instanceof MushroomCow mushroomcow) {
|
||||
optional = Optional.of(mushroomcow.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<Holder<PaintingVariant>> PAINTING = EntityVariantPredicate.create(BuiltInRegistries.PAINTING_VARIANT.holderByNameCodec(), (p_262509_) -> {
|
||||
Optional optional;
|
||||
if (p_262509_ instanceof Painting painting) {
|
||||
optional = Optional.of(painting.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<Rabbit.Variant> RABBIT = EntityVariantPredicate.create(Rabbit.Variant.CODEC, (p_262511_) -> {
|
||||
Optional optional;
|
||||
if (p_262511_ instanceof Rabbit rabbit) {
|
||||
optional = Optional.of(rabbit.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<Variant> HORSE = EntityVariantPredicate.create(Variant.CODEC, (p_262516_) -> {
|
||||
Optional optional;
|
||||
if (p_262516_ instanceof Horse horse) {
|
||||
optional = Optional.of(horse.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<Llama.Variant> LLAMA = EntityVariantPredicate.create(Llama.Variant.CODEC, (p_262515_) -> {
|
||||
Optional optional;
|
||||
if (p_262515_ instanceof Llama llama) {
|
||||
optional = Optional.of(llama.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<VillagerType> VILLAGER = EntityVariantPredicate.create(BuiltInRegistries.VILLAGER_TYPE.byNameCodec(), (p_262512_) -> {
|
||||
Optional optional;
|
||||
if (p_262512_ instanceof VillagerDataHolder villagerdataholder) {
|
||||
optional = Optional.of(villagerdataholder.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<Parrot.Variant> PARROT = EntityVariantPredicate.create(Parrot.Variant.CODEC, (p_262506_) -> {
|
||||
Optional optional;
|
||||
if (p_262506_ instanceof Parrot parrot) {
|
||||
optional = Optional.of(parrot.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final EntityVariantPredicate<TropicalFish.Pattern> TROPICAL_FISH = EntityVariantPredicate.create(TropicalFish.Pattern.CODEC, (p_262517_) -> {
|
||||
Optional optional;
|
||||
if (p_262517_ instanceof TropicalFish tropicalfish) {
|
||||
optional = Optional.of(tropicalfish.getVariant());
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
});
|
||||
public static final BiMap<String, EntitySubPredicate.Type> TYPES = ImmutableBiMap.<String, EntitySubPredicate.Type>builder().put("any", ANY).put("lightning", LIGHTNING).put("fishing_hook", FISHING_HOOK).put("player", PLAYER).put("slime", SLIME).put("cat", CAT.type()).put("frog", FROG.type()).put("axolotl", AXOLOTL.type()).put("boat", BOAT.type()).put("fox", FOX.type()).put("mooshroom", MOOSHROOM.type()).put("painting", PAINTING.type()).put("rabbit", RABBIT.type()).put("horse", HORSE.type()).put("llama", LLAMA.type()).put("villager", VILLAGER.type()).put("parrot", PARROT.type()).put("tropical_fish", TROPICAL_FISH.type()).buildOrThrow();
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
||||
public abstract class EntityTypePredicate {
|
||||
public static final EntityTypePredicate ANY = new EntityTypePredicate() {
|
||||
public boolean matches(EntityType<?> p_37652_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
};
|
||||
private static final Joiner COMMA_JOINER = Joiner.on(", ");
|
||||
|
||||
public abstract boolean matches(EntityType<?> pType);
|
||||
|
||||
public abstract JsonElement serializeToJson();
|
||||
|
||||
public static EntityTypePredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
String s = GsonHelper.convertToString(pJson, "type");
|
||||
if (s.startsWith("#")) {
|
||||
ResourceLocation resourcelocation1 = new ResourceLocation(s.substring(1));
|
||||
return new EntityTypePredicate.TagPredicate(TagKey.create(Registries.ENTITY_TYPE, resourcelocation1));
|
||||
} else {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(s);
|
||||
EntityType<?> entitytype = BuiltInRegistries.ENTITY_TYPE.getOptional(resourcelocation).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown entity type '" + resourcelocation + "', valid types are: " + COMMA_JOINER.join(BuiltInRegistries.ENTITY_TYPE.keySet()));
|
||||
});
|
||||
return new EntityTypePredicate.TypePredicate(entitytype);
|
||||
}
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityTypePredicate of(EntityType<?> pType) {
|
||||
return new EntityTypePredicate.TypePredicate(pType);
|
||||
}
|
||||
|
||||
public static EntityTypePredicate of(TagKey<EntityType<?>> pTag) {
|
||||
return new EntityTypePredicate.TagPredicate(pTag);
|
||||
}
|
||||
|
||||
static class TagPredicate extends EntityTypePredicate {
|
||||
private final TagKey<EntityType<?>> tag;
|
||||
|
||||
public TagPredicate(TagKey<EntityType<?>> pTag) {
|
||||
this.tag = pTag;
|
||||
}
|
||||
|
||||
public boolean matches(EntityType<?> pType) {
|
||||
return pType.is(this.tag);
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
return new JsonPrimitive("#" + this.tag.location());
|
||||
}
|
||||
}
|
||||
|
||||
static class TypePredicate extends EntityTypePredicate {
|
||||
private final EntityType<?> type;
|
||||
|
||||
public TypePredicate(EntityType<?> pType) {
|
||||
this.type = pType;
|
||||
}
|
||||
|
||||
public boolean matches(EntityType<?> pType) {
|
||||
return this.type == pType;
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
return new JsonPrimitive(BuiltInRegistries.ENTITY_TYPE.getKey(this.type).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.Dynamic;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class EntityVariantPredicate<V> {
|
||||
private static final String VARIANT_KEY = "variant";
|
||||
final Codec<V> variantCodec;
|
||||
final Function<Entity, Optional<V>> getter;
|
||||
final EntitySubPredicate.Type type;
|
||||
|
||||
public static <V> EntityVariantPredicate<V> create(Registry<V> p_219094_, Function<Entity, Optional<V>> p_219095_) {
|
||||
return new EntityVariantPredicate<>(p_219094_.byNameCodec(), p_219095_);
|
||||
}
|
||||
|
||||
public static <V> EntityVariantPredicate<V> create(Codec<V> p_262671_, Function<Entity, Optional<V>> p_262652_) {
|
||||
return new EntityVariantPredicate<>(p_262671_, p_262652_);
|
||||
}
|
||||
|
||||
private EntityVariantPredicate(Codec<V> p_262574_, Function<Entity, Optional<V>> p_262610_) {
|
||||
this.variantCodec = p_262574_;
|
||||
this.getter = p_262610_;
|
||||
this.type = (p_262519_) -> {
|
||||
JsonElement jsonelement = p_262519_.get("variant");
|
||||
if (jsonelement == null) {
|
||||
throw new JsonParseException("Missing variant field");
|
||||
} else {
|
||||
V v = Util.getOrThrow(p_262574_.decode(new Dynamic<>(JsonOps.INSTANCE, jsonelement)), JsonParseException::new).getFirst();
|
||||
return this.createPredicate(v);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public EntitySubPredicate.Type type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public EntitySubPredicate createPredicate(final V p_219097_) {
|
||||
return new EntitySubPredicate() {
|
||||
public boolean matches(Entity p_219105_, ServerLevel p_219106_, @Nullable Vec3 p_219107_) {
|
||||
return EntityVariantPredicate.this.getter.apply(p_219105_).filter((p_219110_) -> {
|
||||
return p_219110_.equals(p_219097_);
|
||||
}).isPresent();
|
||||
}
|
||||
|
||||
public JsonObject serializeCustomData() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("variant", Util.getOrThrow(EntityVariantPredicate.this.variantCodec.encodeStart(JsonOps.INSTANCE, p_219097_), (p_262521_) -> {
|
||||
return new JsonParseException("Can't serialize variant " + p_219097_ + ", message " + p_262521_);
|
||||
}));
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public EntitySubPredicate.Type type() {
|
||||
return EntityVariantPredicate.this.type;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class FilledBucketTrigger extends SimpleCriterionTrigger<FilledBucketTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("filled_bucket");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public FilledBucketTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(pJson.get("item"));
|
||||
return new FilledBucketTrigger.TriggerInstance(pPredicate, itempredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ItemStack pStack) {
|
||||
this.trigger(pPlayer, (p_38777_) -> {
|
||||
return p_38777_.matches(pStack);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ItemPredicate item;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ItemPredicate pItem) {
|
||||
super(FilledBucketTrigger.ID, pPlayer);
|
||||
this.item = pItem;
|
||||
}
|
||||
|
||||
public static FilledBucketTrigger.TriggerInstance filledBucket(ItemPredicate pItem) {
|
||||
return new FilledBucketTrigger.TriggerInstance(ContextAwarePredicate.ANY, pItem);
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack pStack) {
|
||||
return this.item.matches(pStack);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.projectile.FishingHook;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class FishingHookPredicate implements EntitySubPredicate {
|
||||
public static final FishingHookPredicate ANY = new FishingHookPredicate(false);
|
||||
private static final String IN_OPEN_WATER_KEY = "in_open_water";
|
||||
private final boolean inOpenWater;
|
||||
|
||||
private FishingHookPredicate(boolean pInOpenWater) {
|
||||
this.inOpenWater = pInOpenWater;
|
||||
}
|
||||
|
||||
public static FishingHookPredicate inOpenWater(boolean pInOpenWater) {
|
||||
return new FishingHookPredicate(pInOpenWater);
|
||||
}
|
||||
|
||||
public static FishingHookPredicate fromJson(JsonObject pJson) {
|
||||
JsonElement jsonelement = pJson.get("in_open_water");
|
||||
return jsonelement != null ? new FishingHookPredicate(GsonHelper.convertToBoolean(jsonelement, "in_open_water")) : ANY;
|
||||
}
|
||||
|
||||
public JsonObject serializeCustomData() {
|
||||
if (this == ANY) {
|
||||
return new JsonObject();
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("in_open_water", new JsonPrimitive(this.inOpenWater));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public EntitySubPredicate.Type type() {
|
||||
return EntitySubPredicate.Types.FISHING_HOOK;
|
||||
}
|
||||
|
||||
public boolean matches(Entity pEntity, ServerLevel pLevel, @Nullable Vec3 p_219718_) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else if (!(pEntity instanceof FishingHook)) {
|
||||
return false;
|
||||
} else {
|
||||
FishingHook fishinghook = (FishingHook)pEntity;
|
||||
return this.inOpenWater == fishinghook.isOpenWaterFishing();
|
||||
}
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.Collection;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.projectile.FishingHook;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
|
||||
public class FishingRodHookedTrigger extends SimpleCriterionTrigger<FishingRodHookedTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("fishing_rod_hooked");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public FishingRodHookedTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(pJson.get("rod"));
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "entity", pDeserializationContext);
|
||||
ItemPredicate itempredicate1 = ItemPredicate.fromJson(pJson.get("item"));
|
||||
return new FishingRodHookedTrigger.TriggerInstance(pPredicate, itempredicate, contextawarepredicate, itempredicate1);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ItemStack pRod, FishingHook pEntity, Collection<ItemStack> pStacks) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, (Entity)(pEntity.getHookedIn() != null ? pEntity.getHookedIn() : pEntity));
|
||||
this.trigger(pPlayer, (p_40425_) -> {
|
||||
return p_40425_.matches(pRod, lootcontext, pStacks);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ItemPredicate rod;
|
||||
private final ContextAwarePredicate entity;
|
||||
private final ItemPredicate item;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ItemPredicate pRod, ContextAwarePredicate pEntity, ItemPredicate pItem) {
|
||||
super(FishingRodHookedTrigger.ID, pPlayer);
|
||||
this.rod = pRod;
|
||||
this.entity = pEntity;
|
||||
this.item = pItem;
|
||||
}
|
||||
|
||||
public static FishingRodHookedTrigger.TriggerInstance fishedItem(ItemPredicate pRod, EntityPredicate pBobber, ItemPredicate pItem) {
|
||||
return new FishingRodHookedTrigger.TriggerInstance(ContextAwarePredicate.ANY, pRod, EntityPredicate.wrap(pBobber), pItem);
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack pRod, LootContext pContext, Collection<ItemStack> pStacks) {
|
||||
if (!this.rod.matches(pRod)) {
|
||||
return false;
|
||||
} else if (!this.entity.matches(pContext)) {
|
||||
return false;
|
||||
} else {
|
||||
if (this.item != ItemPredicate.ANY) {
|
||||
boolean flag = false;
|
||||
Entity entity = pContext.getParamOrNull(LootContextParams.THIS_ENTITY);
|
||||
if (entity instanceof ItemEntity) {
|
||||
ItemEntity itementity = (ItemEntity)entity;
|
||||
if (this.item.matches(itementity.getItem())) {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
for(ItemStack itemstack : pStacks) {
|
||||
if (this.item.matches(itemstack)) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("rod", this.rod.serializeToJson());
|
||||
jsonobject.add("entity", this.entity.toJson(pConditions));
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
|
||||
public class FluidPredicate {
|
||||
public static final FluidPredicate ANY = new FluidPredicate((TagKey<Fluid>)null, (Fluid)null, StatePropertiesPredicate.ANY);
|
||||
@Nullable
|
||||
private final TagKey<Fluid> tag;
|
||||
@Nullable
|
||||
private final Fluid fluid;
|
||||
private final StatePropertiesPredicate properties;
|
||||
|
||||
public FluidPredicate(@Nullable TagKey<Fluid> pTag, @Nullable Fluid pFluid, StatePropertiesPredicate pProperties) {
|
||||
this.tag = pTag;
|
||||
this.fluid = pFluid;
|
||||
this.properties = pProperties;
|
||||
}
|
||||
|
||||
public boolean matches(ServerLevel pLevel, BlockPos pPos) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else if (!pLevel.isLoaded(pPos)) {
|
||||
return false;
|
||||
} else {
|
||||
FluidState fluidstate = pLevel.getFluidState(pPos);
|
||||
if (this.tag != null && !fluidstate.is(this.tag)) {
|
||||
return false;
|
||||
} else if (this.fluid != null && !fluidstate.is(this.fluid)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.properties.matches(fluidstate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static FluidPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "fluid");
|
||||
Fluid fluid = null;
|
||||
if (jsonobject.has("fluid")) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(jsonobject, "fluid"));
|
||||
fluid = BuiltInRegistries.FLUID.get(resourcelocation);
|
||||
}
|
||||
|
||||
TagKey<Fluid> tagkey = null;
|
||||
if (jsonobject.has("tag")) {
|
||||
ResourceLocation resourcelocation1 = new ResourceLocation(GsonHelper.getAsString(jsonobject, "tag"));
|
||||
tagkey = TagKey.create(Registries.FLUID, resourcelocation1);
|
||||
}
|
||||
|
||||
StatePropertiesPredicate statepropertiespredicate = StatePropertiesPredicate.fromJson(jsonobject.get("state"));
|
||||
return new FluidPredicate(tagkey, fluid, statepropertiespredicate);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (this.fluid != null) {
|
||||
jsonobject.addProperty("fluid", BuiltInRegistries.FLUID.getKey(this.fluid).toString());
|
||||
}
|
||||
|
||||
if (this.tag != null) {
|
||||
jsonobject.addProperty("tag", this.tag.location().toString());
|
||||
}
|
||||
|
||||
jsonobject.add("state", this.properties.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@Nullable
|
||||
private Fluid fluid;
|
||||
@Nullable
|
||||
private TagKey<Fluid> fluids;
|
||||
private StatePropertiesPredicate properties = StatePropertiesPredicate.ANY;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
public static FluidPredicate.Builder fluid() {
|
||||
return new FluidPredicate.Builder();
|
||||
}
|
||||
|
||||
public FluidPredicate.Builder of(Fluid pFluid) {
|
||||
this.fluid = pFluid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluidPredicate.Builder of(TagKey<Fluid> pFluids) {
|
||||
this.fluids = pFluids;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluidPredicate.Builder setProperties(StatePropertiesPredicate pProperties) {
|
||||
this.properties = pProperties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluidPredicate build() {
|
||||
return new FluidPredicate(this.fluids, this.fluid, this.properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.advancements.CriterionTrigger;
|
||||
import net.minecraft.advancements.CriterionTriggerInstance;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.PlayerAdvancements;
|
||||
|
||||
public class ImpossibleTrigger implements CriterionTrigger<ImpossibleTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("impossible");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public void addPlayerListener(PlayerAdvancements pPlayerAdvancements, CriterionTrigger.Listener<ImpossibleTrigger.TriggerInstance> pListener) {
|
||||
}
|
||||
|
||||
public void removePlayerListener(PlayerAdvancements pPlayerAdvancements, CriterionTrigger.Listener<ImpossibleTrigger.TriggerInstance> pListener) {
|
||||
}
|
||||
|
||||
public void removePlayerListeners(PlayerAdvancements pPlayerAdvancements) {
|
||||
}
|
||||
|
||||
public ImpossibleTrigger.TriggerInstance createInstance(JsonObject pObject, DeserializationContext pConditions) {
|
||||
return new ImpossibleTrigger.TriggerInstance();
|
||||
}
|
||||
|
||||
public static class TriggerInstance implements CriterionTriggerInstance {
|
||||
public ResourceLocation getCriterion() {
|
||||
return ImpossibleTrigger.ID;
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
return new JsonObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.alchemy.Potion;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
|
||||
public class InventoryChangeTrigger extends SimpleCriterionTrigger<InventoryChangeTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("inventory_changed");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public InventoryChangeTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
JsonObject jsonobject = GsonHelper.getAsJsonObject(pJson, "slots", new JsonObject());
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(jsonobject.get("occupied"));
|
||||
MinMaxBounds.Ints minmaxbounds$ints1 = MinMaxBounds.Ints.fromJson(jsonobject.get("full"));
|
||||
MinMaxBounds.Ints minmaxbounds$ints2 = MinMaxBounds.Ints.fromJson(jsonobject.get("empty"));
|
||||
ItemPredicate[] aitempredicate = ItemPredicate.fromJsonArray(pJson.get("items"));
|
||||
return new InventoryChangeTrigger.TriggerInstance(pPredicate, minmaxbounds$ints, minmaxbounds$ints1, minmaxbounds$ints2, aitempredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Inventory pInventory, ItemStack pStack) {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
|
||||
for(int l = 0; l < pInventory.getContainerSize(); ++l) {
|
||||
ItemStack itemstack = pInventory.getItem(l);
|
||||
if (itemstack.isEmpty()) {
|
||||
++j;
|
||||
} else {
|
||||
++k;
|
||||
if (itemstack.getCount() >= itemstack.getMaxStackSize()) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.trigger(pPlayer, pInventory, pStack, i, j, k);
|
||||
}
|
||||
|
||||
private void trigger(ServerPlayer pPlayer, Inventory pInventory, ItemStack pStack, int pFull, int pEmpty, int pOccupied) {
|
||||
this.trigger(pPlayer, (p_43166_) -> {
|
||||
return p_43166_.matches(pInventory, pStack, pFull, pEmpty, pOccupied);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final MinMaxBounds.Ints slotsOccupied;
|
||||
private final MinMaxBounds.Ints slotsFull;
|
||||
private final MinMaxBounds.Ints slotsEmpty;
|
||||
private final ItemPredicate[] predicates;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, MinMaxBounds.Ints pSlotsOccupied, MinMaxBounds.Ints pSlotsFull, MinMaxBounds.Ints pSlotsEmpty, ItemPredicate[] pPredicates) {
|
||||
super(InventoryChangeTrigger.ID, pPlayer);
|
||||
this.slotsOccupied = pSlotsOccupied;
|
||||
this.slotsFull = pSlotsFull;
|
||||
this.slotsEmpty = pSlotsEmpty;
|
||||
this.predicates = pPredicates;
|
||||
}
|
||||
|
||||
public static InventoryChangeTrigger.TriggerInstance hasItems(ItemPredicate... pItems) {
|
||||
return new InventoryChangeTrigger.TriggerInstance(ContextAwarePredicate.ANY, MinMaxBounds.Ints.ANY, MinMaxBounds.Ints.ANY, MinMaxBounds.Ints.ANY, pItems);
|
||||
}
|
||||
|
||||
public static InventoryChangeTrigger.TriggerInstance hasItems(ItemLike... pItems) {
|
||||
ItemPredicate[] aitempredicate = new ItemPredicate[pItems.length];
|
||||
|
||||
for(int i = 0; i < pItems.length; ++i) {
|
||||
aitempredicate[i] = new ItemPredicate((TagKey<Item>)null, ImmutableSet.of(pItems[i].asItem()), MinMaxBounds.Ints.ANY, MinMaxBounds.Ints.ANY, EnchantmentPredicate.NONE, EnchantmentPredicate.NONE, (Potion)null, NbtPredicate.ANY);
|
||||
}
|
||||
|
||||
return hasItems(aitempredicate);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
if (!this.slotsOccupied.isAny() || !this.slotsFull.isAny() || !this.slotsEmpty.isAny()) {
|
||||
JsonObject jsonobject1 = new JsonObject();
|
||||
jsonobject1.add("occupied", this.slotsOccupied.serializeToJson());
|
||||
jsonobject1.add("full", this.slotsFull.serializeToJson());
|
||||
jsonobject1.add("empty", this.slotsEmpty.serializeToJson());
|
||||
jsonobject.add("slots", jsonobject1);
|
||||
}
|
||||
|
||||
if (this.predicates.length > 0) {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
for(ItemPredicate itempredicate : this.predicates) {
|
||||
jsonarray.add(itempredicate.serializeToJson());
|
||||
}
|
||||
|
||||
jsonobject.add("items", jsonarray);
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public boolean matches(Inventory pInventory, ItemStack pStack, int pFull, int pEmpty, int pOccupied) {
|
||||
if (!this.slotsFull.matches(pFull)) {
|
||||
return false;
|
||||
} else if (!this.slotsEmpty.matches(pEmpty)) {
|
||||
return false;
|
||||
} else if (!this.slotsOccupied.matches(pOccupied)) {
|
||||
return false;
|
||||
} else {
|
||||
int i = this.predicates.length;
|
||||
if (i == 0) {
|
||||
return true;
|
||||
} else if (i != 1) {
|
||||
List<ItemPredicate> list = new ObjectArrayList<>(this.predicates);
|
||||
int j = pInventory.getContainerSize();
|
||||
|
||||
for(int k = 0; k < j; ++k) {
|
||||
if (list.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ItemStack itemstack = pInventory.getItem(k);
|
||||
if (!itemstack.isEmpty()) {
|
||||
list.removeIf((p_43194_) -> {
|
||||
return p_43194_.matches(itemstack);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return list.isEmpty();
|
||||
} else {
|
||||
return !pStack.isEmpty() && this.predicates[0].matches(pStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class ItemDurabilityTrigger extends SimpleCriterionTrigger<ItemDurabilityTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("item_durability_changed");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public ItemDurabilityTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(pJson.get("item"));
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(pJson.get("durability"));
|
||||
MinMaxBounds.Ints minmaxbounds$ints1 = MinMaxBounds.Ints.fromJson(pJson.get("delta"));
|
||||
return new ItemDurabilityTrigger.TriggerInstance(pPredicate, itempredicate, minmaxbounds$ints, minmaxbounds$ints1);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ItemStack pItem, int pNewDurability) {
|
||||
this.trigger(pPlayer, (p_43676_) -> {
|
||||
return p_43676_.matches(pItem, pNewDurability);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ItemPredicate item;
|
||||
private final MinMaxBounds.Ints durability;
|
||||
private final MinMaxBounds.Ints delta;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ItemPredicate pItem, MinMaxBounds.Ints pDurability, MinMaxBounds.Ints pDelta) {
|
||||
super(ItemDurabilityTrigger.ID, pPlayer);
|
||||
this.item = pItem;
|
||||
this.durability = pDurability;
|
||||
this.delta = pDelta;
|
||||
}
|
||||
|
||||
public static ItemDurabilityTrigger.TriggerInstance changedDurability(ItemPredicate pItem, MinMaxBounds.Ints pDurability) {
|
||||
return changedDurability(ContextAwarePredicate.ANY, pItem, pDurability);
|
||||
}
|
||||
|
||||
public static ItemDurabilityTrigger.TriggerInstance changedDurability(ContextAwarePredicate pPlayer, ItemPredicate pItem, MinMaxBounds.Ints pDurability) {
|
||||
return new ItemDurabilityTrigger.TriggerInstance(pPlayer, pItem, pDurability, MinMaxBounds.Ints.ANY);
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack pItem, int pDurability) {
|
||||
if (!this.item.matches(pItem)) {
|
||||
return false;
|
||||
} else if (!this.durability.matches(pItem.getMaxDamage() - pDurability)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.delta.matches(pItem.getDamageValue() - pDurability);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
jsonobject.add("durability", this.durability.serializeToJson());
|
||||
jsonobject.add("delta", this.delta.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+299
@@ -0,0 +1,299 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.EnchantedBookItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.alchemy.Potion;
|
||||
import net.minecraft.world.item.alchemy.PotionUtils;
|
||||
import net.minecraft.world.item.enchantment.Enchantment;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
|
||||
public class ItemPredicate {
|
||||
private static final Map<ResourceLocation, java.util.function.Function<JsonObject, ItemPredicate>> custom_predicates = new java.util.HashMap<>();
|
||||
private static final Map<ResourceLocation, java.util.function.Function<JsonObject, ItemPredicate>> unmod_predicates = java.util.Collections.unmodifiableMap(custom_predicates);
|
||||
public static final ItemPredicate ANY = new ItemPredicate();
|
||||
@Nullable
|
||||
private final TagKey<Item> tag;
|
||||
@Nullable
|
||||
private final Set<Item> items;
|
||||
private final MinMaxBounds.Ints count;
|
||||
private final MinMaxBounds.Ints durability;
|
||||
private final EnchantmentPredicate[] enchantments;
|
||||
private final EnchantmentPredicate[] storedEnchantments;
|
||||
@Nullable
|
||||
private final Potion potion;
|
||||
private final NbtPredicate nbt;
|
||||
|
||||
public ItemPredicate() {
|
||||
this.tag = null;
|
||||
this.items = null;
|
||||
this.potion = null;
|
||||
this.count = MinMaxBounds.Ints.ANY;
|
||||
this.durability = MinMaxBounds.Ints.ANY;
|
||||
this.enchantments = EnchantmentPredicate.NONE;
|
||||
this.storedEnchantments = EnchantmentPredicate.NONE;
|
||||
this.nbt = NbtPredicate.ANY;
|
||||
}
|
||||
|
||||
public ItemPredicate(@Nullable TagKey<Item> pTag, @Nullable Set<Item> pItems, MinMaxBounds.Ints pCount, MinMaxBounds.Ints pDurability, EnchantmentPredicate[] pEnchantments, EnchantmentPredicate[] pStoredEnchantments, @Nullable Potion pPotion, NbtPredicate pNbt) {
|
||||
this.tag = pTag;
|
||||
this.items = pItems;
|
||||
this.count = pCount;
|
||||
this.durability = pDurability;
|
||||
this.enchantments = pEnchantments;
|
||||
this.storedEnchantments = pStoredEnchantments;
|
||||
this.potion = pPotion;
|
||||
this.nbt = pNbt;
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack pItem) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else if (this.tag != null && !pItem.is(this.tag)) {
|
||||
return false;
|
||||
} else if (this.items != null && !this.items.contains(pItem.getItem())) {
|
||||
return false;
|
||||
} else if (!this.count.matches(pItem.getCount())) {
|
||||
return false;
|
||||
} else if (!this.durability.isAny() && !pItem.isDamageableItem()) {
|
||||
return false;
|
||||
} else if (!this.durability.matches(pItem.getMaxDamage() - pItem.getDamageValue())) {
|
||||
return false;
|
||||
} else if (!this.nbt.matches(pItem)) {
|
||||
return false;
|
||||
} else {
|
||||
if (this.enchantments.length > 0) {
|
||||
Map<Enchantment, Integer> map = pItem.getAllEnchantments();
|
||||
|
||||
for(EnchantmentPredicate enchantmentpredicate : this.enchantments) {
|
||||
if (!enchantmentpredicate.containedIn(map)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.storedEnchantments.length > 0) {
|
||||
Map<Enchantment, Integer> map1 = EnchantmentHelper.deserializeEnchantments(EnchantedBookItem.getEnchantments(pItem));
|
||||
|
||||
for(EnchantmentPredicate enchantmentpredicate1 : this.storedEnchantments) {
|
||||
if (!enchantmentpredicate1.containedIn(map1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Potion potion = PotionUtils.getPotion(pItem);
|
||||
return this.potion == null || this.potion == potion;
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "item");
|
||||
if (jsonobject.has("type")) {
|
||||
final ResourceLocation rl = new ResourceLocation(GsonHelper.getAsString(jsonobject, "type"));
|
||||
if (custom_predicates.containsKey(rl)) return custom_predicates.get(rl).apply(jsonobject);
|
||||
else throw new JsonSyntaxException("There is no ItemPredicate of type "+rl);
|
||||
}
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(jsonobject.get("count"));
|
||||
MinMaxBounds.Ints minmaxbounds$ints1 = MinMaxBounds.Ints.fromJson(jsonobject.get("durability"));
|
||||
if (jsonobject.has("data")) {
|
||||
throw new JsonParseException("Disallowed data tag found");
|
||||
} else {
|
||||
NbtPredicate nbtpredicate = NbtPredicate.fromJson(jsonobject.get("nbt"));
|
||||
Set<Item> set = null;
|
||||
JsonArray jsonarray = GsonHelper.getAsJsonArray(jsonobject, "items", (JsonArray)null);
|
||||
if (jsonarray != null) {
|
||||
ImmutableSet.Builder<Item> builder = ImmutableSet.builder();
|
||||
|
||||
for(JsonElement jsonelement : jsonarray) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.convertToString(jsonelement, "item"));
|
||||
builder.add(BuiltInRegistries.ITEM.getOptional(resourcelocation).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown item id '" + resourcelocation + "'");
|
||||
}));
|
||||
}
|
||||
|
||||
set = builder.build();
|
||||
}
|
||||
|
||||
TagKey<Item> tagkey = null;
|
||||
if (jsonobject.has("tag")) {
|
||||
ResourceLocation resourcelocation1 = new ResourceLocation(GsonHelper.getAsString(jsonobject, "tag"));
|
||||
tagkey = TagKey.create(Registries.ITEM, resourcelocation1);
|
||||
}
|
||||
|
||||
Potion potion = null;
|
||||
if (jsonobject.has("potion")) {
|
||||
ResourceLocation resourcelocation2 = new ResourceLocation(GsonHelper.getAsString(jsonobject, "potion"));
|
||||
potion = BuiltInRegistries.POTION.getOptional(resourcelocation2).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown potion '" + resourcelocation2 + "'");
|
||||
});
|
||||
}
|
||||
|
||||
EnchantmentPredicate[] aenchantmentpredicate = EnchantmentPredicate.fromJsonArray(jsonobject.get("enchantments"));
|
||||
EnchantmentPredicate[] aenchantmentpredicate1 = EnchantmentPredicate.fromJsonArray(jsonobject.get("stored_enchantments"));
|
||||
return new ItemPredicate(tagkey, set, minmaxbounds$ints, minmaxbounds$ints1, aenchantmentpredicate, aenchantmentpredicate1, potion, nbtpredicate);
|
||||
}
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (this.items != null) {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
for(Item item : this.items) {
|
||||
jsonarray.add(BuiltInRegistries.ITEM.getKey(item).toString());
|
||||
}
|
||||
|
||||
jsonobject.add("items", jsonarray);
|
||||
}
|
||||
|
||||
if (this.tag != null) {
|
||||
jsonobject.addProperty("tag", this.tag.location().toString());
|
||||
}
|
||||
|
||||
jsonobject.add("count", this.count.serializeToJson());
|
||||
jsonobject.add("durability", this.durability.serializeToJson());
|
||||
jsonobject.add("nbt", this.nbt.serializeToJson());
|
||||
if (this.enchantments.length > 0) {
|
||||
JsonArray jsonarray1 = new JsonArray();
|
||||
|
||||
for(EnchantmentPredicate enchantmentpredicate : this.enchantments) {
|
||||
jsonarray1.add(enchantmentpredicate.serializeToJson());
|
||||
}
|
||||
|
||||
jsonobject.add("enchantments", jsonarray1);
|
||||
}
|
||||
|
||||
if (this.storedEnchantments.length > 0) {
|
||||
JsonArray jsonarray2 = new JsonArray();
|
||||
|
||||
for(EnchantmentPredicate enchantmentpredicate1 : this.storedEnchantments) {
|
||||
jsonarray2.add(enchantmentpredicate1.serializeToJson());
|
||||
}
|
||||
|
||||
jsonobject.add("stored_enchantments", jsonarray2);
|
||||
}
|
||||
|
||||
if (this.potion != null) {
|
||||
jsonobject.addProperty("potion", BuiltInRegistries.POTION.getKey(this.potion).toString());
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemPredicate[] fromJsonArray(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonArray jsonarray = GsonHelper.convertToJsonArray(pJson, "items");
|
||||
ItemPredicate[] aitempredicate = new ItemPredicate[jsonarray.size()];
|
||||
|
||||
for(int i = 0; i < aitempredicate.length; ++i) {
|
||||
aitempredicate[i] = fromJson(jsonarray.get(i));
|
||||
}
|
||||
|
||||
return aitempredicate;
|
||||
} else {
|
||||
return new ItemPredicate[0];
|
||||
}
|
||||
}
|
||||
|
||||
public static void register(ResourceLocation name, java.util.function.Function<JsonObject, ItemPredicate> deserializer) {
|
||||
custom_predicates.put(name, deserializer);
|
||||
}
|
||||
|
||||
public static Map<ResourceLocation, java.util.function.Function<JsonObject, ItemPredicate>> getPredicates() {
|
||||
return unmod_predicates;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final List<EnchantmentPredicate> enchantments = Lists.newArrayList();
|
||||
private final List<EnchantmentPredicate> storedEnchantments = Lists.newArrayList();
|
||||
@Nullable
|
||||
private Set<Item> items;
|
||||
@Nullable
|
||||
private TagKey<Item> tag;
|
||||
private MinMaxBounds.Ints count = MinMaxBounds.Ints.ANY;
|
||||
private MinMaxBounds.Ints durability = MinMaxBounds.Ints.ANY;
|
||||
@Nullable
|
||||
private Potion potion;
|
||||
private NbtPredicate nbt = NbtPredicate.ANY;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
public static ItemPredicate.Builder item() {
|
||||
return new ItemPredicate.Builder();
|
||||
}
|
||||
|
||||
public ItemPredicate.Builder of(ItemLike... pItems) {
|
||||
this.items = Stream.of(pItems).map(ItemLike::asItem).collect(ImmutableSet.toImmutableSet());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemPredicate.Builder of(TagKey<Item> pTag) {
|
||||
this.tag = pTag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemPredicate.Builder withCount(MinMaxBounds.Ints pCount) {
|
||||
this.count = pCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemPredicate.Builder hasDurability(MinMaxBounds.Ints pDurability) {
|
||||
this.durability = pDurability;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemPredicate.Builder isPotion(Potion pPotion) {
|
||||
this.potion = pPotion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemPredicate.Builder hasNbt(CompoundTag pNbt) {
|
||||
this.nbt = new NbtPredicate(pNbt);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemPredicate.Builder hasEnchantment(EnchantmentPredicate pEnchantment) {
|
||||
this.enchantments.add(pEnchantment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemPredicate.Builder hasStoredEnchantment(EnchantmentPredicate pStoredEnchantment) {
|
||||
this.storedEnchantments.add(pStoredEnchantment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemPredicate build() {
|
||||
return new ItemPredicate(this.tag, this.items, this.count, this.durability, this.enchantments.toArray(EnchantmentPredicate.NONE), this.storedEnchantments.toArray(EnchantmentPredicate.NONE), this.potion, this.nbt);
|
||||
}
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.util.Arrays;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.LootParams;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LocationCheck;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.MatchTool;
|
||||
|
||||
public class ItemUsedOnLocationTrigger extends SimpleCriterionTrigger<ItemUsedOnLocationTrigger.TriggerInstance> {
|
||||
final ResourceLocation id;
|
||||
|
||||
public ItemUsedOnLocationTrigger(ResourceLocation pId) {
|
||||
this.id = pId;
|
||||
}
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public ItemUsedOnLocationTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ContextAwarePredicate contextawarepredicate = ContextAwarePredicate.fromElement("location", pDeserializationContext, pJson.get("location"), LootContextParamSets.ADVANCEMENT_LOCATION);
|
||||
if (contextawarepredicate == null) {
|
||||
throw new JsonParseException("Failed to parse 'location' field");
|
||||
} else {
|
||||
return new ItemUsedOnLocationTrigger.TriggerInstance(this.id, pPredicate, contextawarepredicate);
|
||||
}
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, BlockPos pPos, ItemStack pStack) {
|
||||
ServerLevel serverlevel = pPlayer.serverLevel();
|
||||
BlockState blockstate = serverlevel.getBlockState(pPos);
|
||||
LootParams lootparams = (new LootParams.Builder(serverlevel)).withParameter(LootContextParams.ORIGIN, pPos.getCenter()).withParameter(LootContextParams.THIS_ENTITY, pPlayer).withParameter(LootContextParams.BLOCK_STATE, blockstate).withParameter(LootContextParams.TOOL, pStack).create(LootContextParamSets.ADVANCEMENT_LOCATION);
|
||||
LootContext lootcontext = (new LootContext.Builder(lootparams)).create((ResourceLocation)null);
|
||||
this.trigger(pPlayer, (p_286596_) -> {
|
||||
return p_286596_.matches(lootcontext);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ContextAwarePredicate location;
|
||||
|
||||
public TriggerInstance(ResourceLocation pCriterion, ContextAwarePredicate pPlayer, ContextAwarePredicate pLocation) {
|
||||
super(pCriterion, pPlayer);
|
||||
this.location = pLocation;
|
||||
}
|
||||
|
||||
public static ItemUsedOnLocationTrigger.TriggerInstance placedBlock(Block pBlock) {
|
||||
ContextAwarePredicate contextawarepredicate = ContextAwarePredicate.create(LootItemBlockStatePropertyCondition.hasBlockStateProperties(pBlock).build());
|
||||
return new ItemUsedOnLocationTrigger.TriggerInstance(CriteriaTriggers.PLACED_BLOCK.id, ContextAwarePredicate.ANY, contextawarepredicate);
|
||||
}
|
||||
|
||||
public static ItemUsedOnLocationTrigger.TriggerInstance placedBlock(LootItemCondition.Builder... pConditions) {
|
||||
ContextAwarePredicate contextawarepredicate = ContextAwarePredicate.create(Arrays.stream(pConditions).map(LootItemCondition.Builder::build).toArray((p_286827_) -> {
|
||||
return new LootItemCondition[p_286827_];
|
||||
}));
|
||||
return new ItemUsedOnLocationTrigger.TriggerInstance(CriteriaTriggers.PLACED_BLOCK.id, ContextAwarePredicate.ANY, contextawarepredicate);
|
||||
}
|
||||
|
||||
private static ItemUsedOnLocationTrigger.TriggerInstance itemUsedOnLocation(LocationPredicate.Builder pLocationPredicate, ItemPredicate.Builder pItemPredicate, ResourceLocation pCriterion) {
|
||||
ContextAwarePredicate contextawarepredicate = ContextAwarePredicate.create(LocationCheck.checkLocation(pLocationPredicate).build(), MatchTool.toolMatches(pItemPredicate).build());
|
||||
return new ItemUsedOnLocationTrigger.TriggerInstance(pCriterion, ContextAwarePredicate.ANY, contextawarepredicate);
|
||||
}
|
||||
|
||||
public static ItemUsedOnLocationTrigger.TriggerInstance itemUsedOnBlock(LocationPredicate.Builder pLocationPredicate, ItemPredicate.Builder pItemPredicate) {
|
||||
return itemUsedOnLocation(pLocationPredicate, pItemPredicate, CriteriaTriggers.ITEM_USED_ON_BLOCK.id);
|
||||
}
|
||||
|
||||
public static ItemUsedOnLocationTrigger.TriggerInstance allayDropItemOnBlock(LocationPredicate.Builder pLocationPredicate, ItemPredicate.Builder pItemPredicate) {
|
||||
return itemUsedOnLocation(pLocationPredicate, pItemPredicate, CriteriaTriggers.ALLAY_DROP_ITEM_ON_BLOCK.id);
|
||||
}
|
||||
|
||||
public boolean matches(LootContext pContext) {
|
||||
return this.location.matches(pContext);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("location", this.location.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class KilledByCrossbowTrigger extends SimpleCriterionTrigger<KilledByCrossbowTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("killed_by_crossbow");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public KilledByCrossbowTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ContextAwarePredicate[] acontextawarepredicate = EntityPredicate.fromJsonArray(pJson, "victims", pDeserializationContext);
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(pJson.get("unique_entity_types"));
|
||||
return new KilledByCrossbowTrigger.TriggerInstance(pPredicate, acontextawarepredicate, minmaxbounds$ints);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Collection<Entity> pEntities) {
|
||||
List<LootContext> list = Lists.newArrayList();
|
||||
Set<EntityType<?>> set = Sets.newHashSet();
|
||||
|
||||
for(Entity entity : pEntities) {
|
||||
set.add(entity.getType());
|
||||
list.add(EntityPredicate.createContext(pPlayer, entity));
|
||||
}
|
||||
|
||||
this.trigger(pPlayer, (p_46881_) -> {
|
||||
return p_46881_.matches(list, set.size());
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ContextAwarePredicate[] victims;
|
||||
private final MinMaxBounds.Ints uniqueEntityTypes;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ContextAwarePredicate[] pVictims, MinMaxBounds.Ints pUniqueEntityTypes) {
|
||||
super(KilledByCrossbowTrigger.ID, pPlayer);
|
||||
this.victims = pVictims;
|
||||
this.uniqueEntityTypes = pUniqueEntityTypes;
|
||||
}
|
||||
|
||||
public static KilledByCrossbowTrigger.TriggerInstance crossbowKilled(EntityPredicate.Builder... pBuilders) {
|
||||
ContextAwarePredicate[] acontextawarepredicate = new ContextAwarePredicate[pBuilders.length];
|
||||
|
||||
for(int i = 0; i < pBuilders.length; ++i) {
|
||||
EntityPredicate.Builder entitypredicate$builder = pBuilders[i];
|
||||
acontextawarepredicate[i] = EntityPredicate.wrap(entitypredicate$builder.build());
|
||||
}
|
||||
|
||||
return new KilledByCrossbowTrigger.TriggerInstance(ContextAwarePredicate.ANY, acontextawarepredicate, MinMaxBounds.Ints.ANY);
|
||||
}
|
||||
|
||||
public static KilledByCrossbowTrigger.TriggerInstance crossbowKilled(MinMaxBounds.Ints pBounds) {
|
||||
ContextAwarePredicate[] acontextawarepredicate = new ContextAwarePredicate[0];
|
||||
return new KilledByCrossbowTrigger.TriggerInstance(ContextAwarePredicate.ANY, acontextawarepredicate, pBounds);
|
||||
}
|
||||
|
||||
public boolean matches(Collection<LootContext> pContexts, int pBounds) {
|
||||
if (this.victims.length > 0) {
|
||||
List<LootContext> list = Lists.newArrayList(pContexts);
|
||||
|
||||
for(ContextAwarePredicate contextawarepredicate : this.victims) {
|
||||
boolean flag = false;
|
||||
Iterator<LootContext> iterator = list.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
LootContext lootcontext = iterator.next();
|
||||
if (contextawarepredicate.matches(lootcontext)) {
|
||||
iterator.remove();
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.uniqueEntityTypes.matches(pBounds);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("victims", ContextAwarePredicate.toJson(this.victims, pConditions));
|
||||
jsonobject.add("unique_entity_types", this.uniqueEntityTypes.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class KilledTrigger extends SimpleCriterionTrigger<KilledTrigger.TriggerInstance> {
|
||||
final ResourceLocation id;
|
||||
|
||||
public KilledTrigger(ResourceLocation pId) {
|
||||
this.id = pId;
|
||||
}
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public KilledTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
return new KilledTrigger.TriggerInstance(this.id, pPredicate, EntityPredicate.fromJson(pJson, "entity", pDeserializationContext), DamageSourcePredicate.fromJson(pJson.get("killing_blow")));
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Entity pEntity, DamageSource pSource) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pEntity);
|
||||
this.trigger(pPlayer, (p_48112_) -> {
|
||||
return p_48112_.matches(pPlayer, lootcontext, pSource);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ContextAwarePredicate entityPredicate;
|
||||
private final DamageSourcePredicate killingBlow;
|
||||
|
||||
public TriggerInstance(ResourceLocation pCriterion, ContextAwarePredicate pPlayer, ContextAwarePredicate pEntityPredicate, DamageSourcePredicate pKillingBlow) {
|
||||
super(pCriterion, pPlayer);
|
||||
this.entityPredicate = pEntityPredicate;
|
||||
this.killingBlow = pKillingBlow;
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance playerKilledEntity(EntityPredicate pEntityPredicate) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.PLAYER_KILLED_ENTITY.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicate), DamageSourcePredicate.ANY);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance playerKilledEntity(EntityPredicate.Builder pEntityPredicateBuilder) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.PLAYER_KILLED_ENTITY.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicateBuilder.build()), DamageSourcePredicate.ANY);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance playerKilledEntity() {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.PLAYER_KILLED_ENTITY.id, ContextAwarePredicate.ANY, ContextAwarePredicate.ANY, DamageSourcePredicate.ANY);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance playerKilledEntity(EntityPredicate pEntityPredicate, DamageSourcePredicate pKillingBlow) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.PLAYER_KILLED_ENTITY.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicate), pKillingBlow);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance playerKilledEntity(EntityPredicate.Builder pEntityPredicateBuilder, DamageSourcePredicate pKillingBlow) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.PLAYER_KILLED_ENTITY.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicateBuilder.build()), pKillingBlow);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance playerKilledEntity(EntityPredicate pEntityPredicate, DamageSourcePredicate.Builder pKillingBlowBuilder) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.PLAYER_KILLED_ENTITY.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicate), pKillingBlowBuilder.build());
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance playerKilledEntity(EntityPredicate.Builder pEntityPredicateBuilder, DamageSourcePredicate.Builder pKillingBlowBuilder) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.PLAYER_KILLED_ENTITY.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicateBuilder.build()), pKillingBlowBuilder.build());
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance playerKilledEntityNearSculkCatalyst() {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.KILL_MOB_NEAR_SCULK_CATALYST.id, ContextAwarePredicate.ANY, ContextAwarePredicate.ANY, DamageSourcePredicate.ANY);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance entityKilledPlayer(EntityPredicate pEntityPredicate) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.ENTITY_KILLED_PLAYER.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicate), DamageSourcePredicate.ANY);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance entityKilledPlayer(EntityPredicate.Builder pEntityPredicateBuilder) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.ENTITY_KILLED_PLAYER.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicateBuilder.build()), DamageSourcePredicate.ANY);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance entityKilledPlayer() {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.ENTITY_KILLED_PLAYER.id, ContextAwarePredicate.ANY, ContextAwarePredicate.ANY, DamageSourcePredicate.ANY);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance entityKilledPlayer(EntityPredicate pEntityPredicate, DamageSourcePredicate pKillingBlow) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.ENTITY_KILLED_PLAYER.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicate), pKillingBlow);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance entityKilledPlayer(EntityPredicate.Builder pEntityPredicateBuilder, DamageSourcePredicate pKillingBlow) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.ENTITY_KILLED_PLAYER.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicateBuilder.build()), pKillingBlow);
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance entityKilledPlayer(EntityPredicate pEntityPredicate, DamageSourcePredicate.Builder pKillingBlowBuilder) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.ENTITY_KILLED_PLAYER.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicate), pKillingBlowBuilder.build());
|
||||
}
|
||||
|
||||
public static KilledTrigger.TriggerInstance entityKilledPlayer(EntityPredicate.Builder pEntityPredicateBuilder, DamageSourcePredicate.Builder pKillingBlowBuilder) {
|
||||
return new KilledTrigger.TriggerInstance(CriteriaTriggers.ENTITY_KILLED_PLAYER.id, ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicateBuilder.build()), pKillingBlowBuilder.build());
|
||||
}
|
||||
|
||||
public boolean matches(ServerPlayer pPlayer, LootContext pContext, DamageSource pSource) {
|
||||
return !this.killingBlow.matches(pPlayer, pSource) ? false : this.entityPredicate.matches(pContext);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("entity", this.entityPredicate.toJson(pConditions));
|
||||
jsonobject.add("killing_blow", this.killingBlow.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class LevitationTrigger extends SimpleCriterionTrigger<LevitationTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("levitation");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public LevitationTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
DistancePredicate distancepredicate = DistancePredicate.fromJson(pJson.get("distance"));
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(pJson.get("duration"));
|
||||
return new LevitationTrigger.TriggerInstance(pPredicate, distancepredicate, minmaxbounds$ints);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Vec3 pStartPos, int pDuration) {
|
||||
this.trigger(pPlayer, (p_49124_) -> {
|
||||
return p_49124_.matches(pPlayer, pStartPos, pDuration);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final DistancePredicate distance;
|
||||
private final MinMaxBounds.Ints duration;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, DistancePredicate pDistance, MinMaxBounds.Ints pDuration) {
|
||||
super(LevitationTrigger.ID, pPlayer);
|
||||
this.distance = pDistance;
|
||||
this.duration = pDuration;
|
||||
}
|
||||
|
||||
public static LevitationTrigger.TriggerInstance levitated(DistancePredicate pDistance) {
|
||||
return new LevitationTrigger.TriggerInstance(ContextAwarePredicate.ANY, pDistance, MinMaxBounds.Ints.ANY);
|
||||
}
|
||||
|
||||
public boolean matches(ServerPlayer pPlayer, Vec3 pStartPos, int pDuration) {
|
||||
if (!this.distance.matches(pStartPos.x, pStartPos.y, pStartPos.z, pPlayer.getX(), pPlayer.getY(), pPlayer.getZ())) {
|
||||
return false;
|
||||
} else {
|
||||
return this.duration.matches(pDuration);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("distance", this.distance.serializeToJson());
|
||||
jsonobject.add("duration", this.duration.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
|
||||
public class LightPredicate {
|
||||
public static final LightPredicate ANY = new LightPredicate(MinMaxBounds.Ints.ANY);
|
||||
private final MinMaxBounds.Ints composite;
|
||||
|
||||
LightPredicate(MinMaxBounds.Ints pComposite) {
|
||||
this.composite = pComposite;
|
||||
}
|
||||
|
||||
public boolean matches(ServerLevel pLevel, BlockPos pPos) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else if (!pLevel.isLoaded(pPos)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.composite.matches(pLevel.getMaxLocalRawBrightness(pPos));
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("light", this.composite.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static LightPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "light");
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(jsonobject.get("light"));
|
||||
return new LightPredicate(minmaxbounds$ints);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private MinMaxBounds.Ints composite = MinMaxBounds.Ints.ANY;
|
||||
|
||||
public static LightPredicate.Builder light() {
|
||||
return new LightPredicate.Builder();
|
||||
}
|
||||
|
||||
public LightPredicate.Builder setComposite(MinMaxBounds.Ints pComposite) {
|
||||
this.composite = pComposite;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LightPredicate build() {
|
||||
return new LightPredicate(this.composite);
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class LighthingBoltPredicate implements EntitySubPredicate {
|
||||
private static final String BLOCKS_SET_ON_FIRE_KEY = "blocks_set_on_fire";
|
||||
private static final String ENTITY_STRUCK_KEY = "entity_struck";
|
||||
private final MinMaxBounds.Ints blocksSetOnFire;
|
||||
private final EntityPredicate entityStruck;
|
||||
|
||||
private LighthingBoltPredicate(MinMaxBounds.Ints pBlocksSetOnFire, EntityPredicate pEntityStruck) {
|
||||
this.blocksSetOnFire = pBlocksSetOnFire;
|
||||
this.entityStruck = pEntityStruck;
|
||||
}
|
||||
|
||||
public static LighthingBoltPredicate blockSetOnFire(MinMaxBounds.Ints pBlocksSetOnFire) {
|
||||
return new LighthingBoltPredicate(pBlocksSetOnFire, EntityPredicate.ANY);
|
||||
}
|
||||
|
||||
public static LighthingBoltPredicate fromJson(JsonObject p_220333_) {
|
||||
return new LighthingBoltPredicate(MinMaxBounds.Ints.fromJson(p_220333_.get("blocks_set_on_fire")), EntityPredicate.fromJson(p_220333_.get("entity_struck")));
|
||||
}
|
||||
|
||||
public JsonObject serializeCustomData() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("blocks_set_on_fire", this.blocksSetOnFire.serializeToJson());
|
||||
jsonobject.add("entity_struck", this.entityStruck.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public EntitySubPredicate.Type type() {
|
||||
return EntitySubPredicate.Types.LIGHTNING;
|
||||
}
|
||||
|
||||
public boolean matches(Entity pEntity, ServerLevel pLevel, @Nullable Vec3 pPosition) {
|
||||
if (!(pEntity instanceof LightningBolt lightningbolt)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.blocksSetOnFire.matches(lightningbolt.getBlocksSetOnFire()) && (this.entityStruck == EntityPredicate.ANY || lightningbolt.getHitEntities().anyMatch((p_153245_) -> {
|
||||
return this.entityStruck.matches(pLevel, pPosition, p_153245_);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class LightningStrikeTrigger extends SimpleCriterionTrigger<LightningStrikeTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("lightning_strike");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public LightningStrikeTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "lightning", pDeserializationContext);
|
||||
ContextAwarePredicate contextawarepredicate1 = EntityPredicate.fromJson(pJson, "bystander", pDeserializationContext);
|
||||
return new LightningStrikeTrigger.TriggerInstance(pPredicate, contextawarepredicate, contextawarepredicate1);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, LightningBolt pLightning, List<Entity> pNearbyEntities) {
|
||||
List<LootContext> list = pNearbyEntities.stream().map((p_153390_) -> {
|
||||
return EntityPredicate.createContext(pPlayer, p_153390_);
|
||||
}).collect(Collectors.toList());
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pLightning);
|
||||
this.trigger(pPlayer, (p_153402_) -> {
|
||||
return p_153402_.matches(lootcontext, list);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ContextAwarePredicate lightning;
|
||||
private final ContextAwarePredicate bystander;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ContextAwarePredicate pLightning, ContextAwarePredicate pBystander) {
|
||||
super(LightningStrikeTrigger.ID, pPlayer);
|
||||
this.lightning = pLightning;
|
||||
this.bystander = pBystander;
|
||||
}
|
||||
|
||||
public static LightningStrikeTrigger.TriggerInstance lighthingStrike(EntityPredicate pLightning, EntityPredicate pBystander) {
|
||||
return new LightningStrikeTrigger.TriggerInstance(ContextAwarePredicate.ANY, EntityPredicate.wrap(pLightning), EntityPredicate.wrap(pBystander));
|
||||
}
|
||||
|
||||
public boolean matches(LootContext pPlayerContext, List<LootContext> pEntityContexts) {
|
||||
if (!this.lightning.matches(pPlayerContext)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.bystander == ContextAwarePredicate.ANY || !pEntityContexts.stream().noneMatch(this.bystander::matches);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("lightning", this.lightning.toJson(pConditions));
|
||||
jsonobject.add("bystander", this.bystander.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.CampfireBlock;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class LocationPredicate {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final LocationPredicate ANY = new LocationPredicate(MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, (ResourceKey<Biome>)null, (ResourceKey<Structure>)null, (ResourceKey<Level>)null, (Boolean)null, LightPredicate.ANY, BlockPredicate.ANY, FluidPredicate.ANY);
|
||||
private final MinMaxBounds.Doubles x;
|
||||
private final MinMaxBounds.Doubles y;
|
||||
private final MinMaxBounds.Doubles z;
|
||||
@Nullable
|
||||
private final ResourceKey<Biome> biome;
|
||||
@Nullable
|
||||
private final ResourceKey<Structure> structure;
|
||||
@Nullable
|
||||
private final ResourceKey<Level> dimension;
|
||||
@Nullable
|
||||
private final Boolean smokey;
|
||||
private final LightPredicate light;
|
||||
private final BlockPredicate block;
|
||||
private final FluidPredicate fluid;
|
||||
|
||||
public LocationPredicate(MinMaxBounds.Doubles pX, MinMaxBounds.Doubles pY, MinMaxBounds.Doubles pZ, @Nullable ResourceKey<Biome> pBiome, @Nullable ResourceKey<Structure> pFeature, @Nullable ResourceKey<Level> pDimension, @Nullable Boolean pSmokey, LightPredicate pLight, BlockPredicate pBlock, FluidPredicate pFluid) {
|
||||
this.x = pX;
|
||||
this.y = pY;
|
||||
this.z = pZ;
|
||||
this.biome = pBiome;
|
||||
this.structure = pFeature;
|
||||
this.dimension = pDimension;
|
||||
this.smokey = pSmokey;
|
||||
this.light = pLight;
|
||||
this.block = pBlock;
|
||||
this.fluid = pFluid;
|
||||
}
|
||||
|
||||
public static LocationPredicate inBiome(ResourceKey<Biome> pBiome) {
|
||||
return new LocationPredicate(MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, pBiome, (ResourceKey<Structure>)null, (ResourceKey<Level>)null, (Boolean)null, LightPredicate.ANY, BlockPredicate.ANY, FluidPredicate.ANY);
|
||||
}
|
||||
|
||||
public static LocationPredicate inDimension(ResourceKey<Level> pDimension) {
|
||||
return new LocationPredicate(MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, (ResourceKey<Biome>)null, (ResourceKey<Structure>)null, pDimension, (Boolean)null, LightPredicate.ANY, BlockPredicate.ANY, FluidPredicate.ANY);
|
||||
}
|
||||
|
||||
public static LocationPredicate inStructure(ResourceKey<Structure> pStructure) {
|
||||
return new LocationPredicate(MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, MinMaxBounds.Doubles.ANY, (ResourceKey<Biome>)null, pStructure, (ResourceKey<Level>)null, (Boolean)null, LightPredicate.ANY, BlockPredicate.ANY, FluidPredicate.ANY);
|
||||
}
|
||||
|
||||
public static LocationPredicate atYLocation(MinMaxBounds.Doubles pYRange) {
|
||||
return new LocationPredicate(MinMaxBounds.Doubles.ANY, pYRange, MinMaxBounds.Doubles.ANY, (ResourceKey<Biome>)null, (ResourceKey<Structure>)null, (ResourceKey<Level>)null, (Boolean)null, LightPredicate.ANY, BlockPredicate.ANY, FluidPredicate.ANY);
|
||||
}
|
||||
|
||||
public boolean matches(ServerLevel pLevel, double pX, double pY, double pZ) {
|
||||
if (!this.x.matches(pX)) {
|
||||
return false;
|
||||
} else if (!this.y.matches(pY)) {
|
||||
return false;
|
||||
} else if (!this.z.matches(pZ)) {
|
||||
return false;
|
||||
} else if (this.dimension != null && this.dimension != pLevel.dimension()) {
|
||||
return false;
|
||||
} else {
|
||||
BlockPos blockpos = BlockPos.containing(pX, pY, pZ);
|
||||
boolean flag = pLevel.isLoaded(blockpos);
|
||||
if (this.biome == null || flag && pLevel.getBiome(blockpos).is(this.biome)) {
|
||||
if (this.structure == null || flag && pLevel.structureManager().getStructureWithPieceAt(blockpos, this.structure).isValid()) {
|
||||
if (this.smokey == null || flag && this.smokey == CampfireBlock.isSmokeyPos(pLevel, blockpos)) {
|
||||
if (!this.light.matches(pLevel, blockpos)) {
|
||||
return false;
|
||||
} else if (!this.block.matches(pLevel, blockpos)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.fluid.matches(pLevel, blockpos);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (!this.x.isAny() || !this.y.isAny() || !this.z.isAny()) {
|
||||
JsonObject jsonobject1 = new JsonObject();
|
||||
jsonobject1.add("x", this.x.serializeToJson());
|
||||
jsonobject1.add("y", this.y.serializeToJson());
|
||||
jsonobject1.add("z", this.z.serializeToJson());
|
||||
jsonobject.add("position", jsonobject1);
|
||||
}
|
||||
|
||||
if (this.dimension != null) {
|
||||
Level.RESOURCE_KEY_CODEC.encodeStart(JsonOps.INSTANCE, this.dimension).resultOrPartial(LOGGER::error).ifPresent((p_52633_) -> {
|
||||
jsonobject.add("dimension", p_52633_);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.structure != null) {
|
||||
jsonobject.addProperty("structure", this.structure.location().toString());
|
||||
}
|
||||
|
||||
if (this.biome != null) {
|
||||
jsonobject.addProperty("biome", this.biome.location().toString());
|
||||
}
|
||||
|
||||
if (this.smokey != null) {
|
||||
jsonobject.addProperty("smokey", this.smokey);
|
||||
}
|
||||
|
||||
jsonobject.add("light", this.light.serializeToJson());
|
||||
jsonobject.add("block", this.block.serializeToJson());
|
||||
jsonobject.add("fluid", this.fluid.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static LocationPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "location");
|
||||
JsonObject jsonobject1 = GsonHelper.getAsJsonObject(jsonobject, "position", new JsonObject());
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles = MinMaxBounds.Doubles.fromJson(jsonobject1.get("x"));
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles1 = MinMaxBounds.Doubles.fromJson(jsonobject1.get("y"));
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles2 = MinMaxBounds.Doubles.fromJson(jsonobject1.get("z"));
|
||||
ResourceKey<Level> resourcekey = jsonobject.has("dimension") ? ResourceLocation.CODEC.parse(JsonOps.INSTANCE, jsonobject.get("dimension")).resultOrPartial(LOGGER::error).map((p_52637_) -> {
|
||||
return ResourceKey.create(Registries.DIMENSION, p_52637_);
|
||||
}).orElse((ResourceKey<Level>)null) : null;
|
||||
ResourceKey<Structure> resourcekey1 = jsonobject.has("structure") ? ResourceLocation.CODEC.parse(JsonOps.INSTANCE, jsonobject.get("structure")).resultOrPartial(LOGGER::error).map((p_207927_) -> {
|
||||
return ResourceKey.create(Registries.STRUCTURE, p_207927_);
|
||||
}).orElse((ResourceKey<Structure>)null) : null;
|
||||
ResourceKey<Biome> resourcekey2 = null;
|
||||
if (jsonobject.has("biome")) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(jsonobject, "biome"));
|
||||
resourcekey2 = ResourceKey.create(Registries.BIOME, resourcelocation);
|
||||
}
|
||||
|
||||
Boolean obool = jsonobject.has("smokey") ? jsonobject.get("smokey").getAsBoolean() : null;
|
||||
LightPredicate lightpredicate = LightPredicate.fromJson(jsonobject.get("light"));
|
||||
BlockPredicate blockpredicate = BlockPredicate.fromJson(jsonobject.get("block"));
|
||||
FluidPredicate fluidpredicate = FluidPredicate.fromJson(jsonobject.get("fluid"));
|
||||
return new LocationPredicate(minmaxbounds$doubles, minmaxbounds$doubles1, minmaxbounds$doubles2, resourcekey2, resourcekey1, resourcekey, obool, lightpredicate, blockpredicate, fluidpredicate);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private MinMaxBounds.Doubles x = MinMaxBounds.Doubles.ANY;
|
||||
private MinMaxBounds.Doubles y = MinMaxBounds.Doubles.ANY;
|
||||
private MinMaxBounds.Doubles z = MinMaxBounds.Doubles.ANY;
|
||||
@Nullable
|
||||
private ResourceKey<Biome> biome;
|
||||
@Nullable
|
||||
private ResourceKey<Structure> structure;
|
||||
@Nullable
|
||||
private ResourceKey<Level> dimension;
|
||||
@Nullable
|
||||
private Boolean smokey;
|
||||
private LightPredicate light = LightPredicate.ANY;
|
||||
private BlockPredicate block = BlockPredicate.ANY;
|
||||
private FluidPredicate fluid = FluidPredicate.ANY;
|
||||
|
||||
public static LocationPredicate.Builder location() {
|
||||
return new LocationPredicate.Builder();
|
||||
}
|
||||
|
||||
public LocationPredicate.Builder setX(MinMaxBounds.Doubles pX) {
|
||||
this.x = pX;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocationPredicate.Builder setY(MinMaxBounds.Doubles pY) {
|
||||
this.y = pY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocationPredicate.Builder setZ(MinMaxBounds.Doubles pZ) {
|
||||
this.z = pZ;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocationPredicate.Builder setBiome(@Nullable ResourceKey<Biome> pBiome) {
|
||||
this.biome = pBiome;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocationPredicate.Builder setStructure(@Nullable ResourceKey<Structure> pStructure) {
|
||||
this.structure = pStructure;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocationPredicate.Builder setDimension(@Nullable ResourceKey<Level> pDimension) {
|
||||
this.dimension = pDimension;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocationPredicate.Builder setLight(LightPredicate pLight) {
|
||||
this.light = pLight;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocationPredicate.Builder setBlock(BlockPredicate pBlock) {
|
||||
this.block = pBlock;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocationPredicate.Builder setFluid(FluidPredicate pFluid) {
|
||||
this.fluid = pFluid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocationPredicate.Builder setSmokey(Boolean pSmokey) {
|
||||
this.smokey = pSmokey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocationPredicate build() {
|
||||
return new LocationPredicate(this.x, this.y, this.z, this.biome, this.structure, this.dimension, this.smokey, this.light, this.block, this.fluid);
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
|
||||
public class LootTableTrigger extends SimpleCriterionTrigger<LootTableTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("player_generates_container_loot");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
protected LootTableTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(pJson, "loot_table"));
|
||||
return new LootTableTrigger.TriggerInstance(pPredicate, resourcelocation);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ResourceLocation pLootTable) {
|
||||
this.trigger(pPlayer, (p_54606_) -> {
|
||||
return p_54606_.matches(pLootTable);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ResourceLocation lootTable;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ResourceLocation pLootTable) {
|
||||
super(LootTableTrigger.ID, pPlayer);
|
||||
this.lootTable = pLootTable;
|
||||
}
|
||||
|
||||
public static LootTableTrigger.TriggerInstance lootTableUsed(ResourceLocation pLootTable) {
|
||||
return new LootTableTrigger.TriggerInstance(ContextAwarePredicate.ANY, pLootTable);
|
||||
}
|
||||
|
||||
public boolean matches(ResourceLocation pLootTable) {
|
||||
return this.lootTable.equals(pLootTable);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.addProperty("loot_table", this.lootTable.toString());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
|
||||
public abstract class MinMaxBounds<T extends Number> {
|
||||
public static final SimpleCommandExceptionType ERROR_EMPTY = new SimpleCommandExceptionType(Component.translatable("argument.range.empty"));
|
||||
public static final SimpleCommandExceptionType ERROR_SWAPPED = new SimpleCommandExceptionType(Component.translatable("argument.range.swapped"));
|
||||
@Nullable
|
||||
protected final T min;
|
||||
@Nullable
|
||||
protected final T max;
|
||||
|
||||
protected MinMaxBounds(@Nullable T pMin, @Nullable T pMax) {
|
||||
this.min = pMin;
|
||||
this.max = pMax;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T getMin() {
|
||||
return this.min;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T getMax() {
|
||||
return this.max;
|
||||
}
|
||||
|
||||
public boolean isAny() {
|
||||
return this.min == null && this.max == null;
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this.isAny()) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else if (this.min != null && this.min.equals(this.max)) {
|
||||
return new JsonPrimitive(this.min);
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (this.min != null) {
|
||||
jsonobject.addProperty("min", this.min);
|
||||
}
|
||||
|
||||
if (this.max != null) {
|
||||
jsonobject.addProperty("max", this.max);
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
protected static <T extends Number, R extends MinMaxBounds<T>> R fromJson(@Nullable JsonElement pJson, R pDefaultValue, BiFunction<JsonElement, String, T> pValueFactory, MinMaxBounds.BoundsFactory<T, R> pBoundedFactory) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
if (GsonHelper.isNumberValue(pJson)) {
|
||||
T t2 = pValueFactory.apply(pJson, "value");
|
||||
return pBoundedFactory.create(t2, t2);
|
||||
} else {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "value");
|
||||
T t = jsonobject.has("min") ? pValueFactory.apply(jsonobject.get("min"), "min") : null;
|
||||
T t1 = jsonobject.has("max") ? pValueFactory.apply(jsonobject.get("max"), "max") : null;
|
||||
return pBoundedFactory.create(t, t1);
|
||||
}
|
||||
} else {
|
||||
return pDefaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
protected static <T extends Number, R extends MinMaxBounds<T>> R fromReader(StringReader pReader, MinMaxBounds.BoundsFromReaderFactory<T, R> pBoundedFactory, Function<String, T> pValueFactory, Supplier<DynamicCommandExceptionType> pCommandExceptionSupplier, Function<T, T> pFormatter) throws CommandSyntaxException {
|
||||
if (!pReader.canRead()) {
|
||||
throw ERROR_EMPTY.createWithContext(pReader);
|
||||
} else {
|
||||
int i = pReader.getCursor();
|
||||
|
||||
try {
|
||||
T t = optionallyFormat(readNumber(pReader, pValueFactory, pCommandExceptionSupplier), pFormatter);
|
||||
T t1;
|
||||
if (pReader.canRead(2) && pReader.peek() == '.' && pReader.peek(1) == '.') {
|
||||
pReader.skip();
|
||||
pReader.skip();
|
||||
t1 = optionallyFormat(readNumber(pReader, pValueFactory, pCommandExceptionSupplier), pFormatter);
|
||||
if (t == null && t1 == null) {
|
||||
throw ERROR_EMPTY.createWithContext(pReader);
|
||||
}
|
||||
} else {
|
||||
t1 = t;
|
||||
}
|
||||
|
||||
if (t == null && t1 == null) {
|
||||
throw ERROR_EMPTY.createWithContext(pReader);
|
||||
} else {
|
||||
return pBoundedFactory.create(pReader, t, t1);
|
||||
}
|
||||
} catch (CommandSyntaxException commandsyntaxexception) {
|
||||
pReader.setCursor(i);
|
||||
throw new CommandSyntaxException(commandsyntaxexception.getType(), commandsyntaxexception.getRawMessage(), commandsyntaxexception.getInput(), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <T extends Number> T readNumber(StringReader pReader, Function<String, T> pStringToValueFunction, Supplier<DynamicCommandExceptionType> pCommandExceptionSupplier) throws CommandSyntaxException {
|
||||
int i = pReader.getCursor();
|
||||
|
||||
while(pReader.canRead() && isAllowedInputChat(pReader)) {
|
||||
pReader.skip();
|
||||
}
|
||||
|
||||
String s = pReader.getString().substring(i, pReader.getCursor());
|
||||
if (s.isEmpty()) {
|
||||
return (T)null;
|
||||
} else {
|
||||
try {
|
||||
return pStringToValueFunction.apply(s);
|
||||
} catch (NumberFormatException numberformatexception) {
|
||||
throw pCommandExceptionSupplier.get().createWithContext(pReader, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAllowedInputChat(StringReader pReader) {
|
||||
char c0 = pReader.peek();
|
||||
if ((c0 < '0' || c0 > '9') && c0 != '-') {
|
||||
if (c0 != '.') {
|
||||
return false;
|
||||
} else {
|
||||
return !pReader.canRead(2) || pReader.peek(1) != '.';
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <T> T optionallyFormat(@Nullable T pValue, Function<T, T> pFormatter) {
|
||||
return (T)(pValue == null ? null : pFormatter.apply(pValue));
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
protected interface BoundsFactory<T extends Number, R extends MinMaxBounds<T>> {
|
||||
R create(@Nullable T pMin, @Nullable T pMax);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
protected interface BoundsFromReaderFactory<T extends Number, R extends MinMaxBounds<T>> {
|
||||
R create(StringReader pReader, @Nullable T pMin, @Nullable T pMax) throws CommandSyntaxException;
|
||||
}
|
||||
|
||||
public static class Doubles extends MinMaxBounds<Double> {
|
||||
public static final MinMaxBounds.Doubles ANY = new MinMaxBounds.Doubles((Double)null, (Double)null);
|
||||
@Nullable
|
||||
private final Double minSq;
|
||||
@Nullable
|
||||
private final Double maxSq;
|
||||
|
||||
private static MinMaxBounds.Doubles create(StringReader p_154796_, @Nullable Double p_154797_, @Nullable Double p_154798_) throws CommandSyntaxException {
|
||||
if (p_154797_ != null && p_154798_ != null && p_154797_ > p_154798_) {
|
||||
throw ERROR_SWAPPED.createWithContext(p_154796_);
|
||||
} else {
|
||||
return new MinMaxBounds.Doubles(p_154797_, p_154798_);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Double squareOpt(@Nullable Double pValue) {
|
||||
return pValue == null ? null : pValue * pValue;
|
||||
}
|
||||
|
||||
private Doubles(@Nullable Double p_154784_, @Nullable Double p_154785_) {
|
||||
super(p_154784_, p_154785_);
|
||||
this.minSq = squareOpt(p_154784_);
|
||||
this.maxSq = squareOpt(p_154785_);
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Doubles exactly(double pValue) {
|
||||
return new MinMaxBounds.Doubles(pValue, pValue);
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Doubles between(double pMin, double pMax) {
|
||||
return new MinMaxBounds.Doubles(pMin, pMax);
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Doubles atLeast(double pMin) {
|
||||
return new MinMaxBounds.Doubles(pMin, (Double)null);
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Doubles atMost(double pMax) {
|
||||
return new MinMaxBounds.Doubles((Double)null, pMax);
|
||||
}
|
||||
|
||||
public boolean matches(double pValue) {
|
||||
if (this.min != null && this.min > pValue) {
|
||||
return false;
|
||||
} else {
|
||||
return this.max == null || !(this.max < pValue);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matchesSqr(double pValue) {
|
||||
if (this.minSq != null && this.minSq > pValue) {
|
||||
return false;
|
||||
} else {
|
||||
return this.maxSq == null || !(this.maxSq < pValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Doubles fromJson(@Nullable JsonElement pJson) {
|
||||
return fromJson(pJson, ANY, GsonHelper::convertToDouble, MinMaxBounds.Doubles::new);
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Doubles fromReader(StringReader pReader) throws CommandSyntaxException {
|
||||
return fromReader(pReader, (p_154807_) -> {
|
||||
return p_154807_;
|
||||
});
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Doubles fromReader(StringReader pReader, Function<Double, Double> pFormatter) throws CommandSyntaxException {
|
||||
return fromReader(pReader, MinMaxBounds.Doubles::create, Double::parseDouble, CommandSyntaxException.BUILT_IN_EXCEPTIONS::readerInvalidDouble, pFormatter);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Ints extends MinMaxBounds<Integer> {
|
||||
public static final MinMaxBounds.Ints ANY = new MinMaxBounds.Ints((Integer)null, (Integer)null);
|
||||
@Nullable
|
||||
private final Long minSq;
|
||||
@Nullable
|
||||
private final Long maxSq;
|
||||
|
||||
private static MinMaxBounds.Ints create(StringReader p_55378_, @Nullable Integer p_55379_, @Nullable Integer p_55380_) throws CommandSyntaxException {
|
||||
if (p_55379_ != null && p_55380_ != null && p_55379_ > p_55380_) {
|
||||
throw ERROR_SWAPPED.createWithContext(p_55378_);
|
||||
} else {
|
||||
return new MinMaxBounds.Ints(p_55379_, p_55380_);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Long squareOpt(@Nullable Integer pValue) {
|
||||
return pValue == null ? null : pValue.longValue() * pValue.longValue();
|
||||
}
|
||||
|
||||
private Ints(@Nullable Integer p_55369_, @Nullable Integer p_55370_) {
|
||||
super(p_55369_, p_55370_);
|
||||
this.minSq = squareOpt(p_55369_);
|
||||
this.maxSq = squareOpt(p_55370_);
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Ints exactly(int pValue) {
|
||||
return new MinMaxBounds.Ints(pValue, pValue);
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Ints between(int pMin, int pMax) {
|
||||
return new MinMaxBounds.Ints(pMin, pMax);
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Ints atLeast(int pMin) {
|
||||
return new MinMaxBounds.Ints(pMin, (Integer)null);
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Ints atMost(int pMax) {
|
||||
return new MinMaxBounds.Ints((Integer)null, pMax);
|
||||
}
|
||||
|
||||
public boolean matches(int pValue) {
|
||||
if (this.min != null && this.min > pValue) {
|
||||
return false;
|
||||
} else {
|
||||
return this.max == null || this.max >= pValue;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matchesSqr(long pValue) {
|
||||
if (this.minSq != null && this.minSq > pValue) {
|
||||
return false;
|
||||
} else {
|
||||
return this.maxSq == null || this.maxSq >= pValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Ints fromJson(@Nullable JsonElement pJson) {
|
||||
return fromJson(pJson, ANY, GsonHelper::convertToInt, MinMaxBounds.Ints::new);
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Ints fromReader(StringReader pReader) throws CommandSyntaxException {
|
||||
return fromReader(pReader, (p_55389_) -> {
|
||||
return p_55389_;
|
||||
});
|
||||
}
|
||||
|
||||
public static MinMaxBounds.Ints fromReader(StringReader pReader, Function<Integer, Integer> pValueFunction) throws CommandSyntaxException {
|
||||
return fromReader(pReader, MinMaxBounds.Ints::create, Integer::parseInt, CommandSyntaxException.BUILT_IN_EXCEPTIONS::readerInvalidInt, pValueFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
|
||||
public class MobEffectsPredicate {
|
||||
public static final MobEffectsPredicate ANY = new MobEffectsPredicate(Collections.emptyMap());
|
||||
private final Map<MobEffect, MobEffectsPredicate.MobEffectInstancePredicate> effects;
|
||||
|
||||
public MobEffectsPredicate(Map<MobEffect, MobEffectsPredicate.MobEffectInstancePredicate> pEffects) {
|
||||
this.effects = pEffects;
|
||||
}
|
||||
|
||||
public static MobEffectsPredicate effects() {
|
||||
return new MobEffectsPredicate(Maps.newLinkedHashMap());
|
||||
}
|
||||
|
||||
public MobEffectsPredicate and(MobEffect pEffect) {
|
||||
this.effects.put(pEffect, new MobEffectsPredicate.MobEffectInstancePredicate());
|
||||
return this;
|
||||
}
|
||||
|
||||
public MobEffectsPredicate and(MobEffect pEffect, MobEffectsPredicate.MobEffectInstancePredicate pPredicate) {
|
||||
this.effects.put(pEffect, pPredicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean matches(Entity pEntity) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else {
|
||||
return pEntity instanceof LivingEntity ? this.matches(((LivingEntity)pEntity).getActiveEffectsMap()) : false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matches(LivingEntity pEntity) {
|
||||
return this == ANY ? true : this.matches(pEntity.getActiveEffectsMap());
|
||||
}
|
||||
|
||||
public boolean matches(Map<MobEffect, MobEffectInstance> pEffects) {
|
||||
if (this == ANY) {
|
||||
return true;
|
||||
} else {
|
||||
for(Map.Entry<MobEffect, MobEffectsPredicate.MobEffectInstancePredicate> entry : this.effects.entrySet()) {
|
||||
MobEffectInstance mobeffectinstance = pEffects.get(entry.getKey());
|
||||
if (!entry.getValue().matches(mobeffectinstance)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static MobEffectsPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "effects");
|
||||
Map<MobEffect, MobEffectsPredicate.MobEffectInstancePredicate> map = Maps.newLinkedHashMap();
|
||||
|
||||
for(Map.Entry<String, JsonElement> entry : jsonobject.entrySet()) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(entry.getKey());
|
||||
MobEffect mobeffect = BuiltInRegistries.MOB_EFFECT.getOptional(resourcelocation).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown effect '" + resourcelocation + "'");
|
||||
});
|
||||
MobEffectsPredicate.MobEffectInstancePredicate mobeffectspredicate$mobeffectinstancepredicate = MobEffectsPredicate.MobEffectInstancePredicate.fromJson(GsonHelper.convertToJsonObject(entry.getValue(), entry.getKey()));
|
||||
map.put(mobeffect, mobeffectspredicate$mobeffectinstancepredicate);
|
||||
}
|
||||
|
||||
return new MobEffectsPredicate(map);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
|
||||
for(Map.Entry<MobEffect, MobEffectsPredicate.MobEffectInstancePredicate> entry : this.effects.entrySet()) {
|
||||
jsonobject.add(BuiltInRegistries.MOB_EFFECT.getKey(entry.getKey()).toString(), entry.getValue().serializeToJson());
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MobEffectInstancePredicate {
|
||||
private final MinMaxBounds.Ints amplifier;
|
||||
private final MinMaxBounds.Ints duration;
|
||||
@Nullable
|
||||
private final Boolean ambient;
|
||||
@Nullable
|
||||
private final Boolean visible;
|
||||
|
||||
public MobEffectInstancePredicate(MinMaxBounds.Ints pAmplifier, MinMaxBounds.Ints pDuration, @Nullable Boolean pAmbient, @Nullable Boolean pVisible) {
|
||||
this.amplifier = pAmplifier;
|
||||
this.duration = pDuration;
|
||||
this.ambient = pAmbient;
|
||||
this.visible = pVisible;
|
||||
}
|
||||
|
||||
public MobEffectInstancePredicate() {
|
||||
this(MinMaxBounds.Ints.ANY, MinMaxBounds.Ints.ANY, (Boolean)null, (Boolean)null);
|
||||
}
|
||||
|
||||
public boolean matches(@Nullable MobEffectInstance pEffect) {
|
||||
if (pEffect == null) {
|
||||
return false;
|
||||
} else if (!this.amplifier.matches(pEffect.getAmplifier())) {
|
||||
return false;
|
||||
} else if (!this.duration.matches(pEffect.getDuration())) {
|
||||
return false;
|
||||
} else if (this.ambient != null && this.ambient != pEffect.isAmbient()) {
|
||||
return false;
|
||||
} else {
|
||||
return this.visible == null || this.visible == pEffect.isVisible();
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("amplifier", this.amplifier.serializeToJson());
|
||||
jsonobject.add("duration", this.duration.serializeToJson());
|
||||
jsonobject.addProperty("ambient", this.ambient);
|
||||
jsonobject.addProperty("visible", this.visible);
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public static MobEffectsPredicate.MobEffectInstancePredicate fromJson(JsonObject pJson) {
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(pJson.get("amplifier"));
|
||||
MinMaxBounds.Ints minmaxbounds$ints1 = MinMaxBounds.Ints.fromJson(pJson.get("duration"));
|
||||
Boolean obool = pJson.has("ambient") ? GsonHelper.getAsBoolean(pJson, "ambient") : null;
|
||||
Boolean obool1 = pJson.has("visible") ? GsonHelper.getAsBoolean(pJson, "visible") : null;
|
||||
return new MobEffectsPredicate.MobEffectInstancePredicate(minmaxbounds$ints, minmaxbounds$ints1, obool, obool1);
|
||||
}
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class NbtPredicate {
|
||||
public static final NbtPredicate ANY = new NbtPredicate((CompoundTag)null);
|
||||
@Nullable
|
||||
private final CompoundTag tag;
|
||||
|
||||
public NbtPredicate(@Nullable CompoundTag pTag) {
|
||||
this.tag = pTag;
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack pStack) {
|
||||
return this == ANY ? true : this.matches(pStack.getTag());
|
||||
}
|
||||
|
||||
public boolean matches(Entity pEntity) {
|
||||
return this == ANY ? true : this.matches(getEntityTagToCompare(pEntity));
|
||||
}
|
||||
|
||||
public boolean matches(@Nullable Tag pTag) {
|
||||
if (pTag == null) {
|
||||
return this == ANY;
|
||||
} else {
|
||||
return this.tag == null || NbtUtils.compareNbt(this.tag, pTag, true);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
return (JsonElement)(this != ANY && this.tag != null ? new JsonPrimitive(this.tag.toString()) : JsonNull.INSTANCE);
|
||||
}
|
||||
|
||||
public static NbtPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
CompoundTag compoundtag;
|
||||
try {
|
||||
compoundtag = TagParser.parseTag(GsonHelper.convertToString(pJson, "nbt"));
|
||||
} catch (CommandSyntaxException commandsyntaxexception) {
|
||||
throw new JsonSyntaxException("Invalid nbt tag: " + commandsyntaxexception.getMessage());
|
||||
}
|
||||
|
||||
return new NbtPredicate(compoundtag);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public static CompoundTag getEntityTagToCompare(Entity pEntity) {
|
||||
CompoundTag compoundtag = pEntity.saveWithoutId(new CompoundTag());
|
||||
if (pEntity instanceof Player) {
|
||||
ItemStack itemstack = ((Player)pEntity).getInventory().getSelected();
|
||||
if (!itemstack.isEmpty()) {
|
||||
compoundtag.put("SelectedItem", itemstack.save(new CompoundTag()));
|
||||
}
|
||||
}
|
||||
|
||||
return compoundtag;
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class PickedUpItemTrigger extends SimpleCriterionTrigger<PickedUpItemTrigger.TriggerInstance> {
|
||||
private final ResourceLocation id;
|
||||
|
||||
public PickedUpItemTrigger(ResourceLocation pId) {
|
||||
this.id = pId;
|
||||
}
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
protected PickedUpItemTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(pJson.get("item"));
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "entity", pDeserializationContext);
|
||||
return new PickedUpItemTrigger.TriggerInstance(this.id, pPredicate, itempredicate, contextawarepredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ItemStack pStack, @Nullable Entity pEntity) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pEntity);
|
||||
this.trigger(pPlayer, (p_221306_) -> {
|
||||
return p_221306_.matches(pPlayer, pStack, lootcontext);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ItemPredicate item;
|
||||
private final ContextAwarePredicate entity;
|
||||
|
||||
public TriggerInstance(ResourceLocation pCriterion, ContextAwarePredicate pPlayer, ItemPredicate pItem, ContextAwarePredicate pEntity) {
|
||||
super(pCriterion, pPlayer);
|
||||
this.item = pItem;
|
||||
this.entity = pEntity;
|
||||
}
|
||||
|
||||
public static PickedUpItemTrigger.TriggerInstance thrownItemPickedUpByEntity(ContextAwarePredicate pPlayer, ItemPredicate pItem, ContextAwarePredicate pEntity) {
|
||||
return new PickedUpItemTrigger.TriggerInstance(CriteriaTriggers.THROWN_ITEM_PICKED_UP_BY_ENTITY.getId(), pPlayer, pItem, pEntity);
|
||||
}
|
||||
|
||||
public static PickedUpItemTrigger.TriggerInstance thrownItemPickedUpByPlayer(ContextAwarePredicate pPlayer, ItemPredicate pItem, ContextAwarePredicate pEntity) {
|
||||
return new PickedUpItemTrigger.TriggerInstance(CriteriaTriggers.THROWN_ITEM_PICKED_UP_BY_PLAYER.getId(), pPlayer, pItem, pEntity);
|
||||
}
|
||||
|
||||
public boolean matches(ServerPlayer pPlayer, ItemStack pStack, LootContext pContext) {
|
||||
if (!this.item.matches(pStack)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.entity.matches(pContext);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
jsonobject.add("entity", this.entity.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class PlayerHurtEntityTrigger extends SimpleCriterionTrigger<PlayerHurtEntityTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("player_hurt_entity");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public PlayerHurtEntityTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
DamagePredicate damagepredicate = DamagePredicate.fromJson(pJson.get("damage"));
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "entity", pDeserializationContext);
|
||||
return new PlayerHurtEntityTrigger.TriggerInstance(pPredicate, damagepredicate, contextawarepredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Entity pEntity, DamageSource pSource, float pAmountDealt, float pAmountTaken, boolean pBlocked) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pEntity);
|
||||
this.trigger(pPlayer, (p_60126_) -> {
|
||||
return p_60126_.matches(pPlayer, lootcontext, pSource, pAmountDealt, pAmountTaken, pBlocked);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final DamagePredicate damage;
|
||||
private final ContextAwarePredicate entity;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, DamagePredicate pDamage, ContextAwarePredicate pEntity) {
|
||||
super(PlayerHurtEntityTrigger.ID, pPlayer);
|
||||
this.damage = pDamage;
|
||||
this.entity = pEntity;
|
||||
}
|
||||
|
||||
public static PlayerHurtEntityTrigger.TriggerInstance playerHurtEntity() {
|
||||
return new PlayerHurtEntityTrigger.TriggerInstance(ContextAwarePredicate.ANY, DamagePredicate.ANY, ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public static PlayerHurtEntityTrigger.TriggerInstance playerHurtEntity(DamagePredicate pDamage) {
|
||||
return new PlayerHurtEntityTrigger.TriggerInstance(ContextAwarePredicate.ANY, pDamage, ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public static PlayerHurtEntityTrigger.TriggerInstance playerHurtEntity(DamagePredicate.Builder pDamageBuilder) {
|
||||
return new PlayerHurtEntityTrigger.TriggerInstance(ContextAwarePredicate.ANY, pDamageBuilder.build(), ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public static PlayerHurtEntityTrigger.TriggerInstance playerHurtEntity(EntityPredicate pEntity) {
|
||||
return new PlayerHurtEntityTrigger.TriggerInstance(ContextAwarePredicate.ANY, DamagePredicate.ANY, EntityPredicate.wrap(pEntity));
|
||||
}
|
||||
|
||||
public static PlayerHurtEntityTrigger.TriggerInstance playerHurtEntity(DamagePredicate pDamage, EntityPredicate pEntity) {
|
||||
return new PlayerHurtEntityTrigger.TriggerInstance(ContextAwarePredicate.ANY, pDamage, EntityPredicate.wrap(pEntity));
|
||||
}
|
||||
|
||||
public static PlayerHurtEntityTrigger.TriggerInstance playerHurtEntity(DamagePredicate.Builder pDamageBuilder, EntityPredicate pEntity) {
|
||||
return new PlayerHurtEntityTrigger.TriggerInstance(ContextAwarePredicate.ANY, pDamageBuilder.build(), EntityPredicate.wrap(pEntity));
|
||||
}
|
||||
|
||||
public boolean matches(ServerPlayer pPlayer, LootContext pContext, DamageSource pDamage, float pDealt, float pTaken, boolean pBlocked) {
|
||||
if (!this.damage.matches(pPlayer, pDamage, pDealt, pTaken, pBlocked)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.entity.matches(pContext);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("damage", this.damage.serializeToJson());
|
||||
jsonobject.add("entity", this.entity.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class PlayerInteractTrigger extends SimpleCriterionTrigger<PlayerInteractTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("player_interacted_with_entity");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
protected PlayerInteractTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(pJson.get("item"));
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "entity", pDeserializationContext);
|
||||
return new PlayerInteractTrigger.TriggerInstance(pPredicate, itempredicate, contextawarepredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ItemStack pItem, Entity pEntity) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pEntity);
|
||||
this.trigger(pPlayer, (p_61501_) -> {
|
||||
return p_61501_.matches(pItem, lootcontext);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ItemPredicate item;
|
||||
private final ContextAwarePredicate entity;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ItemPredicate pItem, ContextAwarePredicate pEntity) {
|
||||
super(PlayerInteractTrigger.ID, pPlayer);
|
||||
this.item = pItem;
|
||||
this.entity = pEntity;
|
||||
}
|
||||
|
||||
public static PlayerInteractTrigger.TriggerInstance itemUsedOnEntity(ContextAwarePredicate pPlayer, ItemPredicate.Builder pItem, ContextAwarePredicate pEntity) {
|
||||
return new PlayerInteractTrigger.TriggerInstance(pPlayer, pItem.build(), pEntity);
|
||||
}
|
||||
|
||||
public static PlayerInteractTrigger.TriggerInstance itemUsedOnEntity(ItemPredicate.Builder pItem, ContextAwarePredicate pEntity) {
|
||||
return itemUsedOnEntity(ContextAwarePredicate.ANY, pItem, pEntity);
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack pItem, LootContext pLootContext) {
|
||||
return !this.item.matches(pItem) ? false : this.entity.matches(pLootContext);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
jsonobject.add("entity", this.entity.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+327
@@ -0,0 +1,327 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.advancements.AdvancementProgress;
|
||||
import net.minecraft.advancements.CriterionProgress;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.PlayerAdvancements;
|
||||
import net.minecraft.server.ServerAdvancementManager;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.stats.RecipeBook;
|
||||
import net.minecraft.stats.Stat;
|
||||
import net.minecraft.stats.StatType;
|
||||
import net.minecraft.stats.StatsCounter;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.projectile.ProjectileUtil;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class PlayerPredicate implements EntitySubPredicate {
|
||||
public static final int LOOKING_AT_RANGE = 100;
|
||||
private final MinMaxBounds.Ints level;
|
||||
@Nullable
|
||||
private final GameType gameType;
|
||||
private final Map<Stat<?>, MinMaxBounds.Ints> stats;
|
||||
private final Object2BooleanMap<ResourceLocation> recipes;
|
||||
private final Map<ResourceLocation, PlayerPredicate.AdvancementPredicate> advancements;
|
||||
private final EntityPredicate lookingAt;
|
||||
|
||||
private static PlayerPredicate.AdvancementPredicate advancementPredicateFromJson(JsonElement pJson) {
|
||||
if (pJson.isJsonPrimitive()) {
|
||||
boolean flag = pJson.getAsBoolean();
|
||||
return new PlayerPredicate.AdvancementDonePredicate(flag);
|
||||
} else {
|
||||
Object2BooleanMap<String> object2booleanmap = new Object2BooleanOpenHashMap<>();
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "criterion data");
|
||||
jsonobject.entrySet().forEach((p_62288_) -> {
|
||||
boolean flag1 = GsonHelper.convertToBoolean(p_62288_.getValue(), "criterion test");
|
||||
object2booleanmap.put(p_62288_.getKey(), flag1);
|
||||
});
|
||||
return new PlayerPredicate.AdvancementCriterionsPredicate(object2booleanmap);
|
||||
}
|
||||
}
|
||||
|
||||
PlayerPredicate(MinMaxBounds.Ints pLevel, @Nullable GameType pGameType, Map<Stat<?>, MinMaxBounds.Ints> pStats, Object2BooleanMap<ResourceLocation> pRecipes, Map<ResourceLocation, PlayerPredicate.AdvancementPredicate> pAdvancements, EntityPredicate pLookingAt) {
|
||||
this.level = pLevel;
|
||||
this.gameType = pGameType;
|
||||
this.stats = pStats;
|
||||
this.recipes = pRecipes;
|
||||
this.advancements = pAdvancements;
|
||||
this.lookingAt = pLookingAt;
|
||||
}
|
||||
|
||||
public boolean matches(Entity pEntity, ServerLevel pLevel, @Nullable Vec3 p_222486_) {
|
||||
if (!(pEntity instanceof ServerPlayer serverplayer)) {
|
||||
return false;
|
||||
} else if (!this.level.matches(serverplayer.experienceLevel)) {
|
||||
return false;
|
||||
} else if (this.gameType != null && this.gameType != serverplayer.gameMode.getGameModeForPlayer()) {
|
||||
return false;
|
||||
} else {
|
||||
StatsCounter statscounter = serverplayer.getStats();
|
||||
|
||||
for(Map.Entry<Stat<?>, MinMaxBounds.Ints> entry : this.stats.entrySet()) {
|
||||
int i = statscounter.getValue(entry.getKey());
|
||||
if (!entry.getValue().matches(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RecipeBook recipebook = serverplayer.getRecipeBook();
|
||||
|
||||
for(Object2BooleanMap.Entry<ResourceLocation> entry2 : this.recipes.object2BooleanEntrySet()) {
|
||||
if (recipebook.contains(entry2.getKey()) != entry2.getBooleanValue()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.advancements.isEmpty()) {
|
||||
PlayerAdvancements playeradvancements = serverplayer.getAdvancements();
|
||||
ServerAdvancementManager serveradvancementmanager = serverplayer.getServer().getAdvancements();
|
||||
|
||||
for(Map.Entry<ResourceLocation, PlayerPredicate.AdvancementPredicate> entry1 : this.advancements.entrySet()) {
|
||||
Advancement advancement = serveradvancementmanager.getAdvancement(entry1.getKey());
|
||||
if (advancement == null || !entry1.getValue().test(playeradvancements.getOrStartProgress(advancement))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.lookingAt != EntityPredicate.ANY) {
|
||||
Vec3 vec3 = serverplayer.getEyePosition();
|
||||
Vec3 vec31 = serverplayer.getViewVector(1.0F);
|
||||
Vec3 vec32 = vec3.add(vec31.x * 100.0D, vec31.y * 100.0D, vec31.z * 100.0D);
|
||||
EntityHitResult entityhitresult = ProjectileUtil.getEntityHitResult(serverplayer.level(), serverplayer, vec3, vec32, (new AABB(vec3, vec32)).inflate(1.0D), (p_156765_) -> {
|
||||
return !p_156765_.isSpectator();
|
||||
}, 0.0F);
|
||||
if (entityhitresult == null || entityhitresult.getType() != HitResult.Type.ENTITY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Entity entity = entityhitresult.getEntity();
|
||||
if (!this.lookingAt.matches(serverplayer, entity) || !serverplayer.hasLineOfSight(entity)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerPredicate fromJson(JsonObject pJson) {
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(pJson.get("level"));
|
||||
String s = GsonHelper.getAsString(pJson, "gamemode", "");
|
||||
GameType gametype = GameType.byName(s, (GameType)null);
|
||||
Map<Stat<?>, MinMaxBounds.Ints> map = Maps.newHashMap();
|
||||
JsonArray jsonarray = GsonHelper.getAsJsonArray(pJson, "stats", (JsonArray)null);
|
||||
if (jsonarray != null) {
|
||||
for(JsonElement jsonelement : jsonarray) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(jsonelement, "stats entry");
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(jsonobject, "type"));
|
||||
StatType<?> stattype = BuiltInRegistries.STAT_TYPE.get(resourcelocation);
|
||||
if (stattype == null) {
|
||||
throw new JsonParseException("Invalid stat type: " + resourcelocation);
|
||||
}
|
||||
|
||||
ResourceLocation resourcelocation1 = new ResourceLocation(GsonHelper.getAsString(jsonobject, "stat"));
|
||||
Stat<?> stat = getStat(stattype, resourcelocation1);
|
||||
MinMaxBounds.Ints minmaxbounds$ints1 = MinMaxBounds.Ints.fromJson(jsonobject.get("value"));
|
||||
map.put(stat, minmaxbounds$ints1);
|
||||
}
|
||||
}
|
||||
|
||||
Object2BooleanMap<ResourceLocation> object2booleanmap = new Object2BooleanOpenHashMap<>();
|
||||
JsonObject jsonobject1 = GsonHelper.getAsJsonObject(pJson, "recipes", new JsonObject());
|
||||
|
||||
for(Map.Entry<String, JsonElement> entry : jsonobject1.entrySet()) {
|
||||
ResourceLocation resourcelocation2 = new ResourceLocation(entry.getKey());
|
||||
boolean flag = GsonHelper.convertToBoolean(entry.getValue(), "recipe present");
|
||||
object2booleanmap.put(resourcelocation2, flag);
|
||||
}
|
||||
|
||||
Map<ResourceLocation, PlayerPredicate.AdvancementPredicate> map1 = Maps.newHashMap();
|
||||
JsonObject jsonobject2 = GsonHelper.getAsJsonObject(pJson, "advancements", new JsonObject());
|
||||
|
||||
for(Map.Entry<String, JsonElement> entry1 : jsonobject2.entrySet()) {
|
||||
ResourceLocation resourcelocation3 = new ResourceLocation(entry1.getKey());
|
||||
PlayerPredicate.AdvancementPredicate playerpredicate$advancementpredicate = advancementPredicateFromJson(entry1.getValue());
|
||||
map1.put(resourcelocation3, playerpredicate$advancementpredicate);
|
||||
}
|
||||
|
||||
EntityPredicate entitypredicate = EntityPredicate.fromJson(pJson.get("looking_at"));
|
||||
return new PlayerPredicate(minmaxbounds$ints, gametype, map, object2booleanmap, map1, entitypredicate);
|
||||
}
|
||||
|
||||
private static <T> Stat<T> getStat(StatType<T> pType, ResourceLocation pId) {
|
||||
Registry<T> registry = pType.getRegistry();
|
||||
T t = registry.get(pId);
|
||||
if (t == null) {
|
||||
throw new JsonParseException("Unknown object " + pId + " for stat type " + BuiltInRegistries.STAT_TYPE.getKey(pType));
|
||||
} else {
|
||||
return pType.get(t);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> ResourceLocation getStatValueId(Stat<T> pStat) {
|
||||
return pStat.getType().getRegistry().getKey(pStat.getValue());
|
||||
}
|
||||
|
||||
public JsonObject serializeCustomData() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("level", this.level.serializeToJson());
|
||||
if (this.gameType != null) {
|
||||
jsonobject.addProperty("gamemode", this.gameType.getName());
|
||||
}
|
||||
|
||||
if (!this.stats.isEmpty()) {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
this.stats.forEach((p_222489_, p_222490_) -> {
|
||||
JsonObject jsonobject3 = new JsonObject();
|
||||
jsonobject3.addProperty("type", BuiltInRegistries.STAT_TYPE.getKey(p_222489_.getType()).toString());
|
||||
jsonobject3.addProperty("stat", getStatValueId(p_222489_).toString());
|
||||
jsonobject3.add("value", p_222490_.serializeToJson());
|
||||
jsonarray.add(jsonobject3);
|
||||
});
|
||||
jsonobject.add("stats", jsonarray);
|
||||
}
|
||||
|
||||
if (!this.recipes.isEmpty()) {
|
||||
JsonObject jsonobject1 = new JsonObject();
|
||||
this.recipes.forEach((p_222499_, p_222500_) -> {
|
||||
jsonobject1.addProperty(p_222499_.toString(), p_222500_);
|
||||
});
|
||||
jsonobject.add("recipes", jsonobject1);
|
||||
}
|
||||
|
||||
if (!this.advancements.isEmpty()) {
|
||||
JsonObject jsonobject2 = new JsonObject();
|
||||
this.advancements.forEach((p_222495_, p_222496_) -> {
|
||||
jsonobject2.add(p_222495_.toString(), p_222496_.toJson());
|
||||
});
|
||||
jsonobject.add("advancements", jsonobject2);
|
||||
}
|
||||
|
||||
jsonobject.add("looking_at", this.lookingAt.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public EntitySubPredicate.Type type() {
|
||||
return EntitySubPredicate.Types.PLAYER;
|
||||
}
|
||||
|
||||
static class AdvancementCriterionsPredicate implements PlayerPredicate.AdvancementPredicate {
|
||||
private final Object2BooleanMap<String> criterions;
|
||||
|
||||
public AdvancementCriterionsPredicate(Object2BooleanMap<String> pCriterions) {
|
||||
this.criterions = pCriterions;
|
||||
}
|
||||
|
||||
public JsonElement toJson() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
this.criterions.forEach(jsonobject::addProperty);
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public boolean test(AdvancementProgress p_62296_) {
|
||||
for(Object2BooleanMap.Entry<String> entry : this.criterions.object2BooleanEntrySet()) {
|
||||
CriterionProgress criterionprogress = p_62296_.getCriterion(entry.getKey());
|
||||
if (criterionprogress == null || criterionprogress.isDone() != entry.getBooleanValue()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class AdvancementDonePredicate implements PlayerPredicate.AdvancementPredicate {
|
||||
private final boolean state;
|
||||
|
||||
public AdvancementDonePredicate(boolean pState) {
|
||||
this.state = pState;
|
||||
}
|
||||
|
||||
public JsonElement toJson() {
|
||||
return new JsonPrimitive(this.state);
|
||||
}
|
||||
|
||||
public boolean test(AdvancementProgress p_62304_) {
|
||||
return p_62304_.isDone() == this.state;
|
||||
}
|
||||
}
|
||||
|
||||
interface AdvancementPredicate extends Predicate<AdvancementProgress> {
|
||||
JsonElement toJson();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private MinMaxBounds.Ints level = MinMaxBounds.Ints.ANY;
|
||||
@Nullable
|
||||
private GameType gameType;
|
||||
private final Map<Stat<?>, MinMaxBounds.Ints> stats = Maps.newHashMap();
|
||||
private final Object2BooleanMap<ResourceLocation> recipes = new Object2BooleanOpenHashMap<>();
|
||||
private final Map<ResourceLocation, PlayerPredicate.AdvancementPredicate> advancements = Maps.newHashMap();
|
||||
private EntityPredicate lookingAt = EntityPredicate.ANY;
|
||||
|
||||
public static PlayerPredicate.Builder player() {
|
||||
return new PlayerPredicate.Builder();
|
||||
}
|
||||
|
||||
public PlayerPredicate.Builder setLevel(MinMaxBounds.Ints pLevel) {
|
||||
this.level = pLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PlayerPredicate.Builder addStat(Stat<?> pStat, MinMaxBounds.Ints pValue) {
|
||||
this.stats.put(pStat, pValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PlayerPredicate.Builder addRecipe(ResourceLocation pRecipe, boolean pUnlocked) {
|
||||
this.recipes.put(pRecipe, pUnlocked);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PlayerPredicate.Builder setGameType(GameType pGameType) {
|
||||
this.gameType = pGameType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PlayerPredicate.Builder setLookingAt(EntityPredicate pLookingAt) {
|
||||
this.lookingAt = pLookingAt;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PlayerPredicate.Builder checkAdvancementDone(ResourceLocation pAdvancement, boolean pDone) {
|
||||
this.advancements.put(pAdvancement, new PlayerPredicate.AdvancementDonePredicate(pDone));
|
||||
return this;
|
||||
}
|
||||
|
||||
public PlayerPredicate.Builder checkAdvancementCriterions(ResourceLocation pAdvancement, Map<String, Boolean> pCriterions) {
|
||||
this.advancements.put(pAdvancement, new PlayerPredicate.AdvancementCriterionsPredicate(new Object2BooleanOpenHashMap<>(pCriterions)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public PlayerPredicate build() {
|
||||
return new PlayerPredicate(this.level, this.gameType, this.stats, this.recipes, this.advancements, this.lookingAt);
|
||||
}
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class PlayerTrigger extends SimpleCriterionTrigger<PlayerTrigger.TriggerInstance> {
|
||||
final ResourceLocation id;
|
||||
|
||||
public PlayerTrigger(ResourceLocation p_222616_) {
|
||||
this.id = p_222616_;
|
||||
}
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public PlayerTrigger.TriggerInstance createInstance(JsonObject p_286310_, ContextAwarePredicate p_286629_, DeserializationContext p_286901_) {
|
||||
return new PlayerTrigger.TriggerInstance(this.id, p_286629_);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer p_222619_) {
|
||||
this.trigger(p_222619_, (p_222625_) -> {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
public TriggerInstance(ResourceLocation p_286413_, ContextAwarePredicate p_286749_) {
|
||||
super(p_286413_, p_286749_);
|
||||
}
|
||||
|
||||
public static PlayerTrigger.TriggerInstance located(LocationPredicate p_222636_) {
|
||||
return new PlayerTrigger.TriggerInstance(CriteriaTriggers.LOCATION.id, EntityPredicate.wrap(EntityPredicate.Builder.entity().located(p_222636_).build()));
|
||||
}
|
||||
|
||||
public static PlayerTrigger.TriggerInstance located(EntityPredicate p_222634_) {
|
||||
return new PlayerTrigger.TriggerInstance(CriteriaTriggers.LOCATION.id, EntityPredicate.wrap(p_222634_));
|
||||
}
|
||||
|
||||
public static PlayerTrigger.TriggerInstance sleptInBed() {
|
||||
return new PlayerTrigger.TriggerInstance(CriteriaTriggers.SLEPT_IN_BED.id, ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public static PlayerTrigger.TriggerInstance raidWon() {
|
||||
return new PlayerTrigger.TriggerInstance(CriteriaTriggers.RAID_WIN.id, ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public static PlayerTrigger.TriggerInstance avoidVibration() {
|
||||
return new PlayerTrigger.TriggerInstance(CriteriaTriggers.AVOID_VIBRATION.id, ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public static PlayerTrigger.TriggerInstance tick() {
|
||||
return new PlayerTrigger.TriggerInstance(CriteriaTriggers.TICK.id, ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public static PlayerTrigger.TriggerInstance walkOnBlockWithEquipment(Block p_222638_, Item p_222639_) {
|
||||
return located(EntityPredicate.Builder.entity().equipment(EntityEquipmentPredicate.Builder.equipment().feet(ItemPredicate.Builder.item().of(p_222639_).build()).build()).steppingOn(LocationPredicate.Builder.location().setBlock(BlockPredicate.Builder.block().of(p_222638_).build()).build()).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class RecipeCraftedTrigger extends SimpleCriterionTrigger<RecipeCraftedTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("recipe_crafted");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
protected RecipeCraftedTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(pJson, "recipe_id"));
|
||||
ItemPredicate[] aitempredicate = ItemPredicate.fromJsonArray(pJson.get("ingredients"));
|
||||
return new RecipeCraftedTrigger.TriggerInstance(pPredicate, resourcelocation, List.of(aitempredicate));
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ResourceLocation pRecipeId, List<ItemStack> pItems) {
|
||||
this.trigger(pPlayer, (p_282798_) -> {
|
||||
return p_282798_.matches(pRecipeId, pItems);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ResourceLocation recipeId;
|
||||
private final List<ItemPredicate> predicates;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ResourceLocation pRecipeId, List<ItemPredicate> pPredicates) {
|
||||
super(RecipeCraftedTrigger.ID, pPlayer);
|
||||
this.recipeId = pRecipeId;
|
||||
this.predicates = pPredicates;
|
||||
}
|
||||
|
||||
public static RecipeCraftedTrigger.TriggerInstance craftedItem(ResourceLocation pRecipeId, List<ItemPredicate> pPredicates) {
|
||||
return new RecipeCraftedTrigger.TriggerInstance(ContextAwarePredicate.ANY, pRecipeId, pPredicates);
|
||||
}
|
||||
|
||||
public static RecipeCraftedTrigger.TriggerInstance craftedItem(ResourceLocation pRecipeId) {
|
||||
return new RecipeCraftedTrigger.TriggerInstance(ContextAwarePredicate.ANY, pRecipeId, List.of());
|
||||
}
|
||||
|
||||
boolean matches(ResourceLocation pRecipeId, List<ItemStack> pItems) {
|
||||
if (!pRecipeId.equals(this.recipeId)) {
|
||||
return false;
|
||||
} else {
|
||||
List<ItemStack> list = new ArrayList<>(pItems);
|
||||
|
||||
for(ItemPredicate itempredicate : this.predicates) {
|
||||
boolean flag = false;
|
||||
Iterator<ItemStack> iterator = list.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
if (itempredicate.matches(iterator.next())) {
|
||||
iterator.remove();
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.addProperty("recipe_id", this.recipeId.toString());
|
||||
if (this.predicates.size() > 0) {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
for(ItemPredicate itempredicate : this.predicates) {
|
||||
jsonarray.add(itempredicate.serializeToJson());
|
||||
}
|
||||
|
||||
jsonobject.add("ingredients", jsonarray);
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
|
||||
public class RecipeUnlockedTrigger extends SimpleCriterionTrigger<RecipeUnlockedTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("recipe_unlocked");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public RecipeUnlockedTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(pJson, "recipe"));
|
||||
return new RecipeUnlockedTrigger.TriggerInstance(pPredicate, resourcelocation);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Recipe<?> pRecipe) {
|
||||
this.trigger(pPlayer, (p_63723_) -> {
|
||||
return p_63723_.matches(pRecipe);
|
||||
});
|
||||
}
|
||||
|
||||
public static RecipeUnlockedTrigger.TriggerInstance unlocked(ResourceLocation pRecipe) {
|
||||
return new RecipeUnlockedTrigger.TriggerInstance(ContextAwarePredicate.ANY, pRecipe);
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ResourceLocation recipe;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ResourceLocation pRecipe) {
|
||||
super(RecipeUnlockedTrigger.ID, pPlayer);
|
||||
this.recipe = pRecipe;
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.addProperty("recipe", this.recipe.toString());
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public boolean matches(Recipe<?> pRecipe) {
|
||||
return this.recipe.equals(pRecipe.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import net.minecraft.world.level.storage.loot.Deserializers;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
|
||||
public class SerializationContext {
|
||||
public static final SerializationContext INSTANCE = new SerializationContext();
|
||||
private final Gson predicateGson = Deserializers.createConditionSerializer().create();
|
||||
|
||||
public final JsonElement serializeConditions(LootItemCondition[] pConditions) {
|
||||
return this.predicateGson.toJsonTree(pConditions);
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
|
||||
public class ShotCrossbowTrigger extends SimpleCriterionTrigger<ShotCrossbowTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("shot_crossbow");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public ShotCrossbowTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(pJson.get("item"));
|
||||
return new ShotCrossbowTrigger.TriggerInstance(pPredicate, itempredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pShooter, ItemStack pStack) {
|
||||
this.trigger(pShooter, (p_65467_) -> {
|
||||
return p_65467_.matches(pStack);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ItemPredicate item;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ItemPredicate pItem) {
|
||||
super(ShotCrossbowTrigger.ID, pPlayer);
|
||||
this.item = pItem;
|
||||
}
|
||||
|
||||
public static ShotCrossbowTrigger.TriggerInstance shotCrossbow(ItemPredicate pItem) {
|
||||
return new ShotCrossbowTrigger.TriggerInstance(ContextAwarePredicate.ANY, pItem);
|
||||
}
|
||||
|
||||
public static ShotCrossbowTrigger.TriggerInstance shotCrossbow(ItemLike pItem) {
|
||||
return new ShotCrossbowTrigger.TriggerInstance(ContextAwarePredicate.ANY, ItemPredicate.Builder.item().of(pItem).build());
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack pItem) {
|
||||
return this.item.matches(pItem);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import net.minecraft.advancements.CriterionTrigger;
|
||||
import net.minecraft.server.PlayerAdvancements;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public abstract class SimpleCriterionTrigger<T extends AbstractCriterionTriggerInstance> implements CriterionTrigger<T> {
|
||||
private final Map<PlayerAdvancements, Set<CriterionTrigger.Listener<T>>> players = Maps.newIdentityHashMap();
|
||||
|
||||
public final void addPlayerListener(PlayerAdvancements pPlayerAdvancements, CriterionTrigger.Listener<T> pListener) {
|
||||
this.players.computeIfAbsent(pPlayerAdvancements, (p_66252_) -> {
|
||||
return Sets.newHashSet();
|
||||
}).add(pListener);
|
||||
}
|
||||
|
||||
public final void removePlayerListener(PlayerAdvancements pPlayerAdvancements, CriterionTrigger.Listener<T> pListener) {
|
||||
Set<CriterionTrigger.Listener<T>> set = this.players.get(pPlayerAdvancements);
|
||||
if (set != null) {
|
||||
set.remove(pListener);
|
||||
if (set.isEmpty()) {
|
||||
this.players.remove(pPlayerAdvancements);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final void removePlayerListeners(PlayerAdvancements pPlayerAdvancements) {
|
||||
this.players.remove(pPlayerAdvancements);
|
||||
}
|
||||
|
||||
protected abstract T createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext);
|
||||
|
||||
public final T createInstance(JsonObject pObject, DeserializationContext pConditions) {
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pObject, "player", pConditions);
|
||||
return this.createInstance(pObject, contextawarepredicate, pConditions);
|
||||
}
|
||||
|
||||
protected void trigger(ServerPlayer pPlayer, Predicate<T> pTestTrigger) {
|
||||
PlayerAdvancements playeradvancements = pPlayer.getAdvancements();
|
||||
Set<CriterionTrigger.Listener<T>> set = this.players.get(playeradvancements);
|
||||
if (set != null && !set.isEmpty()) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pPlayer);
|
||||
List<CriterionTrigger.Listener<T>> list = null;
|
||||
|
||||
for(CriterionTrigger.Listener<T> listener : set) {
|
||||
T t = listener.getTriggerInstance();
|
||||
if (pTestTrigger.test(t) && t.getPlayerPredicate().matches(lootcontext)) {
|
||||
if (list == null) {
|
||||
list = Lists.newArrayList();
|
||||
}
|
||||
|
||||
list.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
if (list != null) {
|
||||
for(CriterionTrigger.Listener<T> listener1 : list) {
|
||||
listener1.run(playeradvancements);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class SlideDownBlockTrigger extends SimpleCriterionTrigger<SlideDownBlockTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("slide_down_block");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public SlideDownBlockTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
Block block = deserializeBlock(pJson);
|
||||
StatePropertiesPredicate statepropertiespredicate = StatePropertiesPredicate.fromJson(pJson.get("state"));
|
||||
if (block != null) {
|
||||
statepropertiespredicate.checkState(block.getStateDefinition(), (p_66983_) -> {
|
||||
throw new JsonSyntaxException("Block " + block + " has no property " + p_66983_);
|
||||
});
|
||||
}
|
||||
|
||||
return new SlideDownBlockTrigger.TriggerInstance(pPredicate, block, statepropertiespredicate);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Block deserializeBlock(JsonObject pJson) {
|
||||
if (pJson.has("block")) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(pJson, "block"));
|
||||
return BuiltInRegistries.BLOCK.getOptional(resourcelocation).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown block type '" + resourcelocation + "'");
|
||||
});
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, BlockState pState) {
|
||||
this.trigger(pPlayer, (p_66986_) -> {
|
||||
return p_66986_.matches(pState);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
@Nullable
|
||||
private final Block block;
|
||||
private final StatePropertiesPredicate state;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, @Nullable Block pBlock, StatePropertiesPredicate pState) {
|
||||
super(SlideDownBlockTrigger.ID, pPlayer);
|
||||
this.block = pBlock;
|
||||
this.state = pState;
|
||||
}
|
||||
|
||||
public static SlideDownBlockTrigger.TriggerInstance slidesDownBlock(Block pBlock) {
|
||||
return new SlideDownBlockTrigger.TriggerInstance(ContextAwarePredicate.ANY, pBlock, StatePropertiesPredicate.ANY);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
if (this.block != null) {
|
||||
jsonobject.addProperty("block", BuiltInRegistries.BLOCK.getKey(this.block).toString());
|
||||
}
|
||||
|
||||
jsonobject.add("state", this.state.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public boolean matches(BlockState pState) {
|
||||
if (this.block != null && !pState.is(this.block)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.state.matches(pState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.monster.Slime;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class SlimePredicate implements EntitySubPredicate {
|
||||
private final MinMaxBounds.Ints size;
|
||||
|
||||
private SlimePredicate(MinMaxBounds.Ints pSize) {
|
||||
this.size = pSize;
|
||||
}
|
||||
|
||||
public static SlimePredicate sized(MinMaxBounds.Ints pSize) {
|
||||
return new SlimePredicate(pSize);
|
||||
}
|
||||
|
||||
public static SlimePredicate fromJson(JsonObject pJson) {
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(pJson.get("size"));
|
||||
return new SlimePredicate(minmaxbounds$ints);
|
||||
}
|
||||
|
||||
public JsonObject serializeCustomData() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.add("size", this.size.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public boolean matches(Entity pEntity, ServerLevel pLevel, @Nullable Vec3 p_223425_) {
|
||||
if (pEntity instanceof Slime slime) {
|
||||
return this.size.matches(slime.getSize());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntitySubPredicate.Type type() {
|
||||
return EntitySubPredicate.Types.SLIME;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
public class StartRidingTrigger extends SimpleCriterionTrigger<StartRidingTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("started_riding");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public StartRidingTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
return new StartRidingTrigger.TriggerInstance(pPredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer) {
|
||||
this.trigger(pPlayer, (p_160394_) -> {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer) {
|
||||
super(StartRidingTrigger.ID, pPlayer);
|
||||
}
|
||||
|
||||
public static StartRidingTrigger.TriggerInstance playerStartsRiding(EntityPredicate.Builder pPlayer) {
|
||||
return new StartRidingTrigger.TriggerInstance(EntityPredicate.wrap(pPlayer.build()));
|
||||
}
|
||||
}
|
||||
}
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.StateHolder;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
|
||||
public class StatePropertiesPredicate {
|
||||
public static final StatePropertiesPredicate ANY = new StatePropertiesPredicate(ImmutableList.of());
|
||||
private final List<StatePropertiesPredicate.PropertyMatcher> properties;
|
||||
|
||||
private static StatePropertiesPredicate.PropertyMatcher fromJson(String pName, JsonElement pJson) {
|
||||
if (pJson.isJsonPrimitive()) {
|
||||
String s2 = pJson.getAsString();
|
||||
return new StatePropertiesPredicate.ExactPropertyMatcher(pName, s2);
|
||||
} else {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "value");
|
||||
String s = jsonobject.has("min") ? getStringOrNull(jsonobject.get("min")) : null;
|
||||
String s1 = jsonobject.has("max") ? getStringOrNull(jsonobject.get("max")) : null;
|
||||
return (StatePropertiesPredicate.PropertyMatcher)(s != null && s.equals(s1) ? new StatePropertiesPredicate.ExactPropertyMatcher(pName, s) : new StatePropertiesPredicate.RangedPropertyMatcher(pName, s, s1));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getStringOrNull(JsonElement pJson) {
|
||||
return pJson.isJsonNull() ? null : pJson.getAsString();
|
||||
}
|
||||
|
||||
StatePropertiesPredicate(List<StatePropertiesPredicate.PropertyMatcher> pProperties) {
|
||||
this.properties = ImmutableList.copyOf(pProperties);
|
||||
}
|
||||
|
||||
public <S extends StateHolder<?, S>> boolean matches(StateDefinition<?, S> pProperties, S pTargetProperty) {
|
||||
for(StatePropertiesPredicate.PropertyMatcher statepropertiespredicate$propertymatcher : this.properties) {
|
||||
if (!statepropertiespredicate$propertymatcher.match(pProperties, pTargetProperty)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean matches(BlockState pState) {
|
||||
return this.matches(pState.getBlock().getStateDefinition(), pState);
|
||||
}
|
||||
|
||||
public boolean matches(FluidState pState) {
|
||||
return this.matches(pState.getType().getStateDefinition(), pState);
|
||||
}
|
||||
|
||||
public void checkState(StateDefinition<?, ?> pProperties, Consumer<String> pPropertyConsumer) {
|
||||
this.properties.forEach((p_67678_) -> {
|
||||
p_67678_.checkState(pProperties, pPropertyConsumer);
|
||||
});
|
||||
}
|
||||
|
||||
public static StatePropertiesPredicate fromJson(@Nullable JsonElement pJson) {
|
||||
if (pJson != null && !pJson.isJsonNull()) {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "properties");
|
||||
List<StatePropertiesPredicate.PropertyMatcher> list = Lists.newArrayList();
|
||||
|
||||
for(Map.Entry<String, JsonElement> entry : jsonobject.entrySet()) {
|
||||
list.add(fromJson(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
return new StatePropertiesPredicate(list);
|
||||
} else {
|
||||
return ANY;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
if (this == ANY) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (!this.properties.isEmpty()) {
|
||||
this.properties.forEach((p_67683_) -> {
|
||||
jsonobject.add(p_67683_.getName(), p_67683_.toJson());
|
||||
});
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final List<StatePropertiesPredicate.PropertyMatcher> matchers = Lists.newArrayList();
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
public static StatePropertiesPredicate.Builder properties() {
|
||||
return new StatePropertiesPredicate.Builder();
|
||||
}
|
||||
|
||||
public StatePropertiesPredicate.Builder hasProperty(Property<?> pProperty, String pValue) {
|
||||
this.matchers.add(new StatePropertiesPredicate.ExactPropertyMatcher(pProperty.getName(), pValue));
|
||||
return this;
|
||||
}
|
||||
|
||||
public StatePropertiesPredicate.Builder hasProperty(Property<Integer> pProperty, int pValue) {
|
||||
return this.hasProperty(pProperty, Integer.toString(pValue));
|
||||
}
|
||||
|
||||
public StatePropertiesPredicate.Builder hasProperty(Property<Boolean> pProperty, boolean pValue) {
|
||||
return this.hasProperty(pProperty, Boolean.toString(pValue));
|
||||
}
|
||||
|
||||
public <T extends Comparable<T> & StringRepresentable> StatePropertiesPredicate.Builder hasProperty(Property<T> pProperty, T pValue) {
|
||||
return this.hasProperty(pProperty, pValue.getSerializedName());
|
||||
}
|
||||
|
||||
public StatePropertiesPredicate build() {
|
||||
return new StatePropertiesPredicate(this.matchers);
|
||||
}
|
||||
}
|
||||
|
||||
static class ExactPropertyMatcher extends StatePropertiesPredicate.PropertyMatcher {
|
||||
private final String value;
|
||||
|
||||
public ExactPropertyMatcher(String pName, String pValue) {
|
||||
super(pName);
|
||||
this.value = pValue;
|
||||
}
|
||||
|
||||
protected <T extends Comparable<T>> boolean match(StateHolder<?, ?> pProperties, Property<T> pPropertyTarget) {
|
||||
T t = pProperties.getValue(pPropertyTarget);
|
||||
Optional<T> optional = pPropertyTarget.getValue(this.value);
|
||||
return optional.isPresent() && t.compareTo(optional.get()) == 0;
|
||||
}
|
||||
|
||||
public JsonElement toJson() {
|
||||
return new JsonPrimitive(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
abstract static class PropertyMatcher {
|
||||
private final String name;
|
||||
|
||||
public PropertyMatcher(String pName) {
|
||||
this.name = pName;
|
||||
}
|
||||
|
||||
public <S extends StateHolder<?, S>> boolean match(StateDefinition<?, S> pProperties, S pPropertyToMatch) {
|
||||
Property<?> property = pProperties.getProperty(this.name);
|
||||
return property == null ? false : this.match(pPropertyToMatch, property);
|
||||
}
|
||||
|
||||
protected abstract <T extends Comparable<T>> boolean match(StateHolder<?, ?> pProperties, Property<T> pProperty);
|
||||
|
||||
public abstract JsonElement toJson();
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void checkState(StateDefinition<?, ?> pProperties, Consumer<String> pPropertyConsumer) {
|
||||
Property<?> property = pProperties.getProperty(this.name);
|
||||
if (property == null) {
|
||||
pPropertyConsumer.accept(this.name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class RangedPropertyMatcher extends StatePropertiesPredicate.PropertyMatcher {
|
||||
@Nullable
|
||||
private final String minValue;
|
||||
@Nullable
|
||||
private final String maxValue;
|
||||
|
||||
public RangedPropertyMatcher(String pName, @Nullable String pMinValue, @Nullable String pMaxValue) {
|
||||
super(pName);
|
||||
this.minValue = pMinValue;
|
||||
this.maxValue = pMaxValue;
|
||||
}
|
||||
|
||||
protected <T extends Comparable<T>> boolean match(StateHolder<?, ?> pProperties, Property<T> pPropertyTarget) {
|
||||
T t = pProperties.getValue(pPropertyTarget);
|
||||
if (this.minValue != null) {
|
||||
Optional<T> optional = pPropertyTarget.getValue(this.minValue);
|
||||
if (!optional.isPresent() || t.compareTo(optional.get()) < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.maxValue != null) {
|
||||
Optional<T> optional1 = pPropertyTarget.getValue(this.maxValue);
|
||||
if (!optional1.isPresent() || t.compareTo(optional1.get()) > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public JsonElement toJson() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (this.minValue != null) {
|
||||
jsonobject.addProperty("min", this.minValue);
|
||||
}
|
||||
|
||||
if (this.maxValue != null) {
|
||||
jsonobject.addProperty("max", this.maxValue);
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class SummonedEntityTrigger extends SimpleCriterionTrigger<SummonedEntityTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("summoned_entity");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public SummonedEntityTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "entity", pDeserializationContext);
|
||||
return new SummonedEntityTrigger.TriggerInstance(pPredicate, contextawarepredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Entity pEntity) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pEntity);
|
||||
this.trigger(pPlayer, (p_68265_) -> {
|
||||
return p_68265_.matches(lootcontext);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ContextAwarePredicate entity;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ContextAwarePredicate pEntity) {
|
||||
super(SummonedEntityTrigger.ID, pPlayer);
|
||||
this.entity = pEntity;
|
||||
}
|
||||
|
||||
public static SummonedEntityTrigger.TriggerInstance summonedEntity(EntityPredicate.Builder pEntityPredicateBuilder) {
|
||||
return new SummonedEntityTrigger.TriggerInstance(ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicateBuilder.build()));
|
||||
}
|
||||
|
||||
public boolean matches(LootContext pLootContext) {
|
||||
return this.entity.matches(pLootContext);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("entity", this.entity.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
|
||||
public class TagPredicate<T> {
|
||||
private final TagKey<T> tag;
|
||||
private final boolean expected;
|
||||
|
||||
public TagPredicate(TagKey<T> pTag, boolean pExpected) {
|
||||
this.tag = pTag;
|
||||
this.expected = pExpected;
|
||||
}
|
||||
|
||||
public static <T> TagPredicate<T> is(TagKey<T> pTag) {
|
||||
return new TagPredicate<>(pTag, true);
|
||||
}
|
||||
|
||||
public static <T> TagPredicate<T> isNot(TagKey<T> pTag) {
|
||||
return new TagPredicate<>(pTag, false);
|
||||
}
|
||||
|
||||
public boolean matches(Holder<T> pValue) {
|
||||
return pValue.is(this.tag) == this.expected;
|
||||
}
|
||||
|
||||
public JsonElement serializeToJson() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
jsonobject.addProperty("id", this.tag.location().toString());
|
||||
jsonobject.addProperty("expected", this.expected);
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public static <T> TagPredicate<T> fromJson(@Nullable JsonElement pJson, ResourceKey<? extends Registry<T>> pRegistry) {
|
||||
if (pJson == null) {
|
||||
throw new JsonParseException("Expected a tag predicate");
|
||||
} else {
|
||||
JsonObject jsonobject = GsonHelper.convertToJsonObject(pJson, "Tag Predicate");
|
||||
ResourceLocation resourcelocation = new ResourceLocation(GsonHelper.getAsString(jsonobject, "id"));
|
||||
boolean flag = GsonHelper.getAsBoolean(jsonobject, "expected");
|
||||
return new TagPredicate<>(TagKey.create(pRegistry, resourcelocation), flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class TameAnimalTrigger extends SimpleCriterionTrigger<TameAnimalTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("tame_animal");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public TameAnimalTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "entity", pDeserializationContext);
|
||||
return new TameAnimalTrigger.TriggerInstance(pPredicate, contextawarepredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Animal pEntity) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pEntity);
|
||||
this.trigger(pPlayer, (p_68838_) -> {
|
||||
return p_68838_.matches(lootcontext);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ContextAwarePredicate entity;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ContextAwarePredicate pEntity) {
|
||||
super(TameAnimalTrigger.ID, pPlayer);
|
||||
this.entity = pEntity;
|
||||
}
|
||||
|
||||
public static TameAnimalTrigger.TriggerInstance tamedAnimal() {
|
||||
return new TameAnimalTrigger.TriggerInstance(ContextAwarePredicate.ANY, ContextAwarePredicate.ANY);
|
||||
}
|
||||
|
||||
public static TameAnimalTrigger.TriggerInstance tamedAnimal(EntityPredicate pEntityPredicate) {
|
||||
return new TameAnimalTrigger.TriggerInstance(ContextAwarePredicate.ANY, EntityPredicate.wrap(pEntityPredicate));
|
||||
}
|
||||
|
||||
public boolean matches(LootContext pLootContext) {
|
||||
return this.entity.matches(pLootContext);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("entity", this.entity.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class TargetBlockTrigger extends SimpleCriterionTrigger<TargetBlockTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("target_hit");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public TargetBlockTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.fromJson(pJson.get("signal_strength"));
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "projectile", pDeserializationContext);
|
||||
return new TargetBlockTrigger.TriggerInstance(pPredicate, minmaxbounds$ints, contextawarepredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, Entity pProjectile, Vec3 pVector, int pSignalStrength) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pProjectile);
|
||||
this.trigger(pPlayer, (p_70224_) -> {
|
||||
return p_70224_.matches(lootcontext, pVector, pSignalStrength);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final MinMaxBounds.Ints signalStrength;
|
||||
private final ContextAwarePredicate projectile;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, MinMaxBounds.Ints pSignalStrength, ContextAwarePredicate pProjectile) {
|
||||
super(TargetBlockTrigger.ID, pPlayer);
|
||||
this.signalStrength = pSignalStrength;
|
||||
this.projectile = pProjectile;
|
||||
}
|
||||
|
||||
public static TargetBlockTrigger.TriggerInstance targetHit(MinMaxBounds.Ints pSignalStrength, ContextAwarePredicate pProjectile) {
|
||||
return new TargetBlockTrigger.TriggerInstance(ContextAwarePredicate.ANY, pSignalStrength, pProjectile);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("signal_strength", this.signalStrength.serializeToJson());
|
||||
jsonobject.add("projectile", this.projectile.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
public boolean matches(LootContext pContext, Vec3 pVector, int pSignalStrength) {
|
||||
if (!this.signalStrength.matches(pSignalStrength)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.projectile.matches(pContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.npc.AbstractVillager;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
|
||||
public class TradeTrigger extends SimpleCriterionTrigger<TradeTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("villager_trade");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public TradeTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ContextAwarePredicate contextawarepredicate = EntityPredicate.fromJson(pJson, "villager", pDeserializationContext);
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(pJson.get("item"));
|
||||
return new TradeTrigger.TriggerInstance(pPredicate, contextawarepredicate, itempredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, AbstractVillager pVillager, ItemStack pStack) {
|
||||
LootContext lootcontext = EntityPredicate.createContext(pPlayer, pVillager);
|
||||
this.trigger(pPlayer, (p_70970_) -> {
|
||||
return p_70970_.matches(lootcontext, pStack);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ContextAwarePredicate villager;
|
||||
private final ItemPredicate item;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ContextAwarePredicate pVillager, ItemPredicate pItem) {
|
||||
super(TradeTrigger.ID, pPlayer);
|
||||
this.villager = pVillager;
|
||||
this.item = pItem;
|
||||
}
|
||||
|
||||
public static TradeTrigger.TriggerInstance tradedWithVillager() {
|
||||
return new TradeTrigger.TriggerInstance(ContextAwarePredicate.ANY, ContextAwarePredicate.ANY, ItemPredicate.ANY);
|
||||
}
|
||||
|
||||
public static TradeTrigger.TriggerInstance tradedWithVillager(EntityPredicate.Builder pVillager) {
|
||||
return new TradeTrigger.TriggerInstance(EntityPredicate.wrap(pVillager.build()), ContextAwarePredicate.ANY, ItemPredicate.ANY);
|
||||
}
|
||||
|
||||
public boolean matches(LootContext pContext, ItemStack pStack) {
|
||||
if (!this.villager.matches(pContext)) {
|
||||
return false;
|
||||
} else {
|
||||
return this.item.matches(pStack);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
jsonobject.add("villager", this.villager.toJson(pConditions));
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
public class UsedEnderEyeTrigger extends SimpleCriterionTrigger<UsedEnderEyeTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("used_ender_eye");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public UsedEnderEyeTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
MinMaxBounds.Doubles minmaxbounds$doubles = MinMaxBounds.Doubles.fromJson(pJson.get("distance"));
|
||||
return new UsedEnderEyeTrigger.TriggerInstance(pPredicate, minmaxbounds$doubles);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, BlockPos pPos) {
|
||||
double d0 = pPlayer.getX() - (double)pPos.getX();
|
||||
double d1 = pPlayer.getZ() - (double)pPos.getZ();
|
||||
double d2 = d0 * d0 + d1 * d1;
|
||||
this.trigger(pPlayer, (p_73934_) -> {
|
||||
return p_73934_.matches(d2);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final MinMaxBounds.Doubles level;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, MinMaxBounds.Doubles pLevel) {
|
||||
super(UsedEnderEyeTrigger.ID, pPlayer);
|
||||
this.level = pLevel;
|
||||
}
|
||||
|
||||
public boolean matches(double pDistanceSq) {
|
||||
return this.level.matchesSqr(pDistanceSq);
|
||||
}
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package net.minecraft.advancements.critereon;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
|
||||
public class UsedTotemTrigger extends SimpleCriterionTrigger<UsedTotemTrigger.TriggerInstance> {
|
||||
static final ResourceLocation ID = new ResourceLocation("used_totem");
|
||||
|
||||
public ResourceLocation getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public UsedTotemTrigger.TriggerInstance createInstance(JsonObject pJson, ContextAwarePredicate pPredicate, DeserializationContext pDeserializationContext) {
|
||||
ItemPredicate itempredicate = ItemPredicate.fromJson(pJson.get("item"));
|
||||
return new UsedTotemTrigger.TriggerInstance(pPredicate, itempredicate);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayer pPlayer, ItemStack pItem) {
|
||||
this.trigger(pPlayer, (p_74436_) -> {
|
||||
return p_74436_.matches(pItem);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TriggerInstance extends AbstractCriterionTriggerInstance {
|
||||
private final ItemPredicate item;
|
||||
|
||||
public TriggerInstance(ContextAwarePredicate pPlayer, ItemPredicate pItem) {
|
||||
super(UsedTotemTrigger.ID, pPlayer);
|
||||
this.item = pItem;
|
||||
}
|
||||
|
||||
public static UsedTotemTrigger.TriggerInstance usedTotem(ItemPredicate pItem) {
|
||||
return new UsedTotemTrigger.TriggerInstance(ContextAwarePredicate.ANY, pItem);
|
||||
}
|
||||
|
||||
public static UsedTotemTrigger.TriggerInstance usedTotem(ItemLike pItem) {
|
||||
return new UsedTotemTrigger.TriggerInstance(ContextAwarePredicate.ANY, ItemPredicate.Builder.item().of(pItem).build());
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack pItem) {
|
||||
return this.item.matches(pItem);
|
||||
}
|
||||
|
||||
public JsonObject serializeToJson(SerializationContext pConditions) {
|
||||
JsonObject jsonobject = super.serializeToJson(pConditions);
|
||||
jsonobject.add("item", this.item.serializeToJson());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 14134 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user