trurwsuieghfdskg
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
import net.minecraft.util.ByIdMap;
|
||||
import net.minecraft.util.OptionEnum;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum AttackIndicatorStatus implements OptionEnum {
|
||||
OFF(0, "options.off"),
|
||||
CROSSHAIR(1, "options.attack.crosshair"),
|
||||
HOTBAR(2, "options.attack.hotbar");
|
||||
|
||||
private static final IntFunction<AttackIndicatorStatus> BY_ID = ByIdMap.continuous(AttackIndicatorStatus::getId, values(), ByIdMap.OutOfBoundsStrategy.WRAP);
|
||||
private final int id;
|
||||
private final String key;
|
||||
|
||||
private AttackIndicatorStatus(int p_90506_, String p_90507_) {
|
||||
this.id = p_90506_;
|
||||
this.key = p_90507_;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public static AttackIndicatorStatus byId(int p_90510_) {
|
||||
return BY_ID.apply(p_90510_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import java.util.Arrays;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.FogType;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Camera {
|
||||
private boolean initialized;
|
||||
private BlockGetter level;
|
||||
private Entity entity;
|
||||
private Vec3 position = Vec3.ZERO;
|
||||
private final BlockPos.MutableBlockPos blockPosition = new BlockPos.MutableBlockPos();
|
||||
private final Vector3f forwards = new Vector3f(0.0F, 0.0F, 1.0F);
|
||||
private final Vector3f up = new Vector3f(0.0F, 1.0F, 0.0F);
|
||||
private final Vector3f left = new Vector3f(1.0F, 0.0F, 0.0F);
|
||||
private float xRot;
|
||||
private float yRot;
|
||||
private final Quaternionf rotation = new Quaternionf(0.0F, 0.0F, 0.0F, 1.0F);
|
||||
private boolean detached;
|
||||
private float eyeHeight;
|
||||
private float eyeHeightOld;
|
||||
public static final float FOG_DISTANCE_SCALE = 0.083333336F;
|
||||
|
||||
public void setup(BlockGetter p_90576_, Entity p_90577_, boolean p_90578_, boolean p_90579_, float p_90580_) {
|
||||
this.initialized = true;
|
||||
this.level = p_90576_;
|
||||
this.entity = p_90577_;
|
||||
this.detached = p_90578_;
|
||||
this.setRotation(p_90577_.getViewYRot(p_90580_), p_90577_.getViewXRot(p_90580_));
|
||||
this.setPosition(Mth.lerp((double)p_90580_, p_90577_.xo, p_90577_.getX()), Mth.lerp((double)p_90580_, p_90577_.yo, p_90577_.getY()) + (double)Mth.lerp(p_90580_, this.eyeHeightOld, this.eyeHeight), Mth.lerp((double)p_90580_, p_90577_.zo, p_90577_.getZ()));
|
||||
if (p_90578_) {
|
||||
if (p_90579_) {
|
||||
this.setRotation(this.yRot + 180.0F, -this.xRot);
|
||||
}
|
||||
|
||||
this.move(-this.getMaxZoom(4.0D), 0.0D, 0.0D);
|
||||
} else if (p_90577_ instanceof LivingEntity && ((LivingEntity)p_90577_).isSleeping()) {
|
||||
Direction direction = ((LivingEntity)p_90577_).getBedOrientation();
|
||||
this.setRotation(direction != null ? direction.toYRot() - 180.0F : 0.0F, 0.0F);
|
||||
this.move(0.0D, 0.3D, 0.0D);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (this.entity != null) {
|
||||
this.eyeHeightOld = this.eyeHeight;
|
||||
this.eyeHeight += (this.entity.getEyeHeight() - this.eyeHeight) * 0.5F;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private double getMaxZoom(double p_90567_) {
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
float f = (float)((i & 1) * 2 - 1);
|
||||
float f1 = (float)((i >> 1 & 1) * 2 - 1);
|
||||
float f2 = (float)((i >> 2 & 1) * 2 - 1);
|
||||
f *= 0.1F;
|
||||
f1 *= 0.1F;
|
||||
f2 *= 0.1F;
|
||||
Vec3 vec3 = this.position.add((double)f, (double)f1, (double)f2);
|
||||
Vec3 vec31 = new Vec3(this.position.x - (double)this.forwards.x() * p_90567_ + (double)f, this.position.y - (double)this.forwards.y() * p_90567_ + (double)f1, this.position.z - (double)this.forwards.z() * p_90567_ + (double)f2);
|
||||
HitResult hitresult = this.level.clip(new ClipContext(vec3, vec31, ClipContext.Block.VISUAL, ClipContext.Fluid.NONE, this.entity));
|
||||
if (hitresult.getType() != HitResult.Type.MISS) {
|
||||
double d0 = hitresult.getLocation().distanceTo(this.position);
|
||||
if (d0 < p_90567_) {
|
||||
p_90567_ = d0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p_90567_;
|
||||
}
|
||||
|
||||
protected void move(double p_90569_, double p_90570_, double p_90571_) {
|
||||
double d0 = (double)this.forwards.x() * p_90569_ + (double)this.up.x() * p_90570_ + (double)this.left.x() * p_90571_;
|
||||
double d1 = (double)this.forwards.y() * p_90569_ + (double)this.up.y() * p_90570_ + (double)this.left.y() * p_90571_;
|
||||
double d2 = (double)this.forwards.z() * p_90569_ + (double)this.up.z() * p_90570_ + (double)this.left.z() * p_90571_;
|
||||
this.setPosition(new Vec3(this.position.x + d0, this.position.y + d1, this.position.z + d2));
|
||||
}
|
||||
|
||||
protected void setRotation(float p_90573_, float p_90574_) {
|
||||
this.xRot = p_90574_;
|
||||
this.yRot = p_90573_;
|
||||
this.rotation.rotationYXZ(-p_90573_ * ((float)Math.PI / 180F), p_90574_ * ((float)Math.PI / 180F), 0.0F);
|
||||
this.forwards.set(0.0F, 0.0F, 1.0F).rotate(this.rotation);
|
||||
this.up.set(0.0F, 1.0F, 0.0F).rotate(this.rotation);
|
||||
this.left.set(1.0F, 0.0F, 0.0F).rotate(this.rotation);
|
||||
}
|
||||
|
||||
protected void setPosition(double p_90585_, double p_90586_, double p_90587_) {
|
||||
this.setPosition(new Vec3(p_90585_, p_90586_, p_90587_));
|
||||
}
|
||||
|
||||
protected void setPosition(Vec3 p_90582_) {
|
||||
this.position = p_90582_;
|
||||
this.blockPosition.set(p_90582_.x, p_90582_.y, p_90582_.z);
|
||||
}
|
||||
|
||||
public Vec3 getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public BlockPos getBlockPosition() {
|
||||
return this.blockPosition;
|
||||
}
|
||||
|
||||
public float getXRot() {
|
||||
return this.xRot;
|
||||
}
|
||||
|
||||
public float getYRot() {
|
||||
return this.yRot;
|
||||
}
|
||||
|
||||
public Quaternionf rotation() {
|
||||
return this.rotation;
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return this.initialized;
|
||||
}
|
||||
|
||||
public boolean isDetached() {
|
||||
return this.detached;
|
||||
}
|
||||
|
||||
public Camera.NearPlane getNearPlane() {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
double d0 = (double)minecraft.getWindow().getWidth() / (double)minecraft.getWindow().getHeight();
|
||||
double d1 = Math.tan((double)((float)minecraft.options.fov().get().intValue() * ((float)Math.PI / 180F)) / 2.0D) * (double)0.05F;
|
||||
double d2 = d1 * d0;
|
||||
Vec3 vec3 = (new Vec3(this.forwards)).scale((double)0.05F);
|
||||
Vec3 vec31 = (new Vec3(this.left)).scale(d2);
|
||||
Vec3 vec32 = (new Vec3(this.up)).scale(d1);
|
||||
return new Camera.NearPlane(vec3, vec31, vec32);
|
||||
}
|
||||
|
||||
public FogType getFluidInCamera() {
|
||||
if (!this.initialized) {
|
||||
return FogType.NONE;
|
||||
} else {
|
||||
FluidState fluidstate = this.level.getFluidState(this.blockPosition);
|
||||
if (fluidstate.is(FluidTags.WATER) && this.position.y < (double)((float)this.blockPosition.getY() + fluidstate.getHeight(this.level, this.blockPosition))) {
|
||||
return FogType.WATER;
|
||||
} else {
|
||||
Camera.NearPlane camera$nearplane = this.getNearPlane();
|
||||
|
||||
for(Vec3 vec3 : Arrays.asList(camera$nearplane.forward, camera$nearplane.getTopLeft(), camera$nearplane.getTopRight(), camera$nearplane.getBottomLeft(), camera$nearplane.getBottomRight())) {
|
||||
Vec3 vec31 = this.position.add(vec3);
|
||||
BlockPos blockpos = BlockPos.containing(vec31);
|
||||
FluidState fluidstate1 = this.level.getFluidState(blockpos);
|
||||
if (fluidstate1.is(FluidTags.LAVA)) {
|
||||
if (vec31.y <= (double)(fluidstate1.getHeight(this.level, blockpos) + (float)blockpos.getY())) {
|
||||
return FogType.LAVA;
|
||||
}
|
||||
} else {
|
||||
BlockState blockstate = this.level.getBlockState(blockpos);
|
||||
if (blockstate.is(Blocks.POWDER_SNOW)) {
|
||||
return FogType.POWDER_SNOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FogType.NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final Vector3f getLookVector() {
|
||||
return this.forwards;
|
||||
}
|
||||
|
||||
public final Vector3f getUpVector() {
|
||||
return this.up;
|
||||
}
|
||||
|
||||
public final Vector3f getLeftVector() {
|
||||
return this.left;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.level = null;
|
||||
this.entity = null;
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
public void setAnglesInternal(float yaw, float pitch) {
|
||||
this.yRot = yaw;
|
||||
this.xRot = pitch;
|
||||
}
|
||||
|
||||
public net.minecraft.world.level.block.state.BlockState getBlockAtCamera() {
|
||||
if (!this.initialized)
|
||||
return net.minecraft.world.level.block.Blocks.AIR.defaultBlockState();
|
||||
else
|
||||
return this.level.getBlockState(this.blockPosition).getStateAtViewpoint(this.level, this.blockPosition, this.position);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class NearPlane {
|
||||
final Vec3 forward;
|
||||
private final Vec3 left;
|
||||
private final Vec3 up;
|
||||
|
||||
NearPlane(Vec3 p_167691_, Vec3 p_167692_, Vec3 p_167693_) {
|
||||
this.forward = p_167691_;
|
||||
this.left = p_167692_;
|
||||
this.up = p_167693_;
|
||||
}
|
||||
|
||||
public Vec3 getTopLeft() {
|
||||
return this.forward.add(this.up).add(this.left);
|
||||
}
|
||||
|
||||
public Vec3 getTopRight() {
|
||||
return this.forward.add(this.up).subtract(this.left);
|
||||
}
|
||||
|
||||
public Vec3 getBottomLeft() {
|
||||
return this.forward.subtract(this.up).add(this.left);
|
||||
}
|
||||
|
||||
public Vec3 getBottomRight() {
|
||||
return this.forward.subtract(this.up).subtract(this.left);
|
||||
}
|
||||
|
||||
public Vec3 getPointOnPlane(float p_167696_, float p_167697_) {
|
||||
return this.forward.add(this.up.scale((double)p_167697_)).subtract(this.left.scale((double)p_167696_));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum CameraType {
|
||||
FIRST_PERSON(true, false),
|
||||
THIRD_PERSON_BACK(false, false),
|
||||
THIRD_PERSON_FRONT(false, true);
|
||||
|
||||
private static final CameraType[] VALUES = values();
|
||||
private final boolean firstPerson;
|
||||
private final boolean mirrored;
|
||||
|
||||
private CameraType(boolean p_90610_, boolean p_90611_) {
|
||||
this.firstPerson = p_90610_;
|
||||
this.mirrored = p_90611_;
|
||||
}
|
||||
|
||||
public boolean isFirstPerson() {
|
||||
return this.firstPerson;
|
||||
}
|
||||
|
||||
public boolean isMirrored() {
|
||||
return this.mirrored;
|
||||
}
|
||||
|
||||
public CameraType cycle() {
|
||||
return VALUES[(this.ordinal() + 1) % VALUES.length];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import net.minecraft.obfuscate.DontObfuscate;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ClientBrandRetriever {
|
||||
public static final String VANILLA_NAME = "vanilla";
|
||||
|
||||
@DontObfuscate
|
||||
public static String getClientModName() {
|
||||
return net.minecraftforge.internal.BrandingControl.getClientBranding();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Table;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeCollection;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.stats.RecipeBook;
|
||||
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
|
||||
import net.minecraft.world.item.crafting.CookingBookCategory;
|
||||
import net.minecraft.world.item.crafting.CraftingRecipe;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ClientRecipeBook extends RecipeBook {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private Map<RecipeBookCategories, List<RecipeCollection>> collectionsByTab = ImmutableMap.of();
|
||||
private List<RecipeCollection> allCollections = ImmutableList.of();
|
||||
|
||||
public void setupCollections(Iterable<Recipe<?>> p_266814_, RegistryAccess p_266878_) {
|
||||
Map<RecipeBookCategories, List<List<Recipe<?>>>> map = categorizeAndGroupRecipes(p_266814_);
|
||||
Map<RecipeBookCategories, List<RecipeCollection>> map1 = Maps.newHashMap();
|
||||
ImmutableList.Builder<RecipeCollection> builder = ImmutableList.builder();
|
||||
map.forEach((p_266602_, p_266603_) -> {
|
||||
map1.put(p_266602_, p_266603_.stream().map((p_266605_) -> {
|
||||
return new RecipeCollection(p_266878_, p_266605_);
|
||||
}).peek(builder::add).collect(ImmutableList.toImmutableList()));
|
||||
});
|
||||
RecipeBookCategories.AGGREGATE_CATEGORIES.forEach((p_90637_, p_90638_) -> {
|
||||
map1.put(p_90637_, p_90638_.stream().flatMap((p_167706_) -> {
|
||||
return map1.getOrDefault(p_167706_, ImmutableList.of()).stream();
|
||||
}).collect(ImmutableList.toImmutableList()));
|
||||
});
|
||||
this.collectionsByTab = ImmutableMap.copyOf(map1);
|
||||
this.allCollections = builder.build();
|
||||
}
|
||||
|
||||
private static Map<RecipeBookCategories, List<List<Recipe<?>>>> categorizeAndGroupRecipes(Iterable<Recipe<?>> p_90643_) {
|
||||
Map<RecipeBookCategories, List<List<Recipe<?>>>> map = Maps.newHashMap();
|
||||
Table<RecipeBookCategories, String, List<Recipe<?>>> table = HashBasedTable.create();
|
||||
|
||||
for(Recipe<?> recipe : p_90643_) {
|
||||
if (!recipe.isSpecial() && !recipe.isIncomplete()) {
|
||||
RecipeBookCategories recipebookcategories = getCategory(recipe);
|
||||
String s = recipe.getGroup().isEmpty() ? recipe.getId().toString() : recipe.getGroup(); // FORGE: Group value defaults to the recipe's ID if the recipe's explicit group is empty.
|
||||
if (s.isEmpty()) {
|
||||
map.computeIfAbsent(recipebookcategories, (p_90645_) -> {
|
||||
return Lists.newArrayList();
|
||||
}).add(ImmutableList.of(recipe));
|
||||
} else {
|
||||
List<Recipe<?>> list = table.get(recipebookcategories, s);
|
||||
if (list == null) {
|
||||
list = Lists.newArrayList();
|
||||
table.put(recipebookcategories, s, list);
|
||||
map.computeIfAbsent(recipebookcategories, (p_90641_) -> {
|
||||
return Lists.newArrayList();
|
||||
}).add(list);
|
||||
}
|
||||
|
||||
list.add(recipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private static RecipeBookCategories getCategory(Recipe<?> p_90647_) {
|
||||
if (p_90647_ instanceof CraftingRecipe) {
|
||||
CraftingRecipe craftingrecipe = (CraftingRecipe)p_90647_;
|
||||
RecipeBookCategories recipebookcategories;
|
||||
switch (craftingrecipe.category()) {
|
||||
case BUILDING:
|
||||
recipebookcategories = RecipeBookCategories.CRAFTING_BUILDING_BLOCKS;
|
||||
break;
|
||||
case EQUIPMENT:
|
||||
recipebookcategories = RecipeBookCategories.CRAFTING_EQUIPMENT;
|
||||
break;
|
||||
case REDSTONE:
|
||||
recipebookcategories = RecipeBookCategories.CRAFTING_REDSTONE;
|
||||
break;
|
||||
case MISC:
|
||||
recipebookcategories = RecipeBookCategories.CRAFTING_MISC;
|
||||
break;
|
||||
default:
|
||||
throw new IncompatibleClassChangeError();
|
||||
}
|
||||
|
||||
return recipebookcategories;
|
||||
} else {
|
||||
RecipeType<?> recipetype = p_90647_.getType();
|
||||
if (p_90647_ instanceof AbstractCookingRecipe) {
|
||||
AbstractCookingRecipe abstractcookingrecipe = (AbstractCookingRecipe)p_90647_;
|
||||
CookingBookCategory cookingbookcategory = abstractcookingrecipe.category();
|
||||
if (recipetype == RecipeType.SMELTING) {
|
||||
RecipeBookCategories recipebookcategories1;
|
||||
switch (cookingbookcategory) {
|
||||
case BLOCKS:
|
||||
recipebookcategories1 = RecipeBookCategories.FURNACE_BLOCKS;
|
||||
break;
|
||||
case FOOD:
|
||||
recipebookcategories1 = RecipeBookCategories.FURNACE_FOOD;
|
||||
break;
|
||||
case MISC:
|
||||
recipebookcategories1 = RecipeBookCategories.FURNACE_MISC;
|
||||
break;
|
||||
default:
|
||||
throw new IncompatibleClassChangeError();
|
||||
}
|
||||
|
||||
return recipebookcategories1;
|
||||
}
|
||||
|
||||
if (recipetype == RecipeType.BLASTING) {
|
||||
return cookingbookcategory == CookingBookCategory.BLOCKS ? RecipeBookCategories.BLAST_FURNACE_BLOCKS : RecipeBookCategories.BLAST_FURNACE_MISC;
|
||||
}
|
||||
|
||||
if (recipetype == RecipeType.SMOKING) {
|
||||
return RecipeBookCategories.SMOKER_FOOD;
|
||||
}
|
||||
|
||||
if (recipetype == RecipeType.CAMPFIRE_COOKING) {
|
||||
return RecipeBookCategories.CAMPFIRE;
|
||||
}
|
||||
}
|
||||
|
||||
if (recipetype == RecipeType.STONECUTTING) {
|
||||
return RecipeBookCategories.STONECUTTER;
|
||||
} else if (recipetype == RecipeType.SMITHING) {
|
||||
return RecipeBookCategories.SMITHING;
|
||||
} else {
|
||||
RecipeBookCategories categories = net.minecraftforge.client.RecipeBookManager.findCategories((RecipeType) recipetype, p_90647_);
|
||||
if (categories != null) return categories;
|
||||
LOGGER.warn("Unknown recipe category: {}/{}", LogUtils.defer(() -> {
|
||||
return BuiltInRegistries.RECIPE_TYPE.getKey(p_90647_.getType());
|
||||
}), LogUtils.defer(p_90647_::getId));
|
||||
return RecipeBookCategories.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<RecipeCollection> getCollections() {
|
||||
return this.allCollections;
|
||||
}
|
||||
|
||||
public List<RecipeCollection> getCollection(RecipeBookCategories p_90624_) {
|
||||
return this.collectionsByTab.getOrDefault(p_90624_, Collections.emptyList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import net.minecraft.util.OptionEnum;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum CloudStatus implements OptionEnum {
|
||||
OFF(0, "options.off"),
|
||||
FAST(1, "options.clouds.fast"),
|
||||
FANCY(2, "options.clouds.fancy");
|
||||
|
||||
private final int id;
|
||||
private final String key;
|
||||
|
||||
private CloudStatus(int p_231334_, String p_231335_) {
|
||||
this.id = p_231334_;
|
||||
this.key = p_231335_;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.network.chat.FormattedText;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ComponentCollector {
|
||||
private final List<FormattedText> parts = Lists.newArrayList();
|
||||
|
||||
public void append(FormattedText p_90676_) {
|
||||
this.parts.add(p_90676_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FormattedText getResult() {
|
||||
if (this.parts.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return this.parts.size() == 1 ? this.parts.get(0) : FormattedText.composite(this.parts);
|
||||
}
|
||||
}
|
||||
|
||||
public FormattedText getResultOrEmpty() {
|
||||
FormattedText formattedtext = this.getResult();
|
||||
return formattedtext != null ? formattedtext : FormattedText.EMPTY;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.parts.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.protocol.game.ServerboundBlockEntityTagQuery;
|
||||
import net.minecraft.network.protocol.game.ServerboundEntityTagQuery;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class DebugQueryHandler {
|
||||
private final ClientPacketListener connection;
|
||||
private int transactionId = -1;
|
||||
@Nullable
|
||||
private Consumer<CompoundTag> callback;
|
||||
|
||||
public DebugQueryHandler(ClientPacketListener p_90701_) {
|
||||
this.connection = p_90701_;
|
||||
}
|
||||
|
||||
public boolean handleResponse(int p_90706_, @Nullable CompoundTag p_90707_) {
|
||||
if (this.transactionId == p_90706_ && this.callback != null) {
|
||||
this.callback.accept(p_90707_);
|
||||
this.callback = null;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private int startTransaction(Consumer<CompoundTag> p_90712_) {
|
||||
this.callback = p_90712_;
|
||||
return ++this.transactionId;
|
||||
}
|
||||
|
||||
public void queryEntityTag(int p_90703_, Consumer<CompoundTag> p_90704_) {
|
||||
int i = this.startTransaction(p_90704_);
|
||||
this.connection.send(new ServerboundEntityTagQuery(i, p_90703_));
|
||||
}
|
||||
|
||||
public void queryBlockEntityTag(BlockPos p_90709_, Consumer<CompoundTag> p_90710_) {
|
||||
int i = this.startTransaction(p_90710_);
|
||||
this.connection.send(new ServerboundBlockEntityTagQuery(i, p_90709_));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.text2speech.Narrator;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.gui.components.toasts.SystemToast;
|
||||
import net.minecraft.client.gui.components.toasts.ToastComponent;
|
||||
import net.minecraft.client.main.SilentInitException;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class GameNarrator {
|
||||
public static final Component NO_TITLE = CommonComponents.EMPTY;
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final Minecraft minecraft;
|
||||
private final Narrator narrator = Narrator.getNarrator();
|
||||
|
||||
public GameNarrator(Minecraft p_240577_) {
|
||||
this.minecraft = p_240577_;
|
||||
}
|
||||
|
||||
public void sayChat(Component p_263413_) {
|
||||
if (this.getStatus().shouldNarrateChat()) {
|
||||
String s = p_263413_.getString();
|
||||
this.logNarratedMessage(s);
|
||||
this.narrator.say(s, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void say(Component p_263389_) {
|
||||
String s = p_263389_.getString();
|
||||
if (this.getStatus().shouldNarrateSystem() && !s.isEmpty()) {
|
||||
this.logNarratedMessage(s);
|
||||
this.narrator.say(s, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void sayNow(Component p_168786_) {
|
||||
this.sayNow(p_168786_.getString());
|
||||
}
|
||||
|
||||
public void sayNow(String p_93320_) {
|
||||
if (this.getStatus().shouldNarrateSystem() && !p_93320_.isEmpty()) {
|
||||
this.logNarratedMessage(p_93320_);
|
||||
if (this.narrator.active()) {
|
||||
this.narrator.clear();
|
||||
this.narrator.say(p_93320_, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private NarratorStatus getStatus() {
|
||||
return this.minecraft.options.narrator().get();
|
||||
}
|
||||
|
||||
private void logNarratedMessage(String p_168788_) {
|
||||
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
||||
LOGGER.debug("Narrating: {}", (Object)p_168788_.replaceAll("\n", "\\\\n"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void updateNarratorStatus(NarratorStatus p_93318_) {
|
||||
this.clear();
|
||||
this.narrator.say(Component.translatable("options.narrator").append(" : ").append(p_93318_.getName()).getString(), true);
|
||||
ToastComponent toastcomponent = Minecraft.getInstance().getToasts();
|
||||
if (this.narrator.active()) {
|
||||
if (p_93318_ == NarratorStatus.OFF) {
|
||||
SystemToast.addOrUpdate(toastcomponent, SystemToast.SystemToastIds.NARRATOR_TOGGLE, Component.translatable("narrator.toast.disabled"), (Component)null);
|
||||
} else {
|
||||
SystemToast.addOrUpdate(toastcomponent, SystemToast.SystemToastIds.NARRATOR_TOGGLE, Component.translatable("narrator.toast.enabled"), p_93318_.getName());
|
||||
}
|
||||
} else {
|
||||
SystemToast.addOrUpdate(toastcomponent, SystemToast.SystemToastIds.NARRATOR_TOGGLE, Component.translatable("narrator.toast.disabled"), Component.translatable("options.narrator.notavailable"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.narrator.active();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (this.getStatus() != NarratorStatus.OFF && this.narrator.active()) {
|
||||
this.narrator.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
this.narrator.destroy();
|
||||
}
|
||||
|
||||
public void checkStatus(boolean p_289016_) {
|
||||
if (p_289016_ && !this.isActive() && !TinyFileDialogs.tinyfd_messageBox("Minecraft", "Failed to initialize text-to-speech library. Do you want to continue?\nIf this problem persists, please report it at bugs.mojang.com", "yesno", "error", true)) {
|
||||
throw new GameNarrator.NarratorInitException("Narrator library is not active");
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class NarratorInitException extends SilentInitException {
|
||||
public NarratorInitException(String p_288985_) {
|
||||
super(p_288985_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
import net.minecraft.util.ByIdMap;
|
||||
import net.minecraft.util.OptionEnum;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum GraphicsStatus implements OptionEnum {
|
||||
FAST(0, "options.graphics.fast"),
|
||||
FANCY(1, "options.graphics.fancy"),
|
||||
FABULOUS(2, "options.graphics.fabulous");
|
||||
|
||||
private static final IntFunction<GraphicsStatus> BY_ID = ByIdMap.continuous(GraphicsStatus::getId, values(), ByIdMap.OutOfBoundsStrategy.WRAP);
|
||||
private final int id;
|
||||
private final String key;
|
||||
|
||||
private GraphicsStatus(int p_90771_, String p_90772_) {
|
||||
this.id = p_90771_;
|
||||
this.key = p_90772_;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String s;
|
||||
switch (this) {
|
||||
case FAST:
|
||||
s = "fast";
|
||||
break;
|
||||
case FANCY:
|
||||
s = "fancy";
|
||||
break;
|
||||
case FABULOUS:
|
||||
s = "fabulous";
|
||||
break;
|
||||
default:
|
||||
throw new IncompatibleClassChangeError();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public static GraphicsStatus byId(int p_90775_) {
|
||||
return BY_ID.apply(p_90775_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MessageSignature;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public record GuiMessage(int addedTime, Component content, @Nullable MessageSignature signature, @Nullable GuiMessageTag tag) {
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record Line(int addedTime, FormattedCharSequence content, @Nullable GuiMessageTag tag, boolean endOfEntry) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public record GuiMessageTag(int indicatorColor, @Nullable GuiMessageTag.Icon icon, @Nullable Component text, @Nullable String logTag) {
|
||||
private static final Component SYSTEM_TEXT = Component.translatable("chat.tag.system");
|
||||
private static final Component SYSTEM_TEXT_SINGLE_PLAYER = Component.translatable("chat.tag.system_single_player");
|
||||
private static final Component CHAT_NOT_SECURE_TEXT = Component.translatable("chat.tag.not_secure");
|
||||
private static final Component CHAT_MODIFIED_TEXT = Component.translatable("chat.tag.modified");
|
||||
private static final int CHAT_NOT_SECURE_INDICATOR_COLOR = 13684944;
|
||||
private static final int CHAT_MODIFIED_INDICATOR_COLOR = 6316128;
|
||||
private static final GuiMessageTag SYSTEM = new GuiMessageTag(13684944, (GuiMessageTag.Icon)null, SYSTEM_TEXT, "System");
|
||||
private static final GuiMessageTag SYSTEM_SINGLE_PLAYER = new GuiMessageTag(13684944, (GuiMessageTag.Icon)null, SYSTEM_TEXT_SINGLE_PLAYER, "System");
|
||||
private static final GuiMessageTag CHAT_NOT_SECURE = new GuiMessageTag(13684944, (GuiMessageTag.Icon)null, CHAT_NOT_SECURE_TEXT, "Not Secure");
|
||||
static final ResourceLocation TEXTURE_LOCATION = new ResourceLocation("textures/gui/chat_tags.png");
|
||||
|
||||
public static GuiMessageTag system() {
|
||||
return SYSTEM;
|
||||
}
|
||||
|
||||
public static GuiMessageTag systemSinglePlayer() {
|
||||
return SYSTEM_SINGLE_PLAYER;
|
||||
}
|
||||
|
||||
public static GuiMessageTag chatNotSecure() {
|
||||
return CHAT_NOT_SECURE;
|
||||
}
|
||||
|
||||
public static GuiMessageTag chatModified(String p_242878_) {
|
||||
Component component = Component.literal(p_242878_).withStyle(ChatFormatting.GRAY);
|
||||
Component component1 = Component.empty().append(CHAT_MODIFIED_TEXT).append(CommonComponents.NEW_LINE).append(component);
|
||||
return new GuiMessageTag(6316128, GuiMessageTag.Icon.CHAT_MODIFIED, component1, "Modified");
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Icon {
|
||||
CHAT_MODIFIED(0, 0, 9, 9);
|
||||
|
||||
public final int u;
|
||||
public final int v;
|
||||
public final int width;
|
||||
public final int height;
|
||||
|
||||
private Icon(int p_240599_, int p_240544_, int p_240607_, int p_240531_) {
|
||||
this.u = p_240599_;
|
||||
this.v = p_240544_;
|
||||
this.width = p_240607_;
|
||||
this.height = p_240531_;
|
||||
}
|
||||
|
||||
public void draw(GuiGraphics p_282284_, int p_282597_, int p_283579_) {
|
||||
p_282284_.blit(GuiMessageTag.TEXTURE_LOCATION, p_282597_, p_283579_, (float)this.u, (float)this.v, this.width, this.height, 32, 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.mojang.datafixers.DataFixer;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.File;
|
||||
import net.minecraft.client.player.inventory.Hotbar;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.util.datafix.DataFixTypes;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class HotbarManager {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final int NUM_HOTBAR_GROUPS = 9;
|
||||
private final File optionsFile;
|
||||
private final DataFixer fixerUpper;
|
||||
private final Hotbar[] hotbars = new Hotbar[9];
|
||||
private boolean loaded;
|
||||
|
||||
public HotbarManager(File p_90803_, DataFixer p_90804_) {
|
||||
this.optionsFile = new File(p_90803_, "hotbar.nbt");
|
||||
this.fixerUpper = p_90804_;
|
||||
|
||||
for(int i = 0; i < 9; ++i) {
|
||||
this.hotbars[i] = new Hotbar();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void load() {
|
||||
try {
|
||||
CompoundTag compoundtag = NbtIo.read(this.optionsFile);
|
||||
if (compoundtag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int i = NbtUtils.getDataVersion(compoundtag, 1343);
|
||||
compoundtag = DataFixTypes.HOTBAR.updateToCurrentVersion(this.fixerUpper, compoundtag, i);
|
||||
|
||||
for(int j = 0; j < 9; ++j) {
|
||||
this.hotbars[j].fromTag(compoundtag.getList(String.valueOf(j), 10));
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Failed to load creative mode options", (Throwable)exception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
CompoundTag compoundtag = NbtUtils.addCurrentDataVersion(new CompoundTag());
|
||||
|
||||
for(int i = 0; i < 9; ++i) {
|
||||
compoundtag.put(String.valueOf(i), this.get(i).createTag());
|
||||
}
|
||||
|
||||
NbtIo.write(compoundtag, this.optionsFile);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Failed to save creative mode options", (Throwable)exception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Hotbar get(int p_90807_) {
|
||||
if (!this.loaded) {
|
||||
this.load();
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
return this.hotbars[p_90807_];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum InputType {
|
||||
NONE,
|
||||
MOUSE,
|
||||
KEYBOARD_ARROW,
|
||||
KEYBOARD_TAB;
|
||||
|
||||
public boolean isMouse() {
|
||||
return this == MOUSE;
|
||||
}
|
||||
|
||||
public boolean isKeyboard() {
|
||||
return this == KEYBOARD_ARROW || this == KEYBOARD_TAB;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class KeyMapping implements Comparable<KeyMapping>, net.minecraftforge.client.extensions.IForgeKeyMapping {
|
||||
private static final Map<String, KeyMapping> ALL = Maps.newHashMap();
|
||||
private static final net.minecraftforge.client.settings.KeyMappingLookup MAP = new net.minecraftforge.client.settings.KeyMappingLookup();
|
||||
private static final Set<String> CATEGORIES = Sets.newHashSet();
|
||||
public static final String CATEGORY_MOVEMENT = "key.categories.movement";
|
||||
public static final String CATEGORY_MISC = "key.categories.misc";
|
||||
public static final String CATEGORY_MULTIPLAYER = "key.categories.multiplayer";
|
||||
public static final String CATEGORY_GAMEPLAY = "key.categories.gameplay";
|
||||
public static final String CATEGORY_INVENTORY = "key.categories.inventory";
|
||||
public static final String CATEGORY_INTERFACE = "key.categories.ui";
|
||||
public static final String CATEGORY_CREATIVE = "key.categories.creative";
|
||||
private static final Map<String, Integer> CATEGORY_SORT_ORDER = Util.make(Maps.newHashMap(), (p_90845_) -> {
|
||||
p_90845_.put("key.categories.movement", 1);
|
||||
p_90845_.put("key.categories.gameplay", 2);
|
||||
p_90845_.put("key.categories.inventory", 3);
|
||||
p_90845_.put("key.categories.creative", 4);
|
||||
p_90845_.put("key.categories.multiplayer", 5);
|
||||
p_90845_.put("key.categories.ui", 6);
|
||||
p_90845_.put("key.categories.misc", 7);
|
||||
});
|
||||
private final String name;
|
||||
private final InputConstants.Key defaultKey;
|
||||
private final String category;
|
||||
private InputConstants.Key key;
|
||||
boolean isDown;
|
||||
private int clickCount;
|
||||
|
||||
public static void click(InputConstants.Key p_90836_) {
|
||||
for (KeyMapping keymapping : MAP.getAll(p_90836_))
|
||||
if (keymapping != null) {
|
||||
++keymapping.clickCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void set(InputConstants.Key p_90838_, boolean p_90839_) {
|
||||
for (KeyMapping keymapping : MAP.getAll(p_90838_))
|
||||
if (keymapping != null) {
|
||||
keymapping.setDown(p_90839_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void setAll() {
|
||||
for(KeyMapping keymapping : ALL.values()) {
|
||||
if (keymapping.key.getType() == InputConstants.Type.KEYSYM && keymapping.key.getValue() != InputConstants.UNKNOWN.getValue()) {
|
||||
keymapping.setDown(InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), keymapping.key.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void releaseAll() {
|
||||
for(KeyMapping keymapping : ALL.values()) {
|
||||
keymapping.release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void resetToggleKeys() {
|
||||
for(KeyMapping keymapping : ALL.values()) {
|
||||
if (keymapping instanceof ToggleKeyMapping togglekeymapping) {
|
||||
togglekeymapping.reset();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void resetMapping() {
|
||||
MAP.clear();
|
||||
|
||||
for(KeyMapping keymapping : ALL.values()) {
|
||||
MAP.put(keymapping.key, keymapping);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public KeyMapping(String p_90821_, int p_90822_, String p_90823_) {
|
||||
this(p_90821_, InputConstants.Type.KEYSYM, p_90822_, p_90823_);
|
||||
}
|
||||
|
||||
public KeyMapping(String p_90825_, InputConstants.Type p_90826_, int p_90827_, String p_90828_) {
|
||||
this.name = p_90825_;
|
||||
this.key = p_90826_.getOrCreate(p_90827_);
|
||||
this.defaultKey = this.key;
|
||||
this.category = p_90828_;
|
||||
ALL.put(p_90825_, this);
|
||||
MAP.put(this.key, this);
|
||||
CATEGORIES.add(p_90828_);
|
||||
}
|
||||
|
||||
public boolean isDown() {
|
||||
return this.isDown && isConflictContextAndModifierActive();
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return this.category;
|
||||
}
|
||||
|
||||
public boolean consumeClick() {
|
||||
if (this.clickCount == 0) {
|
||||
return false;
|
||||
} else {
|
||||
--this.clickCount;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void release() {
|
||||
this.clickCount = 0;
|
||||
this.setDown(false);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public InputConstants.Key getDefaultKey() {
|
||||
return this.defaultKey;
|
||||
}
|
||||
|
||||
public void setKey(InputConstants.Key p_90849_) {
|
||||
this.key = p_90849_;
|
||||
}
|
||||
|
||||
public int compareTo(KeyMapping p_90841_) {
|
||||
if (this.category.equals(p_90841_.category)) return I18n.get(this.name).compareTo(I18n.get(p_90841_.name));
|
||||
Integer tCat = CATEGORY_SORT_ORDER.get(this.category);
|
||||
Integer oCat = CATEGORY_SORT_ORDER.get(p_90841_.category);
|
||||
if (tCat == null && oCat != null) return 1;
|
||||
if (tCat != null && oCat == null) return -1;
|
||||
if (tCat == null && oCat == null) return I18n.get(this.category).compareTo(I18n.get(p_90841_.category));
|
||||
return tCat.compareTo(oCat);
|
||||
}
|
||||
|
||||
public static Supplier<Component> createNameSupplier(String p_90843_) {
|
||||
KeyMapping keymapping = ALL.get(p_90843_);
|
||||
return keymapping == null ? () -> {
|
||||
return Component.translatable(p_90843_);
|
||||
} : keymapping::getTranslatedKeyMessage;
|
||||
}
|
||||
|
||||
public boolean same(KeyMapping p_90851_) {
|
||||
if (getKeyConflictContext().conflicts(p_90851_.getKeyConflictContext()) || p_90851_.getKeyConflictContext().conflicts(getKeyConflictContext())) {
|
||||
net.minecraftforge.client.settings.KeyModifier keyModifier = getKeyModifier();
|
||||
net.minecraftforge.client.settings.KeyModifier otherKeyModifier = p_90851_.getKeyModifier();
|
||||
if (keyModifier.matches(p_90851_.getKey()) || otherKeyModifier.matches(getKey())) {
|
||||
return true;
|
||||
} else if (getKey().equals(p_90851_.getKey())) {
|
||||
// IN_GAME key contexts have a conflict when at least one modifier is NONE.
|
||||
// For example: If you hold shift to crouch, you can still press E to open your inventory. This means that a Shift+E hotkey is in conflict with E.
|
||||
// GUI and other key contexts do not have this limitation.
|
||||
return keyModifier == otherKeyModifier ||
|
||||
(getKeyConflictContext().conflicts(net.minecraftforge.client.settings.KeyConflictContext.IN_GAME) &&
|
||||
(keyModifier == net.minecraftforge.client.settings.KeyModifier.NONE || otherKeyModifier == net.minecraftforge.client.settings.KeyModifier.NONE));
|
||||
}
|
||||
}
|
||||
return this.key.equals(p_90851_.key);
|
||||
}
|
||||
|
||||
public boolean isUnbound() {
|
||||
return this.key.equals(InputConstants.UNKNOWN);
|
||||
}
|
||||
|
||||
public boolean matches(int p_90833_, int p_90834_) {
|
||||
if (p_90833_ == InputConstants.UNKNOWN.getValue()) {
|
||||
return this.key.getType() == InputConstants.Type.SCANCODE && this.key.getValue() == p_90834_;
|
||||
} else {
|
||||
return this.key.getType() == InputConstants.Type.KEYSYM && this.key.getValue() == p_90833_;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matchesMouse(int p_90831_) {
|
||||
return this.key.getType() == InputConstants.Type.MOUSE && this.key.getValue() == p_90831_;
|
||||
}
|
||||
|
||||
public Component getTranslatedKeyMessage() {
|
||||
return getKeyModifier().getCombinedName(key, () -> {
|
||||
return this.key.getDisplayName();
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
return this.key.equals(this.defaultKey) && getKeyModifier() == getDefaultKeyModifier();
|
||||
}
|
||||
|
||||
public String saveString() {
|
||||
return this.key.getName();
|
||||
}
|
||||
|
||||
public void setDown(boolean p_90846_) {
|
||||
this.isDown = p_90846_;
|
||||
}
|
||||
|
||||
private net.minecraftforge.client.settings.KeyModifier keyModifierDefault = net.minecraftforge.client.settings.KeyModifier.NONE;
|
||||
private net.minecraftforge.client.settings.KeyModifier keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE;
|
||||
private net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext = net.minecraftforge.client.settings.KeyConflictContext.UNIVERSAL;
|
||||
|
||||
/**
|
||||
* Convenience constructor for creating KeyBindings with keyConflictContext set.
|
||||
*/
|
||||
public KeyMapping(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, final InputConstants.Type inputType, final int keyCode, String category) {
|
||||
this(description, keyConflictContext, inputType.getOrCreate(keyCode), category);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor for creating KeyBindings with keyConflictContext set.
|
||||
*/
|
||||
public KeyMapping(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, InputConstants.Key keyCode, String category) {
|
||||
this(description, keyConflictContext, net.minecraftforge.client.settings.KeyModifier.NONE, keyCode, category);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor for creating KeyBindings with keyConflictContext and keyModifier set.
|
||||
*/
|
||||
public KeyMapping(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, net.minecraftforge.client.settings.KeyModifier keyModifier, final InputConstants.Type inputType, final int keyCode, String category) {
|
||||
this(description, keyConflictContext, keyModifier, inputType.getOrCreate(keyCode), category);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor for creating KeyBindings with keyConflictContext and keyModifier set.
|
||||
*/
|
||||
public KeyMapping(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, net.minecraftforge.client.settings.KeyModifier keyModifier, InputConstants.Key keyCode, String category) {
|
||||
this.name = description;
|
||||
this.key = keyCode;
|
||||
this.defaultKey = keyCode;
|
||||
this.category = category;
|
||||
this.keyConflictContext = keyConflictContext;
|
||||
this.keyModifier = keyModifier;
|
||||
this.keyModifierDefault = keyModifier;
|
||||
if (this.keyModifier.matches(keyCode))
|
||||
this.keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE;
|
||||
ALL.put(description, this);
|
||||
MAP.put(keyCode, this);
|
||||
CATEGORIES.add(category);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputConstants.Key getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeyConflictContext(net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext) {
|
||||
this.keyConflictContext = keyConflictContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraftforge.client.settings.IKeyConflictContext getKeyConflictContext() {
|
||||
return keyConflictContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraftforge.client.settings.KeyModifier getDefaultKeyModifier() {
|
||||
return keyModifierDefault;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraftforge.client.settings.KeyModifier getKeyModifier() {
|
||||
return keyModifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeyModifierAndCode(@org.jetbrains.annotations.Nullable net.minecraftforge.client.settings.KeyModifier keyModifier, InputConstants.Key keyCode) {
|
||||
MAP.remove(this);
|
||||
|
||||
if (keyModifier == null)
|
||||
keyModifier = net.minecraftforge.client.settings.KeyModifier.getModifier(this.key);
|
||||
if (keyModifier == null || keyCode == InputConstants.UNKNOWN || net.minecraftforge.client.settings.KeyModifier.isKeyCodeModifier(keyCode))
|
||||
keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE;
|
||||
|
||||
this.key = keyCode;
|
||||
this.keyModifier = keyModifier;
|
||||
|
||||
MAP.put(keyCode, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,517 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.mojang.blaze3d.Blaze3D;
|
||||
import com.mojang.blaze3d.platform.ClipboardManager;
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import com.mojang.blaze3d.platform.TextureUtil;
|
||||
import java.nio.file.Path;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.CrashReport;
|
||||
import net.minecraft.CrashReportCategory;
|
||||
import net.minecraft.ReportedException;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.gui.components.ChatComponent;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.SimpleOptionsSubScreen;
|
||||
import net.minecraft.client.gui.screens.controls.KeyBindsScreen;
|
||||
import net.minecraft.client.gui.screens.debug.GameModeSwitcherScreen;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.commands.arguments.blocks.BlockStateParser;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.network.chat.ClickEvent;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.NativeModuleLister;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class KeyboardHandler {
|
||||
public static final int DEBUG_CRASH_TIME = 10000;
|
||||
private final Minecraft minecraft;
|
||||
private final ClipboardManager clipboardManager = new ClipboardManager();
|
||||
private long debugCrashKeyTime = -1L;
|
||||
private long debugCrashKeyReportedTime = -1L;
|
||||
private long debugCrashKeyReportedCount = -1L;
|
||||
private boolean handledDebugKey;
|
||||
|
||||
public KeyboardHandler(Minecraft p_90875_) {
|
||||
this.minecraft = p_90875_;
|
||||
}
|
||||
|
||||
private boolean handleChunkDebugKeys(int p_167814_) {
|
||||
switch (p_167814_) {
|
||||
case 69:
|
||||
this.minecraft.chunkPath = !this.minecraft.chunkPath;
|
||||
this.debugFeedback("ChunkPath: {0}", this.minecraft.chunkPath ? "shown" : "hidden");
|
||||
return true;
|
||||
case 76:
|
||||
this.minecraft.smartCull = !this.minecraft.smartCull;
|
||||
this.debugFeedback("SmartCull: {0}", this.minecraft.smartCull ? "enabled" : "disabled");
|
||||
return true;
|
||||
case 85:
|
||||
if (Screen.hasShiftDown()) {
|
||||
this.minecraft.levelRenderer.killFrustum();
|
||||
this.debugFeedback("Killed frustum");
|
||||
} else {
|
||||
this.minecraft.levelRenderer.captureFrustum();
|
||||
this.debugFeedback("Captured frustum");
|
||||
}
|
||||
|
||||
return true;
|
||||
case 86:
|
||||
this.minecraft.chunkVisibility = !this.minecraft.chunkVisibility;
|
||||
this.debugFeedback("ChunkVisibility: {0}", this.minecraft.chunkVisibility ? "enabled" : "disabled");
|
||||
return true;
|
||||
case 87:
|
||||
this.minecraft.wireframe = !this.minecraft.wireframe;
|
||||
this.debugFeedback("WireFrame: {0}", this.minecraft.wireframe ? "enabled" : "disabled");
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void debugComponent(ChatFormatting p_167825_, Component p_167826_) {
|
||||
this.minecraft.gui.getChat().addMessage(Component.empty().append(Component.translatable("debug.prefix").withStyle(p_167825_, ChatFormatting.BOLD)).append(CommonComponents.SPACE).append(p_167826_));
|
||||
}
|
||||
|
||||
private void debugFeedbackComponent(Component p_167823_) {
|
||||
this.debugComponent(ChatFormatting.YELLOW, p_167823_);
|
||||
}
|
||||
|
||||
private void debugFeedbackTranslated(String p_90914_, Object... p_90915_) {
|
||||
this.debugFeedbackComponent(Component.translatable(p_90914_, p_90915_));
|
||||
}
|
||||
|
||||
private void debugWarningTranslated(String p_90949_, Object... p_90950_) {
|
||||
this.debugComponent(ChatFormatting.RED, Component.translatable(p_90949_, p_90950_));
|
||||
}
|
||||
|
||||
private void debugFeedback(String p_167838_, Object... p_167839_) {
|
||||
this.debugFeedbackComponent(Component.literal(MessageFormat.format(p_167838_, p_167839_)));
|
||||
}
|
||||
|
||||
private boolean handleDebugKeys(int p_90933_) {
|
||||
if (this.debugCrashKeyTime > 0L && this.debugCrashKeyTime < Util.getMillis() - 100L) {
|
||||
return true;
|
||||
} else {
|
||||
switch (p_90933_) {
|
||||
case 65:
|
||||
this.minecraft.levelRenderer.allChanged();
|
||||
this.debugFeedbackTranslated("debug.reload_chunks.message");
|
||||
return true;
|
||||
case 66:
|
||||
boolean flag = !this.minecraft.getEntityRenderDispatcher().shouldRenderHitBoxes();
|
||||
this.minecraft.getEntityRenderDispatcher().setRenderHitBoxes(flag);
|
||||
this.debugFeedbackTranslated(flag ? "debug.show_hitboxes.on" : "debug.show_hitboxes.off");
|
||||
return true;
|
||||
case 67:
|
||||
if (this.minecraft.player.isReducedDebugInfo()) {
|
||||
return false;
|
||||
} else {
|
||||
ClientPacketListener clientpacketlistener = this.minecraft.player.connection;
|
||||
if (clientpacketlistener == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.debugFeedbackTranslated("debug.copy_location.message");
|
||||
this.setClipboard(String.format(Locale.ROOT, "/execute in %s run tp @s %.2f %.2f %.2f %.2f %.2f", this.minecraft.player.level().dimension().location(), this.minecraft.player.getX(), this.minecraft.player.getY(), this.minecraft.player.getZ(), this.minecraft.player.getYRot(), this.minecraft.player.getXRot()));
|
||||
return true;
|
||||
}
|
||||
case 68:
|
||||
if (this.minecraft.gui != null) {
|
||||
this.minecraft.gui.getChat().clearMessages(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 71:
|
||||
boolean flag1 = this.minecraft.debugRenderer.switchRenderChunkborder();
|
||||
this.debugFeedbackTranslated(flag1 ? "debug.chunk_boundaries.on" : "debug.chunk_boundaries.off");
|
||||
return true;
|
||||
case 72:
|
||||
this.minecraft.options.advancedItemTooltips = !this.minecraft.options.advancedItemTooltips;
|
||||
this.debugFeedbackTranslated(this.minecraft.options.advancedItemTooltips ? "debug.advanced_tooltips.on" : "debug.advanced_tooltips.off");
|
||||
this.minecraft.options.save();
|
||||
return true;
|
||||
case 73:
|
||||
if (!this.minecraft.player.isReducedDebugInfo()) {
|
||||
this.copyRecreateCommand(this.minecraft.player.hasPermissions(2), !Screen.hasShiftDown());
|
||||
}
|
||||
|
||||
return true;
|
||||
case 76:
|
||||
if (this.minecraft.debugClientMetricsStart(this::debugFeedbackComponent)) {
|
||||
this.debugFeedbackTranslated("debug.profiling.start", 10);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 78:
|
||||
if (!this.minecraft.player.hasPermissions(2)) {
|
||||
this.debugFeedbackTranslated("debug.creative_spectator.error");
|
||||
} else if (!this.minecraft.player.isSpectator()) {
|
||||
this.minecraft.player.connection.sendUnsignedCommand("gamemode spectator");
|
||||
} else {
|
||||
this.minecraft.player.connection.sendUnsignedCommand("gamemode " + MoreObjects.firstNonNull(this.minecraft.gameMode.getPreviousPlayerMode(), GameType.CREATIVE).getName());
|
||||
}
|
||||
|
||||
return true;
|
||||
case 80:
|
||||
this.minecraft.options.pauseOnLostFocus = !this.minecraft.options.pauseOnLostFocus;
|
||||
this.minecraft.options.save();
|
||||
this.debugFeedbackTranslated(this.minecraft.options.pauseOnLostFocus ? "debug.pause_focus.on" : "debug.pause_focus.off");
|
||||
return true;
|
||||
case 81:
|
||||
this.debugFeedbackTranslated("debug.help.message");
|
||||
ChatComponent chatcomponent = this.minecraft.gui.getChat();
|
||||
chatcomponent.addMessage(Component.translatable("debug.reload_chunks.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.show_hitboxes.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.copy_location.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.clear_chat.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.chunk_boundaries.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.advanced_tooltips.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.inspect.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.profiling.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.creative_spectator.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.pause_focus.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.help.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.dump_dynamic_textures.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.reload_resourcepacks.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.pause.help"));
|
||||
chatcomponent.addMessage(Component.translatable("debug.gamemodes.help"));
|
||||
return true;
|
||||
case 83:
|
||||
Path path = this.minecraft.gameDirectory.toPath().toAbsolutePath();
|
||||
Path path1 = TextureUtil.getDebugTexturePath(path);
|
||||
this.minecraft.getTextureManager().dumpAllSheets(path1);
|
||||
Component component = Component.literal(path.relativize(path1).toString()).withStyle(ChatFormatting.UNDERLINE).withStyle((p_276097_) -> {
|
||||
return p_276097_.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, path1.toFile().toString()));
|
||||
});
|
||||
this.debugFeedbackTranslated("debug.dump_dynamic_textures", component);
|
||||
return true;
|
||||
case 84:
|
||||
this.debugFeedbackTranslated("debug.reload_resourcepacks.message");
|
||||
this.minecraft.reloadResourcePacks();
|
||||
return true;
|
||||
case 293:
|
||||
if (!this.minecraft.player.hasPermissions(2)) {
|
||||
this.debugFeedbackTranslated("debug.gamemodes.error");
|
||||
} else {
|
||||
this.minecraft.setScreen(new GameModeSwitcherScreen());
|
||||
}
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyRecreateCommand(boolean p_90929_, boolean p_90930_) {
|
||||
HitResult hitresult = this.minecraft.hitResult;
|
||||
if (hitresult != null) {
|
||||
switch (hitresult.getType()) {
|
||||
case BLOCK:
|
||||
BlockPos blockpos = ((BlockHitResult)hitresult).getBlockPos();
|
||||
BlockState blockstate = this.minecraft.player.level().getBlockState(blockpos);
|
||||
if (p_90929_) {
|
||||
if (p_90930_) {
|
||||
this.minecraft.player.connection.getDebugQueryHandler().queryBlockEntityTag(blockpos, (p_90947_) -> {
|
||||
this.copyCreateBlockCommand(blockstate, blockpos, p_90947_);
|
||||
this.debugFeedbackTranslated("debug.inspect.server.block");
|
||||
});
|
||||
} else {
|
||||
BlockEntity blockentity = this.minecraft.player.level().getBlockEntity(blockpos);
|
||||
CompoundTag compoundtag1 = blockentity != null ? blockentity.saveWithoutMetadata() : null;
|
||||
this.copyCreateBlockCommand(blockstate, blockpos, compoundtag1);
|
||||
this.debugFeedbackTranslated("debug.inspect.client.block");
|
||||
}
|
||||
} else {
|
||||
this.copyCreateBlockCommand(blockstate, blockpos, (CompoundTag)null);
|
||||
this.debugFeedbackTranslated("debug.inspect.client.block");
|
||||
}
|
||||
break;
|
||||
case ENTITY:
|
||||
Entity entity = ((EntityHitResult)hitresult).getEntity();
|
||||
ResourceLocation resourcelocation = BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType());
|
||||
if (p_90929_) {
|
||||
if (p_90930_) {
|
||||
this.minecraft.player.connection.getDebugQueryHandler().queryEntityTag(entity.getId(), (p_90921_) -> {
|
||||
this.copyCreateEntityCommand(resourcelocation, entity.position(), p_90921_);
|
||||
this.debugFeedbackTranslated("debug.inspect.server.entity");
|
||||
});
|
||||
} else {
|
||||
CompoundTag compoundtag = entity.saveWithoutId(new CompoundTag());
|
||||
this.copyCreateEntityCommand(resourcelocation, entity.position(), compoundtag);
|
||||
this.debugFeedbackTranslated("debug.inspect.client.entity");
|
||||
}
|
||||
} else {
|
||||
this.copyCreateEntityCommand(resourcelocation, entity.position(), (CompoundTag)null);
|
||||
this.debugFeedbackTranslated("debug.inspect.client.entity");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void copyCreateBlockCommand(BlockState p_90900_, BlockPos p_90901_, @Nullable CompoundTag p_90902_) {
|
||||
StringBuilder stringbuilder = new StringBuilder(BlockStateParser.serialize(p_90900_));
|
||||
if (p_90902_ != null) {
|
||||
stringbuilder.append((Object)p_90902_);
|
||||
}
|
||||
|
||||
String s = String.format(Locale.ROOT, "/setblock %d %d %d %s", p_90901_.getX(), p_90901_.getY(), p_90901_.getZ(), stringbuilder);
|
||||
this.setClipboard(s);
|
||||
}
|
||||
|
||||
private void copyCreateEntityCommand(ResourceLocation p_90923_, Vec3 p_90924_, @Nullable CompoundTag p_90925_) {
|
||||
String s;
|
||||
if (p_90925_ != null) {
|
||||
p_90925_.remove("UUID");
|
||||
p_90925_.remove("Pos");
|
||||
p_90925_.remove("Dimension");
|
||||
String s1 = NbtUtils.toPrettyComponent(p_90925_).getString();
|
||||
s = String.format(Locale.ROOT, "/summon %s %.2f %.2f %.2f %s", p_90923_.toString(), p_90924_.x, p_90924_.y, p_90924_.z, s1);
|
||||
} else {
|
||||
s = String.format(Locale.ROOT, "/summon %s %.2f %.2f %.2f", p_90923_.toString(), p_90924_.x, p_90924_.y, p_90924_.z);
|
||||
}
|
||||
|
||||
this.setClipboard(s);
|
||||
}
|
||||
|
||||
public void keyPress(long p_90894_, int p_90895_, int p_90896_, int p_90897_, int p_90898_) {
|
||||
if (p_90894_ == this.minecraft.getWindow().getWindow()) {
|
||||
if (this.debugCrashKeyTime > 0L) {
|
||||
if (!InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 67) || !InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 292)) {
|
||||
this.debugCrashKeyTime = -1L;
|
||||
}
|
||||
} else if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 67) && InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 292)) {
|
||||
this.handledDebugKey = true;
|
||||
this.debugCrashKeyTime = Util.getMillis();
|
||||
this.debugCrashKeyReportedTime = Util.getMillis();
|
||||
this.debugCrashKeyReportedCount = 0L;
|
||||
}
|
||||
|
||||
Screen screen = this.minecraft.screen;
|
||||
if (screen != null) {
|
||||
switch (p_90895_) {
|
||||
case 258:
|
||||
this.minecraft.setLastInputType(InputType.KEYBOARD_TAB);
|
||||
case 259:
|
||||
case 260:
|
||||
case 261:
|
||||
default:
|
||||
break;
|
||||
case 262:
|
||||
case 263:
|
||||
case 264:
|
||||
case 265:
|
||||
this.minecraft.setLastInputType(InputType.KEYBOARD_ARROW);
|
||||
}
|
||||
}
|
||||
|
||||
if (p_90897_ == 1 && (!(this.minecraft.screen instanceof KeyBindsScreen) || ((KeyBindsScreen)screen).lastKeySelection <= Util.getMillis() - 20L)) {
|
||||
if (this.minecraft.options.keyFullscreen.matches(p_90895_, p_90896_)) {
|
||||
this.minecraft.getWindow().toggleFullScreen();
|
||||
this.minecraft.options.fullscreen().set(this.minecraft.getWindow().isFullscreen());
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.minecraft.options.keyScreenshot.matches(p_90895_, p_90896_)) {
|
||||
if (Screen.hasControlDown()) {
|
||||
}
|
||||
|
||||
Screenshot.grab(this.minecraft.gameDirectory, this.minecraft.getMainRenderTarget(), (p_90917_) -> {
|
||||
this.minecraft.execute(() -> {
|
||||
this.minecraft.gui.getChat().addMessage(p_90917_);
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.minecraft.getNarrator().isActive()) {
|
||||
boolean flag = screen == null || !(screen.getFocused() instanceof EditBox) || !((EditBox)screen.getFocused()).canConsumeInput();
|
||||
if (p_90897_ != 0 && p_90895_ == 66 && Screen.hasControlDown() && flag) {
|
||||
boolean flag1 = this.minecraft.options.narrator().get() == NarratorStatus.OFF;
|
||||
this.minecraft.options.narrator().set(NarratorStatus.byId(this.minecraft.options.narrator().get().getId() + 1));
|
||||
if (screen instanceof SimpleOptionsSubScreen) {
|
||||
((SimpleOptionsSubScreen)screen).updateNarratorButton();
|
||||
}
|
||||
|
||||
if (flag1 && screen != null) {
|
||||
screen.narrationEnabled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screen != null) {
|
||||
boolean[] aboolean = new boolean[]{false};
|
||||
Screen.wrapScreenError(() -> {
|
||||
if (p_90897_ != 1 && p_90897_ != 2) {
|
||||
if (p_90897_ == 0) {
|
||||
aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyReleasedPre(screen, p_90895_, p_90896_, p_90898_);
|
||||
if (!aboolean[0]) aboolean[0] = screen.keyReleased(p_90895_, p_90896_, p_90898_);
|
||||
if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyReleasedPost(screen, p_90895_, p_90896_, p_90898_);
|
||||
}
|
||||
} else {
|
||||
screen.afterKeyboardAction();
|
||||
aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyPressedPre(screen, p_90895_, p_90896_, p_90898_);
|
||||
if (!aboolean[0]) aboolean[0] = screen.keyPressed(p_90895_, p_90896_, p_90898_);
|
||||
if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyPressedPost(screen, p_90895_, p_90896_, p_90898_);
|
||||
}
|
||||
|
||||
}, "keyPressed event handler", screen.getClass().getCanonicalName());
|
||||
if (aboolean[0]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.minecraft.screen == null) {
|
||||
InputConstants.Key inputconstants$key = InputConstants.getKey(p_90895_, p_90896_);
|
||||
if (p_90897_ == 0) {
|
||||
KeyMapping.set(inputconstants$key, false);
|
||||
if (p_90895_ == 292) {
|
||||
if (this.handledDebugKey) {
|
||||
this.handledDebugKey = false;
|
||||
} else {
|
||||
this.minecraft.options.renderDebug = !this.minecraft.options.renderDebug;
|
||||
this.minecraft.options.renderDebugCharts = this.minecraft.options.renderDebug && Screen.hasShiftDown();
|
||||
this.minecraft.options.renderFpsChart = this.minecraft.options.renderDebug && Screen.hasAltDown();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (p_90895_ == 293 && this.minecraft.gameRenderer != null) {
|
||||
this.minecraft.gameRenderer.togglePostEffect();
|
||||
}
|
||||
|
||||
boolean flag3 = false;
|
||||
if (p_90895_ == 256) {
|
||||
boolean flag2 = InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 292);
|
||||
this.minecraft.pauseGame(flag2);
|
||||
}
|
||||
|
||||
flag3 = InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 292) && this.handleDebugKeys(p_90895_);
|
||||
this.handledDebugKey |= flag3;
|
||||
if (p_90895_ == 290) {
|
||||
this.minecraft.options.hideGui = !this.minecraft.options.hideGui;
|
||||
}
|
||||
|
||||
if (flag3) {
|
||||
KeyMapping.set(inputconstants$key, false);
|
||||
} else {
|
||||
KeyMapping.set(inputconstants$key, true);
|
||||
KeyMapping.click(inputconstants$key);
|
||||
}
|
||||
|
||||
if (this.minecraft.options.renderDebugCharts && p_90895_ >= 48 && p_90895_ <= 57) {
|
||||
this.minecraft.debugFpsMeterKeyPress(p_90895_ - 48);
|
||||
}
|
||||
}
|
||||
}
|
||||
net.minecraftforge.client.ForgeHooksClient.onKeyInput(p_90895_, p_90896_, p_90897_, p_90898_);
|
||||
}
|
||||
}
|
||||
|
||||
private void charTyped(long p_90890_, int p_90891_, int p_90892_) {
|
||||
if (p_90890_ == this.minecraft.getWindow().getWindow()) {
|
||||
Screen guieventlistener = this.minecraft.screen;
|
||||
if (guieventlistener != null && this.minecraft.getOverlay() == null) {
|
||||
if (Character.charCount(p_90891_) == 1) {
|
||||
Screen.wrapScreenError(() -> {
|
||||
if (net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPre(guieventlistener, (char)p_90891_, p_90892_)) return;
|
||||
if (guieventlistener.charTyped((char)p_90891_, p_90892_)) return;
|
||||
net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPost(guieventlistener, (char)p_90891_, p_90892_);
|
||||
}, "charTyped event handler", guieventlistener.getClass().getCanonicalName());
|
||||
} else {
|
||||
for(char c0 : Character.toChars(p_90891_)) {
|
||||
Screen.wrapScreenError(() -> {
|
||||
if (net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPre(guieventlistener, c0, p_90892_)) return;
|
||||
if (guieventlistener.charTyped(c0, p_90892_)) return;
|
||||
net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPost(guieventlistener, c0, p_90892_);
|
||||
}, "charTyped event handler", guieventlistener.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setup(long p_90888_) {
|
||||
InputConstants.setupKeyboardCallbacks(p_90888_, (p_90939_, p_90940_, p_90941_, p_90942_, p_90943_) -> {
|
||||
this.minecraft.execute(() -> {
|
||||
this.keyPress(p_90939_, p_90940_, p_90941_, p_90942_, p_90943_);
|
||||
});
|
||||
}, (p_90935_, p_90936_, p_90937_) -> {
|
||||
this.minecraft.execute(() -> {
|
||||
this.charTyped(p_90935_, p_90936_, p_90937_);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public String getClipboard() {
|
||||
return this.clipboardManager.getClipboard(this.minecraft.getWindow().getWindow(), (p_90878_, p_90879_) -> {
|
||||
if (p_90878_ != 65545) {
|
||||
this.minecraft.getWindow().defaultErrorCallback(p_90878_, p_90879_);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void setClipboard(String p_90912_) {
|
||||
if (!p_90912_.isEmpty()) {
|
||||
this.clipboardManager.setClipboard(this.minecraft.getWindow().getWindow(), p_90912_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (this.debugCrashKeyTime > 0L) {
|
||||
long i = Util.getMillis();
|
||||
long j = 10000L - (i - this.debugCrashKeyTime);
|
||||
long k = i - this.debugCrashKeyReportedTime;
|
||||
if (j < 0L) {
|
||||
if (Screen.hasControlDown()) {
|
||||
Blaze3D.youJustLostTheGame();
|
||||
}
|
||||
|
||||
String s = "Manually triggered debug crash";
|
||||
CrashReport crashreport = new CrashReport("Manually triggered debug crash", new Throwable("Manually triggered debug crash"));
|
||||
CrashReportCategory crashreportcategory = crashreport.addCategory("Manual crash details");
|
||||
NativeModuleLister.addCrashSection(crashreportcategory);
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
|
||||
if (k >= 1000L) {
|
||||
if (this.debugCrashKeyReportedCount == 0L) {
|
||||
this.debugFeedbackTranslated("debug.crash.message");
|
||||
} else {
|
||||
this.debugWarningTranslated("debug.crash.warning", Mth.ceil((float)j / 1000.0F));
|
||||
}
|
||||
|
||||
this.debugCrashKeyReportedTime = i;
|
||||
++this.debugCrashKeyReportedCount;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,360 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.mojang.blaze3d.Blaze3D;
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.SmoothDouble;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.glfw.GLFWDropCallback;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class MouseHandler {
|
||||
private final Minecraft minecraft;
|
||||
private boolean isLeftPressed;
|
||||
private boolean isMiddlePressed;
|
||||
private boolean isRightPressed;
|
||||
private double xpos;
|
||||
private double ypos;
|
||||
private int fakeRightMouse;
|
||||
private int activeButton = -1;
|
||||
private boolean ignoreFirstMove = true;
|
||||
private int clickDepth;
|
||||
private double mousePressedTime;
|
||||
private final SmoothDouble smoothTurnX = new SmoothDouble();
|
||||
private final SmoothDouble smoothTurnY = new SmoothDouble();
|
||||
private double accumulatedDX;
|
||||
private double accumulatedDY;
|
||||
private double accumulatedScroll;
|
||||
private double lastMouseEventTime = Double.MIN_VALUE;
|
||||
private boolean mouseGrabbed;
|
||||
|
||||
public MouseHandler(Minecraft p_91522_) {
|
||||
this.minecraft = p_91522_;
|
||||
}
|
||||
|
||||
private void onPress(long p_91531_, int p_91532_, int p_91533_, int p_91534_) {
|
||||
if (p_91531_ == this.minecraft.getWindow().getWindow()) {
|
||||
if (this.minecraft.screen != null) {
|
||||
this.minecraft.setLastInputType(InputType.MOUSE);
|
||||
}
|
||||
|
||||
boolean flag = p_91533_ == 1;
|
||||
if (Minecraft.ON_OSX && p_91532_ == 0) {
|
||||
if (flag) {
|
||||
if ((p_91534_ & 2) == 2) {
|
||||
p_91532_ = 1;
|
||||
++this.fakeRightMouse;
|
||||
}
|
||||
} else if (this.fakeRightMouse > 0) {
|
||||
p_91532_ = 1;
|
||||
--this.fakeRightMouse;
|
||||
}
|
||||
}
|
||||
|
||||
int i = p_91532_;
|
||||
if (flag) {
|
||||
if (this.minecraft.options.touchscreen().get() && this.clickDepth++ > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.activeButton = i;
|
||||
this.mousePressedTime = Blaze3D.getTime();
|
||||
} else if (this.activeButton != -1) {
|
||||
if (this.minecraft.options.touchscreen().get() && --this.clickDepth > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.activeButton = -1;
|
||||
}
|
||||
|
||||
if (net.minecraftforge.client.ForgeHooksClient.onMouseButtonPre(p_91532_, p_91533_, p_91534_)) return;
|
||||
boolean[] aboolean = new boolean[]{false};
|
||||
if (this.minecraft.getOverlay() == null) {
|
||||
if (this.minecraft.screen == null) {
|
||||
if (!this.mouseGrabbed && flag) {
|
||||
this.grabMouse();
|
||||
}
|
||||
} else {
|
||||
double d0 = this.xpos * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getScreenWidth();
|
||||
double d1 = this.ypos * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getScreenHeight();
|
||||
Screen screen = this.minecraft.screen;
|
||||
if (flag) {
|
||||
screen.afterMouseAction();
|
||||
Screen.wrapScreenError(() -> {
|
||||
aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseClickedPre(screen, d0, d1, i);
|
||||
if (!aboolean[0]) {
|
||||
aboolean[0] = this.minecraft.screen.mouseClicked(d0, d1, i);
|
||||
aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseClickedPost(screen, d0, d1, i, aboolean[0]);
|
||||
}
|
||||
}, "mouseClicked event handler", screen.getClass().getCanonicalName());
|
||||
} else {
|
||||
Screen.wrapScreenError(() -> {
|
||||
aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseReleasedPre(screen, d0, d1, i);
|
||||
if (!aboolean[0]) {
|
||||
aboolean[0] = this.minecraft.screen.mouseReleased(d0, d1, i);
|
||||
aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseReleasedPost(screen, d0, d1, i, aboolean[0]);
|
||||
}
|
||||
}, "mouseReleased event handler", screen.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!aboolean[0] && this.minecraft.screen == null && this.minecraft.getOverlay() == null) {
|
||||
if (i == 0) {
|
||||
this.isLeftPressed = flag;
|
||||
} else if (i == 2) {
|
||||
this.isMiddlePressed = flag;
|
||||
} else if (i == 1) {
|
||||
this.isRightPressed = flag;
|
||||
}
|
||||
|
||||
KeyMapping.set(InputConstants.Type.MOUSE.getOrCreate(i), flag);
|
||||
if (flag) {
|
||||
if (this.minecraft.player.isSpectator() && i == 2) {
|
||||
this.minecraft.gui.getSpectatorGui().onMouseMiddleClick();
|
||||
} else {
|
||||
KeyMapping.click(InputConstants.Type.MOUSE.getOrCreate(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
net.minecraftforge.client.ForgeHooksClient.onMouseButtonPost(p_91532_, p_91533_, p_91534_);
|
||||
}
|
||||
}
|
||||
|
||||
private void onScroll(long p_91527_, double p_91528_, double p_91529_) {
|
||||
if (p_91527_ == Minecraft.getInstance().getWindow().getWindow()) {
|
||||
// FORGE: Allows for Horizontal Scroll to be recognized as Vertical Scroll - Fixes MC-121772
|
||||
double offset = p_91529_;
|
||||
if (Minecraft.ON_OSX && p_91529_ == 0) {
|
||||
offset = p_91528_;
|
||||
}
|
||||
double d0 = (this.minecraft.options.discreteMouseScroll().get() ? Math.signum(offset) : offset) * this.minecraft.options.mouseWheelSensitivity().get();
|
||||
if (this.minecraft.getOverlay() == null) {
|
||||
if (this.minecraft.screen != null) {
|
||||
double d1 = this.xpos * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getScreenWidth();
|
||||
double d2 = this.ypos * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getScreenHeight();
|
||||
this.minecraft.screen.afterMouseAction();
|
||||
if (net.minecraftforge.client.ForgeHooksClient.onScreenMouseScrollPre(this, this.minecraft.screen, d0)) return;
|
||||
if (this.minecraft.screen.mouseScrolled(d1, d2, d0)) return;
|
||||
net.minecraftforge.client.ForgeHooksClient.onScreenMouseScrollPost(this, this.minecraft.screen, d0);
|
||||
} else if (this.minecraft.player != null) {
|
||||
if (this.accumulatedScroll != 0.0D && Math.signum(d0) != Math.signum(this.accumulatedScroll)) {
|
||||
this.accumulatedScroll = 0.0D;
|
||||
}
|
||||
|
||||
this.accumulatedScroll += d0;
|
||||
int i = (int)this.accumulatedScroll;
|
||||
if (i == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.accumulatedScroll -= (double)i;
|
||||
if (net.minecraftforge.client.ForgeHooksClient.onMouseScroll(this, d0)) return;
|
||||
if (this.minecraft.player.isSpectator()) {
|
||||
if (this.minecraft.gui.getSpectatorGui().isMenuActive()) {
|
||||
this.minecraft.gui.getSpectatorGui().onMouseScrolled(-i);
|
||||
} else {
|
||||
float f = Mth.clamp(this.minecraft.player.getAbilities().getFlyingSpeed() + (float)i * 0.005F, 0.0F, 0.2F);
|
||||
this.minecraft.player.getAbilities().setFlyingSpeed(f);
|
||||
}
|
||||
} else {
|
||||
this.minecraft.player.getInventory().swapPaint((double)i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onDrop(long p_91540_, List<Path> p_91541_) {
|
||||
if (this.minecraft.screen != null) {
|
||||
this.minecraft.screen.onFilesDrop(p_91541_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setup(long p_91525_) {
|
||||
InputConstants.setupMouseCallbacks(p_91525_, (p_91591_, p_91592_, p_91593_) -> {
|
||||
this.minecraft.execute(() -> {
|
||||
this.onMove(p_91591_, p_91592_, p_91593_);
|
||||
});
|
||||
}, (p_91566_, p_91567_, p_91568_, p_91569_) -> {
|
||||
this.minecraft.execute(() -> {
|
||||
this.onPress(p_91566_, p_91567_, p_91568_, p_91569_);
|
||||
});
|
||||
}, (p_91576_, p_91577_, p_91578_) -> {
|
||||
this.minecraft.execute(() -> {
|
||||
this.onScroll(p_91576_, p_91577_, p_91578_);
|
||||
});
|
||||
}, (p_91536_, p_91537_, p_91538_) -> {
|
||||
Path[] apath = new Path[p_91537_];
|
||||
|
||||
for(int i = 0; i < p_91537_; ++i) {
|
||||
apath[i] = Paths.get(GLFWDropCallback.getName(p_91538_, i));
|
||||
}
|
||||
|
||||
this.minecraft.execute(() -> {
|
||||
this.onDrop(p_91536_, Arrays.asList(apath));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void onMove(long p_91562_, double p_91563_, double p_91564_) {
|
||||
if (p_91562_ == Minecraft.getInstance().getWindow().getWindow()) {
|
||||
if (this.ignoreFirstMove) {
|
||||
this.xpos = p_91563_;
|
||||
this.ypos = p_91564_;
|
||||
this.ignoreFirstMove = false;
|
||||
}
|
||||
|
||||
Screen screen = this.minecraft.screen;
|
||||
if (screen != null && this.minecraft.getOverlay() == null) {
|
||||
double d0 = p_91563_ * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getScreenWidth();
|
||||
double d1 = p_91564_ * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getScreenHeight();
|
||||
Screen.wrapScreenError(() -> {
|
||||
screen.mouseMoved(d0, d1);
|
||||
}, "mouseMoved event handler", screen.getClass().getCanonicalName());
|
||||
if (this.activeButton != -1 && this.mousePressedTime > 0.0D) {
|
||||
double d2 = (p_91563_ - this.xpos) * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getScreenWidth();
|
||||
double d3 = (p_91564_ - this.ypos) * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getScreenHeight();
|
||||
Screen.wrapScreenError(() -> {
|
||||
if (net.minecraftforge.client.ForgeHooksClient.onScreenMouseDragPre(screen, d0, d1, this.activeButton, d2, d3)) return;
|
||||
if (screen.mouseDragged(d0, d1, this.activeButton, d2, d3)) return;
|
||||
net.minecraftforge.client.ForgeHooksClient.onScreenMouseDragPost(screen, d0, d1, this.activeButton, d2, d3);
|
||||
}, "mouseDragged event handler", screen.getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
screen.afterMouseMove();
|
||||
}
|
||||
|
||||
this.minecraft.getProfiler().push("mouse");
|
||||
if (this.isMouseGrabbed() && this.minecraft.isWindowActive()) {
|
||||
this.accumulatedDX += p_91563_ - this.xpos;
|
||||
this.accumulatedDY += p_91564_ - this.ypos;
|
||||
}
|
||||
|
||||
this.turnPlayer();
|
||||
this.xpos = p_91563_;
|
||||
this.ypos = p_91564_;
|
||||
this.minecraft.getProfiler().pop();
|
||||
}
|
||||
}
|
||||
|
||||
public void turnPlayer() {
|
||||
double d0 = Blaze3D.getTime();
|
||||
double d1 = d0 - this.lastMouseEventTime;
|
||||
this.lastMouseEventTime = d0;
|
||||
if (this.isMouseGrabbed() && this.minecraft.isWindowActive()) {
|
||||
double d4 = this.minecraft.options.sensitivity().get() * (double)0.6F + (double)0.2F;
|
||||
double d5 = d4 * d4 * d4;
|
||||
double d6 = d5 * 8.0D;
|
||||
double d2;
|
||||
double d3;
|
||||
if (this.minecraft.options.smoothCamera) {
|
||||
double d7 = this.smoothTurnX.getNewDeltaValue(this.accumulatedDX * d6, d1 * d6);
|
||||
double d8 = this.smoothTurnY.getNewDeltaValue(this.accumulatedDY * d6, d1 * d6);
|
||||
d2 = d7;
|
||||
d3 = d8;
|
||||
} else if (this.minecraft.options.getCameraType().isFirstPerson() && this.minecraft.player.isScoping()) {
|
||||
this.smoothTurnX.reset();
|
||||
this.smoothTurnY.reset();
|
||||
d2 = this.accumulatedDX * d5;
|
||||
d3 = this.accumulatedDY * d5;
|
||||
} else {
|
||||
this.smoothTurnX.reset();
|
||||
this.smoothTurnY.reset();
|
||||
d2 = this.accumulatedDX * d6;
|
||||
d3 = this.accumulatedDY * d6;
|
||||
}
|
||||
|
||||
this.accumulatedDX = 0.0D;
|
||||
this.accumulatedDY = 0.0D;
|
||||
int i = 1;
|
||||
if (this.minecraft.options.invertYMouse().get()) {
|
||||
i = -1;
|
||||
}
|
||||
|
||||
this.minecraft.getTutorial().onMouse(d2, d3);
|
||||
if (this.minecraft.player != null) {
|
||||
this.minecraft.player.turn(d2, d3 * (double)i);
|
||||
}
|
||||
|
||||
} else {
|
||||
this.accumulatedDX = 0.0D;
|
||||
this.accumulatedDY = 0.0D;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isLeftPressed() {
|
||||
return this.isLeftPressed;
|
||||
}
|
||||
|
||||
public boolean isMiddlePressed() {
|
||||
return this.isMiddlePressed;
|
||||
}
|
||||
|
||||
public boolean isRightPressed() {
|
||||
return this.isRightPressed;
|
||||
}
|
||||
|
||||
public double xpos() {
|
||||
return this.xpos;
|
||||
}
|
||||
|
||||
public double ypos() {
|
||||
return this.ypos;
|
||||
}
|
||||
|
||||
public double getXVelocity() {
|
||||
return this.accumulatedDX;
|
||||
}
|
||||
|
||||
public double getYVelocity() {
|
||||
return this.accumulatedDY;
|
||||
}
|
||||
|
||||
public void setIgnoreFirstMove() {
|
||||
this.ignoreFirstMove = true;
|
||||
}
|
||||
|
||||
public boolean isMouseGrabbed() {
|
||||
return this.mouseGrabbed;
|
||||
}
|
||||
|
||||
public void grabMouse() {
|
||||
if (this.minecraft.isWindowActive()) {
|
||||
if (!this.mouseGrabbed) {
|
||||
if (!Minecraft.ON_OSX) {
|
||||
KeyMapping.setAll();
|
||||
}
|
||||
|
||||
this.mouseGrabbed = true;
|
||||
this.xpos = (double)(this.minecraft.getWindow().getScreenWidth() / 2);
|
||||
this.ypos = (double)(this.minecraft.getWindow().getScreenHeight() / 2);
|
||||
InputConstants.grabOrReleaseMouse(this.minecraft.getWindow().getWindow(), 212995, this.xpos, this.ypos);
|
||||
this.minecraft.setScreen((Screen)null);
|
||||
this.minecraft.missTime = 10000;
|
||||
this.ignoreFirstMove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseMouse() {
|
||||
if (this.mouseGrabbed) {
|
||||
this.mouseGrabbed = false;
|
||||
this.xpos = (double)(this.minecraft.getWindow().getScreenWidth() / 2);
|
||||
this.ypos = (double)(this.minecraft.getWindow().getScreenHeight() / 2);
|
||||
InputConstants.grabOrReleaseMouse(this.minecraft.getWindow().getWindow(), 212993, this.xpos, this.ypos);
|
||||
}
|
||||
}
|
||||
|
||||
public void cursorEntered() {
|
||||
this.ignoreFirstMove = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.ByIdMap;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum NarratorStatus {
|
||||
OFF(0, "options.narrator.off"),
|
||||
ALL(1, "options.narrator.all"),
|
||||
CHAT(2, "options.narrator.chat"),
|
||||
SYSTEM(3, "options.narrator.system");
|
||||
|
||||
private static final IntFunction<NarratorStatus> BY_ID = ByIdMap.continuous(NarratorStatus::getId, values(), ByIdMap.OutOfBoundsStrategy.WRAP);
|
||||
private final int id;
|
||||
private final Component name;
|
||||
|
||||
private NarratorStatus(int p_91616_, String p_91617_) {
|
||||
this.id = p_91616_;
|
||||
this.name = Component.translatable(p_91617_);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Component getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public static NarratorStatus byId(int p_91620_) {
|
||||
return BY_ID.apply(p_91620_);
|
||||
}
|
||||
|
||||
public boolean shouldNarrateChat() {
|
||||
return this == ALL || this == CHAT;
|
||||
}
|
||||
|
||||
public boolean shouldNarrateSystem() {
|
||||
return this == ALL || this == SYSTEM;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,425 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.DoubleFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.IntSupplier;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.stream.IntStream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.components.AbstractOptionSliderButton;
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.components.CycleButton;
|
||||
import net.minecraft.client.gui.components.Tooltip;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.OptionEnum;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final class OptionInstance<T> {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final OptionInstance.Enum<Boolean> BOOLEAN_VALUES = new OptionInstance.Enum<>(ImmutableList.of(Boolean.TRUE, Boolean.FALSE), Codec.BOOL);
|
||||
public static final OptionInstance.CaptionBasedToString<Boolean> BOOLEAN_TO_STRING = (p_231544_, p_231545_) -> {
|
||||
return p_231545_ ? CommonComponents.OPTION_ON : CommonComponents.OPTION_OFF;
|
||||
};
|
||||
private final OptionInstance.TooltipSupplier<T> tooltip;
|
||||
final Function<T, Component> toString;
|
||||
private final OptionInstance.ValueSet<T> values;
|
||||
private final Codec<T> codec;
|
||||
private final T initialValue;
|
||||
private final Consumer<T> onValueUpdate;
|
||||
final Component caption;
|
||||
T value;
|
||||
|
||||
public static OptionInstance<Boolean> createBoolean(String p_231529_, boolean p_231530_, Consumer<Boolean> p_231531_) {
|
||||
return createBoolean(p_231529_, noTooltip(), p_231530_, p_231531_);
|
||||
}
|
||||
|
||||
public static OptionInstance<Boolean> createBoolean(String p_231526_, boolean p_231527_) {
|
||||
return createBoolean(p_231526_, noTooltip(), p_231527_, (p_231548_) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public static OptionInstance<Boolean> createBoolean(String p_259291_, OptionInstance.TooltipSupplier<Boolean> p_260306_, boolean p_259985_) {
|
||||
return createBoolean(p_259291_, p_260306_, p_259985_, (p_231513_) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public static OptionInstance<Boolean> createBoolean(String p_259289_, OptionInstance.TooltipSupplier<Boolean> p_260210_, boolean p_259359_, Consumer<Boolean> p_259975_) {
|
||||
return createBoolean(p_259289_, p_260210_, BOOLEAN_TO_STRING, p_259359_, p_259975_);
|
||||
}
|
||||
|
||||
public static OptionInstance<Boolean> createBoolean(String p_262002_, OptionInstance.TooltipSupplier<Boolean> p_261507_, OptionInstance.CaptionBasedToString<Boolean> p_262099_, boolean p_262136_, Consumer<Boolean> p_261984_) {
|
||||
return new OptionInstance<>(p_262002_, p_261507_, p_262099_, BOOLEAN_VALUES, p_262136_, p_261984_);
|
||||
}
|
||||
|
||||
public OptionInstance(String p_260248_, OptionInstance.TooltipSupplier<T> p_259437_, OptionInstance.CaptionBasedToString<T> p_259148_, OptionInstance.ValueSet<T> p_259590_, T p_260067_, Consumer<T> p_259392_) {
|
||||
this(p_260248_, p_259437_, p_259148_, p_259590_, p_259590_.codec(), p_260067_, p_259392_);
|
||||
}
|
||||
|
||||
public OptionInstance(String p_259964_, OptionInstance.TooltipSupplier<T> p_260354_, OptionInstance.CaptionBasedToString<T> p_259496_, OptionInstance.ValueSet<T> p_259090_, Codec<T> p_259043_, T p_259396_, Consumer<T> p_260147_) {
|
||||
this.caption = Component.translatable(p_259964_);
|
||||
this.tooltip = p_260354_;
|
||||
this.toString = (p_231506_) -> {
|
||||
return p_259496_.toString(this.caption, p_231506_);
|
||||
};
|
||||
this.values = p_259090_;
|
||||
this.codec = p_259043_;
|
||||
this.initialValue = p_259396_;
|
||||
this.onValueUpdate = p_260147_;
|
||||
this.value = this.initialValue;
|
||||
}
|
||||
|
||||
public static <T> OptionInstance.TooltipSupplier<T> noTooltip() {
|
||||
return (p_258114_) -> {
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> OptionInstance.TooltipSupplier<T> cachedConstantTooltip(Component p_231536_) {
|
||||
return (p_258116_) -> {
|
||||
return Tooltip.create(p_231536_);
|
||||
};
|
||||
}
|
||||
|
||||
public static <T extends OptionEnum> OptionInstance.CaptionBasedToString<T> forOptionEnum() {
|
||||
return (p_231538_, p_231539_) -> {
|
||||
return p_231539_.getCaption();
|
||||
};
|
||||
}
|
||||
|
||||
public AbstractWidget createButton(Options p_231508_, int p_231509_, int p_231510_, int p_231511_) {
|
||||
return this.createButton(p_231508_, p_231509_, p_231510_, p_231511_, (p_261336_) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public AbstractWidget createButton(Options p_261971_, int p_261486_, int p_261569_, int p_261677_, Consumer<T> p_261912_) {
|
||||
return this.values.createButton(this.tooltip, p_261971_, p_261486_, p_261569_, p_261677_, p_261912_).apply(this);
|
||||
}
|
||||
|
||||
public T get() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public Codec<T> codec() {
|
||||
return this.codec;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.caption.getString();
|
||||
}
|
||||
|
||||
public void set(T p_231515_) {
|
||||
T t = this.values.validateValue(p_231515_).orElseGet(() -> {
|
||||
LOGGER.error("Illegal option value " + p_231515_ + " for " + this.caption);
|
||||
return this.initialValue;
|
||||
});
|
||||
if (!Minecraft.getInstance().isRunning()) {
|
||||
this.value = t;
|
||||
} else {
|
||||
if (!Objects.equals(this.value, t)) {
|
||||
this.value = t;
|
||||
this.onValueUpdate.accept(this.value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public OptionInstance.ValueSet<T> values() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record AltEnum<T>(List<T> values, List<T> altValues, BooleanSupplier altCondition, OptionInstance.CycleableValueSet.ValueSetter<T> valueSetter, Codec<T> codec) implements OptionInstance.CycleableValueSet<T> {
|
||||
public CycleButton.ValueListSupplier<T> valueListSupplier() {
|
||||
return CycleButton.ValueListSupplier.create(this.altCondition, this.values, this.altValues);
|
||||
}
|
||||
|
||||
public Optional<T> validateValue(T p_231570_) {
|
||||
return (this.altCondition.getAsBoolean() ? this.altValues : this.values).contains(p_231570_) ? Optional.of(p_231570_) : Optional.empty();
|
||||
}
|
||||
|
||||
public OptionInstance.CycleableValueSet.ValueSetter<T> valueSetter() {
|
||||
return this.valueSetter;
|
||||
}
|
||||
|
||||
public Codec<T> codec() {
|
||||
return this.codec;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface CaptionBasedToString<T> {
|
||||
Component toString(Component p_231581_, T p_231582_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record ClampingLazyMaxIntRange(int minInclusive, IntSupplier maxSupplier, int encodableMaxInclusive) implements OptionInstance.IntRangeBase, OptionInstance.SliderableOrCyclableValueSet<Integer> {
|
||||
public Optional<Integer> validateValue(Integer p_231590_) {
|
||||
return Optional.of(Mth.clamp(p_231590_, this.minInclusive(), this.maxInclusive()));
|
||||
}
|
||||
|
||||
public int maxInclusive() {
|
||||
return this.maxSupplier.getAsInt();
|
||||
}
|
||||
|
||||
public Codec<Integer> codec() {
|
||||
return ExtraCodecs.validate(Codec.INT, (p_276098_) -> {
|
||||
int i = this.encodableMaxInclusive + 1;
|
||||
return p_276098_.compareTo(this.minInclusive) >= 0 && p_276098_.compareTo(i) <= 0 ? DataResult.success(p_276098_) : DataResult.error(() -> {
|
||||
return "Value " + p_276098_ + " outside of range [" + this.minInclusive + ":" + i + "]";
|
||||
}, p_276098_);
|
||||
});
|
||||
}
|
||||
|
||||
public boolean createCycleButton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public CycleButton.ValueListSupplier<Integer> valueListSupplier() {
|
||||
return CycleButton.ValueListSupplier.create(IntStream.range(this.minInclusive, this.maxInclusive() + 1).boxed().toList());
|
||||
}
|
||||
|
||||
public int minInclusive() {
|
||||
return this.minInclusive;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
interface CycleableValueSet<T> extends OptionInstance.ValueSet<T> {
|
||||
CycleButton.ValueListSupplier<T> valueListSupplier();
|
||||
|
||||
default OptionInstance.CycleableValueSet.ValueSetter<T> valueSetter() {
|
||||
return OptionInstance::set;
|
||||
}
|
||||
|
||||
default Function<OptionInstance<T>, AbstractWidget> createButton(OptionInstance.TooltipSupplier<T> p_261801_, Options p_261824_, int p_261649_, int p_262114_, int p_261536_, Consumer<T> p_261642_) {
|
||||
return (p_261343_) -> {
|
||||
return CycleButton.builder(p_261343_.toString).withValues(this.valueListSupplier()).withTooltip(p_261801_).withInitialValue(p_261343_.value).create(p_261649_, p_262114_, p_261536_, 20, p_261343_.caption, (p_261347_, p_261348_) -> {
|
||||
this.valueSetter().set(p_261343_, p_261348_);
|
||||
p_261824_.save();
|
||||
p_261642_.accept(p_261348_);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface ValueSetter<T> {
|
||||
void set(OptionInstance<T> p_231623_, T p_231624_);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record Enum<T>(List<T> values, Codec<T> codec) implements OptionInstance.CycleableValueSet<T> {
|
||||
public Optional<T> validateValue(T p_231632_) {
|
||||
return this.values.contains(p_231632_) ? Optional.of(p_231632_) : Optional.empty();
|
||||
}
|
||||
|
||||
public CycleButton.ValueListSupplier<T> valueListSupplier() {
|
||||
return CycleButton.ValueListSupplier.create(this.values);
|
||||
}
|
||||
|
||||
public Codec<T> codec() {
|
||||
return this.codec;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record IntRange(int minInclusive, int maxInclusive) implements OptionInstance.IntRangeBase {
|
||||
public Optional<Integer> validateValue(Integer p_231645_) {
|
||||
return p_231645_.compareTo(this.minInclusive()) >= 0 && p_231645_.compareTo(this.maxInclusive()) <= 0 ? Optional.of(p_231645_) : Optional.empty();
|
||||
}
|
||||
|
||||
public Codec<Integer> codec() {
|
||||
return Codec.intRange(this.minInclusive, this.maxInclusive + 1);
|
||||
}
|
||||
|
||||
public int minInclusive() {
|
||||
return this.minInclusive;
|
||||
}
|
||||
|
||||
public int maxInclusive() {
|
||||
return this.maxInclusive;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
interface IntRangeBase extends OptionInstance.SliderableValueSet<Integer> {
|
||||
int minInclusive();
|
||||
|
||||
int maxInclusive();
|
||||
|
||||
default double toSliderValue(Integer p_231663_) {
|
||||
return (double)Mth.map((float)p_231663_.intValue(), (float)this.minInclusive(), (float)this.maxInclusive(), 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
default Integer fromSliderValue(double p_231656_) {
|
||||
return Mth.floor(Mth.map(p_231656_, 0.0D, 1.0D, (double)this.minInclusive(), (double)this.maxInclusive()));
|
||||
}
|
||||
|
||||
default <R> OptionInstance.SliderableValueSet<R> xmap(final IntFunction<? extends R> p_231658_, final ToIntFunction<? super R> p_231659_) {
|
||||
return new OptionInstance.SliderableValueSet<R>() {
|
||||
public Optional<R> validateValue(R p_231674_) {
|
||||
return IntRangeBase.this.validateValue(Integer.valueOf(p_231659_.applyAsInt(p_231674_))).map(p_231658_::apply);
|
||||
}
|
||||
|
||||
public double toSliderValue(R p_231678_) {
|
||||
return IntRangeBase.this.toSliderValue(p_231659_.applyAsInt(p_231678_));
|
||||
}
|
||||
|
||||
public R fromSliderValue(double p_231676_) {
|
||||
return p_231658_.apply(IntRangeBase.this.fromSliderValue(p_231676_));
|
||||
}
|
||||
|
||||
public Codec<R> codec() {
|
||||
return IntRangeBase.this.codec().xmap(p_231658_::apply, p_231659_::applyAsInt);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record LazyEnum<T>(Supplier<List<T>> values, Function<T, Optional<T>> validateValue, Codec<T> codec) implements OptionInstance.CycleableValueSet<T> {
|
||||
public Optional<T> validateValue(T p_231689_) {
|
||||
return this.validateValue.apply(p_231689_);
|
||||
}
|
||||
|
||||
public CycleButton.ValueListSupplier<T> valueListSupplier() {
|
||||
return CycleButton.ValueListSupplier.create(this.values.get());
|
||||
}
|
||||
|
||||
public Codec<T> codec() {
|
||||
return this.codec;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static final class OptionInstanceSliderButton<N> extends AbstractOptionSliderButton {
|
||||
private final OptionInstance<N> instance;
|
||||
private final OptionInstance.SliderableValueSet<N> values;
|
||||
private final OptionInstance.TooltipSupplier<N> tooltipSupplier;
|
||||
private final Consumer<N> onValueChanged;
|
||||
|
||||
OptionInstanceSliderButton(Options p_261713_, int p_261873_, int p_261656_, int p_261799_, int p_261893_, OptionInstance<N> p_262129_, OptionInstance.SliderableValueSet<N> p_261995_, OptionInstance.TooltipSupplier<N> p_261963_, Consumer<N> p_261829_) {
|
||||
super(p_261713_, p_261873_, p_261656_, p_261799_, p_261893_, p_261995_.toSliderValue(p_262129_.get()));
|
||||
this.instance = p_262129_;
|
||||
this.values = p_261995_;
|
||||
this.tooltipSupplier = p_261963_;
|
||||
this.onValueChanged = p_261829_;
|
||||
this.updateMessage();
|
||||
}
|
||||
|
||||
protected void updateMessage() {
|
||||
this.setMessage(this.instance.toString.apply(this.instance.get()));
|
||||
this.setTooltip(this.tooltipSupplier.apply(this.values.fromSliderValue(this.value)));
|
||||
}
|
||||
|
||||
protected void applyValue() {
|
||||
this.instance.set(this.values.fromSliderValue(this.value));
|
||||
this.options.save();
|
||||
this.onValueChanged.accept(this.instance.get());
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
interface SliderableOrCyclableValueSet<T> extends OptionInstance.CycleableValueSet<T>, OptionInstance.SliderableValueSet<T> {
|
||||
boolean createCycleButton();
|
||||
|
||||
default Function<OptionInstance<T>, AbstractWidget> createButton(OptionInstance.TooltipSupplier<T> p_261786_, Options p_262030_, int p_261940_, int p_262149_, int p_261495_, Consumer<T> p_261881_) {
|
||||
return this.createCycleButton() ? OptionInstance.CycleableValueSet.super.createButton(p_261786_, p_262030_, p_261940_, p_262149_, p_261495_, p_261881_) : OptionInstance.SliderableValueSet.super.createButton(p_261786_, p_262030_, p_261940_, p_262149_, p_261495_, p_261881_);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
interface SliderableValueSet<T> extends OptionInstance.ValueSet<T> {
|
||||
double toSliderValue(T p_231732_);
|
||||
|
||||
T fromSliderValue(double p_231731_);
|
||||
|
||||
default Function<OptionInstance<T>, AbstractWidget> createButton(OptionInstance.TooltipSupplier<T> p_261993_, Options p_262177_, int p_261706_, int p_261683_, int p_261573_, Consumer<T> p_261969_) {
|
||||
return (p_261355_) -> {
|
||||
return new OptionInstance.OptionInstanceSliderButton<>(p_262177_, p_261706_, p_261683_, p_261573_, 20, p_261355_, this, p_261993_, p_261969_);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface TooltipSupplier<T> {
|
||||
@Nullable
|
||||
Tooltip apply(T p_259319_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum UnitDouble implements OptionInstance.SliderableValueSet<Double> {
|
||||
INSTANCE;
|
||||
|
||||
public Optional<Double> validateValue(Double p_231747_) {
|
||||
return p_231747_ >= 0.0D && p_231747_ <= 1.0D ? Optional.of(p_231747_) : Optional.empty();
|
||||
}
|
||||
|
||||
public double toSliderValue(Double p_231756_) {
|
||||
return p_231756_;
|
||||
}
|
||||
|
||||
public Double fromSliderValue(double p_231741_) {
|
||||
return p_231741_;
|
||||
}
|
||||
|
||||
public <R> OptionInstance.SliderableValueSet<R> xmap(final DoubleFunction<? extends R> p_231751_, final ToDoubleFunction<? super R> p_231752_) {
|
||||
return new OptionInstance.SliderableValueSet<R>() {
|
||||
public Optional<R> validateValue(R p_231773_) {
|
||||
return UnitDouble.this.validateValue(p_231752_.applyAsDouble(p_231773_)).map(p_231751_::apply);
|
||||
}
|
||||
|
||||
public double toSliderValue(R p_231777_) {
|
||||
return UnitDouble.this.toSliderValue(p_231752_.applyAsDouble(p_231777_));
|
||||
}
|
||||
|
||||
public R fromSliderValue(double p_231775_) {
|
||||
return p_231751_.apply(UnitDouble.this.fromSliderValue(p_231775_));
|
||||
}
|
||||
|
||||
public Codec<R> codec() {
|
||||
return UnitDouble.this.codec().xmap(p_231751_::apply, p_231752_::applyAsDouble);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Codec<Double> codec() {
|
||||
return Codec.either(Codec.doubleRange(0.0D, 1.0D), Codec.BOOL).xmap((p_231743_) -> {
|
||||
return p_231743_.map((p_231760_) -> {
|
||||
return p_231760_;
|
||||
}, (p_231745_) -> {
|
||||
return p_231745_ ? 1.0D : 0.0D;
|
||||
});
|
||||
}, Either::left);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
interface ValueSet<T> {
|
||||
Function<OptionInstance<T>, AbstractWidget> createButton(OptionInstance.TooltipSupplier<T> p_231779_, Options p_231780_, int p_231781_, int p_231782_, int p_231783_, Consumer<T> p_261976_);
|
||||
|
||||
Optional<T> validateValue(T p_231784_);
|
||||
|
||||
Codec<T> codec();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
import net.minecraft.util.ByIdMap;
|
||||
import net.minecraft.util.OptionEnum;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum ParticleStatus implements OptionEnum {
|
||||
ALL(0, "options.particles.all"),
|
||||
DECREASED(1, "options.particles.decreased"),
|
||||
MINIMAL(2, "options.particles.minimal");
|
||||
|
||||
private static final IntFunction<ParticleStatus> BY_ID = ByIdMap.continuous(ParticleStatus::getId, values(), ByIdMap.OutOfBoundsStrategy.WRAP);
|
||||
private final int id;
|
||||
private final String key;
|
||||
|
||||
private ParticleStatus(int p_92193_, String p_92194_) {
|
||||
this.id = p_92193_;
|
||||
this.key = p_92194_;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public static ParticleStatus byId(int p_92197_) {
|
||||
return BY_ID.apply(p_92197_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.math.LongMath;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanFunction;
|
||||
import java.io.Reader;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.gui.components.toasts.SystemToast;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.server.packs.resources.SimplePreparableReloadListener;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PeriodicNotificationManager extends SimplePreparableReloadListener<Map<String, List<PeriodicNotificationManager.Notification>>> implements AutoCloseable {
|
||||
private static final Codec<Map<String, List<PeriodicNotificationManager.Notification>>> CODEC = Codec.unboundedMap(Codec.STRING, RecordCodecBuilder.<PeriodicNotificationManager.Notification>create((p_205303_) -> {
|
||||
return p_205303_.group(Codec.LONG.optionalFieldOf("delay", Long.valueOf(0L)).forGetter(PeriodicNotificationManager.Notification::delay), Codec.LONG.fieldOf("period").forGetter(PeriodicNotificationManager.Notification::period), Codec.STRING.fieldOf("title").forGetter(PeriodicNotificationManager.Notification::title), Codec.STRING.fieldOf("message").forGetter(PeriodicNotificationManager.Notification::message)).apply(p_205303_, PeriodicNotificationManager.Notification::new);
|
||||
}).listOf());
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final ResourceLocation notifications;
|
||||
private final Object2BooleanFunction<String> selector;
|
||||
@Nullable
|
||||
private java.util.Timer timer;
|
||||
@Nullable
|
||||
private PeriodicNotificationManager.NotificationTask notificationTask;
|
||||
|
||||
public PeriodicNotificationManager(ResourceLocation p_205293_, Object2BooleanFunction<String> p_205294_) {
|
||||
this.notifications = p_205293_;
|
||||
this.selector = p_205294_;
|
||||
}
|
||||
|
||||
protected Map<String, List<PeriodicNotificationManager.Notification>> prepare(ResourceManager p_205300_, ProfilerFiller p_205301_) {
|
||||
try (Reader reader = p_205300_.openAsReader(this.notifications)) {
|
||||
return CODEC.parse(JsonOps.INSTANCE, JsonParser.parseReader(reader)).result().orElseThrow();
|
||||
} catch (Exception exception) {
|
||||
LOGGER.warn("Failed to load {}", this.notifications, exception);
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
}
|
||||
|
||||
protected void apply(Map<String, List<PeriodicNotificationManager.Notification>> p_205318_, ResourceManager p_205319_, ProfilerFiller p_205320_) {
|
||||
List<PeriodicNotificationManager.Notification> list = p_205318_.entrySet().stream().filter((p_205316_) -> {
|
||||
return this.selector.apply(p_205316_.getKey());
|
||||
}).map(Map.Entry::getValue).flatMap(Collection::stream).collect(Collectors.toList());
|
||||
if (list.isEmpty()) {
|
||||
this.stopTimer();
|
||||
} else if (list.stream().anyMatch((p_205326_) -> {
|
||||
return p_205326_.period == 0L;
|
||||
})) {
|
||||
Util.logAndPauseIfInIde("A periodic notification in " + this.notifications + " has a period of zero minutes");
|
||||
this.stopTimer();
|
||||
} else {
|
||||
long i = this.calculateInitialDelay(list);
|
||||
long j = this.calculateOptimalPeriod(list, i);
|
||||
if (this.timer == null) {
|
||||
this.timer = new java.util.Timer();
|
||||
}
|
||||
|
||||
if (this.notificationTask == null) {
|
||||
this.notificationTask = new PeriodicNotificationManager.NotificationTask(list, i, j);
|
||||
} else {
|
||||
this.notificationTask = this.notificationTask.reset(list, j);
|
||||
}
|
||||
|
||||
this.timer.scheduleAtFixedRate(this.notificationTask, TimeUnit.MINUTES.toMillis(i), TimeUnit.MINUTES.toMillis(j));
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.stopTimer();
|
||||
}
|
||||
|
||||
private void stopTimer() {
|
||||
if (this.timer != null) {
|
||||
this.timer.cancel();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private long calculateOptimalPeriod(List<PeriodicNotificationManager.Notification> p_205313_, long p_205314_) {
|
||||
return p_205313_.stream().mapToLong((p_205298_) -> {
|
||||
long i = p_205298_.delay - p_205314_;
|
||||
return LongMath.gcd(i, p_205298_.period);
|
||||
}).reduce(LongMath::gcd).orElseThrow(() -> {
|
||||
return new IllegalStateException("Empty notifications from: " + this.notifications);
|
||||
});
|
||||
}
|
||||
|
||||
private long calculateInitialDelay(List<PeriodicNotificationManager.Notification> p_205311_) {
|
||||
return p_205311_.stream().mapToLong((p_205305_) -> {
|
||||
return p_205305_.delay;
|
||||
}).min().orElse(0L);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record Notification(long delay, long period, String title, String message) {
|
||||
public Notification(long delay, long period, String title, String message) {
|
||||
this.delay = delay != 0L ? delay : period;
|
||||
this.period = period;
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class NotificationTask extends TimerTask {
|
||||
private final Minecraft minecraft = Minecraft.getInstance();
|
||||
private final List<PeriodicNotificationManager.Notification> notifications;
|
||||
private final long period;
|
||||
private final AtomicLong elapsed;
|
||||
|
||||
public NotificationTask(List<PeriodicNotificationManager.Notification> p_205350_, long p_205351_, long p_205352_) {
|
||||
this.notifications = p_205350_;
|
||||
this.period = p_205352_;
|
||||
this.elapsed = new AtomicLong(p_205351_);
|
||||
}
|
||||
|
||||
public PeriodicNotificationManager.NotificationTask reset(List<PeriodicNotificationManager.Notification> p_205357_, long p_205358_) {
|
||||
this.cancel();
|
||||
return new PeriodicNotificationManager.NotificationTask(p_205357_, this.elapsed.get(), p_205358_);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
long i = this.elapsed.getAndAdd(this.period);
|
||||
long j = this.elapsed.get();
|
||||
|
||||
for(PeriodicNotificationManager.Notification periodicnotificationmanager$notification : this.notifications) {
|
||||
if (i >= periodicnotificationmanager$notification.delay) {
|
||||
long k = i / periodicnotificationmanager$notification.period;
|
||||
long l = j / periodicnotificationmanager$notification.period;
|
||||
if (k != l) {
|
||||
this.minecraft.execute(() -> {
|
||||
SystemToast.add(Minecraft.getInstance().getToasts(), SystemToast.SystemToastIds.PERIODIC_NOTIFICATION, Component.translatable(periodicnotificationmanager$notification.title, k), Component.translatable(periodicnotificationmanager$notification.message, k));
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
import net.minecraft.util.ByIdMap;
|
||||
import net.minecraft.util.OptionEnum;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum PrioritizeChunkUpdates implements OptionEnum {
|
||||
NONE(0, "options.prioritizeChunkUpdates.none"),
|
||||
PLAYER_AFFECTED(1, "options.prioritizeChunkUpdates.byPlayer"),
|
||||
NEARBY(2, "options.prioritizeChunkUpdates.nearby");
|
||||
|
||||
private static final IntFunction<PrioritizeChunkUpdates> BY_ID = ByIdMap.continuous(PrioritizeChunkUpdates::getId, values(), ByIdMap.OutOfBoundsStrategy.WRAP);
|
||||
private final int id;
|
||||
private final String key;
|
||||
|
||||
private PrioritizeChunkUpdates(int p_193784_, String p_193785_) {
|
||||
this.id = p_193784_;
|
||||
this.key = p_193785_;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public static PrioritizeChunkUpdates byId(int p_193788_) {
|
||||
return BY_ID.apply(p_193788_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.multiplayer.Realms32bitWarningScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Realms32BitWarningStatus {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final Minecraft minecraft;
|
||||
@Nullable
|
||||
private CompletableFuture<Boolean> subscriptionCheck;
|
||||
private boolean warningScreenShown;
|
||||
|
||||
public Realms32BitWarningStatus(Minecraft p_232204_) {
|
||||
this.minecraft = p_232204_;
|
||||
}
|
||||
|
||||
public void showRealms32BitWarningIfNeeded(Screen p_232209_) {
|
||||
if (!this.minecraft.is64Bit() && !this.minecraft.options.skipRealms32bitWarning && !this.warningScreenShown && this.checkForRealmsSubscription()) {
|
||||
this.minecraft.setScreen(new Realms32bitWarningScreen(p_232209_));
|
||||
this.warningScreenShown = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Boolean checkForRealmsSubscription() {
|
||||
if (this.subscriptionCheck == null) {
|
||||
this.subscriptionCheck = CompletableFuture.supplyAsync(this::hasRealmsSubscription, Util.backgroundExecutor());
|
||||
}
|
||||
|
||||
try {
|
||||
return this.subscriptionCheck.getNow(false);
|
||||
} catch (CompletionException completionexception) {
|
||||
LOGGER.warn("Failed to retrieve realms subscriptions", (Throwable)completionexception);
|
||||
this.warningScreenShown = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasRealmsSubscription() {
|
||||
try {
|
||||
return RealmsClient.create(this.minecraft).listWorlds().servers.stream().anyMatch((p_232207_) -> {
|
||||
return p_232207_.ownerUUID != null && !p_232207_.expired && p_232207_.ownerUUID.equals(this.minecraft.getUser().getUuid());
|
||||
});
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum RecipeBookCategories implements net.minecraftforge.common.IExtensibleEnum {
|
||||
CRAFTING_SEARCH(new ItemStack(Items.COMPASS)),
|
||||
CRAFTING_BUILDING_BLOCKS(new ItemStack(Blocks.BRICKS)),
|
||||
CRAFTING_REDSTONE(new ItemStack(Items.REDSTONE)),
|
||||
CRAFTING_EQUIPMENT(new ItemStack(Items.IRON_AXE), new ItemStack(Items.GOLDEN_SWORD)),
|
||||
CRAFTING_MISC(new ItemStack(Items.LAVA_BUCKET), new ItemStack(Items.APPLE)),
|
||||
FURNACE_SEARCH(new ItemStack(Items.COMPASS)),
|
||||
FURNACE_FOOD(new ItemStack(Items.PORKCHOP)),
|
||||
FURNACE_BLOCKS(new ItemStack(Blocks.STONE)),
|
||||
FURNACE_MISC(new ItemStack(Items.LAVA_BUCKET), new ItemStack(Items.EMERALD)),
|
||||
BLAST_FURNACE_SEARCH(new ItemStack(Items.COMPASS)),
|
||||
BLAST_FURNACE_BLOCKS(new ItemStack(Blocks.REDSTONE_ORE)),
|
||||
BLAST_FURNACE_MISC(new ItemStack(Items.IRON_SHOVEL), new ItemStack(Items.GOLDEN_LEGGINGS)),
|
||||
SMOKER_SEARCH(new ItemStack(Items.COMPASS)),
|
||||
SMOKER_FOOD(new ItemStack(Items.PORKCHOP)),
|
||||
STONECUTTER(new ItemStack(Items.CHISELED_STONE_BRICKS)),
|
||||
SMITHING(new ItemStack(Items.NETHERITE_CHESTPLATE)),
|
||||
CAMPFIRE(new ItemStack(Items.PORKCHOP)),
|
||||
UNKNOWN(new ItemStack(Items.BARRIER));
|
||||
|
||||
public static final List<RecipeBookCategories> SMOKER_CATEGORIES = ImmutableList.of(SMOKER_SEARCH, SMOKER_FOOD);
|
||||
public static final List<RecipeBookCategories> BLAST_FURNACE_CATEGORIES = ImmutableList.of(BLAST_FURNACE_SEARCH, BLAST_FURNACE_BLOCKS, BLAST_FURNACE_MISC);
|
||||
public static final List<RecipeBookCategories> FURNACE_CATEGORIES = ImmutableList.of(FURNACE_SEARCH, FURNACE_FOOD, FURNACE_BLOCKS, FURNACE_MISC);
|
||||
public static final List<RecipeBookCategories> CRAFTING_CATEGORIES = ImmutableList.of(CRAFTING_SEARCH, CRAFTING_EQUIPMENT, CRAFTING_BUILDING_BLOCKS, CRAFTING_MISC, CRAFTING_REDSTONE);
|
||||
public static final Map<RecipeBookCategories, List<RecipeBookCategories>> AGGREGATE_CATEGORIES = net.minecraftforge.client.RecipeBookManager.getAggregateCategories();
|
||||
private final List<ItemStack> itemIcons;
|
||||
|
||||
private RecipeBookCategories(ItemStack... p_92267_) {
|
||||
this.itemIcons = ImmutableList.copyOf(p_92267_);
|
||||
}
|
||||
|
||||
public static List<RecipeBookCategories> getCategories(RecipeBookType p_92270_) {
|
||||
List list;
|
||||
switch (p_92270_) {
|
||||
case CRAFTING:
|
||||
list = CRAFTING_CATEGORIES;
|
||||
break;
|
||||
case FURNACE:
|
||||
list = FURNACE_CATEGORIES;
|
||||
break;
|
||||
case BLAST_FURNACE:
|
||||
list = BLAST_FURNACE_CATEGORIES;
|
||||
break;
|
||||
case SMOKER:
|
||||
list = SMOKER_CATEGORIES;
|
||||
break;
|
||||
default:
|
||||
return net.minecraftforge.client.RecipeBookManager.getCustomCategoriesOrEmpty(p_92270_);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<ItemStack> getIconItems() {
|
||||
return this.itemIcons;
|
||||
}
|
||||
|
||||
public static RecipeBookCategories create(String name, ItemStack... icons) {
|
||||
throw new IllegalStateException("Enum not extended");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.CrashReport;
|
||||
import net.minecraft.CrashReportCategory;
|
||||
import net.minecraft.server.packs.PackResources;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ResourceLoadStateTracker {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@Nullable
|
||||
private ResourceLoadStateTracker.ReloadState reloadState;
|
||||
private int reloadCount;
|
||||
|
||||
public void startReload(ResourceLoadStateTracker.ReloadReason p_168558_, List<PackResources> p_168559_) {
|
||||
++this.reloadCount;
|
||||
if (this.reloadState != null && !this.reloadState.finished) {
|
||||
LOGGER.warn("Reload already ongoing, replacing");
|
||||
}
|
||||
|
||||
this.reloadState = new ResourceLoadStateTracker.ReloadState(p_168558_, p_168559_.stream().map(PackResources::packId).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
|
||||
public void startRecovery(Throwable p_168561_) {
|
||||
if (this.reloadState == null) {
|
||||
LOGGER.warn("Trying to signal reload recovery, but nothing was started");
|
||||
this.reloadState = new ResourceLoadStateTracker.ReloadState(ResourceLoadStateTracker.ReloadReason.UNKNOWN, ImmutableList.of());
|
||||
}
|
||||
|
||||
this.reloadState.recoveryReloadInfo = new ResourceLoadStateTracker.RecoveryInfo(p_168561_);
|
||||
}
|
||||
|
||||
public void finishReload() {
|
||||
if (this.reloadState == null) {
|
||||
LOGGER.warn("Trying to finish reload, but nothing was started");
|
||||
} else {
|
||||
this.reloadState.finished = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void fillCrashReport(CrashReport p_168563_) {
|
||||
CrashReportCategory crashreportcategory = p_168563_.addCategory("Last reload");
|
||||
crashreportcategory.setDetail("Reload number", this.reloadCount);
|
||||
if (this.reloadState != null) {
|
||||
this.reloadState.fillCrashInfo(crashreportcategory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class RecoveryInfo {
|
||||
private final Throwable error;
|
||||
|
||||
RecoveryInfo(Throwable p_168566_) {
|
||||
this.error = p_168566_;
|
||||
}
|
||||
|
||||
public void fillCrashInfo(CrashReportCategory p_168569_) {
|
||||
p_168569_.setDetail("Recovery", "Yes");
|
||||
p_168569_.setDetail("Recovery reason", () -> {
|
||||
StringWriter stringwriter = new StringWriter();
|
||||
this.error.printStackTrace(new PrintWriter(stringwriter));
|
||||
return stringwriter.toString();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum ReloadReason {
|
||||
INITIAL("initial"),
|
||||
MANUAL("manual"),
|
||||
UNKNOWN("unknown");
|
||||
|
||||
final String name;
|
||||
|
||||
private ReloadReason(String p_168579_) {
|
||||
this.name = p_168579_;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class ReloadState {
|
||||
private final ResourceLoadStateTracker.ReloadReason reloadReason;
|
||||
private final List<String> packs;
|
||||
@Nullable
|
||||
ResourceLoadStateTracker.RecoveryInfo recoveryReloadInfo;
|
||||
boolean finished;
|
||||
|
||||
ReloadState(ResourceLoadStateTracker.ReloadReason p_168589_, List<String> p_168590_) {
|
||||
this.reloadReason = p_168589_;
|
||||
this.packs = p_168590_;
|
||||
}
|
||||
|
||||
public void fillCrashInfo(CrashReportCategory p_168593_) {
|
||||
p_168593_.setDetail("Reload reason", this.reloadReason.name);
|
||||
p_168593_.setDetail("Finished", this.finished ? "Yes" : "No");
|
||||
p_168593_.setDetail("Packs", () -> {
|
||||
return String.join(", ", this.packs);
|
||||
});
|
||||
if (this.recoveryReloadInfo != null) {
|
||||
this.recoveryReloadInfo.fillCrashInfo(p_168593_);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.mojang.blaze3d.pipeline.RenderTarget;
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.network.chat.ClickEvent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Screenshot {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final String SCREENSHOT_DIR = "screenshots";
|
||||
private int rowHeight;
|
||||
private final DataOutputStream outputStream;
|
||||
private final byte[] bytes;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private File file;
|
||||
|
||||
public static void grab(File p_92290_, RenderTarget p_92293_, Consumer<Component> p_92294_) {
|
||||
grab(p_92290_, (String)null, p_92293_, p_92294_);
|
||||
}
|
||||
|
||||
public static void grab(File p_92296_, @Nullable String p_92297_, RenderTarget p_92300_, Consumer<Component> p_92301_) {
|
||||
if (!RenderSystem.isOnRenderThread()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
_grab(p_92296_, p_92297_, p_92300_, p_92301_);
|
||||
});
|
||||
} else {
|
||||
_grab(p_92296_, p_92297_, p_92300_, p_92301_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void _grab(File p_92306_, @Nullable String p_92307_, RenderTarget p_92310_, Consumer<Component> p_92311_) {
|
||||
NativeImage nativeimage = takeScreenshot(p_92310_);
|
||||
File file1 = new File(p_92306_, "screenshots");
|
||||
file1.mkdir();
|
||||
File file2;
|
||||
if (p_92307_ == null) {
|
||||
file2 = getFile(file1);
|
||||
} else {
|
||||
file2 = new File(file1, p_92307_);
|
||||
}
|
||||
|
||||
net.minecraftforge.client.event.ScreenshotEvent event = net.minecraftforge.client.ForgeHooksClient.onScreenshot(nativeimage, file2);
|
||||
if (event.isCanceled()) {
|
||||
p_92311_.accept(event.getCancelMessage());
|
||||
return;
|
||||
}
|
||||
final File target = event.getScreenshotFile();
|
||||
|
||||
Util.ioPool().execute(() -> {
|
||||
try {
|
||||
nativeimage.writeToFile(target);
|
||||
Component component = Component.literal(file2.getName()).withStyle(ChatFormatting.UNDERLINE).withStyle((p_168608_) -> {
|
||||
return p_168608_.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, target.getAbsolutePath()));
|
||||
});
|
||||
if (event.getResultMessage() != null)
|
||||
p_92311_.accept(event.getResultMessage());
|
||||
else
|
||||
p_92311_.accept(Component.translatable("screenshot.success", component));
|
||||
} catch (Exception exception) {
|
||||
LOGGER.warn("Couldn't save screenshot", (Throwable)exception);
|
||||
p_92311_.accept(Component.translatable("screenshot.failure", exception.getMessage()));
|
||||
} finally {
|
||||
nativeimage.close();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public static NativeImage takeScreenshot(RenderTarget p_92282_) {
|
||||
int i = p_92282_.width;
|
||||
int j = p_92282_.height;
|
||||
NativeImage nativeimage = new NativeImage(i, j, false);
|
||||
RenderSystem.bindTexture(p_92282_.getColorTextureId());
|
||||
nativeimage.downloadTexture(0, true);
|
||||
nativeimage.flipY();
|
||||
return nativeimage;
|
||||
}
|
||||
|
||||
private static File getFile(File p_92288_) {
|
||||
String s = Util.getFilenameFormattedDateTime();
|
||||
int i = 1;
|
||||
|
||||
while(true) {
|
||||
File file1 = new File(p_92288_, s + (i == 1 ? "" : "_" + i) + ".png");
|
||||
if (!file1.exists()) {
|
||||
return file1;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
public Screenshot(File p_168601_, int p_168602_, int p_168603_, int p_168604_) throws IOException {
|
||||
this.width = p_168602_;
|
||||
this.height = p_168603_;
|
||||
this.rowHeight = p_168604_;
|
||||
File file1 = new File(p_168601_, "screenshots");
|
||||
file1.mkdir();
|
||||
String s = "huge_" + Util.getFilenameFormattedDateTime();
|
||||
|
||||
for(int i = 1; (this.file = new File(file1, s + (i == 1 ? "" : "_" + i) + ".tga")).exists(); ++i) {
|
||||
}
|
||||
|
||||
byte[] abyte = new byte[18];
|
||||
abyte[2] = 2;
|
||||
abyte[12] = (byte)(p_168602_ % 256);
|
||||
abyte[13] = (byte)(p_168602_ / 256);
|
||||
abyte[14] = (byte)(p_168603_ % 256);
|
||||
abyte[15] = (byte)(p_168603_ / 256);
|
||||
abyte[16] = 24;
|
||||
this.bytes = new byte[p_168602_ * p_168604_ * 3];
|
||||
this.outputStream = new DataOutputStream(new FileOutputStream(this.file));
|
||||
this.outputStream.write(abyte);
|
||||
}
|
||||
|
||||
public void addRegion(ByteBuffer p_168610_, int p_168611_, int p_168612_, int p_168613_, int p_168614_) {
|
||||
int i = p_168613_;
|
||||
int j = p_168614_;
|
||||
if (p_168613_ > this.width - p_168611_) {
|
||||
i = this.width - p_168611_;
|
||||
}
|
||||
|
||||
if (p_168614_ > this.height - p_168612_) {
|
||||
j = this.height - p_168612_;
|
||||
}
|
||||
|
||||
this.rowHeight = j;
|
||||
|
||||
for(int k = 0; k < j; ++k) {
|
||||
p_168610_.position((p_168614_ - j) * p_168613_ * 3 + k * p_168613_ * 3);
|
||||
int l = (p_168611_ + k * this.width) * 3;
|
||||
p_168610_.get(this.bytes, l, i * 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void saveRow() throws IOException {
|
||||
this.outputStream.write(this.bytes, 0, this.width * 3 * this.rowHeight);
|
||||
}
|
||||
|
||||
public File close() throws IOException {
|
||||
this.outputStream.close();
|
||||
return this.file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.network.chat.FormattedText;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.util.FormattedCharSink;
|
||||
import net.minecraft.util.StringDecomposer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.lang3.mutable.MutableFloat;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class StringSplitter {
|
||||
final StringSplitter.WidthProvider widthProvider;
|
||||
|
||||
public StringSplitter(StringSplitter.WidthProvider p_92335_) {
|
||||
this.widthProvider = p_92335_;
|
||||
}
|
||||
|
||||
public float stringWidth(@Nullable String p_92354_) {
|
||||
if (p_92354_ == null) {
|
||||
return 0.0F;
|
||||
} else {
|
||||
MutableFloat mutablefloat = new MutableFloat();
|
||||
StringDecomposer.iterateFormatted(p_92354_, Style.EMPTY, (p_92429_, p_92430_, p_92431_) -> {
|
||||
mutablefloat.add(this.widthProvider.getWidth(p_92431_, p_92430_));
|
||||
return true;
|
||||
});
|
||||
return mutablefloat.floatValue();
|
||||
}
|
||||
}
|
||||
|
||||
public float stringWidth(FormattedText p_92385_) {
|
||||
MutableFloat mutablefloat = new MutableFloat();
|
||||
StringDecomposer.iterateFormatted(p_92385_, Style.EMPTY, (p_92420_, p_92421_, p_92422_) -> {
|
||||
mutablefloat.add(this.widthProvider.getWidth(p_92422_, p_92421_));
|
||||
return true;
|
||||
});
|
||||
return mutablefloat.floatValue();
|
||||
}
|
||||
|
||||
public float stringWidth(FormattedCharSequence p_92337_) {
|
||||
MutableFloat mutablefloat = new MutableFloat();
|
||||
p_92337_.accept((p_92400_, p_92401_, p_92402_) -> {
|
||||
mutablefloat.add(this.widthProvider.getWidth(p_92402_, p_92401_));
|
||||
return true;
|
||||
});
|
||||
return mutablefloat.floatValue();
|
||||
}
|
||||
|
||||
public int plainIndexAtWidth(String p_92361_, int p_92362_, Style p_92363_) {
|
||||
StringSplitter.WidthLimitedCharSink stringsplitter$widthlimitedcharsink = new StringSplitter.WidthLimitedCharSink((float)p_92362_);
|
||||
StringDecomposer.iterate(p_92361_, p_92363_, stringsplitter$widthlimitedcharsink);
|
||||
return stringsplitter$widthlimitedcharsink.getPosition();
|
||||
}
|
||||
|
||||
public String plainHeadByWidth(String p_92411_, int p_92412_, Style p_92413_) {
|
||||
return p_92411_.substring(0, this.plainIndexAtWidth(p_92411_, p_92412_, p_92413_));
|
||||
}
|
||||
|
||||
public String plainTailByWidth(String p_92424_, int p_92425_, Style p_92426_) {
|
||||
MutableFloat mutablefloat = new MutableFloat();
|
||||
MutableInt mutableint = new MutableInt(p_92424_.length());
|
||||
StringDecomposer.iterateBackwards(p_92424_, p_92426_, (p_92407_, p_92408_, p_92409_) -> {
|
||||
float f = mutablefloat.addAndGet(this.widthProvider.getWidth(p_92409_, p_92408_));
|
||||
if (f > (float)p_92425_) {
|
||||
return false;
|
||||
} else {
|
||||
mutableint.setValue(p_92407_);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return p_92424_.substring(mutableint.intValue());
|
||||
}
|
||||
|
||||
public int formattedIndexByWidth(String p_168627_, int p_168628_, Style p_168629_) {
|
||||
StringSplitter.WidthLimitedCharSink stringsplitter$widthlimitedcharsink = new StringSplitter.WidthLimitedCharSink((float)p_168628_);
|
||||
StringDecomposer.iterateFormatted(p_168627_, p_168629_, stringsplitter$widthlimitedcharsink);
|
||||
return stringsplitter$widthlimitedcharsink.getPosition();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Style componentStyleAtWidth(FormattedText p_92387_, int p_92388_) {
|
||||
StringSplitter.WidthLimitedCharSink stringsplitter$widthlimitedcharsink = new StringSplitter.WidthLimitedCharSink((float)p_92388_);
|
||||
return p_92387_.visit((p_92343_, p_92344_) -> {
|
||||
return StringDecomposer.iterateFormatted(p_92344_, p_92343_, stringsplitter$widthlimitedcharsink) ? Optional.empty() : Optional.of(p_92343_);
|
||||
}, Style.EMPTY).orElse((Style)null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Style componentStyleAtWidth(FormattedCharSequence p_92339_, int p_92340_) {
|
||||
StringSplitter.WidthLimitedCharSink stringsplitter$widthlimitedcharsink = new StringSplitter.WidthLimitedCharSink((float)p_92340_);
|
||||
MutableObject<Style> mutableobject = new MutableObject<>();
|
||||
p_92339_.accept((p_92348_, p_92349_, p_92350_) -> {
|
||||
if (!stringsplitter$widthlimitedcharsink.accept(p_92348_, p_92349_, p_92350_)) {
|
||||
mutableobject.setValue(p_92349_);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return mutableobject.getValue();
|
||||
}
|
||||
|
||||
public String formattedHeadByWidth(String p_168631_, int p_168632_, Style p_168633_) {
|
||||
return p_168631_.substring(0, this.formattedIndexByWidth(p_168631_, p_168632_, p_168633_));
|
||||
}
|
||||
|
||||
public FormattedText headByWidth(FormattedText p_92390_, int p_92391_, Style p_92392_) {
|
||||
final StringSplitter.WidthLimitedCharSink stringsplitter$widthlimitedcharsink = new StringSplitter.WidthLimitedCharSink((float)p_92391_);
|
||||
return p_92390_.visit(new FormattedText.StyledContentConsumer<FormattedText>() {
|
||||
private final ComponentCollector collector = new ComponentCollector();
|
||||
|
||||
public Optional<FormattedText> accept(Style p_92443_, String p_92444_) {
|
||||
stringsplitter$widthlimitedcharsink.resetPosition();
|
||||
if (!StringDecomposer.iterateFormatted(p_92444_, p_92443_, stringsplitter$widthlimitedcharsink)) {
|
||||
String s = p_92444_.substring(0, stringsplitter$widthlimitedcharsink.getPosition());
|
||||
if (!s.isEmpty()) {
|
||||
this.collector.append(FormattedText.of(s, p_92443_));
|
||||
}
|
||||
|
||||
return Optional.of(this.collector.getResultOrEmpty());
|
||||
} else {
|
||||
if (!p_92444_.isEmpty()) {
|
||||
this.collector.append(FormattedText.of(p_92444_, p_92443_));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}, p_92392_).orElse(p_92390_);
|
||||
}
|
||||
|
||||
public int findLineBreak(String p_168635_, int p_168636_, Style p_168637_) {
|
||||
StringSplitter.LineBreakFinder stringsplitter$linebreakfinder = new StringSplitter.LineBreakFinder((float)p_168636_);
|
||||
StringDecomposer.iterateFormatted(p_168635_, p_168637_, stringsplitter$linebreakfinder);
|
||||
return stringsplitter$linebreakfinder.getSplitPosition();
|
||||
}
|
||||
|
||||
public static int getWordPosition(String p_92356_, int p_92357_, int p_92358_, boolean p_92359_) {
|
||||
int i = p_92358_;
|
||||
boolean flag = p_92357_ < 0;
|
||||
int j = Math.abs(p_92357_);
|
||||
|
||||
for(int k = 0; k < j; ++k) {
|
||||
if (flag) {
|
||||
while(p_92359_ && i > 0 && (p_92356_.charAt(i - 1) == ' ' || p_92356_.charAt(i - 1) == '\n')) {
|
||||
--i;
|
||||
}
|
||||
|
||||
while(i > 0 && p_92356_.charAt(i - 1) != ' ' && p_92356_.charAt(i - 1) != '\n') {
|
||||
--i;
|
||||
}
|
||||
} else {
|
||||
int l = p_92356_.length();
|
||||
int i1 = p_92356_.indexOf(32, i);
|
||||
int j1 = p_92356_.indexOf(10, i);
|
||||
if (i1 == -1 && j1 == -1) {
|
||||
i = -1;
|
||||
} else if (i1 != -1 && j1 != -1) {
|
||||
i = Math.min(i1, j1);
|
||||
} else if (i1 != -1) {
|
||||
i = i1;
|
||||
} else {
|
||||
i = j1;
|
||||
}
|
||||
|
||||
if (i == -1) {
|
||||
i = l;
|
||||
} else {
|
||||
while(p_92359_ && i < l && (p_92356_.charAt(i) == ' ' || p_92356_.charAt(i) == '\n')) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public void splitLines(String p_92365_, int p_92366_, Style p_92367_, boolean p_92368_, StringSplitter.LinePosConsumer p_92369_) {
|
||||
int i = 0;
|
||||
int j = p_92365_.length();
|
||||
|
||||
StringSplitter.LineBreakFinder stringsplitter$linebreakfinder;
|
||||
for(Style style = p_92367_; i < j; style = stringsplitter$linebreakfinder.getSplitStyle()) {
|
||||
stringsplitter$linebreakfinder = new StringSplitter.LineBreakFinder((float)p_92366_);
|
||||
boolean flag = StringDecomposer.iterateFormatted(p_92365_, i, style, p_92367_, stringsplitter$linebreakfinder);
|
||||
if (flag) {
|
||||
p_92369_.accept(style, i, j);
|
||||
break;
|
||||
}
|
||||
|
||||
int k = stringsplitter$linebreakfinder.getSplitPosition();
|
||||
char c0 = p_92365_.charAt(k);
|
||||
int l = c0 != '\n' && c0 != ' ' ? k : k + 1;
|
||||
p_92369_.accept(style, i, p_92368_ ? l : k);
|
||||
i = l;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<FormattedText> splitLines(String p_92433_, int p_92434_, Style p_92435_) {
|
||||
List<FormattedText> list = Lists.newArrayList();
|
||||
this.splitLines(p_92433_, p_92434_, p_92435_, false, (p_92373_, p_92374_, p_92375_) -> {
|
||||
list.add(FormattedText.of(p_92433_.substring(p_92374_, p_92375_), p_92373_));
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<FormattedText> splitLines(FormattedText p_92415_, int p_92416_, Style p_92417_) {
|
||||
List<FormattedText> list = Lists.newArrayList();
|
||||
this.splitLines(p_92415_, p_92416_, p_92417_, (p_92378_, p_92379_) -> {
|
||||
list.add(p_92378_);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<FormattedText> splitLines(FormattedText p_168622_, int p_168623_, Style p_168624_, FormattedText p_168625_) {
|
||||
List<FormattedText> list = Lists.newArrayList();
|
||||
this.splitLines(p_168622_, p_168623_, p_168624_, (p_168619_, p_168620_) -> {
|
||||
list.add(p_168620_ ? FormattedText.composite(p_168625_, p_168619_) : p_168619_);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public void splitLines(FormattedText p_92394_, int p_92395_, Style p_92396_, BiConsumer<FormattedText, Boolean> p_92397_) {
|
||||
List<StringSplitter.LineComponent> list = Lists.newArrayList();
|
||||
p_92394_.visit((p_92382_, p_92383_) -> {
|
||||
if (!p_92383_.isEmpty()) {
|
||||
list.add(new StringSplitter.LineComponent(p_92383_, p_92382_));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}, p_92396_);
|
||||
StringSplitter.FlatComponents stringsplitter$flatcomponents = new StringSplitter.FlatComponents(list);
|
||||
boolean flag = true;
|
||||
boolean flag1 = false;
|
||||
boolean flag2 = false;
|
||||
|
||||
while(flag) {
|
||||
flag = false;
|
||||
StringSplitter.LineBreakFinder stringsplitter$linebreakfinder = new StringSplitter.LineBreakFinder((float)p_92395_);
|
||||
|
||||
for(StringSplitter.LineComponent stringsplitter$linecomponent : stringsplitter$flatcomponents.parts) {
|
||||
boolean flag3 = StringDecomposer.iterateFormatted(stringsplitter$linecomponent.contents, 0, stringsplitter$linecomponent.style, p_92396_, stringsplitter$linebreakfinder);
|
||||
if (!flag3) {
|
||||
int i = stringsplitter$linebreakfinder.getSplitPosition();
|
||||
Style style = stringsplitter$linebreakfinder.getSplitStyle();
|
||||
char c0 = stringsplitter$flatcomponents.charAt(i);
|
||||
boolean flag4 = c0 == '\n';
|
||||
boolean flag5 = flag4 || c0 == ' ';
|
||||
flag1 = flag4;
|
||||
FormattedText formattedtext = stringsplitter$flatcomponents.splitAt(i, flag5 ? 1 : 0, style);
|
||||
p_92397_.accept(formattedtext, flag2);
|
||||
flag2 = !flag4;
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
|
||||
stringsplitter$linebreakfinder.addToOffset(stringsplitter$linecomponent.contents.length());
|
||||
}
|
||||
}
|
||||
|
||||
FormattedText formattedtext1 = stringsplitter$flatcomponents.getRemainder();
|
||||
if (formattedtext1 != null) {
|
||||
p_92397_.accept(formattedtext1, flag2);
|
||||
} else if (flag1) {
|
||||
p_92397_.accept(FormattedText.EMPTY, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class FlatComponents {
|
||||
final List<StringSplitter.LineComponent> parts;
|
||||
private String flatParts;
|
||||
|
||||
public FlatComponents(List<StringSplitter.LineComponent> p_92448_) {
|
||||
this.parts = p_92448_;
|
||||
this.flatParts = p_92448_.stream().map((p_92459_) -> {
|
||||
return p_92459_.contents;
|
||||
}).collect(Collectors.joining());
|
||||
}
|
||||
|
||||
public char charAt(int p_92451_) {
|
||||
return this.flatParts.charAt(p_92451_);
|
||||
}
|
||||
|
||||
public FormattedText splitAt(int p_92453_, int p_92454_, Style p_92455_) {
|
||||
ComponentCollector componentcollector = new ComponentCollector();
|
||||
ListIterator<StringSplitter.LineComponent> listiterator = this.parts.listIterator();
|
||||
int i = p_92453_;
|
||||
boolean flag = false;
|
||||
|
||||
while(listiterator.hasNext()) {
|
||||
StringSplitter.LineComponent stringsplitter$linecomponent = listiterator.next();
|
||||
String s = stringsplitter$linecomponent.contents;
|
||||
int j = s.length();
|
||||
if (!flag) {
|
||||
if (i > j) {
|
||||
componentcollector.append(stringsplitter$linecomponent);
|
||||
listiterator.remove();
|
||||
i -= j;
|
||||
} else {
|
||||
String s1 = s.substring(0, i);
|
||||
if (!s1.isEmpty()) {
|
||||
componentcollector.append(FormattedText.of(s1, stringsplitter$linecomponent.style));
|
||||
}
|
||||
|
||||
i += p_92454_;
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
if (i <= j) {
|
||||
String s2 = s.substring(i);
|
||||
if (s2.isEmpty()) {
|
||||
listiterator.remove();
|
||||
} else {
|
||||
listiterator.set(new StringSplitter.LineComponent(s2, p_92455_));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
listiterator.remove();
|
||||
i -= j;
|
||||
}
|
||||
}
|
||||
|
||||
this.flatParts = this.flatParts.substring(p_92453_ + p_92454_);
|
||||
return componentcollector.getResultOrEmpty();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FormattedText getRemainder() {
|
||||
ComponentCollector componentcollector = new ComponentCollector();
|
||||
this.parts.forEach(componentcollector::append);
|
||||
this.parts.clear();
|
||||
return componentcollector.getResult();
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class LineBreakFinder implements FormattedCharSink {
|
||||
private final float maxWidth;
|
||||
private int lineBreak = -1;
|
||||
private Style lineBreakStyle = Style.EMPTY;
|
||||
private boolean hadNonZeroWidthChar;
|
||||
private float width;
|
||||
private int lastSpace = -1;
|
||||
private Style lastSpaceStyle = Style.EMPTY;
|
||||
private int nextChar;
|
||||
private int offset;
|
||||
|
||||
public LineBreakFinder(float p_92472_) {
|
||||
this.maxWidth = Math.max(p_92472_, 1.0F);
|
||||
}
|
||||
|
||||
public boolean accept(int p_92480_, Style p_92481_, int p_92482_) {
|
||||
int i = p_92480_ + this.offset;
|
||||
switch (p_92482_) {
|
||||
case 10:
|
||||
return this.finishIteration(i, p_92481_);
|
||||
case 32:
|
||||
this.lastSpace = i;
|
||||
this.lastSpaceStyle = p_92481_;
|
||||
default:
|
||||
float f = StringSplitter.this.widthProvider.getWidth(p_92482_, p_92481_);
|
||||
this.width += f;
|
||||
if (this.hadNonZeroWidthChar && this.width > this.maxWidth) {
|
||||
return this.lastSpace != -1 ? this.finishIteration(this.lastSpace, this.lastSpaceStyle) : this.finishIteration(i, p_92481_);
|
||||
} else {
|
||||
this.hadNonZeroWidthChar |= f != 0.0F;
|
||||
this.nextChar = i + Character.charCount(p_92482_);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean finishIteration(int p_92477_, Style p_92478_) {
|
||||
this.lineBreak = p_92477_;
|
||||
this.lineBreakStyle = p_92478_;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean lineBreakFound() {
|
||||
return this.lineBreak != -1;
|
||||
}
|
||||
|
||||
public int getSplitPosition() {
|
||||
return this.lineBreakFound() ? this.lineBreak : this.nextChar;
|
||||
}
|
||||
|
||||
public Style getSplitStyle() {
|
||||
return this.lineBreakStyle;
|
||||
}
|
||||
|
||||
public void addToOffset(int p_92475_) {
|
||||
this.offset += p_92475_;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class LineComponent implements FormattedText {
|
||||
final String contents;
|
||||
final Style style;
|
||||
|
||||
public LineComponent(String p_92488_, Style p_92489_) {
|
||||
this.contents = p_92488_;
|
||||
this.style = p_92489_;
|
||||
}
|
||||
|
||||
public <T> Optional<T> visit(FormattedText.ContentConsumer<T> p_92493_) {
|
||||
return p_92493_.accept(this.contents);
|
||||
}
|
||||
|
||||
public <T> Optional<T> visit(FormattedText.StyledContentConsumer<T> p_92495_, Style p_92496_) {
|
||||
return p_92495_.accept(this.style.applyTo(p_92496_), this.contents);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface LinePosConsumer {
|
||||
void accept(Style p_92500_, int p_92501_, int p_92502_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class WidthLimitedCharSink implements FormattedCharSink {
|
||||
private float maxWidth;
|
||||
private int position;
|
||||
|
||||
public WidthLimitedCharSink(float p_92508_) {
|
||||
this.maxWidth = p_92508_;
|
||||
}
|
||||
|
||||
public boolean accept(int p_92511_, Style p_92512_, int p_92513_) {
|
||||
this.maxWidth -= StringSplitter.this.widthProvider.getWidth(p_92513_, p_92512_);
|
||||
if (this.maxWidth >= 0.0F) {
|
||||
this.position = p_92511_ + Character.charCount(p_92513_);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public void resetPosition() {
|
||||
this.position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface WidthProvider {
|
||||
float getWidth(int p_92516_, Style p_92517_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Timer {
|
||||
public float partialTick;
|
||||
public float tickDelta;
|
||||
private long lastMs;
|
||||
private final float msPerTick;
|
||||
|
||||
public Timer(float p_92523_, long p_92524_) {
|
||||
this.msPerTick = 1000.0F / p_92523_;
|
||||
this.lastMs = p_92524_;
|
||||
}
|
||||
|
||||
public int advanceTime(long p_92526_) {
|
||||
this.tickDelta = (float)(p_92526_ - this.lastMs) / this.msPerTick;
|
||||
this.lastMs = p_92526_;
|
||||
this.partialTick += this.tickDelta;
|
||||
int i = (int)this.partialTick;
|
||||
this.partialTick -= (float)i;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ToggleKeyMapping extends KeyMapping {
|
||||
private final BooleanSupplier needsToggle;
|
||||
|
||||
public ToggleKeyMapping(String p_92529_, int p_92530_, String p_92531_, BooleanSupplier p_92532_) {
|
||||
super(p_92529_, InputConstants.Type.KEYSYM, p_92530_, p_92531_);
|
||||
this.needsToggle = p_92532_;
|
||||
}
|
||||
|
||||
public void setDown(boolean p_92534_) {
|
||||
if (this.needsToggle.getAsBoolean()) {
|
||||
if (p_92534_ && isConflictContextAndModifierActive()) {
|
||||
super.setDown(!this.isDown());
|
||||
}
|
||||
} else {
|
||||
super.setDown(p_92534_);
|
||||
}
|
||||
|
||||
}
|
||||
@Override public boolean isDown() { return this.isDown && (isConflictContextAndModifierActive() || needsToggle.getAsBoolean()); }
|
||||
|
||||
protected void reset() {
|
||||
super.setDown(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package net.minecraft.client;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.util.UUIDTypeAdapter;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class User {
|
||||
private final String name;
|
||||
private final String uuid;
|
||||
private final String accessToken;
|
||||
private final Optional<String> xuid;
|
||||
private final Optional<String> clientId;
|
||||
private final User.Type type;
|
||||
/** Forge: Cache of the local session's GameProfile properties. */
|
||||
private com.mojang.authlib.properties.PropertyMap properties;
|
||||
|
||||
public User(String p_193799_, String p_193800_, String p_193801_, Optional<String> p_193802_, Optional<String> p_193803_, User.Type p_193804_) {
|
||||
if (p_193799_ == null || p_193799_.isEmpty()) {
|
||||
p_193799_ = "MissingName";
|
||||
p_193800_ = p_193801_ = "NotValid";
|
||||
org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getLogger(getClass().getName());
|
||||
logger.warn("=========================================================");
|
||||
logger.warn("WARNING!! the username was not set for this session, typically");
|
||||
logger.warn("this means you installed Forge incorrectly. We have set your");
|
||||
logger.warn("name to \"MissingName\" and your session to nothing. Please");
|
||||
logger.warn("check your installation and post a console log from the launcher");
|
||||
logger.warn("when asking for help!");
|
||||
logger.warn("=========================================================");
|
||||
}
|
||||
this.name = p_193799_;
|
||||
this.uuid = p_193800_;
|
||||
this.accessToken = p_193801_;
|
||||
this.xuid = p_193802_;
|
||||
this.clientId = p_193803_;
|
||||
this.type = p_193804_;
|
||||
}
|
||||
|
||||
public String getSessionId() {
|
||||
return "token:" + this.accessToken + ":" + this.uuid;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return this.accessToken;
|
||||
}
|
||||
|
||||
public Optional<String> getClientId() {
|
||||
return this.clientId;
|
||||
}
|
||||
|
||||
public Optional<String> getXuid() {
|
||||
return this.xuid;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public UUID getProfileId() {
|
||||
try {
|
||||
return UUIDTypeAdapter.fromString(this.getUuid());
|
||||
} catch (IllegalArgumentException illegalargumentexception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//For internal use only. Modders should never need to use this.
|
||||
public void setProperties(com.mojang.authlib.properties.PropertyMap properties) {
|
||||
if (this.properties == null)
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public boolean hasCachedProperties() {
|
||||
return properties != null;
|
||||
}
|
||||
|
||||
public GameProfile getGameProfile() {
|
||||
// FORGE: Add cached GameProfile properties to returned GameProfile. This helps to cut down on calls to the session service.
|
||||
GameProfile ret = new GameProfile(this.getProfileId(), this.getName());
|
||||
if (this.properties != null)
|
||||
ret.getProperties().putAll(this.properties);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public User.Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Type {
|
||||
LEGACY("legacy"),
|
||||
MOJANG("mojang"),
|
||||
MSA("msa");
|
||||
|
||||
private static final Map<String, User.Type> BY_NAME = Arrays.stream(values()).collect(Collectors.toMap((p_92560_) -> {
|
||||
return p_92560_.name;
|
||||
}, Function.identity()));
|
||||
private final String name;
|
||||
|
||||
private Type(String p_92558_) {
|
||||
this.name = p_92558_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static User.Type byName(String p_92562_) {
|
||||
return BY_NAME.get(p_92562_.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package net.minecraft.client.animation;
|
||||
|
||||
import net.minecraft.client.model.geom.ModelPart;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public record AnimationChannel(AnimationChannel.Target target, Keyframe... keyframes) {
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface Interpolation {
|
||||
Vector3f apply(Vector3f p_253818_, float p_232224_, Keyframe[] p_232225_, int p_232226_, int p_232227_, float p_232228_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Interpolations {
|
||||
public static final AnimationChannel.Interpolation LINEAR = (p_253292_, p_253293_, p_253294_, p_253295_, p_253296_, p_253297_) -> {
|
||||
Vector3f vector3f = p_253294_[p_253295_].target();
|
||||
Vector3f vector3f1 = p_253294_[p_253296_].target();
|
||||
return vector3f.lerp(vector3f1, p_253293_, p_253292_).mul(p_253297_);
|
||||
};
|
||||
public static final AnimationChannel.Interpolation CATMULLROM = (p_254076_, p_232235_, p_232236_, p_232237_, p_232238_, p_232239_) -> {
|
||||
Vector3f vector3f = p_232236_[Math.max(0, p_232237_ - 1)].target();
|
||||
Vector3f vector3f1 = p_232236_[p_232237_].target();
|
||||
Vector3f vector3f2 = p_232236_[p_232238_].target();
|
||||
Vector3f vector3f3 = p_232236_[Math.min(p_232236_.length - 1, p_232238_ + 1)].target();
|
||||
p_254076_.set(Mth.catmullrom(p_232235_, vector3f.x(), vector3f1.x(), vector3f2.x(), vector3f3.x()) * p_232239_, Mth.catmullrom(p_232235_, vector3f.y(), vector3f1.y(), vector3f2.y(), vector3f3.y()) * p_232239_, Mth.catmullrom(p_232235_, vector3f.z(), vector3f1.z(), vector3f2.z(), vector3f3.z()) * p_232239_);
|
||||
return p_254076_;
|
||||
};
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface Target {
|
||||
void apply(ModelPart p_232248_, Vector3f p_253771_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Targets {
|
||||
public static final AnimationChannel.Target POSITION = ModelPart::offsetPos;
|
||||
public static final AnimationChannel.Target ROTATION = ModelPart::offsetRotation;
|
||||
public static final AnimationChannel.Target SCALE = ModelPart::offsetScale;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package net.minecraft.client.animation;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.compress.utils.Lists;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public record AnimationDefinition(float lengthInSeconds, boolean looping, Map<String, List<AnimationChannel>> boneAnimations) {
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Builder {
|
||||
private final float length;
|
||||
private final Map<String, List<AnimationChannel>> animationByBone = Maps.newHashMap();
|
||||
private boolean looping;
|
||||
|
||||
public static AnimationDefinition.Builder withLength(float p_232276_) {
|
||||
return new AnimationDefinition.Builder(p_232276_);
|
||||
}
|
||||
|
||||
private Builder(float p_232273_) {
|
||||
this.length = p_232273_;
|
||||
}
|
||||
|
||||
public AnimationDefinition.Builder looping() {
|
||||
this.looping = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnimationDefinition.Builder addAnimation(String p_232280_, AnimationChannel p_232281_) {
|
||||
this.animationByBone.computeIfAbsent(p_232280_, (p_232278_) -> {
|
||||
return Lists.newArrayList();
|
||||
}).add(p_232281_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnimationDefinition build() {
|
||||
return new AnimationDefinition(this.length, this.looping, this.animationByBone);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.minecraft.client.animation;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public record Keyframe(float timestamp, Vector3f target, AnimationChannel.Interpolation interpolation) {
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package net.minecraft.client.animation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.client.model.HierarchicalModel;
|
||||
import net.minecraft.client.model.geom.ModelPart;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class KeyframeAnimations {
|
||||
public static void animate(HierarchicalModel<?> p_232320_, AnimationDefinition p_232321_, long p_232322_, float p_232323_, Vector3f p_253861_) {
|
||||
float f = getElapsedSeconds(p_232321_, p_232322_);
|
||||
|
||||
for(Map.Entry<String, List<AnimationChannel>> entry : p_232321_.boneAnimations().entrySet()) {
|
||||
Optional<ModelPart> optional = p_232320_.getAnyDescendantWithName(entry.getKey());
|
||||
List<AnimationChannel> list = entry.getValue();
|
||||
optional.ifPresent((p_232330_) -> {
|
||||
list.forEach((p_288241_) -> {
|
||||
Keyframe[] akeyframe = p_288241_.keyframes();
|
||||
int i = Math.max(0, Mth.binarySearch(0, akeyframe.length, (p_232315_) -> {
|
||||
return f <= akeyframe[p_232315_].timestamp();
|
||||
}) - 1);
|
||||
int j = Math.min(akeyframe.length - 1, i + 1);
|
||||
Keyframe keyframe = akeyframe[i];
|
||||
Keyframe keyframe1 = akeyframe[j];
|
||||
float f1 = f - keyframe.timestamp();
|
||||
float f2;
|
||||
if (j != i) {
|
||||
f2 = Mth.clamp(f1 / (keyframe1.timestamp() - keyframe.timestamp()), 0.0F, 1.0F);
|
||||
} else {
|
||||
f2 = 0.0F;
|
||||
}
|
||||
|
||||
keyframe1.interpolation().apply(p_253861_, f2, akeyframe, i, j, p_232323_);
|
||||
p_288241_.target().apply(p_232330_, p_253861_);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static float getElapsedSeconds(AnimationDefinition p_232317_, long p_232318_) {
|
||||
float f = (float)p_232318_ / 1000.0F;
|
||||
return p_232317_.looping() ? f % p_232317_.lengthInSeconds() : f;
|
||||
}
|
||||
|
||||
public static Vector3f posVec(float p_253691_, float p_254046_, float p_254461_) {
|
||||
return new Vector3f(p_253691_, -p_254046_, p_254461_);
|
||||
}
|
||||
|
||||
public static Vector3f degreeVec(float p_254402_, float p_253917_, float p_254397_) {
|
||||
return new Vector3f(p_254402_ * ((float)Math.PI / 180F), p_253917_ * ((float)Math.PI / 180F), p_254397_ * ((float)Math.PI / 180F));
|
||||
}
|
||||
|
||||
public static Vector3f scaleVec(double p_253806_, double p_253647_, double p_254396_) {
|
||||
return new Vector3f((float)(p_253806_ - 1.0D), (float)(p_253647_ - 1.0D), (float)(p_254396_ - 1.0D));
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package net.minecraft.client.animation.definitions;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package net.minecraft.client.animation;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.minecraft.client.color.block;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface BlockColor {
|
||||
int getColor(BlockState p_92567_, @Nullable BlockAndTintGetter p_92568_, @Nullable BlockPos p_92569_, int p_92570_);
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package net.minecraft.client.color.block;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.renderer.BiomeColors;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.IdMapper;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.FoliageColor;
|
||||
import net.minecraft.world.level.GrassColor;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.DoublePlantBlock;
|
||||
import net.minecraft.world.level.block.RedStoneWireBlock;
|
||||
import net.minecraft.world.level.block.StemBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.MapColor;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class BlockColors {
|
||||
private static final int DEFAULT = -1;
|
||||
// FORGE: Use registry delegate as non-Vanilla block ids are not constant
|
||||
private final java.util.Map<net.minecraft.core.Holder.Reference<Block>, BlockColor> blockColors = new java.util.HashMap<>();
|
||||
private final Map<Block, Set<Property<?>>> coloringStates = Maps.newHashMap();
|
||||
|
||||
public static BlockColors createDefault() {
|
||||
BlockColors blockcolors = new BlockColors();
|
||||
blockcolors.register((p_276233_, p_276234_, p_276235_, p_276236_) -> {
|
||||
return p_276234_ != null && p_276235_ != null ? BiomeColors.getAverageGrassColor(p_276234_, p_276233_.getValue(DoublePlantBlock.HALF) == DoubleBlockHalf.UPPER ? p_276235_.below() : p_276235_) : GrassColor.getDefaultColor();
|
||||
}, Blocks.LARGE_FERN, Blocks.TALL_GRASS);
|
||||
blockcolors.addColoringState(DoublePlantBlock.HALF, Blocks.LARGE_FERN, Blocks.TALL_GRASS);
|
||||
blockcolors.register((p_276237_, p_276238_, p_276239_, p_276240_) -> {
|
||||
return p_276238_ != null && p_276239_ != null ? BiomeColors.getAverageGrassColor(p_276238_, p_276239_) : GrassColor.getDefaultColor();
|
||||
}, Blocks.GRASS_BLOCK, Blocks.FERN, Blocks.GRASS, Blocks.POTTED_FERN);
|
||||
blockcolors.register((p_276241_, p_276242_, p_276243_, p_276244_) -> {
|
||||
if (p_276244_ != 0) {
|
||||
return p_276242_ != null && p_276243_ != null ? BiomeColors.getAverageGrassColor(p_276242_, p_276243_) : GrassColor.getDefaultColor();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}, Blocks.PINK_PETALS);
|
||||
blockcolors.register((p_92636_, p_92637_, p_92638_, p_92639_) -> {
|
||||
return FoliageColor.getEvergreenColor();
|
||||
}, Blocks.SPRUCE_LEAVES);
|
||||
blockcolors.register((p_92631_, p_92632_, p_92633_, p_92634_) -> {
|
||||
return FoliageColor.getBirchColor();
|
||||
}, Blocks.BIRCH_LEAVES);
|
||||
blockcolors.register((p_92626_, p_92627_, p_92628_, p_92629_) -> {
|
||||
return p_92627_ != null && p_92628_ != null ? BiomeColors.getAverageFoliageColor(p_92627_, p_92628_) : FoliageColor.getDefaultColor();
|
||||
}, Blocks.OAK_LEAVES, Blocks.JUNGLE_LEAVES, Blocks.ACACIA_LEAVES, Blocks.DARK_OAK_LEAVES, Blocks.VINE, Blocks.MANGROVE_LEAVES);
|
||||
blockcolors.register((p_92621_, p_92622_, p_92623_, p_92624_) -> {
|
||||
return p_92622_ != null && p_92623_ != null ? BiomeColors.getAverageWaterColor(p_92622_, p_92623_) : -1;
|
||||
}, Blocks.WATER, Blocks.BUBBLE_COLUMN, Blocks.WATER_CAULDRON);
|
||||
blockcolors.register((p_92616_, p_92617_, p_92618_, p_92619_) -> {
|
||||
return RedStoneWireBlock.getColorForPower(p_92616_.getValue(RedStoneWireBlock.POWER));
|
||||
}, Blocks.REDSTONE_WIRE);
|
||||
blockcolors.addColoringState(RedStoneWireBlock.POWER, Blocks.REDSTONE_WIRE);
|
||||
blockcolors.register((p_92611_, p_92612_, p_92613_, p_92614_) -> {
|
||||
return p_92612_ != null && p_92613_ != null ? BiomeColors.getAverageGrassColor(p_92612_, p_92613_) : -1;
|
||||
}, Blocks.SUGAR_CANE);
|
||||
blockcolors.register((p_92606_, p_92607_, p_92608_, p_92609_) -> {
|
||||
return 14731036;
|
||||
}, Blocks.ATTACHED_MELON_STEM, Blocks.ATTACHED_PUMPKIN_STEM);
|
||||
blockcolors.register((p_92601_, p_92602_, p_92603_, p_92604_) -> {
|
||||
int i = p_92601_.getValue(StemBlock.AGE);
|
||||
int j = i * 32;
|
||||
int k = 255 - i * 8;
|
||||
int l = i * 4;
|
||||
return j << 16 | k << 8 | l;
|
||||
}, Blocks.MELON_STEM, Blocks.PUMPKIN_STEM);
|
||||
blockcolors.addColoringState(StemBlock.AGE, Blocks.MELON_STEM, Blocks.PUMPKIN_STEM);
|
||||
blockcolors.register((p_92596_, p_92597_, p_92598_, p_92599_) -> {
|
||||
return p_92597_ != null && p_92598_ != null ? 2129968 : 7455580;
|
||||
}, Blocks.LILY_PAD);
|
||||
net.minecraftforge.client.ForgeHooksClient.onBlockColorsInit(blockcolors);
|
||||
return blockcolors;
|
||||
}
|
||||
|
||||
public int getColor(BlockState p_92583_, Level p_92584_, BlockPos p_92585_) {
|
||||
BlockColor blockcolor = this.blockColors.get(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(p_92583_.getBlock()));
|
||||
if (blockcolor != null) {
|
||||
return blockcolor.getColor(p_92583_, (BlockAndTintGetter)null, (BlockPos)null, 0);
|
||||
} else {
|
||||
MapColor mapcolor = p_92583_.getMapColor(p_92584_, p_92585_);
|
||||
return mapcolor != null ? mapcolor.col : -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getColor(BlockState p_92578_, @Nullable BlockAndTintGetter p_92579_, @Nullable BlockPos p_92580_, int p_92581_) {
|
||||
BlockColor blockcolor = this.blockColors.get(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(p_92578_.getBlock()));
|
||||
return blockcolor == null ? -1 : blockcolor.getColor(p_92578_, p_92579_, p_92580_, p_92581_);
|
||||
}
|
||||
|
||||
/** @deprecated Register via {@link net.minecraftforge.client.event.RegisterColorHandlersEvent.Block} */
|
||||
@Deprecated
|
||||
public void register(BlockColor p_92590_, Block... p_92591_) {
|
||||
for(Block block : p_92591_) {
|
||||
this.blockColors.put(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(block), p_92590_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addColoringStates(Set<Property<?>> p_92593_, Block... p_92594_) {
|
||||
for(Block block : p_92594_) {
|
||||
this.coloringStates.put(block, p_92593_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addColoringState(Property<?> p_92587_, Block... p_92588_) {
|
||||
this.addColoringStates(ImmutableSet.of(p_92587_), p_92588_);
|
||||
}
|
||||
|
||||
public Set<Property<?>> getColoringProperties(Block p_92576_) {
|
||||
return this.coloringStates.getOrDefault(p_92576_, ImmutableSet.of());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package net.minecraft.client.color.block;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.ToIntFunction;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class BlockTintCache {
|
||||
private static final int MAX_CACHE_ENTRIES = 256;
|
||||
private final ThreadLocal<BlockTintCache.LatestCacheInfo> latestChunkOnThread = ThreadLocal.withInitial(BlockTintCache.LatestCacheInfo::new);
|
||||
private final Long2ObjectLinkedOpenHashMap<BlockTintCache.CacheData> cache = new Long2ObjectLinkedOpenHashMap<>(256, 0.25F);
|
||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
private final ToIntFunction<BlockPos> source;
|
||||
|
||||
public BlockTintCache(ToIntFunction<BlockPos> p_193811_) {
|
||||
this.source = p_193811_;
|
||||
}
|
||||
|
||||
public int getColor(BlockPos p_193813_) {
|
||||
int i = SectionPos.blockToSectionCoord(p_193813_.getX());
|
||||
int j = SectionPos.blockToSectionCoord(p_193813_.getZ());
|
||||
BlockTintCache.LatestCacheInfo blocktintcache$latestcacheinfo = this.latestChunkOnThread.get();
|
||||
if (blocktintcache$latestcacheinfo.x != i || blocktintcache$latestcacheinfo.z != j || blocktintcache$latestcacheinfo.cache == null || blocktintcache$latestcacheinfo.cache.isInvalidated()) {
|
||||
blocktintcache$latestcacheinfo.x = i;
|
||||
blocktintcache$latestcacheinfo.z = j;
|
||||
blocktintcache$latestcacheinfo.cache = this.findOrCreateChunkCache(i, j);
|
||||
}
|
||||
|
||||
int[] aint = blocktintcache$latestcacheinfo.cache.getLayer(p_193813_.getY());
|
||||
int k = p_193813_.getX() & 15;
|
||||
int l = p_193813_.getZ() & 15;
|
||||
int i1 = l << 4 | k;
|
||||
int j1 = aint[i1];
|
||||
if (j1 != -1) {
|
||||
return j1;
|
||||
} else {
|
||||
int k1 = this.source.applyAsInt(p_193813_);
|
||||
aint[i1] = k1;
|
||||
return k1;
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidateForChunk(int p_92656_, int p_92657_) {
|
||||
try {
|
||||
this.lock.writeLock().lock();
|
||||
|
||||
for(int i = -1; i <= 1; ++i) {
|
||||
for(int j = -1; j <= 1; ++j) {
|
||||
long k = ChunkPos.asLong(p_92656_ + i, p_92657_ + j);
|
||||
BlockTintCache.CacheData blocktintcache$cachedata = this.cache.remove(k);
|
||||
if (blocktintcache$cachedata != null) {
|
||||
blocktintcache$cachedata.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.lock.writeLock().unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void invalidateAll() {
|
||||
try {
|
||||
this.lock.writeLock().lock();
|
||||
this.cache.values().forEach(BlockTintCache.CacheData::invalidate);
|
||||
this.cache.clear();
|
||||
} finally {
|
||||
this.lock.writeLock().unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private BlockTintCache.CacheData findOrCreateChunkCache(int p_193815_, int p_193816_) {
|
||||
long i = ChunkPos.asLong(p_193815_, p_193816_);
|
||||
this.lock.readLock().lock();
|
||||
|
||||
try {
|
||||
BlockTintCache.CacheData blocktintcache$cachedata = this.cache.get(i);
|
||||
if (blocktintcache$cachedata != null) {
|
||||
return blocktintcache$cachedata;
|
||||
}
|
||||
} finally {
|
||||
this.lock.readLock().unlock();
|
||||
}
|
||||
|
||||
this.lock.writeLock().lock();
|
||||
|
||||
BlockTintCache.CacheData blocktintcache$cachedata3;
|
||||
try {
|
||||
BlockTintCache.CacheData blocktintcache$cachedata2 = this.cache.get(i);
|
||||
if (blocktintcache$cachedata2 == null) {
|
||||
blocktintcache$cachedata3 = new BlockTintCache.CacheData();
|
||||
if (this.cache.size() >= 256) {
|
||||
BlockTintCache.CacheData blocktintcache$cachedata1 = this.cache.removeFirst();
|
||||
if (blocktintcache$cachedata1 != null) {
|
||||
blocktintcache$cachedata1.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
this.cache.put(i, blocktintcache$cachedata3);
|
||||
return blocktintcache$cachedata3;
|
||||
}
|
||||
|
||||
blocktintcache$cachedata3 = blocktintcache$cachedata2;
|
||||
} finally {
|
||||
this.lock.writeLock().unlock();
|
||||
}
|
||||
|
||||
return blocktintcache$cachedata3;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class CacheData {
|
||||
private final Int2ObjectArrayMap<int[]> cache = new Int2ObjectArrayMap<>(16);
|
||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
private static final int BLOCKS_PER_LAYER = Mth.square(16);
|
||||
private volatile boolean invalidated;
|
||||
|
||||
public int[] getLayer(int p_193824_) {
|
||||
this.lock.readLock().lock();
|
||||
|
||||
try {
|
||||
int[] aint = this.cache.get(p_193824_);
|
||||
if (aint != null) {
|
||||
return aint;
|
||||
}
|
||||
} finally {
|
||||
this.lock.readLock().unlock();
|
||||
}
|
||||
|
||||
this.lock.writeLock().lock();
|
||||
|
||||
int[] aint1;
|
||||
try {
|
||||
aint1 = this.cache.computeIfAbsent(p_193824_, (p_193826_) -> {
|
||||
return this.allocateLayer();
|
||||
});
|
||||
} finally {
|
||||
this.lock.writeLock().unlock();
|
||||
}
|
||||
|
||||
return aint1;
|
||||
}
|
||||
|
||||
private int[] allocateLayer() {
|
||||
int[] aint = new int[BLOCKS_PER_LAYER];
|
||||
Arrays.fill(aint, -1);
|
||||
return aint;
|
||||
}
|
||||
|
||||
public boolean isInvalidated() {
|
||||
return this.invalidated;
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
this.invalidated = true;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class LatestCacheInfo {
|
||||
public int x = Integer.MIN_VALUE;
|
||||
public int z = Integer.MIN_VALUE;
|
||||
@Nullable
|
||||
BlockTintCache.CacheData cache;
|
||||
|
||||
private LatestCacheInfo() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package net.minecraft.client.color.block;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,10 @@
|
||||
package net.minecraft.client.color.item;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface ItemColor {
|
||||
int getColor(ItemStack p_92672_, int p_92673_);
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package net.minecraft.client.color.item;
|
||||
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.IdMapper;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.DyeableLeatherItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.MapItem;
|
||||
import net.minecraft.world.item.SpawnEggItem;
|
||||
import net.minecraft.world.item.alchemy.PotionUtils;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.FoliageColor;
|
||||
import net.minecraft.world.level.GrassColor;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ItemColors {
|
||||
private static final int DEFAULT = -1;
|
||||
// FORGE: Use registry delegate as non-Vanilla item ids are not constant
|
||||
private final java.util.Map<net.minecraft.core.Holder.Reference<Item>, ItemColor> itemColors = new java.util.HashMap<>();
|
||||
|
||||
public static ItemColors createDefault(BlockColors p_92684_) {
|
||||
ItemColors itemcolors = new ItemColors();
|
||||
itemcolors.register((p_92708_, p_92709_) -> {
|
||||
return p_92709_ > 0 ? -1 : ((DyeableLeatherItem)p_92708_.getItem()).getColor(p_92708_);
|
||||
}, Items.LEATHER_HELMET, Items.LEATHER_CHESTPLATE, Items.LEATHER_LEGGINGS, Items.LEATHER_BOOTS, Items.LEATHER_HORSE_ARMOR);
|
||||
itemcolors.register((p_92705_, p_92706_) -> {
|
||||
return GrassColor.get(0.5D, 1.0D);
|
||||
}, Blocks.TALL_GRASS, Blocks.LARGE_FERN);
|
||||
itemcolors.register((p_92702_, p_92703_) -> {
|
||||
if (p_92703_ != 1) {
|
||||
return -1;
|
||||
} else {
|
||||
CompoundTag compoundtag = p_92702_.getTagElement("Explosion");
|
||||
int[] aint = compoundtag != null && compoundtag.contains("Colors", 11) ? compoundtag.getIntArray("Colors") : null;
|
||||
if (aint != null && aint.length != 0) {
|
||||
if (aint.length == 1) {
|
||||
return aint[0];
|
||||
} else {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
|
||||
for(int l : aint) {
|
||||
i += (l & 16711680) >> 16;
|
||||
j += (l & '\uff00') >> 8;
|
||||
k += (l & 255) >> 0;
|
||||
}
|
||||
|
||||
i /= aint.length;
|
||||
j /= aint.length;
|
||||
k /= aint.length;
|
||||
return i << 16 | j << 8 | k;
|
||||
}
|
||||
} else {
|
||||
return 9079434;
|
||||
}
|
||||
}
|
||||
}, Items.FIREWORK_STAR);
|
||||
itemcolors.register((p_92699_, p_92700_) -> {
|
||||
return p_92700_ > 0 ? -1 : PotionUtils.getColor(p_92699_);
|
||||
}, Items.POTION, Items.SPLASH_POTION, Items.LINGERING_POTION);
|
||||
|
||||
for(SpawnEggItem spawneggitem : SpawnEggItem.eggs()) {
|
||||
itemcolors.register((p_92681_, p_92682_) -> {
|
||||
return spawneggitem.getColor(p_92682_);
|
||||
}, spawneggitem);
|
||||
}
|
||||
|
||||
itemcolors.register((p_92687_, p_92688_) -> {
|
||||
BlockState blockstate = ((BlockItem)p_92687_.getItem()).getBlock().defaultBlockState();
|
||||
return p_92684_.getColor(blockstate, (BlockAndTintGetter)null, (BlockPos)null, p_92688_);
|
||||
}, Blocks.GRASS_BLOCK, Blocks.GRASS, Blocks.FERN, Blocks.VINE, Blocks.OAK_LEAVES, Blocks.SPRUCE_LEAVES, Blocks.BIRCH_LEAVES, Blocks.JUNGLE_LEAVES, Blocks.ACACIA_LEAVES, Blocks.DARK_OAK_LEAVES, Blocks.LILY_PAD);
|
||||
itemcolors.register((p_92696_, p_92697_) -> {
|
||||
return FoliageColor.getMangroveColor();
|
||||
}, Blocks.MANGROVE_LEAVES);
|
||||
itemcolors.register((p_92693_, p_92694_) -> {
|
||||
return p_92694_ == 0 ? PotionUtils.getColor(p_92693_) : -1;
|
||||
}, Items.TIPPED_ARROW);
|
||||
itemcolors.register((p_232352_, p_232353_) -> {
|
||||
return p_232353_ == 0 ? -1 : MapItem.getColor(p_232352_);
|
||||
}, Items.FILLED_MAP);
|
||||
net.minecraftforge.client.ForgeHooksClient.onItemColorsInit(itemcolors, p_92684_);
|
||||
return itemcolors;
|
||||
}
|
||||
|
||||
public int getColor(ItemStack p_92677_, int p_92678_) {
|
||||
ItemColor itemcolor = this.itemColors.get(net.minecraftforge.registries.ForgeRegistries.ITEMS.getDelegateOrThrow(p_92677_.getItem()));
|
||||
return itemcolor == null ? -1 : itemcolor.getColor(p_92677_, p_92678_);
|
||||
}
|
||||
|
||||
/** @deprecated Register via {@link net.minecraftforge.client.event.RegisterColorHandlersEvent.Item} */
|
||||
@Deprecated
|
||||
public void register(ItemColor p_92690_, ItemLike... p_92691_) {
|
||||
for(ItemLike itemlike : p_92691_) {
|
||||
this.itemColors.put(net.minecraftforge.registries.ForgeRegistries.ITEMS.getDelegateOrThrow(itemlike.asItem()), p_92690_);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package net.minecraft.client.color.item;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,61 @@
|
||||
package net.minecraft.client.gui;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.components.events.ContainerEventHandler;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface ComponentPath {
|
||||
static ComponentPath leaf(GuiEventListener p_265344_) {
|
||||
return new ComponentPath.Leaf(p_265344_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static ComponentPath path(ContainerEventHandler p_265254_, @Nullable ComponentPath p_265405_) {
|
||||
return p_265405_ == null ? null : new ComponentPath.Path(p_265254_, p_265405_);
|
||||
}
|
||||
|
||||
static ComponentPath path(GuiEventListener p_265555_, ContainerEventHandler... p_265487_) {
|
||||
ComponentPath componentpath = leaf(p_265555_);
|
||||
|
||||
for(ContainerEventHandler containereventhandler : p_265487_) {
|
||||
componentpath = path(containereventhandler, componentpath);
|
||||
}
|
||||
|
||||
return componentpath;
|
||||
}
|
||||
|
||||
GuiEventListener component();
|
||||
|
||||
void applyFocus(boolean p_265077_);
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record Leaf(GuiEventListener component) implements ComponentPath {
|
||||
public void applyFocus(boolean p_265248_) {
|
||||
this.component.setFocused(p_265248_);
|
||||
}
|
||||
|
||||
public GuiEventListener component() {
|
||||
return this.component;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record Path(ContainerEventHandler component, ComponentPath childPath) implements ComponentPath {
|
||||
public void applyFocus(boolean p_265230_) {
|
||||
if (!p_265230_) {
|
||||
this.component.setFocused((GuiEventListener)null);
|
||||
} else {
|
||||
this.component.setFocused(this.childPath.component());
|
||||
}
|
||||
|
||||
this.childPath.applyFocus(p_265230_);
|
||||
}
|
||||
|
||||
public ContainerEventHandler component() {
|
||||
return this.component;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
package net.minecraft.client.gui;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.ibm.icu.text.ArabicShaping;
|
||||
import com.ibm.icu.text.ArabicShapingException;
|
||||
import com.ibm.icu.text.Bidi;
|
||||
import com.mojang.blaze3d.font.GlyphInfo;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.StringSplitter;
|
||||
import net.minecraft.client.gui.font.FontSet;
|
||||
import net.minecraft.client.gui.font.glyphs.BakedGlyph;
|
||||
import net.minecraft.client.gui.font.glyphs.EmptyGlyph;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.locale.Language;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.FormattedText;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.network.chat.TextColor;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.util.FormattedCharSink;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.StringDecomposer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Font implements net.minecraftforge.client.extensions.IForgeFont {
|
||||
private static final float EFFECT_DEPTH = 0.01F;
|
||||
private static final Vector3f SHADOW_OFFSET = new Vector3f(0.0F, 0.0F, 0.03F);
|
||||
public static final int ALPHA_CUTOFF = 8;
|
||||
public final int lineHeight = 9;
|
||||
public final RandomSource random = RandomSource.create();
|
||||
private final Function<ResourceLocation, FontSet> fonts;
|
||||
final boolean filterFishyGlyphs;
|
||||
private final StringSplitter splitter;
|
||||
|
||||
public Font(Function<ResourceLocation, FontSet> p_243253_, boolean p_243245_) {
|
||||
this.fonts = p_243253_;
|
||||
this.filterFishyGlyphs = p_243245_;
|
||||
this.splitter = new StringSplitter((p_92722_, p_92723_) -> {
|
||||
return this.getFontSet(p_92723_.getFont()).getGlyphInfo(p_92722_, this.filterFishyGlyphs).getAdvance(p_92723_.isBold());
|
||||
});
|
||||
}
|
||||
|
||||
FontSet getFontSet(ResourceLocation p_92864_) {
|
||||
return this.fonts.apply(p_92864_);
|
||||
}
|
||||
|
||||
public String bidirectionalShaping(String p_92802_) {
|
||||
try {
|
||||
Bidi bidi = new Bidi((new ArabicShaping(8)).shape(p_92802_), 127);
|
||||
bidi.setReorderingMode(0);
|
||||
return bidi.writeReordered(2);
|
||||
} catch (ArabicShapingException arabicshapingexception) {
|
||||
return p_92802_;
|
||||
}
|
||||
}
|
||||
|
||||
public int drawInBatch(String p_272751_, float p_272661_, float p_273129_, int p_273272_, boolean p_273209_, Matrix4f p_272940_, MultiBufferSource p_273017_, Font.DisplayMode p_272608_, int p_273365_, int p_272755_) {
|
||||
return this.drawInBatch(p_272751_, p_272661_, p_273129_, p_273272_, p_273209_, p_272940_, p_273017_, p_272608_, p_273365_, p_272755_, this.isBidirectional());
|
||||
}
|
||||
|
||||
public int drawInBatch(String p_272780_, float p_272811_, float p_272610_, int p_273422_, boolean p_273016_, Matrix4f p_273443_, MultiBufferSource p_273387_, Font.DisplayMode p_273551_, int p_272706_, int p_273114_, boolean p_273022_) {
|
||||
return this.drawInternal(p_272780_, p_272811_, p_272610_, p_273422_, p_273016_, p_273443_, p_273387_, p_273551_, p_272706_, p_273114_, p_273022_);
|
||||
}
|
||||
|
||||
public int drawInBatch(Component p_273032_, float p_273249_, float p_273594_, int p_273714_, boolean p_273050_, Matrix4f p_272974_, MultiBufferSource p_273695_, Font.DisplayMode p_272782_, int p_272603_, int p_273632_) {
|
||||
return this.drawInBatch(p_273032_.getVisualOrderText(), p_273249_, p_273594_, p_273714_, p_273050_, p_272974_, p_273695_, p_272782_, p_272603_, p_273632_);
|
||||
}
|
||||
|
||||
public int drawInBatch(FormattedCharSequence p_273262_, float p_273006_, float p_273254_, int p_273375_, boolean p_273674_, Matrix4f p_273525_, MultiBufferSource p_272624_, Font.DisplayMode p_273418_, int p_273330_, int p_272981_) {
|
||||
return this.drawInternal(p_273262_, p_273006_, p_273254_, p_273375_, p_273674_, p_273525_, p_272624_, p_273418_, p_273330_, p_272981_);
|
||||
}
|
||||
|
||||
public void drawInBatch8xOutline(FormattedCharSequence p_168646_, float p_168647_, float p_168648_, int p_168649_, int p_168650_, Matrix4f p_254170_, MultiBufferSource p_168652_, int p_168653_) {
|
||||
int i = adjustColor(p_168650_);
|
||||
Font.StringRenderOutput font$stringrenderoutput = new Font.StringRenderOutput(p_168652_, 0.0F, 0.0F, i, false, p_254170_, Font.DisplayMode.NORMAL, p_168653_);
|
||||
|
||||
for(int j = -1; j <= 1; ++j) {
|
||||
for(int k = -1; k <= 1; ++k) {
|
||||
if (j != 0 || k != 0) {
|
||||
float[] afloat = new float[]{p_168647_};
|
||||
int l = j;
|
||||
int i1 = k;
|
||||
p_168646_.accept((p_168661_, p_168662_, p_168663_) -> {
|
||||
boolean flag = p_168662_.isBold();
|
||||
FontSet fontset = this.getFontSet(p_168662_.getFont());
|
||||
GlyphInfo glyphinfo = fontset.getGlyphInfo(p_168663_, this.filterFishyGlyphs);
|
||||
font$stringrenderoutput.x = afloat[0] + (float)l * glyphinfo.getShadowOffset();
|
||||
font$stringrenderoutput.y = p_168648_ + (float)i1 * glyphinfo.getShadowOffset();
|
||||
afloat[0] += glyphinfo.getAdvance(flag);
|
||||
return font$stringrenderoutput.accept(p_168661_, p_168662_.withColor(i), p_168663_);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Font.StringRenderOutput font$stringrenderoutput1 = new Font.StringRenderOutput(p_168652_, p_168647_, p_168648_, adjustColor(p_168649_), false, p_254170_, Font.DisplayMode.POLYGON_OFFSET, p_168653_);
|
||||
p_168646_.accept(font$stringrenderoutput1);
|
||||
font$stringrenderoutput1.finish(0, p_168647_);
|
||||
}
|
||||
|
||||
private static int adjustColor(int p_92720_) {
|
||||
return (p_92720_ & -67108864) == 0 ? p_92720_ | -16777216 : p_92720_;
|
||||
}
|
||||
|
||||
private int drawInternal(String p_273658_, float p_273086_, float p_272883_, int p_273547_, boolean p_272778_, Matrix4f p_272662_, MultiBufferSource p_273012_, Font.DisplayMode p_273381_, int p_272855_, int p_272745_, boolean p_272785_) {
|
||||
if (p_272785_) {
|
||||
p_273658_ = this.bidirectionalShaping(p_273658_);
|
||||
}
|
||||
|
||||
p_273547_ = adjustColor(p_273547_);
|
||||
Matrix4f matrix4f = new Matrix4f(p_272662_);
|
||||
if (p_272778_) {
|
||||
this.renderText(p_273658_, p_273086_, p_272883_, p_273547_, true, p_272662_, p_273012_, p_273381_, p_272855_, p_272745_);
|
||||
matrix4f.translate(SHADOW_OFFSET);
|
||||
}
|
||||
|
||||
p_273086_ = this.renderText(p_273658_, p_273086_, p_272883_, p_273547_, false, matrix4f, p_273012_, p_273381_, p_272855_, p_272745_);
|
||||
return (int)p_273086_ + (p_272778_ ? 1 : 0);
|
||||
}
|
||||
|
||||
private int drawInternal(FormattedCharSequence p_273025_, float p_273121_, float p_272717_, int p_273653_, boolean p_273531_, Matrix4f p_273265_, MultiBufferSource p_273560_, Font.DisplayMode p_273342_, int p_273373_, int p_273266_) {
|
||||
p_273653_ = adjustColor(p_273653_);
|
||||
Matrix4f matrix4f = new Matrix4f(p_273265_);
|
||||
if (p_273531_) {
|
||||
this.renderText(p_273025_, p_273121_, p_272717_, p_273653_, true, p_273265_, p_273560_, p_273342_, p_273373_, p_273266_);
|
||||
matrix4f.translate(SHADOW_OFFSET);
|
||||
}
|
||||
|
||||
p_273121_ = this.renderText(p_273025_, p_273121_, p_272717_, p_273653_, false, matrix4f, p_273560_, p_273342_, p_273373_, p_273266_);
|
||||
return (int)p_273121_ + (p_273531_ ? 1 : 0);
|
||||
}
|
||||
|
||||
private float renderText(String p_273765_, float p_273532_, float p_272783_, int p_273217_, boolean p_273583_, Matrix4f p_272734_, MultiBufferSource p_272595_, Font.DisplayMode p_273610_, int p_273727_, int p_273199_) {
|
||||
Font.StringRenderOutput font$stringrenderoutput = new Font.StringRenderOutput(p_272595_, p_273532_, p_272783_, p_273217_, p_273583_, p_272734_, p_273610_, p_273199_);
|
||||
StringDecomposer.iterateFormatted(p_273765_, Style.EMPTY, font$stringrenderoutput);
|
||||
return font$stringrenderoutput.finish(p_273727_, p_273532_);
|
||||
}
|
||||
|
||||
private float renderText(FormattedCharSequence p_273322_, float p_272632_, float p_273541_, int p_273200_, boolean p_273312_, Matrix4f p_273276_, MultiBufferSource p_273392_, Font.DisplayMode p_272625_, int p_273774_, int p_273371_) {
|
||||
Font.StringRenderOutput font$stringrenderoutput = new Font.StringRenderOutput(p_273392_, p_272632_, p_273541_, p_273200_, p_273312_, p_273276_, p_272625_, p_273371_);
|
||||
p_273322_.accept(font$stringrenderoutput);
|
||||
return font$stringrenderoutput.finish(p_273774_, p_272632_);
|
||||
}
|
||||
|
||||
void renderChar(BakedGlyph p_254105_, boolean p_254001_, boolean p_254262_, float p_254256_, float p_253753_, float p_253629_, Matrix4f p_254014_, VertexConsumer p_253852_, float p_254317_, float p_253809_, float p_253870_, float p_254287_, int p_253905_) {
|
||||
p_254105_.render(p_254262_, p_253753_, p_253629_, p_254014_, p_253852_, p_254317_, p_253809_, p_253870_, p_254287_, p_253905_);
|
||||
if (p_254001_) {
|
||||
p_254105_.render(p_254262_, p_253753_ + p_254256_, p_253629_, p_254014_, p_253852_, p_254317_, p_253809_, p_253870_, p_254287_, p_253905_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int width(String p_92896_) {
|
||||
return Mth.ceil(this.splitter.stringWidth(p_92896_));
|
||||
}
|
||||
|
||||
public int width(FormattedText p_92853_) {
|
||||
return Mth.ceil(this.splitter.stringWidth(p_92853_));
|
||||
}
|
||||
|
||||
public int width(FormattedCharSequence p_92725_) {
|
||||
return Mth.ceil(this.splitter.stringWidth(p_92725_));
|
||||
}
|
||||
|
||||
public String plainSubstrByWidth(String p_92838_, int p_92839_, boolean p_92840_) {
|
||||
return p_92840_ ? this.splitter.plainTailByWidth(p_92838_, p_92839_, Style.EMPTY) : this.splitter.plainHeadByWidth(p_92838_, p_92839_, Style.EMPTY);
|
||||
}
|
||||
|
||||
public String plainSubstrByWidth(String p_92835_, int p_92836_) {
|
||||
return this.splitter.plainHeadByWidth(p_92835_, p_92836_, Style.EMPTY);
|
||||
}
|
||||
|
||||
public FormattedText substrByWidth(FormattedText p_92855_, int p_92856_) {
|
||||
return this.splitter.headByWidth(p_92855_, p_92856_, Style.EMPTY);
|
||||
}
|
||||
|
||||
public int wordWrapHeight(String p_92921_, int p_92922_) {
|
||||
return 9 * this.splitter.splitLines(p_92921_, p_92922_, Style.EMPTY).size();
|
||||
}
|
||||
|
||||
public int wordWrapHeight(FormattedText p_239134_, int p_239135_) {
|
||||
return 9 * this.splitter.splitLines(p_239134_, p_239135_, Style.EMPTY).size();
|
||||
}
|
||||
|
||||
public List<FormattedCharSequence> split(FormattedText p_92924_, int p_92925_) {
|
||||
return Language.getInstance().getVisualOrder(this.splitter.splitLines(p_92924_, p_92925_, Style.EMPTY));
|
||||
}
|
||||
|
||||
public boolean isBidirectional() {
|
||||
return Language.getInstance().isDefaultRightToLeft();
|
||||
}
|
||||
|
||||
public StringSplitter getSplitter() {
|
||||
return this.splitter;
|
||||
}
|
||||
|
||||
@Override public Font self() { return this; }
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum DisplayMode {
|
||||
NORMAL,
|
||||
SEE_THROUGH,
|
||||
POLYGON_OFFSET;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class StringRenderOutput implements FormattedCharSink {
|
||||
final MultiBufferSource bufferSource;
|
||||
private final boolean dropShadow;
|
||||
private final float dimFactor;
|
||||
private final float r;
|
||||
private final float g;
|
||||
private final float b;
|
||||
private final float a;
|
||||
private final Matrix4f pose;
|
||||
private final Font.DisplayMode mode;
|
||||
private final int packedLightCoords;
|
||||
float x;
|
||||
float y;
|
||||
@Nullable
|
||||
private List<BakedGlyph.Effect> effects;
|
||||
|
||||
private void addEffect(BakedGlyph.Effect p_92965_) {
|
||||
if (this.effects == null) {
|
||||
this.effects = Lists.newArrayList();
|
||||
}
|
||||
|
||||
this.effects.add(p_92965_);
|
||||
}
|
||||
|
||||
public StringRenderOutput(MultiBufferSource p_181365_, float p_181366_, float p_181367_, int p_181368_, boolean p_181369_, Matrix4f p_254510_, Font.DisplayMode p_181371_, int p_181372_) {
|
||||
this.bufferSource = p_181365_;
|
||||
this.x = p_181366_;
|
||||
this.y = p_181367_;
|
||||
this.dropShadow = p_181369_;
|
||||
this.dimFactor = p_181369_ ? 0.25F : 1.0F;
|
||||
this.r = (float)(p_181368_ >> 16 & 255) / 255.0F * this.dimFactor;
|
||||
this.g = (float)(p_181368_ >> 8 & 255) / 255.0F * this.dimFactor;
|
||||
this.b = (float)(p_181368_ & 255) / 255.0F * this.dimFactor;
|
||||
this.a = (float)(p_181368_ >> 24 & 255) / 255.0F;
|
||||
this.pose = p_254510_;
|
||||
this.mode = p_181371_;
|
||||
this.packedLightCoords = p_181372_;
|
||||
}
|
||||
|
||||
public boolean accept(int p_92967_, Style p_92968_, int p_92969_) {
|
||||
FontSet fontset = Font.this.getFontSet(p_92968_.getFont());
|
||||
GlyphInfo glyphinfo = fontset.getGlyphInfo(p_92969_, Font.this.filterFishyGlyphs);
|
||||
BakedGlyph bakedglyph = p_92968_.isObfuscated() && p_92969_ != 32 ? fontset.getRandomGlyph(glyphinfo) : fontset.getGlyph(p_92969_);
|
||||
boolean flag = p_92968_.isBold();
|
||||
float f3 = this.a;
|
||||
TextColor textcolor = p_92968_.getColor();
|
||||
float f;
|
||||
float f1;
|
||||
float f2;
|
||||
if (textcolor != null) {
|
||||
int i = textcolor.getValue();
|
||||
f = (float)(i >> 16 & 255) / 255.0F * this.dimFactor;
|
||||
f1 = (float)(i >> 8 & 255) / 255.0F * this.dimFactor;
|
||||
f2 = (float)(i & 255) / 255.0F * this.dimFactor;
|
||||
} else {
|
||||
f = this.r;
|
||||
f1 = this.g;
|
||||
f2 = this.b;
|
||||
}
|
||||
|
||||
if (!(bakedglyph instanceof EmptyGlyph)) {
|
||||
float f5 = flag ? glyphinfo.getBoldOffset() : 0.0F;
|
||||
float f4 = this.dropShadow ? glyphinfo.getShadowOffset() : 0.0F;
|
||||
VertexConsumer vertexconsumer = this.bufferSource.getBuffer(bakedglyph.renderType(this.mode));
|
||||
Font.this.renderChar(bakedglyph, flag, p_92968_.isItalic(), f5, this.x + f4, this.y + f4, this.pose, vertexconsumer, f, f1, f2, f3, this.packedLightCoords);
|
||||
}
|
||||
|
||||
float f6 = glyphinfo.getAdvance(flag);
|
||||
float f7 = this.dropShadow ? 1.0F : 0.0F;
|
||||
if (p_92968_.isStrikethrough()) {
|
||||
this.addEffect(new BakedGlyph.Effect(this.x + f7 - 1.0F, this.y + f7 + 4.5F, this.x + f7 + f6, this.y + f7 + 4.5F - 1.0F, 0.01F, f, f1, f2, f3));
|
||||
}
|
||||
|
||||
if (p_92968_.isUnderlined()) {
|
||||
this.addEffect(new BakedGlyph.Effect(this.x + f7 - 1.0F, this.y + f7 + 9.0F, this.x + f7 + f6, this.y + f7 + 9.0F - 1.0F, 0.01F, f, f1, f2, f3));
|
||||
}
|
||||
|
||||
this.x += f6;
|
||||
return true;
|
||||
}
|
||||
|
||||
public float finish(int p_92962_, float p_92963_) {
|
||||
if (p_92962_ != 0) {
|
||||
float f = (float)(p_92962_ >> 24 & 255) / 255.0F;
|
||||
float f1 = (float)(p_92962_ >> 16 & 255) / 255.0F;
|
||||
float f2 = (float)(p_92962_ >> 8 & 255) / 255.0F;
|
||||
float f3 = (float)(p_92962_ & 255) / 255.0F;
|
||||
this.addEffect(new BakedGlyph.Effect(p_92963_ - 1.0F, this.y + 9.0F, this.x + 1.0F, this.y - 1.0F, 0.01F, f1, f2, f3, f));
|
||||
}
|
||||
|
||||
if (this.effects != null) {
|
||||
BakedGlyph bakedglyph = Font.this.getFontSet(Style.DEFAULT_FONT).whiteGlyph();
|
||||
VertexConsumer vertexconsumer = this.bufferSource.getBuffer(bakedglyph.renderType(this.mode));
|
||||
|
||||
for(BakedGlyph.Effect bakedglyph$effect : this.effects) {
|
||||
bakedglyph.renderEffect(bakedglyph$effect, this.pose, vertexconsumer, this.packedLightCoords);
|
||||
}
|
||||
}
|
||||
|
||||
return this.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,692 @@
|
||||
package net.minecraft.client.gui;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.platform.Lighting;
|
||||
import com.mojang.blaze3d.platform.Window;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.BufferUploader;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.math.Divisor;
|
||||
import it.unimi.dsi.fastutil.ints.IntIterator;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.CrashReport;
|
||||
import net.minecraft.CrashReportCategory;
|
||||
import net.minecraft.ReportedException;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.navigation.ScreenRectangle;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipPositioner;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.DefaultTooltipPositioner;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.TooltipRenderUtil;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.FormattedText;
|
||||
import net.minecraft.network.chat.HoverEvent;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.inventory.tooltip.TooltipComponent;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector2ic;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class GuiGraphics implements net.minecraftforge.client.extensions.IForgeGuiGraphics {
|
||||
public static final float MAX_GUI_Z = 10000.0F;
|
||||
public static final float MIN_GUI_Z = -10000.0F;
|
||||
private static final int EXTRA_SPACE_AFTER_FIRST_TOOLTIP_LINE = 2;
|
||||
private final Minecraft minecraft;
|
||||
private final PoseStack pose;
|
||||
private final MultiBufferSource.BufferSource bufferSource;
|
||||
private final GuiGraphics.ScissorStack scissorStack = new GuiGraphics.ScissorStack();
|
||||
private boolean managed;
|
||||
|
||||
private GuiGraphics(Minecraft p_282144_, PoseStack p_281551_, MultiBufferSource.BufferSource p_281460_) {
|
||||
this.minecraft = p_282144_;
|
||||
this.pose = p_281551_;
|
||||
this.bufferSource = p_281460_;
|
||||
}
|
||||
|
||||
public GuiGraphics(Minecraft p_283406_, MultiBufferSource.BufferSource p_282238_) {
|
||||
this(p_283406_, new PoseStack(), p_282238_);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
public void drawManaged(Runnable p_286277_) {
|
||||
this.flush();
|
||||
this.managed = true;
|
||||
p_286277_.run();
|
||||
this.managed = false;
|
||||
this.flush();
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
private void flushIfUnmanaged() {
|
||||
if (!this.managed) {
|
||||
this.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
private void flushIfManaged() {
|
||||
if (this.managed) {
|
||||
this.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int guiWidth() {
|
||||
return this.minecraft.getWindow().getGuiScaledWidth();
|
||||
}
|
||||
|
||||
public int guiHeight() {
|
||||
return this.minecraft.getWindow().getGuiScaledHeight();
|
||||
}
|
||||
|
||||
public PoseStack pose() {
|
||||
return this.pose;
|
||||
}
|
||||
|
||||
public MultiBufferSource.BufferSource bufferSource() {
|
||||
return this.bufferSource;
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
RenderSystem.disableDepthTest();
|
||||
this.bufferSource.endBatch();
|
||||
RenderSystem.enableDepthTest();
|
||||
}
|
||||
|
||||
public void hLine(int p_283318_, int p_281662_, int p_281346_, int p_281672_) {
|
||||
this.hLine(RenderType.gui(), p_283318_, p_281662_, p_281346_, p_281672_);
|
||||
}
|
||||
|
||||
public void hLine(RenderType p_286630_, int p_286453_, int p_286247_, int p_286814_, int p_286623_) {
|
||||
if (p_286247_ < p_286453_) {
|
||||
int i = p_286453_;
|
||||
p_286453_ = p_286247_;
|
||||
p_286247_ = i;
|
||||
}
|
||||
|
||||
this.fill(p_286630_, p_286453_, p_286814_, p_286247_ + 1, p_286814_ + 1, p_286623_);
|
||||
}
|
||||
|
||||
public void vLine(int p_282951_, int p_281591_, int p_281568_, int p_282718_) {
|
||||
this.vLine(RenderType.gui(), p_282951_, p_281591_, p_281568_, p_282718_);
|
||||
}
|
||||
|
||||
public void vLine(RenderType p_286607_, int p_286309_, int p_286480_, int p_286707_, int p_286855_) {
|
||||
if (p_286707_ < p_286480_) {
|
||||
int i = p_286480_;
|
||||
p_286480_ = p_286707_;
|
||||
p_286707_ = i;
|
||||
}
|
||||
|
||||
this.fill(p_286607_, p_286309_, p_286480_ + 1, p_286309_ + 1, p_286707_, p_286855_);
|
||||
}
|
||||
|
||||
public void enableScissor(int p_281479_, int p_282788_, int p_282924_, int p_282826_) {
|
||||
this.applyScissor(this.scissorStack.push(new ScreenRectangle(p_281479_, p_282788_, p_282924_ - p_281479_, p_282826_ - p_282788_)));
|
||||
}
|
||||
|
||||
public void disableScissor() {
|
||||
this.applyScissor(this.scissorStack.pop());
|
||||
}
|
||||
|
||||
private void applyScissor(@Nullable ScreenRectangle p_281569_) {
|
||||
this.flushIfManaged();
|
||||
if (p_281569_ != null) {
|
||||
Window window = Minecraft.getInstance().getWindow();
|
||||
int i = window.getHeight();
|
||||
double d0 = window.getGuiScale();
|
||||
double d1 = (double)p_281569_.left() * d0;
|
||||
double d2 = (double)i - (double)p_281569_.bottom() * d0;
|
||||
double d3 = (double)p_281569_.width() * d0;
|
||||
double d4 = (double)p_281569_.height() * d0;
|
||||
RenderSystem.enableScissor((int)d1, (int)d2, Math.max(0, (int)d3), Math.max(0, (int)d4));
|
||||
} else {
|
||||
RenderSystem.disableScissor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setColor(float p_281272_, float p_281734_, float p_282022_, float p_281752_) {
|
||||
this.flushIfManaged();
|
||||
RenderSystem.setShaderColor(p_281272_, p_281734_, p_282022_, p_281752_);
|
||||
}
|
||||
|
||||
public void fill(int p_282988_, int p_282861_, int p_281278_, int p_281710_, int p_281470_) {
|
||||
this.fill(p_282988_, p_282861_, p_281278_, p_281710_, 0, p_281470_);
|
||||
}
|
||||
|
||||
public void fill(int p_281437_, int p_283660_, int p_282606_, int p_283413_, int p_283428_, int p_283253_) {
|
||||
this.fill(RenderType.gui(), p_281437_, p_283660_, p_282606_, p_283413_, p_283428_, p_283253_);
|
||||
}
|
||||
|
||||
public void fill(RenderType p_286602_, int p_286738_, int p_286614_, int p_286741_, int p_286610_, int p_286560_) {
|
||||
this.fill(p_286602_, p_286738_, p_286614_, p_286741_, p_286610_, 0, p_286560_);
|
||||
}
|
||||
|
||||
public void fill(RenderType p_286711_, int p_286234_, int p_286444_, int p_286244_, int p_286411_, int p_286671_, int p_286599_) {
|
||||
Matrix4f matrix4f = this.pose.last().pose();
|
||||
if (p_286234_ < p_286244_) {
|
||||
int i = p_286234_;
|
||||
p_286234_ = p_286244_;
|
||||
p_286244_ = i;
|
||||
}
|
||||
|
||||
if (p_286444_ < p_286411_) {
|
||||
int j = p_286444_;
|
||||
p_286444_ = p_286411_;
|
||||
p_286411_ = j;
|
||||
}
|
||||
|
||||
float f3 = (float)FastColor.ARGB32.alpha(p_286599_) / 255.0F;
|
||||
float f = (float)FastColor.ARGB32.red(p_286599_) / 255.0F;
|
||||
float f1 = (float)FastColor.ARGB32.green(p_286599_) / 255.0F;
|
||||
float f2 = (float)FastColor.ARGB32.blue(p_286599_) / 255.0F;
|
||||
VertexConsumer vertexconsumer = this.bufferSource.getBuffer(p_286711_);
|
||||
vertexconsumer.vertex(matrix4f, (float)p_286234_, (float)p_286444_, (float)p_286671_).color(f, f1, f2, f3).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, (float)p_286234_, (float)p_286411_, (float)p_286671_).color(f, f1, f2, f3).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, (float)p_286244_, (float)p_286411_, (float)p_286671_).color(f, f1, f2, f3).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, (float)p_286244_, (float)p_286444_, (float)p_286671_).color(f, f1, f2, f3).endVertex();
|
||||
this.flushIfUnmanaged();
|
||||
}
|
||||
|
||||
public void fillGradient(int p_283290_, int p_283278_, int p_282670_, int p_281698_, int p_283374_, int p_283076_) {
|
||||
this.fillGradient(p_283290_, p_283278_, p_282670_, p_281698_, 0, p_283374_, p_283076_);
|
||||
}
|
||||
|
||||
public void fillGradient(int p_282702_, int p_282331_, int p_281415_, int p_283118_, int p_282419_, int p_281954_, int p_282607_) {
|
||||
this.fillGradient(RenderType.gui(), p_282702_, p_282331_, p_281415_, p_283118_, p_281954_, p_282607_, p_282419_);
|
||||
}
|
||||
|
||||
public void fillGradient(RenderType p_286522_, int p_286535_, int p_286839_, int p_286242_, int p_286856_, int p_286809_, int p_286833_, int p_286706_) {
|
||||
VertexConsumer vertexconsumer = this.bufferSource.getBuffer(p_286522_);
|
||||
this.fillGradient(vertexconsumer, p_286535_, p_286839_, p_286242_, p_286856_, p_286706_, p_286809_, p_286833_);
|
||||
this.flushIfUnmanaged();
|
||||
}
|
||||
|
||||
private void fillGradient(VertexConsumer p_286862_, int p_283414_, int p_281397_, int p_283587_, int p_281521_, int p_283505_, int p_283131_, int p_282949_) {
|
||||
float f = (float)FastColor.ARGB32.alpha(p_283131_) / 255.0F;
|
||||
float f1 = (float)FastColor.ARGB32.red(p_283131_) / 255.0F;
|
||||
float f2 = (float)FastColor.ARGB32.green(p_283131_) / 255.0F;
|
||||
float f3 = (float)FastColor.ARGB32.blue(p_283131_) / 255.0F;
|
||||
float f4 = (float)FastColor.ARGB32.alpha(p_282949_) / 255.0F;
|
||||
float f5 = (float)FastColor.ARGB32.red(p_282949_) / 255.0F;
|
||||
float f6 = (float)FastColor.ARGB32.green(p_282949_) / 255.0F;
|
||||
float f7 = (float)FastColor.ARGB32.blue(p_282949_) / 255.0F;
|
||||
Matrix4f matrix4f = this.pose.last().pose();
|
||||
p_286862_.vertex(matrix4f, (float)p_283414_, (float)p_281397_, (float)p_283505_).color(f1, f2, f3, f).endVertex();
|
||||
p_286862_.vertex(matrix4f, (float)p_283414_, (float)p_281521_, (float)p_283505_).color(f5, f6, f7, f4).endVertex();
|
||||
p_286862_.vertex(matrix4f, (float)p_283587_, (float)p_281521_, (float)p_283505_).color(f5, f6, f7, f4).endVertex();
|
||||
p_286862_.vertex(matrix4f, (float)p_283587_, (float)p_281397_, (float)p_283505_).color(f1, f2, f3, f).endVertex();
|
||||
}
|
||||
|
||||
public void drawCenteredString(Font p_282122_, String p_282898_, int p_281490_, int p_282853_, int p_281258_) {
|
||||
this.drawString(p_282122_, p_282898_, p_281490_ - p_282122_.width(p_282898_) / 2, p_282853_, p_281258_);
|
||||
}
|
||||
|
||||
public void drawCenteredString(Font p_282901_, Component p_282456_, int p_283083_, int p_282276_, int p_281457_) {
|
||||
FormattedCharSequence formattedcharsequence = p_282456_.getVisualOrderText();
|
||||
this.drawString(p_282901_, formattedcharsequence, p_283083_ - p_282901_.width(formattedcharsequence) / 2, p_282276_, p_281457_);
|
||||
}
|
||||
|
||||
public void drawCenteredString(Font p_282592_, FormattedCharSequence p_281854_, int p_281573_, int p_283511_, int p_282577_) {
|
||||
this.drawString(p_282592_, p_281854_, p_281573_ - p_282592_.width(p_281854_) / 2, p_283511_, p_282577_);
|
||||
}
|
||||
|
||||
public int drawString(Font p_282003_, @Nullable String p_281403_, int p_282714_, int p_282041_, int p_281908_) {
|
||||
return this.drawString(p_282003_, p_281403_, p_282714_, p_282041_, p_281908_, true);
|
||||
}
|
||||
|
||||
public int drawString(Font p_283343_, @Nullable String p_281896_, int p_283569_, int p_283418_, int p_281560_, boolean p_282130_) {
|
||||
return this.drawString(p_283343_, p_281896_, (float)p_283569_, (float)p_283418_, p_281560_, p_282130_);
|
||||
}
|
||||
|
||||
// Forge: Add float variant for x,y coordinates
|
||||
public int drawString(Font p_283343_, @Nullable String p_281896_, float p_283569_, float p_283418_, int p_281560_, boolean p_282130_) {
|
||||
if (p_281896_ == null) {
|
||||
return 0;
|
||||
} else {
|
||||
int i = p_283343_.drawInBatch(p_281896_, (float)p_283569_, (float)p_283418_, p_281560_, p_282130_, this.pose.last().pose(), this.bufferSource, Font.DisplayMode.NORMAL, 0, 15728880, p_283343_.isBidirectional());
|
||||
this.flushIfUnmanaged();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
public int drawString(Font p_283019_, FormattedCharSequence p_283376_, int p_283379_, int p_283346_, int p_282119_) {
|
||||
return this.drawString(p_283019_, p_283376_, p_283379_, p_283346_, p_282119_, true);
|
||||
}
|
||||
|
||||
public int drawString(Font p_282636_, FormattedCharSequence p_281596_, int p_281586_, int p_282816_, int p_281743_, boolean p_282394_) {
|
||||
return this.drawString(p_282636_, p_281596_, (float)p_281586_, (float)p_282816_, p_281743_, p_282394_);
|
||||
}
|
||||
|
||||
// Forge: Add float variant for x,y coordinates
|
||||
public int drawString(Font p_282636_, FormattedCharSequence p_281596_, float p_281586_, float p_282816_, int p_281743_, boolean p_282394_) {
|
||||
int i = p_282636_.drawInBatch(p_281596_, (float)p_281586_, (float)p_282816_, p_281743_, p_282394_, this.pose.last().pose(), this.bufferSource, Font.DisplayMode.NORMAL, 0, 15728880);
|
||||
this.flushIfUnmanaged();
|
||||
return i;
|
||||
}
|
||||
|
||||
public int drawString(Font p_281653_, Component p_283140_, int p_283102_, int p_282347_, int p_281429_) {
|
||||
return this.drawString(p_281653_, p_283140_, p_283102_, p_282347_, p_281429_, true);
|
||||
}
|
||||
|
||||
public int drawString(Font p_281547_, Component p_282131_, int p_282857_, int p_281250_, int p_282195_, boolean p_282791_) {
|
||||
return this.drawString(p_281547_, p_282131_.getVisualOrderText(), p_282857_, p_281250_, p_282195_, p_282791_);
|
||||
}
|
||||
|
||||
public void drawWordWrap(Font p_281494_, FormattedText p_283463_, int p_282183_, int p_283250_, int p_282564_, int p_282629_) {
|
||||
for(FormattedCharSequence formattedcharsequence : p_281494_.split(p_283463_, p_282564_)) {
|
||||
this.drawString(p_281494_, formattedcharsequence, p_282183_, p_283250_, p_282629_, false);
|
||||
p_283250_ += 9;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void blit(int p_282225_, int p_281487_, int p_281985_, int p_281329_, int p_283035_, TextureAtlasSprite p_281614_) {
|
||||
this.innerBlit(p_281614_.atlasLocation(), p_282225_, p_282225_ + p_281329_, p_281487_, p_281487_ + p_283035_, p_281985_, p_281614_.getU0(), p_281614_.getU1(), p_281614_.getV0(), p_281614_.getV1());
|
||||
}
|
||||
|
||||
public void blit(int p_282416_, int p_282989_, int p_282618_, int p_282755_, int p_281717_, TextureAtlasSprite p_281874_, float p_283559_, float p_282730_, float p_283530_, float p_282246_) {
|
||||
this.innerBlit(p_281874_.atlasLocation(), p_282416_, p_282416_ + p_282755_, p_282989_, p_282989_ + p_281717_, p_282618_, p_281874_.getU0(), p_281874_.getU1(), p_281874_.getV0(), p_281874_.getV1(), p_283559_, p_282730_, p_283530_, p_282246_);
|
||||
}
|
||||
|
||||
public void renderOutline(int p_281496_, int p_282076_, int p_281334_, int p_283576_, int p_283618_) {
|
||||
this.fill(p_281496_, p_282076_, p_281496_ + p_281334_, p_282076_ + 1, p_283618_);
|
||||
this.fill(p_281496_, p_282076_ + p_283576_ - 1, p_281496_ + p_281334_, p_282076_ + p_283576_, p_283618_);
|
||||
this.fill(p_281496_, p_282076_ + 1, p_281496_ + 1, p_282076_ + p_283576_ - 1, p_283618_);
|
||||
this.fill(p_281496_ + p_281334_ - 1, p_282076_ + 1, p_281496_ + p_281334_, p_282076_ + p_283576_ - 1, p_283618_);
|
||||
}
|
||||
|
||||
public void blit(ResourceLocation p_283377_, int p_281970_, int p_282111_, int p_283134_, int p_282778_, int p_281478_, int p_281821_) {
|
||||
this.blit(p_283377_, p_281970_, p_282111_, 0, (float)p_283134_, (float)p_282778_, p_281478_, p_281821_, 256, 256);
|
||||
}
|
||||
|
||||
public void blit(ResourceLocation p_283573_, int p_283574_, int p_283670_, int p_283545_, float p_283029_, float p_283061_, int p_282845_, int p_282558_, int p_282832_, int p_281851_) {
|
||||
this.blit(p_283573_, p_283574_, p_283574_ + p_282845_, p_283670_, p_283670_ + p_282558_, p_283545_, p_282845_, p_282558_, p_283029_, p_283061_, p_282832_, p_281851_);
|
||||
}
|
||||
|
||||
public void blit(ResourceLocation p_282034_, int p_283671_, int p_282377_, int p_282058_, int p_281939_, float p_282285_, float p_283199_, int p_282186_, int p_282322_, int p_282481_, int p_281887_) {
|
||||
this.blit(p_282034_, p_283671_, p_283671_ + p_282058_, p_282377_, p_282377_ + p_281939_, 0, p_282186_, p_282322_, p_282285_, p_283199_, p_282481_, p_281887_);
|
||||
}
|
||||
|
||||
public void blit(ResourceLocation p_283272_, int p_283605_, int p_281879_, float p_282809_, float p_282942_, int p_281922_, int p_282385_, int p_282596_, int p_281699_) {
|
||||
this.blit(p_283272_, p_283605_, p_281879_, p_281922_, p_282385_, p_282809_, p_282942_, p_281922_, p_282385_, p_282596_, p_281699_);
|
||||
}
|
||||
|
||||
void blit(ResourceLocation p_282639_, int p_282732_, int p_283541_, int p_281760_, int p_283298_, int p_283429_, int p_282193_, int p_281980_, float p_282660_, float p_281522_, int p_282315_, int p_281436_) {
|
||||
this.innerBlit(p_282639_, p_282732_, p_283541_, p_281760_, p_283298_, p_283429_, (p_282660_ + 0.0F) / (float)p_282315_, (p_282660_ + (float)p_282193_) / (float)p_282315_, (p_281522_ + 0.0F) / (float)p_281436_, (p_281522_ + (float)p_281980_) / (float)p_281436_);
|
||||
}
|
||||
|
||||
void innerBlit(ResourceLocation p_283461_, int p_281399_, int p_283222_, int p_283615_, int p_283430_, int p_281729_, float p_283247_, float p_282598_, float p_282883_, float p_283017_) {
|
||||
RenderSystem.setShaderTexture(0, p_283461_);
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
Matrix4f matrix4f = this.pose.last().pose();
|
||||
BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder();
|
||||
bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);
|
||||
bufferbuilder.vertex(matrix4f, (float)p_281399_, (float)p_283615_, (float)p_281729_).uv(p_283247_, p_282883_).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)p_281399_, (float)p_283430_, (float)p_281729_).uv(p_283247_, p_283017_).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)p_283222_, (float)p_283430_, (float)p_281729_).uv(p_282598_, p_283017_).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)p_283222_, (float)p_283615_, (float)p_281729_).uv(p_282598_, p_282883_).endVertex();
|
||||
BufferUploader.drawWithShader(bufferbuilder.end());
|
||||
}
|
||||
|
||||
void innerBlit(ResourceLocation p_283254_, int p_283092_, int p_281930_, int p_282113_, int p_281388_, int p_283583_, float p_281327_, float p_281676_, float p_283166_, float p_282630_, float p_282800_, float p_282850_, float p_282375_, float p_282754_) {
|
||||
RenderSystem.setShaderTexture(0, p_283254_);
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
|
||||
RenderSystem.enableBlend();
|
||||
Matrix4f matrix4f = this.pose.last().pose();
|
||||
BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder();
|
||||
bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
|
||||
bufferbuilder.vertex(matrix4f, (float)p_283092_, (float)p_282113_, (float)p_283583_).color(p_282800_, p_282850_, p_282375_, p_282754_).uv(p_281327_, p_283166_).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)p_283092_, (float)p_281388_, (float)p_283583_).color(p_282800_, p_282850_, p_282375_, p_282754_).uv(p_281327_, p_282630_).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)p_281930_, (float)p_281388_, (float)p_283583_).color(p_282800_, p_282850_, p_282375_, p_282754_).uv(p_281676_, p_282630_).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)p_281930_, (float)p_282113_, (float)p_283583_).color(p_282800_, p_282850_, p_282375_, p_282754_).uv(p_281676_, p_283166_).endVertex();
|
||||
BufferUploader.drawWithShader(bufferbuilder.end());
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
public void blitNineSliced(ResourceLocation p_282546_, int p_282275_, int p_281581_, int p_283274_, int p_281626_, int p_283005_, int p_282047_, int p_282125_, int p_283423_, int p_281424_) {
|
||||
this.blitNineSliced(p_282546_, p_282275_, p_281581_, p_283274_, p_281626_, p_283005_, p_283005_, p_283005_, p_283005_, p_282047_, p_282125_, p_283423_, p_281424_);
|
||||
}
|
||||
|
||||
public void blitNineSliced(ResourceLocation p_282543_, int p_281513_, int p_281865_, int p_282482_, int p_282661_, int p_282068_, int p_281294_, int p_281681_, int p_281957_, int p_282300_, int p_282769_) {
|
||||
this.blitNineSliced(p_282543_, p_281513_, p_281865_, p_282482_, p_282661_, p_282068_, p_281294_, p_282068_, p_281294_, p_281681_, p_281957_, p_282300_, p_282769_);
|
||||
}
|
||||
|
||||
public void blitNineSliced(ResourceLocation p_282712_, int p_283509_, int p_283259_, int p_283273_, int p_282043_, int p_281430_, int p_281412_, int p_282566_, int p_281971_, int p_282879_, int p_281529_, int p_281924_, int p_281407_) {
|
||||
p_281430_ = Math.min(p_281430_, p_283273_ / 2);
|
||||
p_282566_ = Math.min(p_282566_, p_283273_ / 2);
|
||||
p_281412_ = Math.min(p_281412_, p_282043_ / 2);
|
||||
p_281971_ = Math.min(p_281971_, p_282043_ / 2);
|
||||
if (p_283273_ == p_282879_ && p_282043_ == p_281529_) {
|
||||
this.blit(p_282712_, p_283509_, p_283259_, p_281924_, p_281407_, p_283273_, p_282043_);
|
||||
} else if (p_282043_ == p_281529_) {
|
||||
this.blit(p_282712_, p_283509_, p_283259_, p_281924_, p_281407_, p_281430_, p_282043_);
|
||||
this.blitRepeating(p_282712_, p_283509_ + p_281430_, p_283259_, p_283273_ - p_282566_ - p_281430_, p_282043_, p_281924_ + p_281430_, p_281407_, p_282879_ - p_282566_ - p_281430_, p_281529_);
|
||||
this.blit(p_282712_, p_283509_ + p_283273_ - p_282566_, p_283259_, p_281924_ + p_282879_ - p_282566_, p_281407_, p_282566_, p_282043_);
|
||||
} else if (p_283273_ == p_282879_) {
|
||||
this.blit(p_282712_, p_283509_, p_283259_, p_281924_, p_281407_, p_283273_, p_281412_);
|
||||
this.blitRepeating(p_282712_, p_283509_, p_283259_ + p_281412_, p_283273_, p_282043_ - p_281971_ - p_281412_, p_281924_, p_281407_ + p_281412_, p_282879_, p_281529_ - p_281971_ - p_281412_);
|
||||
this.blit(p_282712_, p_283509_, p_283259_ + p_282043_ - p_281971_, p_281924_, p_281407_ + p_281529_ - p_281971_, p_283273_, p_281971_);
|
||||
} else {
|
||||
this.blit(p_282712_, p_283509_, p_283259_, p_281924_, p_281407_, p_281430_, p_281412_);
|
||||
this.blitRepeating(p_282712_, p_283509_ + p_281430_, p_283259_, p_283273_ - p_282566_ - p_281430_, p_281412_, p_281924_ + p_281430_, p_281407_, p_282879_ - p_282566_ - p_281430_, p_281412_);
|
||||
this.blit(p_282712_, p_283509_ + p_283273_ - p_282566_, p_283259_, p_281924_ + p_282879_ - p_282566_, p_281407_, p_282566_, p_281412_);
|
||||
this.blit(p_282712_, p_283509_, p_283259_ + p_282043_ - p_281971_, p_281924_, p_281407_ + p_281529_ - p_281971_, p_281430_, p_281971_);
|
||||
this.blitRepeating(p_282712_, p_283509_ + p_281430_, p_283259_ + p_282043_ - p_281971_, p_283273_ - p_282566_ - p_281430_, p_281971_, p_281924_ + p_281430_, p_281407_ + p_281529_ - p_281971_, p_282879_ - p_282566_ - p_281430_, p_281971_);
|
||||
this.blit(p_282712_, p_283509_ + p_283273_ - p_282566_, p_283259_ + p_282043_ - p_281971_, p_281924_ + p_282879_ - p_282566_, p_281407_ + p_281529_ - p_281971_, p_282566_, p_281971_);
|
||||
this.blitRepeating(p_282712_, p_283509_, p_283259_ + p_281412_, p_281430_, p_282043_ - p_281971_ - p_281412_, p_281924_, p_281407_ + p_281412_, p_281430_, p_281529_ - p_281971_ - p_281412_);
|
||||
this.blitRepeating(p_282712_, p_283509_ + p_281430_, p_283259_ + p_281412_, p_283273_ - p_282566_ - p_281430_, p_282043_ - p_281971_ - p_281412_, p_281924_ + p_281430_, p_281407_ + p_281412_, p_282879_ - p_282566_ - p_281430_, p_281529_ - p_281971_ - p_281412_);
|
||||
this.blitRepeating(p_282712_, p_283509_ + p_283273_ - p_282566_, p_283259_ + p_281412_, p_281430_, p_282043_ - p_281971_ - p_281412_, p_281924_ + p_282879_ - p_282566_, p_281407_ + p_281412_, p_282566_, p_281529_ - p_281971_ - p_281412_);
|
||||
}
|
||||
}
|
||||
|
||||
public void blitRepeating(ResourceLocation p_283059_, int p_283575_, int p_283192_, int p_281790_, int p_283642_, int p_282691_, int p_281912_, int p_281728_, int p_282324_) {
|
||||
blitRepeating(p_283059_, p_283575_, p_283192_, p_281790_, p_283642_, p_282691_, p_281912_, p_281728_, p_282324_, 256, 256);
|
||||
}
|
||||
|
||||
public void blitRepeating(ResourceLocation p_283059_, int p_283575_, int p_283192_, int p_281790_, int p_283642_, int p_282691_, int p_281912_, int p_281728_, int p_282324_, int textureWidth, int textureHeight) {
|
||||
int i = p_283575_;
|
||||
|
||||
int j;
|
||||
for(IntIterator intiterator = slices(p_281790_, p_281728_); intiterator.hasNext(); i += j) {
|
||||
j = intiterator.nextInt();
|
||||
int k = (p_281728_ - j) / 2;
|
||||
int l = p_283192_;
|
||||
|
||||
int i1;
|
||||
for(IntIterator intiterator1 = slices(p_283642_, p_282324_); intiterator1.hasNext(); l += i1) {
|
||||
i1 = intiterator1.nextInt();
|
||||
int j1 = (p_282324_ - i1) / 2;
|
||||
this.blit(p_283059_, i, l, p_282691_ + k, p_281912_ + j1, j, i1, textureWidth, textureHeight);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static IntIterator slices(int p_282197_, int p_282161_) {
|
||||
int i = Mth.positiveCeilDiv(p_282197_, p_282161_);
|
||||
return new Divisor(p_282197_, i);
|
||||
}
|
||||
|
||||
public void renderItem(ItemStack p_281978_, int p_282647_, int p_281944_) {
|
||||
this.renderItem(this.minecraft.player, this.minecraft.level, p_281978_, p_282647_, p_281944_, 0);
|
||||
}
|
||||
|
||||
public void renderItem(ItemStack p_282262_, int p_283221_, int p_283496_, int p_283435_) {
|
||||
this.renderItem(this.minecraft.player, this.minecraft.level, p_282262_, p_283221_, p_283496_, p_283435_);
|
||||
}
|
||||
|
||||
public void renderItem(ItemStack p_282786_, int p_282502_, int p_282976_, int p_281592_, int p_282314_) {
|
||||
this.renderItem(this.minecraft.player, this.minecraft.level, p_282786_, p_282502_, p_282976_, p_281592_, p_282314_);
|
||||
}
|
||||
|
||||
public void renderFakeItem(ItemStack p_281946_, int p_283299_, int p_283674_) {
|
||||
this.renderItem((LivingEntity)null, this.minecraft.level, p_281946_, p_283299_, p_283674_, 0);
|
||||
}
|
||||
|
||||
public void renderItem(LivingEntity p_282154_, ItemStack p_282777_, int p_282110_, int p_281371_, int p_283572_) {
|
||||
this.renderItem(p_282154_, p_282154_.level(), p_282777_, p_282110_, p_281371_, p_283572_);
|
||||
}
|
||||
|
||||
private void renderItem(@Nullable LivingEntity p_283524_, @Nullable Level p_282461_, ItemStack p_283653_, int p_283141_, int p_282560_, int p_282425_) {
|
||||
this.renderItem(p_283524_, p_282461_, p_283653_, p_283141_, p_282560_, p_282425_, 0);
|
||||
}
|
||||
|
||||
private void renderItem(@Nullable LivingEntity p_282619_, @Nullable Level p_281754_, ItemStack p_281675_, int p_281271_, int p_282210_, int p_283260_, int p_281995_) {
|
||||
if (!p_281675_.isEmpty()) {
|
||||
BakedModel bakedmodel = this.minecraft.getItemRenderer().getModel(p_281675_, p_281754_, p_282619_, p_283260_);
|
||||
this.pose.pushPose();
|
||||
this.pose.translate((float)(p_281271_ + 8), (float)(p_282210_ + 8), (float)(150 + (bakedmodel.isGui3d() ? p_281995_ : 0)));
|
||||
|
||||
try {
|
||||
this.pose.mulPoseMatrix((new Matrix4f()).scaling(1.0F, -1.0F, 1.0F));
|
||||
this.pose.scale(16.0F, 16.0F, 16.0F);
|
||||
boolean flag = !bakedmodel.usesBlockLight();
|
||||
if (flag) {
|
||||
Lighting.setupForFlatItems();
|
||||
}
|
||||
|
||||
this.minecraft.getItemRenderer().render(p_281675_, ItemDisplayContext.GUI, false, this.pose, this.bufferSource(), 15728880, OverlayTexture.NO_OVERLAY, bakedmodel);
|
||||
this.flush();
|
||||
if (flag) {
|
||||
Lighting.setupFor3DItems();
|
||||
}
|
||||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(throwable, "Rendering item");
|
||||
CrashReportCategory crashreportcategory = crashreport.addCategory("Item being rendered");
|
||||
crashreportcategory.setDetail("Item Type", () -> {
|
||||
return String.valueOf((Object)p_281675_.getItem());
|
||||
});
|
||||
crashreportcategory.setDetail("Registry Name", () -> String.valueOf(net.minecraftforge.registries.ForgeRegistries.ITEMS.getKey(p_281675_.getItem())));
|
||||
crashreportcategory.setDetail("Item Damage", () -> {
|
||||
return String.valueOf(p_281675_.getDamageValue());
|
||||
});
|
||||
crashreportcategory.setDetail("Item NBT", () -> {
|
||||
return String.valueOf((Object)p_281675_.getTag());
|
||||
});
|
||||
crashreportcategory.setDetail("Item Foil", () -> {
|
||||
return String.valueOf(p_281675_.hasFoil());
|
||||
});
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
|
||||
this.pose.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
public void renderItemDecorations(Font p_281721_, ItemStack p_281514_, int p_282056_, int p_282683_) {
|
||||
this.renderItemDecorations(p_281721_, p_281514_, p_282056_, p_282683_, (String)null);
|
||||
}
|
||||
|
||||
public void renderItemDecorations(Font p_282005_, ItemStack p_283349_, int p_282641_, int p_282146_, @Nullable String p_282803_) {
|
||||
if (!p_283349_.isEmpty()) {
|
||||
this.pose.pushPose();
|
||||
if (p_283349_.getCount() != 1 || p_282803_ != null) {
|
||||
String s = p_282803_ == null ? String.valueOf(p_283349_.getCount()) : p_282803_;
|
||||
this.pose.translate(0.0F, 0.0F, 200.0F);
|
||||
this.drawString(p_282005_, s, p_282641_ + 19 - 2 - p_282005_.width(s), p_282146_ + 6 + 3, 16777215, true);
|
||||
}
|
||||
|
||||
if (p_283349_.isBarVisible()) {
|
||||
int l = p_283349_.getBarWidth();
|
||||
int i = p_283349_.getBarColor();
|
||||
int j = p_282641_ + 2;
|
||||
int k = p_282146_ + 13;
|
||||
this.fill(RenderType.guiOverlay(), j, k, j + 13, k + 2, -16777216);
|
||||
this.fill(RenderType.guiOverlay(), j, k, j + l, k + 1, i | -16777216);
|
||||
}
|
||||
|
||||
LocalPlayer localplayer = this.minecraft.player;
|
||||
float f = localplayer == null ? 0.0F : localplayer.getCooldowns().getCooldownPercent(p_283349_.getItem(), this.minecraft.getFrameTime());
|
||||
if (f > 0.0F) {
|
||||
int i1 = p_282146_ + Mth.floor(16.0F * (1.0F - f));
|
||||
int j1 = i1 + Mth.ceil(16.0F * f);
|
||||
this.fill(RenderType.guiOverlay(), p_282641_, i1, p_282641_ + 16, j1, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
this.pose.popPose();
|
||||
net.minecraftforge.client.ItemDecoratorHandler.of(p_283349_).render(this, p_282005_, p_283349_, p_282641_, p_282146_);
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack tooltipStack = ItemStack.EMPTY;
|
||||
|
||||
public void renderTooltip(Font p_282308_, ItemStack p_282781_, int p_282687_, int p_282292_) {
|
||||
this.tooltipStack = p_282781_;
|
||||
this.renderTooltip(p_282308_, Screen.getTooltipFromItem(this.minecraft, p_282781_), p_282781_.getTooltipImage(), p_282687_, p_282292_);
|
||||
this.tooltipStack = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
public void renderTooltip(Font font, List<Component> textComponents, Optional<TooltipComponent> tooltipComponent, ItemStack stack, int mouseX, int mouseY) {
|
||||
this.tooltipStack = stack;
|
||||
this.renderTooltip(font, textComponents, tooltipComponent, mouseX, mouseY);
|
||||
this.tooltipStack = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
public void renderTooltip(Font p_283128_, List<Component> p_282716_, Optional<TooltipComponent> p_281682_, int p_283678_, int p_281696_) {
|
||||
List<ClientTooltipComponent> list = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, p_282716_, p_281682_, p_283678_, guiWidth(), guiHeight(), p_283128_);
|
||||
this.renderTooltipInternal(p_283128_, list, p_283678_, p_281696_, DefaultTooltipPositioner.INSTANCE);
|
||||
}
|
||||
|
||||
public void renderTooltip(Font p_282269_, Component p_282572_, int p_282044_, int p_282545_) {
|
||||
this.renderTooltip(p_282269_, List.of(p_282572_.getVisualOrderText()), p_282044_, p_282545_);
|
||||
}
|
||||
|
||||
public void renderComponentTooltip(Font p_282739_, List<Component> p_281832_, int p_282191_, int p_282446_) {
|
||||
List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, p_281832_, p_282191_, guiWidth(), guiHeight(), p_282739_);
|
||||
this.renderTooltipInternal(p_282739_, components, p_282191_, p_282446_, DefaultTooltipPositioner.INSTANCE);
|
||||
}
|
||||
|
||||
public void renderComponentTooltip(Font font, List<? extends net.minecraft.network.chat.FormattedText> tooltips, int mouseX, int mouseY, ItemStack stack) {
|
||||
this.tooltipStack = stack;
|
||||
List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(stack, tooltips, mouseX, guiWidth(), guiHeight(), font);
|
||||
this.renderTooltipInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE);
|
||||
this.tooltipStack = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
public void renderComponentTooltipFromElements(Font font, List<com.mojang.datafixers.util.Either<FormattedText, TooltipComponent>> elements, int mouseX, int mouseY, ItemStack stack) {
|
||||
this.tooltipStack = stack;
|
||||
List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponentsFromElements(stack, elements, mouseX, guiWidth(), guiHeight(), font);
|
||||
this.renderTooltipInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE);
|
||||
this.tooltipStack = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
public void renderTooltip(Font p_282192_, List<? extends FormattedCharSequence> p_282297_, int p_281680_, int p_283325_) {
|
||||
this.renderTooltipInternal(p_282192_, p_282297_.stream().map(ClientTooltipComponent::create).collect(Collectors.toList()), p_281680_, p_283325_, DefaultTooltipPositioner.INSTANCE);
|
||||
}
|
||||
|
||||
public void renderTooltip(Font p_281627_, List<FormattedCharSequence> p_283313_, ClientTooltipPositioner p_283571_, int p_282367_, int p_282806_) {
|
||||
this.renderTooltipInternal(p_281627_, p_283313_.stream().map(ClientTooltipComponent::create).collect(Collectors.toList()), p_282367_, p_282806_, p_283571_);
|
||||
}
|
||||
|
||||
private void renderTooltipInternal(Font p_282675_, List<ClientTooltipComponent> p_282615_, int p_283230_, int p_283417_, ClientTooltipPositioner p_282442_) {
|
||||
if (!p_282615_.isEmpty()) {
|
||||
net.minecraftforge.client.event.RenderTooltipEvent.Pre preEvent = net.minecraftforge.client.ForgeHooksClient.onRenderTooltipPre(this.tooltipStack, this, p_283230_, p_283417_, guiWidth(), guiHeight(), p_282615_, p_282675_, p_282442_);
|
||||
if (preEvent.isCanceled()) return;
|
||||
int i = 0;
|
||||
int j = p_282615_.size() == 1 ? -2 : 0;
|
||||
|
||||
for(ClientTooltipComponent clienttooltipcomponent : p_282615_) {
|
||||
int k = clienttooltipcomponent.getWidth(preEvent.getFont());
|
||||
if (k > i) {
|
||||
i = k;
|
||||
}
|
||||
|
||||
j += clienttooltipcomponent.getHeight();
|
||||
}
|
||||
|
||||
int i2 = i;
|
||||
int j2 = j;
|
||||
Vector2ic vector2ic = p_282442_.positionTooltip(this.guiWidth(), this.guiHeight(), preEvent.getX(), preEvent.getY(), i2, j2);
|
||||
int l = vector2ic.x();
|
||||
int i1 = vector2ic.y();
|
||||
this.pose.pushPose();
|
||||
int j1 = 400;
|
||||
this.drawManaged(() -> {
|
||||
net.minecraftforge.client.event.RenderTooltipEvent.Color colorEvent = net.minecraftforge.client.ForgeHooksClient.onRenderTooltipColor(this.tooltipStack, this, l, i1, preEvent.getFont(), p_282615_);
|
||||
TooltipRenderUtil.renderTooltipBackground(this, l, i1, i2, j2, 400, colorEvent.getBackgroundStart(), colorEvent.getBackgroundEnd(), colorEvent.getBorderStart(), colorEvent.getBorderEnd());
|
||||
});
|
||||
this.pose.translate(0.0F, 0.0F, 400.0F);
|
||||
int k1 = i1;
|
||||
|
||||
for(int l1 = 0; l1 < p_282615_.size(); ++l1) {
|
||||
ClientTooltipComponent clienttooltipcomponent1 = p_282615_.get(l1);
|
||||
clienttooltipcomponent1.renderText(preEvent.getFont(), l, k1, this.pose.last().pose(), this.bufferSource);
|
||||
k1 += clienttooltipcomponent1.getHeight() + (l1 == 0 ? 2 : 0);
|
||||
}
|
||||
|
||||
k1 = i1;
|
||||
|
||||
for(int k2 = 0; k2 < p_282615_.size(); ++k2) {
|
||||
ClientTooltipComponent clienttooltipcomponent2 = p_282615_.get(k2);
|
||||
clienttooltipcomponent2.renderImage(preEvent.getFont(), l, k1, this);
|
||||
k1 += clienttooltipcomponent2.getHeight() + (k2 == 0 ? 2 : 0);
|
||||
}
|
||||
|
||||
this.pose.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
public void renderComponentHoverEffect(Font p_282584_, @Nullable Style p_282156_, int p_283623_, int p_282114_) {
|
||||
if (p_282156_ != null && p_282156_.getHoverEvent() != null) {
|
||||
HoverEvent hoverevent = p_282156_.getHoverEvent();
|
||||
HoverEvent.ItemStackInfo hoverevent$itemstackinfo = hoverevent.getValue(HoverEvent.Action.SHOW_ITEM);
|
||||
if (hoverevent$itemstackinfo != null) {
|
||||
this.renderTooltip(p_282584_, hoverevent$itemstackinfo.getItemStack(), p_283623_, p_282114_);
|
||||
} else {
|
||||
HoverEvent.EntityTooltipInfo hoverevent$entitytooltipinfo = hoverevent.getValue(HoverEvent.Action.SHOW_ENTITY);
|
||||
if (hoverevent$entitytooltipinfo != null) {
|
||||
if (this.minecraft.options.advancedItemTooltips) {
|
||||
this.renderComponentTooltip(p_282584_, hoverevent$entitytooltipinfo.getTooltipLines(), p_283623_, p_282114_);
|
||||
}
|
||||
} else {
|
||||
Component component = hoverevent.getValue(HoverEvent.Action.SHOW_TEXT);
|
||||
if (component != null) {
|
||||
this.renderTooltip(p_282584_, p_282584_.split(component, Math.max(this.guiWidth() / 2, 200)), p_283623_, p_282114_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class ScissorStack {
|
||||
private final Deque<ScreenRectangle> stack = new ArrayDeque<>();
|
||||
|
||||
public ScreenRectangle push(ScreenRectangle p_281812_) {
|
||||
ScreenRectangle screenrectangle = this.stack.peekLast();
|
||||
if (screenrectangle != null) {
|
||||
ScreenRectangle screenrectangle1 = Objects.requireNonNullElse(p_281812_.intersection(screenrectangle), ScreenRectangle.empty());
|
||||
this.stack.addLast(screenrectangle1);
|
||||
return screenrectangle1;
|
||||
} else {
|
||||
this.stack.addLast(p_281812_);
|
||||
return p_281812_;
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable ScreenRectangle pop() {
|
||||
if (this.stack.isEmpty()) {
|
||||
throw new IllegalStateException("Scissor stack underflow");
|
||||
} else {
|
||||
this.stack.removeLast();
|
||||
return this.stack.peekLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package net.minecraft.client.gui;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.math.Axis;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.material.MapColor;
|
||||
import net.minecraft.world.level.saveddata.maps.MapDecoration;
|
||||
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class MapRenderer implements AutoCloseable {
|
||||
private static final ResourceLocation MAP_ICONS_LOCATION = new ResourceLocation("textures/map/map_icons.png");
|
||||
static final RenderType MAP_ICONS = RenderType.text(MAP_ICONS_LOCATION);
|
||||
private static final int WIDTH = 128;
|
||||
private static final int HEIGHT = 128;
|
||||
final TextureManager textureManager;
|
||||
private final Int2ObjectMap<MapRenderer.MapInstance> maps = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
public MapRenderer(TextureManager p_93259_) {
|
||||
this.textureManager = p_93259_;
|
||||
}
|
||||
|
||||
public void update(int p_168766_, MapItemSavedData p_168767_) {
|
||||
this.getOrCreateMapInstance(p_168766_, p_168767_).forceUpload();
|
||||
}
|
||||
|
||||
public void render(PoseStack p_168772_, MultiBufferSource p_168773_, int p_168774_, MapItemSavedData p_168775_, boolean p_168776_, int p_168777_) {
|
||||
this.getOrCreateMapInstance(p_168774_, p_168775_).draw(p_168772_, p_168773_, p_168776_, p_168777_);
|
||||
}
|
||||
|
||||
private MapRenderer.MapInstance getOrCreateMapInstance(int p_168779_, MapItemSavedData p_168780_) {
|
||||
return this.maps.compute(p_168779_, (p_182563_, p_182564_) -> {
|
||||
if (p_182564_ == null) {
|
||||
return new MapRenderer.MapInstance(p_182563_, p_168780_);
|
||||
} else {
|
||||
p_182564_.replaceMapData(p_168780_);
|
||||
return p_182564_;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void resetData() {
|
||||
for(MapRenderer.MapInstance maprenderer$mapinstance : this.maps.values()) {
|
||||
maprenderer$mapinstance.close();
|
||||
}
|
||||
|
||||
this.maps.clear();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.resetData();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class MapInstance implements AutoCloseable {
|
||||
private MapItemSavedData data;
|
||||
private final DynamicTexture texture;
|
||||
private final RenderType renderType;
|
||||
private boolean requiresUpload = true;
|
||||
|
||||
MapInstance(int p_168783_, MapItemSavedData p_168784_) {
|
||||
this.data = p_168784_;
|
||||
this.texture = new DynamicTexture(128, 128, true);
|
||||
ResourceLocation resourcelocation = MapRenderer.this.textureManager.register("map/" + p_168783_, this.texture);
|
||||
this.renderType = RenderType.text(resourcelocation);
|
||||
}
|
||||
|
||||
void replaceMapData(MapItemSavedData p_182568_) {
|
||||
boolean flag = this.data != p_182568_;
|
||||
this.data = p_182568_;
|
||||
this.requiresUpload |= flag;
|
||||
}
|
||||
|
||||
public void forceUpload() {
|
||||
this.requiresUpload = true;
|
||||
}
|
||||
|
||||
private void updateTexture() {
|
||||
for(int i = 0; i < 128; ++i) {
|
||||
for(int j = 0; j < 128; ++j) {
|
||||
int k = j + i * 128;
|
||||
this.texture.getPixels().setPixelRGBA(j, i, MapColor.getColorFromPackedId(this.data.colors[k]));
|
||||
}
|
||||
}
|
||||
|
||||
this.texture.upload();
|
||||
}
|
||||
|
||||
void draw(PoseStack p_93292_, MultiBufferSource p_93293_, boolean p_93294_, int p_93295_) {
|
||||
if (this.requiresUpload) {
|
||||
this.updateTexture();
|
||||
this.requiresUpload = false;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
float f = 0.0F;
|
||||
Matrix4f matrix4f = p_93292_.last().pose();
|
||||
VertexConsumer vertexconsumer = p_93293_.getBuffer(this.renderType);
|
||||
vertexconsumer.vertex(matrix4f, 0.0F, 128.0F, -0.01F).color(255, 255, 255, 255).uv(0.0F, 1.0F).uv2(p_93295_).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, 128.0F, 128.0F, -0.01F).color(255, 255, 255, 255).uv(1.0F, 1.0F).uv2(p_93295_).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, 128.0F, 0.0F, -0.01F).color(255, 255, 255, 255).uv(1.0F, 0.0F).uv2(p_93295_).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, 0.0F, 0.0F, -0.01F).color(255, 255, 255, 255).uv(0.0F, 0.0F).uv2(p_93295_).endVertex();
|
||||
int k = 0;
|
||||
|
||||
for(MapDecoration mapdecoration : this.data.getDecorations()) {
|
||||
if (!p_93294_ || mapdecoration.renderOnFrame()) {
|
||||
if (mapdecoration.render(k)) { k++; continue; }
|
||||
p_93292_.pushPose();
|
||||
p_93292_.translate(0.0F + (float)mapdecoration.getX() / 2.0F + 64.0F, 0.0F + (float)mapdecoration.getY() / 2.0F + 64.0F, -0.02F);
|
||||
p_93292_.mulPose(Axis.ZP.rotationDegrees((float)(mapdecoration.getRot() * 360) / 16.0F));
|
||||
p_93292_.scale(4.0F, 4.0F, 3.0F);
|
||||
p_93292_.translate(-0.125F, 0.125F, 0.0F);
|
||||
byte b0 = mapdecoration.getImage();
|
||||
float f1 = (float)(b0 % 16 + 0) / 16.0F;
|
||||
float f2 = (float)(b0 / 16 + 0) / 16.0F;
|
||||
float f3 = (float)(b0 % 16 + 1) / 16.0F;
|
||||
float f4 = (float)(b0 / 16 + 1) / 16.0F;
|
||||
Matrix4f matrix4f1 = p_93292_.last().pose();
|
||||
float f5 = -0.001F;
|
||||
VertexConsumer vertexconsumer1 = p_93293_.getBuffer(MapRenderer.MAP_ICONS);
|
||||
vertexconsumer1.vertex(matrix4f1, -1.0F, 1.0F, (float)k * -0.001F).color(255, 255, 255, 255).uv(f1, f2).uv2(p_93295_).endVertex();
|
||||
vertexconsumer1.vertex(matrix4f1, 1.0F, 1.0F, (float)k * -0.001F).color(255, 255, 255, 255).uv(f3, f2).uv2(p_93295_).endVertex();
|
||||
vertexconsumer1.vertex(matrix4f1, 1.0F, -1.0F, (float)k * -0.001F).color(255, 255, 255, 255).uv(f3, f4).uv2(p_93295_).endVertex();
|
||||
vertexconsumer1.vertex(matrix4f1, -1.0F, -1.0F, (float)k * -0.001F).color(255, 255, 255, 255).uv(f1, f4).uv2(p_93295_).endVertex();
|
||||
p_93292_.popPose();
|
||||
if (mapdecoration.getName() != null) {
|
||||
Font font = Minecraft.getInstance().font;
|
||||
Component component = mapdecoration.getName();
|
||||
float f6 = (float)font.width(component);
|
||||
float f7 = Mth.clamp(25.0F / f6, 0.0F, 6.0F / 9.0F);
|
||||
p_93292_.pushPose();
|
||||
p_93292_.translate(0.0F + (float)mapdecoration.getX() / 2.0F + 64.0F - f6 * f7 / 2.0F, 0.0F + (float)mapdecoration.getY() / 2.0F + 64.0F + 4.0F, -0.025F);
|
||||
p_93292_.scale(f7, f7, 1.0F);
|
||||
p_93292_.translate(0.0F, 0.0F, -0.1F);
|
||||
font.drawInBatch(component, 0.0F, 0.0F, -1, false, p_93292_.last().pose(), p_93293_, Font.DisplayMode.NORMAL, Integer.MIN_VALUE, p_93295_);
|
||||
p_93292_.popPose();
|
||||
}
|
||||
|
||||
++k;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.texture.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.navigation.CommonInputs;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class AbstractButton extends AbstractWidget {
|
||||
protected static final int TEXTURE_Y_OFFSET = 46;
|
||||
protected static final int TEXTURE_WIDTH = 200;
|
||||
protected static final int TEXTURE_HEIGHT = 20;
|
||||
protected static final int TEXTURE_BORDER_X = 20;
|
||||
protected static final int TEXTURE_BORDER_Y = 4;
|
||||
protected static final int TEXT_MARGIN = 2;
|
||||
|
||||
public AbstractButton(int p_93365_, int p_93366_, int p_93367_, int p_93368_, Component p_93369_) {
|
||||
super(p_93365_, p_93366_, p_93367_, p_93368_, p_93369_);
|
||||
}
|
||||
|
||||
public abstract void onPress();
|
||||
|
||||
protected void renderWidget(GuiGraphics p_281670_, int p_282682_, int p_281714_, float p_282542_) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
p_281670_.setColor(1.0F, 1.0F, 1.0F, this.alpha);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.enableDepthTest();
|
||||
p_281670_.blitNineSliced(WIDGETS_LOCATION, this.getX(), this.getY(), this.getWidth(), this.getHeight(), 20, 4, 200, 20, 0, this.getTextureY());
|
||||
p_281670_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
int i = getFGColor();
|
||||
this.renderString(p_281670_, minecraft.font, i | Mth.ceil(this.alpha * 255.0F) << 24);
|
||||
}
|
||||
|
||||
public void renderString(GuiGraphics p_283366_, Font p_283054_, int p_281656_) {
|
||||
this.renderScrollingString(p_283366_, p_283054_, 2, p_281656_);
|
||||
}
|
||||
|
||||
private int getTextureY() {
|
||||
int i = 1;
|
||||
if (!this.active) {
|
||||
i = 0;
|
||||
} else if (this.isHoveredOrFocused()) {
|
||||
i = 2;
|
||||
}
|
||||
|
||||
return 46 + i * 20;
|
||||
}
|
||||
|
||||
public void onClick(double p_93371_, double p_93372_) {
|
||||
this.onPress();
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_93374_, int p_93375_, int p_93376_) {
|
||||
if (this.active && this.visible) {
|
||||
if (CommonInputs.selected(p_93374_)) {
|
||||
this.playDownSound(Minecraft.getInstance().getSoundManager());
|
||||
this.onPress();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.Options;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class AbstractOptionSliderButton extends AbstractSliderButton {
|
||||
protected final Options options;
|
||||
|
||||
protected AbstractOptionSliderButton(Options p_93379_, int p_93380_, int p_93381_, int p_93382_, int p_93383_, double p_93384_) {
|
||||
super(p_93380_, p_93381_, p_93382_, p_93383_, CommonComponents.EMPTY, p_93384_);
|
||||
this.options = p_93379_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class AbstractScrollWidget extends AbstractWidget implements Renderable, GuiEventListener {
|
||||
private static final int BORDER_COLOR_FOCUSED = -1;
|
||||
private static final int BORDER_COLOR = -6250336;
|
||||
private static final int BACKGROUND_COLOR = -16777216;
|
||||
private static final int INNER_PADDING = 4;
|
||||
private double scrollAmount;
|
||||
private boolean scrolling;
|
||||
|
||||
public AbstractScrollWidget(int p_240025_, int p_240026_, int p_240027_, int p_240028_, Component p_240029_) {
|
||||
super(p_240025_, p_240026_, p_240027_, p_240028_, p_240029_);
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_240170_, double p_240171_, int p_240172_) {
|
||||
if (!this.visible) {
|
||||
return false;
|
||||
} else {
|
||||
boolean flag = this.withinContentAreaPoint(p_240170_, p_240171_);
|
||||
boolean flag1 = this.scrollbarVisible() && p_240170_ >= (double)(this.getX() + this.width) && p_240170_ <= (double)(this.getX() + this.width + 8) && p_240171_ >= (double)this.getY() && p_240171_ < (double)(this.getY() + this.height);
|
||||
if (flag1 && p_240172_ == 0) {
|
||||
this.scrolling = true;
|
||||
return true;
|
||||
} else {
|
||||
return flag || flag1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseReleased(double p_239063_, double p_239064_, int p_239065_) {
|
||||
if (p_239065_ == 0) {
|
||||
this.scrolling = false;
|
||||
}
|
||||
|
||||
return super.mouseReleased(p_239063_, p_239064_, p_239065_);
|
||||
}
|
||||
|
||||
public boolean mouseDragged(double p_239639_, double p_239640_, int p_239641_, double p_239642_, double p_239643_) {
|
||||
if (this.visible && this.isFocused() && this.scrolling) {
|
||||
if (p_239640_ < (double)this.getY()) {
|
||||
this.setScrollAmount(0.0D);
|
||||
} else if (p_239640_ > (double)(this.getY() + this.height)) {
|
||||
this.setScrollAmount((double)this.getMaxScrollAmount());
|
||||
} else {
|
||||
int i = this.getScrollBarHeight();
|
||||
double d0 = (double)Math.max(1, this.getMaxScrollAmount() / (this.height - i));
|
||||
this.setScrollAmount(this.scrollAmount + p_239643_ * d0);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double p_239308_, double p_239309_, double p_239310_) {
|
||||
if (!this.visible) {
|
||||
return false;
|
||||
} else {
|
||||
this.setScrollAmount(this.scrollAmount - p_239310_ * this.scrollRate());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_276060_, int p_276046_, int p_276030_) {
|
||||
boolean flag = p_276060_ == 265;
|
||||
boolean flag1 = p_276060_ == 264;
|
||||
if (flag || flag1) {
|
||||
double d0 = this.scrollAmount;
|
||||
this.setScrollAmount(this.scrollAmount + (double)(flag ? -1 : 1) * this.scrollRate());
|
||||
if (d0 != this.scrollAmount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.keyPressed(p_276060_, p_276046_, p_276030_);
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_282213_, int p_282468_, int p_282209_, float p_283300_) {
|
||||
if (this.visible) {
|
||||
this.renderBackground(p_282213_);
|
||||
p_282213_.enableScissor(this.getX() + 1, this.getY() + 1, this.getX() + this.width - 1, this.getY() + this.height - 1);
|
||||
p_282213_.pose().pushPose();
|
||||
p_282213_.pose().translate(0.0D, -this.scrollAmount, 0.0D);
|
||||
this.renderContents(p_282213_, p_282468_, p_282209_, p_283300_);
|
||||
p_282213_.pose().popPose();
|
||||
p_282213_.disableScissor();
|
||||
this.renderDecorations(p_282213_);
|
||||
}
|
||||
}
|
||||
|
||||
private int getScrollBarHeight() {
|
||||
return Mth.clamp((int)((float)(this.height * this.height) / (float)this.getContentHeight()), 32, this.height);
|
||||
}
|
||||
|
||||
protected void renderDecorations(GuiGraphics p_283178_) {
|
||||
if (this.scrollbarVisible()) {
|
||||
this.renderScrollBar(p_283178_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected int innerPadding() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected int totalInnerPadding() {
|
||||
return this.innerPadding() * 2;
|
||||
}
|
||||
|
||||
protected double scrollAmount() {
|
||||
return this.scrollAmount;
|
||||
}
|
||||
|
||||
protected void setScrollAmount(double p_240207_) {
|
||||
this.scrollAmount = Mth.clamp(p_240207_, 0.0D, (double)this.getMaxScrollAmount());
|
||||
}
|
||||
|
||||
protected int getMaxScrollAmount() {
|
||||
return Math.max(0, this.getContentHeight() - (this.height - 4));
|
||||
}
|
||||
|
||||
private int getContentHeight() {
|
||||
return this.getInnerHeight() + 4;
|
||||
}
|
||||
|
||||
protected void renderBackground(GuiGraphics p_282207_) {
|
||||
this.renderBorder(p_282207_, this.getX(), this.getY(), this.getWidth(), this.getHeight());
|
||||
}
|
||||
|
||||
protected void renderBorder(GuiGraphics p_289776_, int p_289792_, int p_289795_, int p_289775_, int p_289762_) {
|
||||
int i = this.isFocused() ? -1 : -6250336;
|
||||
p_289776_.fill(p_289792_, p_289795_, p_289792_ + p_289775_, p_289795_ + p_289762_, i);
|
||||
p_289776_.fill(p_289792_ + 1, p_289795_ + 1, p_289792_ + p_289775_ - 1, p_289795_ + p_289762_ - 1, -16777216);
|
||||
}
|
||||
|
||||
private void renderScrollBar(GuiGraphics p_282305_) {
|
||||
int i = this.getScrollBarHeight();
|
||||
int j = this.getX() + this.width;
|
||||
int k = this.getX() + this.width + 8;
|
||||
int l = Math.max(this.getY(), (int)this.scrollAmount * (this.height - i) / this.getMaxScrollAmount() + this.getY());
|
||||
int i1 = l + i;
|
||||
p_282305_.fill(j, l, k, i1, -8355712);
|
||||
p_282305_.fill(j, l, k - 1, i1 - 1, -4144960);
|
||||
}
|
||||
|
||||
protected boolean withinContentAreaTopBottom(int p_239943_, int p_239944_) {
|
||||
return (double)p_239944_ - this.scrollAmount >= (double)this.getY() && (double)p_239943_ - this.scrollAmount <= (double)(this.getY() + this.height);
|
||||
}
|
||||
|
||||
protected boolean withinContentAreaPoint(double p_239607_, double p_239608_) {
|
||||
return p_239607_ >= (double)this.getX() && p_239607_ < (double)(this.getX() + this.width) && p_239608_ >= (double)this.getY() && p_239608_ < (double)(this.getY() + this.height);
|
||||
}
|
||||
|
||||
protected boolean scrollbarVisible() {
|
||||
return this.getInnerHeight() > this.getHeight();
|
||||
}
|
||||
|
||||
protected abstract int getInnerHeight();
|
||||
|
||||
protected abstract double scrollRate();
|
||||
|
||||
protected abstract void renderContents(GuiGraphics p_282975_, int p_239199_, int p_239200_, float p_239201_);
|
||||
}
|
||||
@@ -0,0 +1,574 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.events.AbstractContainerEventHandler;
|
||||
import net.minecraft.client.gui.components.events.ContainerEventHandler;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.gui.navigation.ScreenDirection;
|
||||
import net.minecraft.client.gui.navigation.ScreenRectangle;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class AbstractSelectionList<E extends AbstractSelectionList.Entry<E>> extends AbstractContainerEventHandler implements Renderable, NarratableEntry {
|
||||
protected final Minecraft minecraft;
|
||||
protected final int itemHeight;
|
||||
private final List<E> children = new AbstractSelectionList.TrackedList();
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected int y0;
|
||||
protected int y1;
|
||||
protected int x1;
|
||||
protected int x0;
|
||||
protected boolean centerListVertically = true;
|
||||
private double scrollAmount;
|
||||
private boolean renderSelection = true;
|
||||
private boolean renderHeader;
|
||||
protected int headerHeight;
|
||||
private boolean scrolling;
|
||||
@Nullable
|
||||
private E selected;
|
||||
private boolean renderBackground = true;
|
||||
private boolean renderTopAndBottom = true;
|
||||
@Nullable
|
||||
private E hovered;
|
||||
|
||||
public AbstractSelectionList(Minecraft p_93404_, int p_93405_, int p_93406_, int p_93407_, int p_93408_, int p_93409_) {
|
||||
this.minecraft = p_93404_;
|
||||
this.width = p_93405_;
|
||||
this.height = p_93406_;
|
||||
this.y0 = p_93407_;
|
||||
this.y1 = p_93408_;
|
||||
this.itemHeight = p_93409_;
|
||||
this.x0 = 0;
|
||||
this.x1 = p_93405_;
|
||||
}
|
||||
|
||||
public void setRenderSelection(boolean p_93472_) {
|
||||
this.renderSelection = p_93472_;
|
||||
}
|
||||
|
||||
protected void setRenderHeader(boolean p_93474_, int p_93475_) {
|
||||
this.renderHeader = p_93474_;
|
||||
this.headerHeight = p_93475_;
|
||||
if (!p_93474_) {
|
||||
this.headerHeight = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getRowWidth() {
|
||||
return 220;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public E getSelected() {
|
||||
return this.selected;
|
||||
}
|
||||
|
||||
public void setSelected(@Nullable E p_93462_) {
|
||||
this.selected = p_93462_;
|
||||
}
|
||||
|
||||
public E getFirstElement() {
|
||||
return this.children.get(0);
|
||||
}
|
||||
|
||||
public void setRenderBackground(boolean p_93489_) {
|
||||
this.renderBackground = p_93489_;
|
||||
}
|
||||
|
||||
public void setRenderTopAndBottom(boolean p_93497_) {
|
||||
this.renderTopAndBottom = p_93497_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public E getFocused() {
|
||||
return (E)(super.getFocused());
|
||||
}
|
||||
|
||||
public final List<E> children() {
|
||||
return this.children;
|
||||
}
|
||||
|
||||
protected void clearEntries() {
|
||||
this.children.clear();
|
||||
this.selected = null;
|
||||
}
|
||||
|
||||
protected void replaceEntries(Collection<E> p_93470_) {
|
||||
this.clearEntries();
|
||||
this.children.addAll(p_93470_);
|
||||
}
|
||||
|
||||
protected E getEntry(int p_93501_) {
|
||||
return this.children().get(p_93501_);
|
||||
}
|
||||
|
||||
protected int addEntry(E p_93487_) {
|
||||
this.children.add(p_93487_);
|
||||
return this.children.size() - 1;
|
||||
}
|
||||
|
||||
protected void addEntryToTop(E p_239858_) {
|
||||
double d0 = (double)this.getMaxScroll() - this.getScrollAmount();
|
||||
this.children.add(0, p_239858_);
|
||||
this.setScrollAmount((double)this.getMaxScroll() - d0);
|
||||
}
|
||||
|
||||
protected boolean removeEntryFromTop(E p_239046_) {
|
||||
double d0 = (double)this.getMaxScroll() - this.getScrollAmount();
|
||||
boolean flag = this.removeEntry(p_239046_);
|
||||
this.setScrollAmount((double)this.getMaxScroll() - d0);
|
||||
return flag;
|
||||
}
|
||||
|
||||
protected int getItemCount() {
|
||||
return this.children().size();
|
||||
}
|
||||
|
||||
protected boolean isSelectedItem(int p_93504_) {
|
||||
return Objects.equals(this.getSelected(), this.children().get(p_93504_));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected final E getEntryAtPosition(double p_93413_, double p_93414_) {
|
||||
int i = this.getRowWidth() / 2;
|
||||
int j = this.x0 + this.width / 2;
|
||||
int k = j - i;
|
||||
int l = j + i;
|
||||
int i1 = Mth.floor(p_93414_ - (double)this.y0) - this.headerHeight + (int)this.getScrollAmount() - 4;
|
||||
int j1 = i1 / this.itemHeight;
|
||||
return (E)(p_93413_ < (double)this.getScrollbarPosition() && p_93413_ >= (double)k && p_93413_ <= (double)l && j1 >= 0 && i1 >= 0 && j1 < this.getItemCount() ? this.children().get(j1) : null);
|
||||
}
|
||||
|
||||
public void updateSize(int p_93438_, int p_93439_, int p_93440_, int p_93441_) {
|
||||
this.width = p_93438_;
|
||||
this.height = p_93439_;
|
||||
this.y0 = p_93440_;
|
||||
this.y1 = p_93441_;
|
||||
this.x0 = 0;
|
||||
this.x1 = p_93438_;
|
||||
}
|
||||
|
||||
public void setLeftPos(int p_93508_) {
|
||||
this.x0 = p_93508_;
|
||||
this.x1 = p_93508_ + this.width;
|
||||
}
|
||||
|
||||
protected int getMaxPosition() {
|
||||
return this.getItemCount() * this.itemHeight + this.headerHeight;
|
||||
}
|
||||
|
||||
protected void clickedHeader(int p_93431_, int p_93432_) {
|
||||
}
|
||||
|
||||
protected void renderHeader(GuiGraphics p_282337_, int p_93444_, int p_93445_) {
|
||||
}
|
||||
|
||||
protected void renderBackground(GuiGraphics p_283512_) {
|
||||
}
|
||||
|
||||
protected void renderDecorations(GuiGraphics p_281477_, int p_93459_, int p_93460_) {
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282708_, int p_283242_, int p_282891_, float p_283683_) {
|
||||
this.renderBackground(p_282708_);
|
||||
int i = this.getScrollbarPosition();
|
||||
int j = i + 6;
|
||||
this.hovered = this.isMouseOver((double)p_283242_, (double)p_282891_) ? this.getEntryAtPosition((double)p_283242_, (double)p_282891_) : null;
|
||||
if (this.renderBackground) {
|
||||
p_282708_.setColor(0.125F, 0.125F, 0.125F, 1.0F);
|
||||
int k = 32;
|
||||
p_282708_.blit(Screen.BACKGROUND_LOCATION, this.x0, this.y0, (float)this.x1, (float)(this.y1 + (int)this.getScrollAmount()), this.x1 - this.x0, this.y1 - this.y0, 32, 32);
|
||||
p_282708_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
int l1 = this.getRowLeft();
|
||||
int l = this.y0 + 4 - (int)this.getScrollAmount();
|
||||
this.enableScissor(p_282708_);
|
||||
if (this.renderHeader) {
|
||||
this.renderHeader(p_282708_, l1, l);
|
||||
}
|
||||
|
||||
this.renderList(p_282708_, p_283242_, p_282891_, p_283683_);
|
||||
p_282708_.disableScissor();
|
||||
if (this.renderTopAndBottom) {
|
||||
int i1 = 32;
|
||||
p_282708_.setColor(0.25F, 0.25F, 0.25F, 1.0F);
|
||||
p_282708_.blit(Screen.BACKGROUND_LOCATION, this.x0, 0, 0.0F, 0.0F, this.width, this.y0, 32, 32);
|
||||
p_282708_.blit(Screen.BACKGROUND_LOCATION, this.x0, this.y1, 0.0F, (float)this.y1, this.width, this.height - this.y1, 32, 32);
|
||||
p_282708_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
int j1 = 4;
|
||||
p_282708_.fillGradient(RenderType.guiOverlay(), this.x0, this.y0, this.x1, this.y0 + 4, -16777216, 0, 0);
|
||||
p_282708_.fillGradient(RenderType.guiOverlay(), this.x0, this.y1 - 4, this.x1, this.y1, 0, -16777216, 0);
|
||||
}
|
||||
|
||||
int i2 = this.getMaxScroll();
|
||||
if (i2 > 0) {
|
||||
int j2 = (int)((float)((this.y1 - this.y0) * (this.y1 - this.y0)) / (float)this.getMaxPosition());
|
||||
j2 = Mth.clamp(j2, 32, this.y1 - this.y0 - 8);
|
||||
int k1 = (int)this.getScrollAmount() * (this.y1 - this.y0 - j2) / i2 + this.y0;
|
||||
if (k1 < this.y0) {
|
||||
k1 = this.y0;
|
||||
}
|
||||
|
||||
p_282708_.fill(i, this.y0, j, this.y1, -16777216);
|
||||
p_282708_.fill(i, k1, j, k1 + j2, -8355712);
|
||||
p_282708_.fill(i, k1, j - 1, k1 + j2 - 1, -4144960);
|
||||
}
|
||||
|
||||
this.renderDecorations(p_282708_, p_283242_, p_282891_);
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
protected void enableScissor(GuiGraphics p_282811_) {
|
||||
p_282811_.enableScissor(this.x0, this.y0, this.x1, this.y1);
|
||||
}
|
||||
|
||||
protected void centerScrollOn(E p_93495_) {
|
||||
this.setScrollAmount((double)(this.children().indexOf(p_93495_) * this.itemHeight + this.itemHeight / 2 - (this.y1 - this.y0) / 2));
|
||||
}
|
||||
|
||||
protected void ensureVisible(E p_93499_) {
|
||||
int i = this.getRowTop(this.children().indexOf(p_93499_));
|
||||
int j = i - this.y0 - 4 - this.itemHeight;
|
||||
if (j < 0) {
|
||||
this.scroll(j);
|
||||
}
|
||||
|
||||
int k = this.y1 - i - this.itemHeight - this.itemHeight;
|
||||
if (k < 0) {
|
||||
this.scroll(-k);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void scroll(int p_93430_) {
|
||||
this.setScrollAmount(this.getScrollAmount() + (double)p_93430_);
|
||||
}
|
||||
|
||||
public double getScrollAmount() {
|
||||
return this.scrollAmount;
|
||||
}
|
||||
|
||||
public void setScrollAmount(double p_93411_) {
|
||||
this.scrollAmount = Mth.clamp(p_93411_, 0.0D, (double)this.getMaxScroll());
|
||||
}
|
||||
|
||||
public int getMaxScroll() {
|
||||
return Math.max(0, this.getMaxPosition() - (this.y1 - this.y0 - 4));
|
||||
}
|
||||
|
||||
public int getScrollBottom() {
|
||||
return (int)this.getScrollAmount() - this.height - this.headerHeight;
|
||||
}
|
||||
|
||||
protected void updateScrollingState(double p_93482_, double p_93483_, int p_93484_) {
|
||||
this.scrolling = p_93484_ == 0 && p_93482_ >= (double)this.getScrollbarPosition() && p_93482_ < (double)(this.getScrollbarPosition() + 6);
|
||||
}
|
||||
|
||||
protected int getScrollbarPosition() {
|
||||
return this.width / 2 + 124;
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_93420_, double p_93421_, int p_93422_) {
|
||||
this.updateScrollingState(p_93420_, p_93421_, p_93422_);
|
||||
if (!this.isMouseOver(p_93420_, p_93421_)) {
|
||||
return false;
|
||||
} else {
|
||||
E e = this.getEntryAtPosition(p_93420_, p_93421_);
|
||||
if (e != null) {
|
||||
if (e.mouseClicked(p_93420_, p_93421_, p_93422_)) {
|
||||
E e1 = this.getFocused();
|
||||
if (e1 != e && e1 instanceof ContainerEventHandler) {
|
||||
ContainerEventHandler containereventhandler = (ContainerEventHandler)e1;
|
||||
containereventhandler.setFocused((GuiEventListener)null);
|
||||
}
|
||||
|
||||
this.setFocused(e);
|
||||
this.setDragging(true);
|
||||
return true;
|
||||
}
|
||||
} else if (p_93422_ == 0) {
|
||||
this.clickedHeader((int)(p_93420_ - (double)(this.x0 + this.width / 2 - this.getRowWidth() / 2)), (int)(p_93421_ - (double)this.y0) + (int)this.getScrollAmount() - 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.scrolling;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseReleased(double p_93491_, double p_93492_, int p_93493_) {
|
||||
if (this.getFocused() != null) {
|
||||
this.getFocused().mouseReleased(p_93491_, p_93492_, p_93493_);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean mouseDragged(double p_93424_, double p_93425_, int p_93426_, double p_93427_, double p_93428_) {
|
||||
if (super.mouseDragged(p_93424_, p_93425_, p_93426_, p_93427_, p_93428_)) {
|
||||
return true;
|
||||
} else if (p_93426_ == 0 && this.scrolling) {
|
||||
if (p_93425_ < (double)this.y0) {
|
||||
this.setScrollAmount(0.0D);
|
||||
} else if (p_93425_ > (double)this.y1) {
|
||||
this.setScrollAmount((double)this.getMaxScroll());
|
||||
} else {
|
||||
double d0 = (double)Math.max(1, this.getMaxScroll());
|
||||
int i = this.y1 - this.y0;
|
||||
int j = Mth.clamp((int)((float)(i * i) / (float)this.getMaxPosition()), 32, i - 8);
|
||||
double d1 = Math.max(1.0D, d0 / (double)(i - j));
|
||||
this.setScrollAmount(this.getScrollAmount() + p_93428_ * d1);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double p_93416_, double p_93417_, double p_93418_) {
|
||||
this.setScrollAmount(this.getScrollAmount() - p_93418_ * (double)this.itemHeight / 2.0D);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setFocused(@Nullable GuiEventListener p_265738_) {
|
||||
super.setFocused(p_265738_);
|
||||
int i = this.children.indexOf(p_265738_);
|
||||
if (i >= 0) {
|
||||
E e = this.children.get(i);
|
||||
this.setSelected(e);
|
||||
if (this.minecraft.getLastInputType().isKeyboard()) {
|
||||
this.ensureVisible(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected E nextEntry(ScreenDirection p_265160_) {
|
||||
return this.nextEntry(p_265160_, (p_93510_) -> {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected E nextEntry(ScreenDirection p_265210_, Predicate<E> p_265604_) {
|
||||
return this.nextEntry(p_265210_, p_265604_, this.getSelected());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected E nextEntry(ScreenDirection p_265159_, Predicate<E> p_265109_, @Nullable E p_265379_) {
|
||||
byte b0;
|
||||
switch (p_265159_) {
|
||||
case RIGHT:
|
||||
case LEFT:
|
||||
b0 = 0;
|
||||
break;
|
||||
case UP:
|
||||
b0 = -1;
|
||||
break;
|
||||
case DOWN:
|
||||
b0 = 1;
|
||||
break;
|
||||
default:
|
||||
throw new IncompatibleClassChangeError();
|
||||
}
|
||||
|
||||
int i = b0;
|
||||
if (!this.children().isEmpty() && i != 0) {
|
||||
int j;
|
||||
if (p_265379_ == null) {
|
||||
j = i > 0 ? 0 : this.children().size() - 1;
|
||||
} else {
|
||||
j = this.children().indexOf(p_265379_) + i;
|
||||
}
|
||||
|
||||
for(int k = j; k >= 0 && k < this.children.size(); k += i) {
|
||||
E e = this.children().get(k);
|
||||
if (p_265109_.test(e)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (E)null;
|
||||
}
|
||||
|
||||
public boolean isMouseOver(double p_93479_, double p_93480_) {
|
||||
return p_93480_ >= (double)this.y0 && p_93480_ <= (double)this.y1 && p_93479_ >= (double)this.x0 && p_93479_ <= (double)this.x1;
|
||||
}
|
||||
|
||||
protected void renderList(GuiGraphics p_282079_, int p_239229_, int p_239230_, float p_239231_) {
|
||||
int i = this.getRowLeft();
|
||||
int j = this.getRowWidth();
|
||||
int k = this.itemHeight - 4;
|
||||
int l = this.getItemCount();
|
||||
|
||||
for(int i1 = 0; i1 < l; ++i1) {
|
||||
int j1 = this.getRowTop(i1);
|
||||
int k1 = this.getRowBottom(i1);
|
||||
if (k1 >= this.y0 && j1 <= this.y1) {
|
||||
this.renderItem(p_282079_, p_239229_, p_239230_, p_239231_, i1, i, j1, j, k);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void renderItem(GuiGraphics p_282205_, int p_238966_, int p_238967_, float p_238968_, int p_238969_, int p_238970_, int p_238971_, int p_238972_, int p_238973_) {
|
||||
E e = this.getEntry(p_238969_);
|
||||
e.renderBack(p_282205_, p_238969_, p_238971_, p_238970_, p_238972_, p_238973_, p_238966_, p_238967_, Objects.equals(this.hovered, e), p_238968_);
|
||||
if (this.renderSelection && this.isSelectedItem(p_238969_)) {
|
||||
int i = this.isFocused() ? -1 : -8355712;
|
||||
this.renderSelection(p_282205_, p_238971_, p_238972_, p_238973_, i, -16777216);
|
||||
}
|
||||
|
||||
e.render(p_282205_, p_238969_, p_238971_, p_238970_, p_238972_, p_238973_, p_238966_, p_238967_, Objects.equals(this.hovered, e), p_238968_);
|
||||
}
|
||||
|
||||
protected void renderSelection(GuiGraphics p_283589_, int p_240142_, int p_240143_, int p_240144_, int p_240145_, int p_240146_) {
|
||||
int i = this.x0 + (this.width - p_240143_) / 2;
|
||||
int j = this.x0 + (this.width + p_240143_) / 2;
|
||||
p_283589_.fill(i, p_240142_ - 2, j, p_240142_ + p_240144_ + 2, p_240145_);
|
||||
p_283589_.fill(i + 1, p_240142_ - 1, j - 1, p_240142_ + p_240144_ + 1, p_240146_);
|
||||
}
|
||||
|
||||
public int getRowLeft() {
|
||||
return this.x0 + this.width / 2 - this.getRowWidth() / 2 + 2;
|
||||
}
|
||||
|
||||
public int getRowRight() {
|
||||
return this.getRowLeft() + this.getRowWidth();
|
||||
}
|
||||
|
||||
protected int getRowTop(int p_93512_) {
|
||||
return this.y0 + 4 - (int)this.getScrollAmount() + p_93512_ * this.itemHeight + this.headerHeight;
|
||||
}
|
||||
|
||||
protected int getRowBottom(int p_93486_) {
|
||||
return this.getRowTop(p_93486_) + this.itemHeight;
|
||||
}
|
||||
|
||||
public NarratableEntry.NarrationPriority narrationPriority() {
|
||||
if (this.isFocused()) {
|
||||
return NarratableEntry.NarrationPriority.FOCUSED;
|
||||
} else {
|
||||
return this.hovered != null ? NarratableEntry.NarrationPriority.HOVERED : NarratableEntry.NarrationPriority.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected E remove(int p_93515_) {
|
||||
E e = this.children.get(p_93515_);
|
||||
return (E)(this.removeEntry(this.children.get(p_93515_)) ? e : null);
|
||||
}
|
||||
|
||||
protected boolean removeEntry(E p_93503_) {
|
||||
boolean flag = this.children.remove(p_93503_);
|
||||
if (flag && p_93503_ == this.getSelected()) {
|
||||
this.setSelected((E)null);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected E getHovered() {
|
||||
return this.hovered;
|
||||
}
|
||||
|
||||
void bindEntryToSelf(AbstractSelectionList.Entry<E> p_93506_) {
|
||||
p_93506_.list = this;
|
||||
}
|
||||
|
||||
protected void narrateListElementPosition(NarrationElementOutput p_168791_, E p_168792_) {
|
||||
List<E> list = this.children();
|
||||
if (list.size() > 1) {
|
||||
int i = list.indexOf(p_168792_);
|
||||
if (i != -1) {
|
||||
p_168791_.add(NarratedElementType.POSITION, Component.translatable("narrator.position.list", i + 1, list.size()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ScreenRectangle getRectangle() {
|
||||
return new ScreenRectangle(this.x0, this.y0, this.x1 - this.x0, this.y1 - this.y0);
|
||||
}
|
||||
|
||||
public int getWidth() { return this.width; }
|
||||
public int getHeight() { return this.height; }
|
||||
public int getTop() { return this.y0; }
|
||||
public int getBottom() { return this.y1; }
|
||||
public int getLeft() { return this.x0; }
|
||||
public int getRight() { return this.x1; }
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected abstract static class Entry<E extends AbstractSelectionList.Entry<E>> implements GuiEventListener {
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
protected AbstractSelectionList<E> list;
|
||||
|
||||
public void setFocused(boolean p_265302_) {
|
||||
}
|
||||
|
||||
public boolean isFocused() {
|
||||
return this.list.getFocused() == this;
|
||||
}
|
||||
|
||||
public abstract void render(GuiGraphics p_283112_, int p_93524_, int p_93525_, int p_93526_, int p_93527_, int p_93528_, int p_93529_, int p_93530_, boolean p_93531_, float p_93532_);
|
||||
|
||||
public void renderBack(GuiGraphics p_282673_, int p_275556_, int p_275667_, int p_275713_, int p_275408_, int p_275330_, int p_275603_, int p_275450_, boolean p_275434_, float p_275384_) {
|
||||
}
|
||||
|
||||
public boolean isMouseOver(double p_93537_, double p_93538_) {
|
||||
return Objects.equals(this.list.getEntryAtPosition(p_93537_, p_93538_), this);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class TrackedList extends AbstractList<E> {
|
||||
private final List<E> delegate = Lists.newArrayList();
|
||||
|
||||
public E get(int p_93557_) {
|
||||
return this.delegate.get(p_93557_);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.delegate.size();
|
||||
}
|
||||
|
||||
public E set(int p_93559_, E p_93560_) {
|
||||
E e = this.delegate.set(p_93559_, p_93560_);
|
||||
AbstractSelectionList.this.bindEntryToSelf(p_93560_);
|
||||
return e;
|
||||
}
|
||||
|
||||
public void add(int p_93567_, E p_93568_) {
|
||||
this.delegate.add(p_93567_, p_93568_);
|
||||
AbstractSelectionList.this.bindEntryToSelf(p_93568_);
|
||||
}
|
||||
|
||||
public E remove(int p_93565_) {
|
||||
return this.delegate.remove(p_93565_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.InputType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.gui.navigation.CommonInputs;
|
||||
import net.minecraft.client.sounds.SoundManager;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class AbstractSliderButton extends AbstractWidget {
|
||||
public static final ResourceLocation SLIDER_LOCATION = new ResourceLocation("textures/gui/slider.png");
|
||||
protected static final int TEXTURE_WIDTH = 200;
|
||||
protected static final int TEXTURE_HEIGHT = 20;
|
||||
protected static final int TEXTURE_BORDER_X = 20;
|
||||
protected static final int TEXTURE_BORDER_Y = 4;
|
||||
protected static final int TEXT_MARGIN = 2;
|
||||
private static final int HEIGHT = 20;
|
||||
private static final int HANDLE_HALF_WIDTH = 4;
|
||||
private static final int HANDLE_WIDTH = 8;
|
||||
private static final int BACKGROUND = 0;
|
||||
private static final int BACKGROUND_FOCUSED = 1;
|
||||
private static final int HANDLE = 2;
|
||||
private static final int HANDLE_FOCUSED = 3;
|
||||
protected double value;
|
||||
private boolean canChangeValue;
|
||||
|
||||
public AbstractSliderButton(int p_93579_, int p_93580_, int p_93581_, int p_93582_, Component p_93583_, double p_93584_) {
|
||||
super(p_93579_, p_93580_, p_93581_, p_93582_, p_93583_);
|
||||
this.value = p_93584_;
|
||||
}
|
||||
|
||||
protected int getTextureY() {
|
||||
int i = this.isFocused() && !this.canChangeValue ? 1 : 0;
|
||||
return i * 20;
|
||||
}
|
||||
|
||||
protected int getHandleTextureY() {
|
||||
int i = !this.isHovered && !this.canChangeValue ? 2 : 3;
|
||||
return i * 20;
|
||||
}
|
||||
|
||||
protected MutableComponent createNarrationMessage() {
|
||||
return Component.translatable("gui.narrate.slider", this.getMessage());
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput p_168798_) {
|
||||
p_168798_.add(NarratedElementType.TITLE, this.createNarrationMessage());
|
||||
if (this.active) {
|
||||
if (this.isFocused()) {
|
||||
p_168798_.add(NarratedElementType.USAGE, Component.translatable("narration.slider.usage.focused"));
|
||||
} else {
|
||||
p_168798_.add(NarratedElementType.USAGE, Component.translatable("narration.slider.usage.hovered"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_283427_, int p_281447_, int p_282852_, float p_282409_) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
p_283427_.setColor(1.0F, 1.0F, 1.0F, this.alpha);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableDepthTest();
|
||||
p_283427_.blitNineSliced(SLIDER_LOCATION, this.getX(), this.getY(), this.getWidth(), this.getHeight(), 20, 4, 200, 20, 0, this.getTextureY());
|
||||
p_283427_.blitNineSliced(SLIDER_LOCATION, this.getX() + (int)(this.value * (double)(this.width - 8)), this.getY(), 8, 20, 20, 4, 200, 20, 0, this.getHandleTextureY());
|
||||
p_283427_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
int i = this.active ? 16777215 : 10526880;
|
||||
this.renderScrollingString(p_283427_, minecraft.font, 2, i | Mth.ceil(this.alpha * 255.0F) << 24);
|
||||
}
|
||||
|
||||
public void onClick(double p_93588_, double p_93589_) {
|
||||
this.setValueFromMouse(p_93588_);
|
||||
}
|
||||
|
||||
public void setFocused(boolean p_265705_) {
|
||||
super.setFocused(p_265705_);
|
||||
if (!p_265705_) {
|
||||
this.canChangeValue = false;
|
||||
} else {
|
||||
InputType inputtype = Minecraft.getInstance().getLastInputType();
|
||||
if (inputtype == InputType.MOUSE || inputtype == InputType.KEYBOARD_TAB) {
|
||||
this.canChangeValue = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_93596_, int p_93597_, int p_93598_) {
|
||||
if (CommonInputs.selected(p_93596_)) {
|
||||
this.canChangeValue = !this.canChangeValue;
|
||||
return true;
|
||||
} else {
|
||||
if (this.canChangeValue) {
|
||||
boolean flag = p_93596_ == 263;
|
||||
if (flag || p_93596_ == 262) {
|
||||
float f = flag ? -1.0F : 1.0F;
|
||||
this.setValue(this.value + (double)(f / (float)(this.width - 8)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void setValueFromMouse(double p_93586_) {
|
||||
this.setValue((p_93586_ - (double)(this.getX() + 4)) / (double)(this.width - 8));
|
||||
}
|
||||
|
||||
private void setValue(double p_93612_) {
|
||||
double d0 = this.value;
|
||||
this.value = Mth.clamp(p_93612_, 0.0D, 1.0D);
|
||||
if (d0 != this.value) {
|
||||
this.applyValue();
|
||||
}
|
||||
|
||||
this.updateMessage();
|
||||
}
|
||||
|
||||
protected void onDrag(double p_93591_, double p_93592_, double p_93593_, double p_93594_) {
|
||||
this.setValueFromMouse(p_93591_);
|
||||
super.onDrag(p_93591_, p_93592_, p_93593_, p_93594_);
|
||||
}
|
||||
|
||||
public void playDownSound(SoundManager p_93605_) {
|
||||
}
|
||||
|
||||
public void onRelease(double p_93609_, double p_93610_) {
|
||||
super.playDownSound(Minecraft.getInstance().getSoundManager());
|
||||
}
|
||||
|
||||
protected abstract void updateMessage();
|
||||
|
||||
protected abstract void applyValue();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class AbstractStringWidget extends AbstractWidget {
|
||||
private final Font font;
|
||||
private int color = 16777215;
|
||||
|
||||
public AbstractStringWidget(int p_270910_, int p_270297_, int p_270088_, int p_270842_, Component p_270063_, Font p_270327_) {
|
||||
super(p_270910_, p_270297_, p_270088_, p_270842_, p_270063_);
|
||||
this.font = p_270327_;
|
||||
}
|
||||
|
||||
protected void updateWidgetNarration(NarrationElementOutput p_270859_) {
|
||||
}
|
||||
|
||||
public AbstractStringWidget setColor(int p_270638_) {
|
||||
this.color = p_270638_;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected final Font getFont() {
|
||||
return this.font;
|
||||
}
|
||||
|
||||
protected final int getColor() {
|
||||
return this.color;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.ComponentPath;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.layouts.LayoutElement;
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.gui.navigation.FocusNavigationEvent;
|
||||
import net.minecraft.client.gui.navigation.ScreenRectangle;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.BelowOrAboveWidgetTooltipPositioner;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipPositioner;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.MenuTooltipPositioner;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.client.sounds.SoundManager;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class AbstractWidget implements Renderable, GuiEventListener, LayoutElement, NarratableEntry {
|
||||
public static final ResourceLocation WIDGETS_LOCATION = new ResourceLocation("textures/gui/widgets.png");
|
||||
public static final ResourceLocation ACCESSIBILITY_TEXTURE = new ResourceLocation("textures/gui/accessibility.png");
|
||||
private static final double PERIOD_PER_SCROLLED_PIXEL = 0.5D;
|
||||
private static final double MIN_SCROLL_PERIOD = 3.0D;
|
||||
protected int width;
|
||||
protected int height;
|
||||
private int x;
|
||||
private int y;
|
||||
private Component message;
|
||||
protected boolean isHovered;
|
||||
public boolean active = true;
|
||||
public boolean visible = true;
|
||||
protected float alpha = 1.0F;
|
||||
private int tabOrderGroup;
|
||||
private boolean focused;
|
||||
@Nullable
|
||||
private Tooltip tooltip;
|
||||
private int tooltipMsDelay;
|
||||
private long hoverOrFocusedStartTime;
|
||||
private boolean wasHoveredOrFocused;
|
||||
|
||||
public AbstractWidget(int p_93629_, int p_93630_, int p_93631_, int p_93632_, Component p_93633_) {
|
||||
this.x = p_93629_;
|
||||
this.y = p_93630_;
|
||||
this.width = p_93631_;
|
||||
this.height = p_93632_;
|
||||
this.message = p_93633_;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282421_, int p_93658_, int p_93659_, float p_93660_) {
|
||||
if (this.visible) {
|
||||
this.isHovered = p_93658_ >= this.getX() && p_93659_ >= this.getY() && p_93658_ < this.getX() + this.width && p_93659_ < this.getY() + this.height;
|
||||
this.renderWidget(p_282421_, p_93658_, p_93659_, p_93660_);
|
||||
this.updateTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTooltip() {
|
||||
if (this.tooltip != null) {
|
||||
boolean flag = this.isHovered || this.isFocused() && Minecraft.getInstance().getLastInputType().isKeyboard();
|
||||
if (flag != this.wasHoveredOrFocused) {
|
||||
if (flag) {
|
||||
this.hoverOrFocusedStartTime = Util.getMillis();
|
||||
}
|
||||
|
||||
this.wasHoveredOrFocused = flag;
|
||||
}
|
||||
|
||||
if (flag && Util.getMillis() - this.hoverOrFocusedStartTime > (long)this.tooltipMsDelay) {
|
||||
Screen screen = Minecraft.getInstance().screen;
|
||||
if (screen != null) {
|
||||
screen.setTooltipForNextRenderPass(this.tooltip, this.createTooltipPositioner(), this.isFocused());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected ClientTooltipPositioner createTooltipPositioner() {
|
||||
return (ClientTooltipPositioner)(!this.isHovered && this.isFocused() && Minecraft.getInstance().getLastInputType().isKeyboard() ? new BelowOrAboveWidgetTooltipPositioner(this) : new MenuTooltipPositioner(this));
|
||||
}
|
||||
|
||||
public void setTooltip(@Nullable Tooltip p_259796_) {
|
||||
this.tooltip = p_259796_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Tooltip getTooltip() {
|
||||
return this.tooltip;
|
||||
}
|
||||
|
||||
public void setTooltipDelay(int p_259732_) {
|
||||
this.tooltipMsDelay = p_259732_;
|
||||
}
|
||||
|
||||
protected MutableComponent createNarrationMessage() {
|
||||
return wrapDefaultNarrationMessage(this.getMessage());
|
||||
}
|
||||
|
||||
public static MutableComponent wrapDefaultNarrationMessage(Component p_168800_) {
|
||||
return Component.translatable("gui.narrate.button", p_168800_);
|
||||
}
|
||||
|
||||
protected abstract void renderWidget(GuiGraphics p_282139_, int p_268034_, int p_268009_, float p_268085_);
|
||||
|
||||
protected static void renderScrollingString(GuiGraphics p_281620_, Font p_282651_, Component p_281467_, int p_283621_, int p_282084_, int p_283398_, int p_281938_, int p_283471_) {
|
||||
int i = p_282651_.width(p_281467_);
|
||||
int j = (p_282084_ + p_281938_ - 9) / 2 + 1;
|
||||
int k = p_283398_ - p_283621_;
|
||||
if (i > k) {
|
||||
int l = i - k;
|
||||
double d0 = (double)Util.getMillis() / 1000.0D;
|
||||
double d1 = Math.max((double)l * 0.5D, 3.0D);
|
||||
double d2 = Math.sin((Math.PI / 2D) * Math.cos((Math.PI * 2D) * d0 / d1)) / 2.0D + 0.5D;
|
||||
double d3 = Mth.lerp(d2, 0.0D, (double)l);
|
||||
p_281620_.enableScissor(p_283621_, p_282084_, p_283398_, p_281938_);
|
||||
p_281620_.drawString(p_282651_, p_281467_, p_283621_ - (int)d3, j, p_283471_);
|
||||
p_281620_.disableScissor();
|
||||
} else {
|
||||
p_281620_.drawCenteredString(p_282651_, p_281467_, (p_283621_ + p_283398_) / 2, j, p_283471_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void renderScrollingString(GuiGraphics p_281857_, Font p_282790_, int p_282664_, int p_282944_) {
|
||||
int i = this.getX() + p_282664_;
|
||||
int j = this.getX() + this.getWidth() - p_282664_;
|
||||
renderScrollingString(p_281857_, p_282790_, this.getMessage(), i, this.getY(), j, this.getY() + this.getHeight(), p_282944_);
|
||||
}
|
||||
|
||||
public void renderTexture(GuiGraphics p_283546_, ResourceLocation p_281674_, int p_281808_, int p_282444_, int p_283651_, int p_281601_, int p_283472_, int p_282390_, int p_281441_, int p_281711_, int p_281541_) {
|
||||
int i = p_281601_;
|
||||
if (!this.isActive()) {
|
||||
i = p_281601_ + p_283472_ * 2;
|
||||
} else if (this.isHoveredOrFocused()) {
|
||||
i = p_281601_ + p_283472_;
|
||||
}
|
||||
|
||||
RenderSystem.enableDepthTest();
|
||||
p_283546_.blit(p_281674_, p_281808_, p_282444_, (float)p_283651_, (float)i, p_282390_, p_281441_, p_281711_, p_281541_);
|
||||
}
|
||||
|
||||
public void onClick(double p_93634_, double p_93635_) {
|
||||
}
|
||||
|
||||
public void onRelease(double p_93669_, double p_93670_) {
|
||||
}
|
||||
|
||||
protected void onDrag(double p_93636_, double p_93637_, double p_93638_, double p_93639_) {
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_93641_, double p_93642_, int p_93643_) {
|
||||
if (this.active && this.visible) {
|
||||
if (this.isValidClickButton(p_93643_)) {
|
||||
boolean flag = this.clicked(p_93641_, p_93642_);
|
||||
if (flag) {
|
||||
this.playDownSound(Minecraft.getInstance().getSoundManager());
|
||||
this.onClick(p_93641_, p_93642_);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseReleased(double p_93684_, double p_93685_, int p_93686_) {
|
||||
if (this.isValidClickButton(p_93686_)) {
|
||||
this.onRelease(p_93684_, p_93685_);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isValidClickButton(int p_93652_) {
|
||||
return p_93652_ == 0;
|
||||
}
|
||||
|
||||
public boolean mouseDragged(double p_93645_, double p_93646_, int p_93647_, double p_93648_, double p_93649_) {
|
||||
if (this.isValidClickButton(p_93647_)) {
|
||||
this.onDrag(p_93645_, p_93646_, p_93648_, p_93649_);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean clicked(double p_93681_, double p_93682_) {
|
||||
return this.active && this.visible && p_93681_ >= (double)this.getX() && p_93682_ >= (double)this.getY() && p_93681_ < (double)(this.getX() + this.width) && p_93682_ < (double)(this.getY() + this.height);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath nextFocusPath(FocusNavigationEvent p_265640_) {
|
||||
if (this.active && this.visible) {
|
||||
return !this.isFocused() ? ComponentPath.leaf(this) : null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMouseOver(double p_93672_, double p_93673_) {
|
||||
return this.active && this.visible && p_93672_ >= (double)this.getX() && p_93673_ >= (double)this.getY() && p_93672_ < (double)(this.getX() + this.width) && p_93673_ < (double)(this.getY() + this.height);
|
||||
}
|
||||
|
||||
public void playDownSound(SoundManager p_93665_) {
|
||||
p_93665_.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public void setWidth(int p_93675_) {
|
||||
this.width = p_93675_;
|
||||
}
|
||||
|
||||
public void setHeight(int value) {
|
||||
this.height = value;
|
||||
}
|
||||
|
||||
public void setAlpha(float p_93651_) {
|
||||
this.alpha = p_93651_;
|
||||
}
|
||||
|
||||
public void setMessage(Component p_93667_) {
|
||||
this.message = p_93667_;
|
||||
}
|
||||
|
||||
public Component getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public boolean isFocused() {
|
||||
return this.focused;
|
||||
}
|
||||
|
||||
public boolean isHovered() {
|
||||
return this.isHovered;
|
||||
}
|
||||
|
||||
public boolean isHoveredOrFocused() {
|
||||
return this.isHovered() || this.isFocused();
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.visible && this.active;
|
||||
}
|
||||
|
||||
public void setFocused(boolean p_93693_) {
|
||||
this.focused = p_93693_;
|
||||
}
|
||||
|
||||
public static final int UNSET_FG_COLOR = -1;
|
||||
protected int packedFGColor = UNSET_FG_COLOR;
|
||||
public int getFGColor() {
|
||||
if (packedFGColor != UNSET_FG_COLOR) return packedFGColor;
|
||||
return this.active ? 16777215 : 10526880; // White : Light Grey
|
||||
}
|
||||
public void setFGColor(int color) {
|
||||
this.packedFGColor = color;
|
||||
}
|
||||
public void clearFGColor() {
|
||||
this.packedFGColor = UNSET_FG_COLOR;
|
||||
}
|
||||
|
||||
public NarratableEntry.NarrationPriority narrationPriority() {
|
||||
if (this.isFocused()) {
|
||||
return NarratableEntry.NarrationPriority.FOCUSED;
|
||||
} else {
|
||||
return this.isHovered ? NarratableEntry.NarrationPriority.HOVERED : NarratableEntry.NarrationPriority.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public final void updateNarration(NarrationElementOutput p_259921_) {
|
||||
this.updateWidgetNarration(p_259921_);
|
||||
if (this.tooltip != null) {
|
||||
this.tooltip.updateNarration(p_259921_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected abstract void updateWidgetNarration(NarrationElementOutput p_259858_);
|
||||
|
||||
protected void defaultButtonNarrationText(NarrationElementOutput p_168803_) {
|
||||
p_168803_.add(NarratedElementType.TITLE, this.createNarrationMessage());
|
||||
if (this.active) {
|
||||
if (this.isFocused()) {
|
||||
p_168803_.add(NarratedElementType.USAGE, Component.translatable("narration.button.usage.focused"));
|
||||
} else {
|
||||
p_168803_.add(NarratedElementType.USAGE, Component.translatable("narration.button.usage.hovered"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public void setX(int p_254495_) {
|
||||
this.x = p_254495_;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public void setY(int p_253718_) {
|
||||
this.y = p_253718_;
|
||||
}
|
||||
|
||||
public void visitWidgets(Consumer<AbstractWidget> p_265566_) {
|
||||
p_265566_.accept(this);
|
||||
}
|
||||
|
||||
public ScreenRectangle getRectangle() {
|
||||
return LayoutElement.super.getRectangle();
|
||||
}
|
||||
|
||||
public int getTabOrderGroup() {
|
||||
return this.tabOrderGroup;
|
||||
}
|
||||
|
||||
public void setTabOrderGroup(int p_268123_) {
|
||||
this.tabOrderGroup = p_268123_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.sounds.SoundManager;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class AccessibilityOnboardingTextWidget extends MultiLineTextWidget {
|
||||
private static final int BORDER_COLOR_FOCUSED = -1;
|
||||
private static final int BORDER_COLOR = -6250336;
|
||||
private static final int BACKGROUND_COLOR = 1426063360;
|
||||
private static final int PADDING = 3;
|
||||
private static final int BORDER = 1;
|
||||
|
||||
public AccessibilityOnboardingTextWidget(Font p_265441_, Component p_265136_, int p_265628_) {
|
||||
super(p_265136_, p_265441_);
|
||||
this.setMaxWidth(p_265628_);
|
||||
this.setCentered(true);
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
protected void updateWidgetNarration(NarrationElementOutput p_265791_) {
|
||||
p_265791_.add(NarratedElementType.TITLE, this.getMessage());
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_283425_, int p_267981_, int p_268038_, float p_268050_) {
|
||||
int i = this.getX() - 3;
|
||||
int j = this.getY() - 3;
|
||||
int k = this.getX() + this.getWidth() + 3;
|
||||
int l = this.getY() + this.getHeight() + 3;
|
||||
int i1 = this.isFocused() ? -1 : -6250336;
|
||||
p_283425_.fill(i - 1, j - 1, i, l + 1, i1);
|
||||
p_283425_.fill(k, j - 1, k + 1, l + 1, i1);
|
||||
p_283425_.fill(i, j, k, j - 1, i1);
|
||||
p_283425_.fill(i, l, k, l + 1, i1);
|
||||
p_283425_.fill(i, j, k, l, 1426063360);
|
||||
super.renderWidget(p_283425_, p_267981_, p_268038_, p_268050_);
|
||||
}
|
||||
|
||||
public void playDownSound(SoundManager p_265780_) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundBossEventPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.BossEvent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class BossHealthOverlay {
|
||||
private static final ResourceLocation GUI_BARS_LOCATION = new ResourceLocation("textures/gui/bars.png");
|
||||
private static final int BAR_WIDTH = 182;
|
||||
private static final int BAR_HEIGHT = 5;
|
||||
private static final int OVERLAY_OFFSET = 80;
|
||||
private final Minecraft minecraft;
|
||||
final Map<UUID, LerpingBossEvent> events = Maps.newLinkedHashMap();
|
||||
|
||||
public BossHealthOverlay(Minecraft p_93702_) {
|
||||
this.minecraft = p_93702_;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_283175_) {
|
||||
if (!this.events.isEmpty()) {
|
||||
int i = p_283175_.guiWidth();
|
||||
int j = 12;
|
||||
|
||||
for(LerpingBossEvent lerpingbossevent : this.events.values()) {
|
||||
int k = i / 2 - 91;
|
||||
var event = net.minecraftforge.client.ForgeHooksClient.onCustomizeBossEventProgress(p_283175_, this.minecraft.getWindow(), lerpingbossevent, k, j, 10 + this.minecraft.font.lineHeight);
|
||||
if (!event.isCanceled()) {
|
||||
this.drawBar(p_283175_, k, j, lerpingbossevent);
|
||||
Component component = lerpingbossevent.getName();
|
||||
int l = this.minecraft.font.width(component);
|
||||
int i1 = i / 2 - l / 2;
|
||||
int j1 = j - 9;
|
||||
p_283175_.drawString(this.minecraft.font, component, i1, j1, 16777215);
|
||||
}
|
||||
j += event.getIncrement();
|
||||
if (j >= p_283175_.guiHeight() / 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void drawBar(GuiGraphics p_283672_, int p_283570_, int p_283306_, BossEvent p_283156_) {
|
||||
this.drawBar(p_283672_, p_283570_, p_283306_, p_283156_, 182, 0);
|
||||
int i = (int)(p_283156_.getProgress() * 183.0F);
|
||||
if (i > 0) {
|
||||
this.drawBar(p_283672_, p_283570_, p_283306_, p_283156_, i, 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawBar(GuiGraphics p_281657_, int p_283675_, int p_282498_, BossEvent p_281288_, int p_283619_, int p_281636_) {
|
||||
p_281657_.blit(GUI_BARS_LOCATION, p_283675_, p_282498_, 0, p_281288_.getColor().ordinal() * 5 * 2 + p_281636_, p_283619_, 5);
|
||||
if (p_281288_.getOverlay() != BossEvent.BossBarOverlay.PROGRESS) {
|
||||
RenderSystem.enableBlend();
|
||||
p_281657_.blit(GUI_BARS_LOCATION, p_283675_, p_282498_, 0, 80 + (p_281288_.getOverlay().ordinal() - 1) * 5 * 2 + p_281636_, p_283619_, 5);
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void update(ClientboundBossEventPacket p_93712_) {
|
||||
p_93712_.dispatch(new ClientboundBossEventPacket.Handler() {
|
||||
public void add(UUID p_168824_, Component p_168825_, float p_168826_, BossEvent.BossBarColor p_168827_, BossEvent.BossBarOverlay p_168828_, boolean p_168829_, boolean p_168830_, boolean p_168831_) {
|
||||
BossHealthOverlay.this.events.put(p_168824_, new LerpingBossEvent(p_168824_, p_168825_, p_168826_, p_168827_, p_168828_, p_168829_, p_168830_, p_168831_));
|
||||
}
|
||||
|
||||
public void remove(UUID p_168812_) {
|
||||
BossHealthOverlay.this.events.remove(p_168812_);
|
||||
}
|
||||
|
||||
public void updateProgress(UUID p_168814_, float p_168815_) {
|
||||
BossHealthOverlay.this.events.get(p_168814_).setProgress(p_168815_);
|
||||
}
|
||||
|
||||
public void updateName(UUID p_168821_, Component p_168822_) {
|
||||
BossHealthOverlay.this.events.get(p_168821_).setName(p_168822_);
|
||||
}
|
||||
|
||||
public void updateStyle(UUID p_168817_, BossEvent.BossBarColor p_168818_, BossEvent.BossBarOverlay p_168819_) {
|
||||
LerpingBossEvent lerpingbossevent = BossHealthOverlay.this.events.get(p_168817_);
|
||||
lerpingbossevent.setColor(p_168818_);
|
||||
lerpingbossevent.setOverlay(p_168819_);
|
||||
}
|
||||
|
||||
public void updateProperties(UUID p_168833_, boolean p_168834_, boolean p_168835_, boolean p_168836_) {
|
||||
LerpingBossEvent lerpingbossevent = BossHealthOverlay.this.events.get(p_168833_);
|
||||
lerpingbossevent.setDarkenScreen(p_168834_);
|
||||
lerpingbossevent.setPlayBossMusic(p_168835_);
|
||||
lerpingbossevent.setCreateWorldFog(p_168836_);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.events.clear();
|
||||
}
|
||||
|
||||
public boolean shouldPlayMusic() {
|
||||
if (!this.events.isEmpty()) {
|
||||
for(BossEvent bossevent : this.events.values()) {
|
||||
if (bossevent.shouldPlayBossMusic()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldDarkenScreen() {
|
||||
if (!this.events.isEmpty()) {
|
||||
for(BossEvent bossevent : this.events.values()) {
|
||||
if (bossevent.shouldDarkenScreen()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldCreateWorldFog() {
|
||||
if (!this.events.isEmpty()) {
|
||||
for(BossEvent bossevent : this.events.values()) {
|
||||
if (bossevent.shouldCreateWorldFog()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Button extends AbstractButton {
|
||||
public static final int SMALL_WIDTH = 120;
|
||||
public static final int DEFAULT_WIDTH = 150;
|
||||
public static final int DEFAULT_HEIGHT = 20;
|
||||
protected static final Button.CreateNarration DEFAULT_NARRATION = (p_253298_) -> {
|
||||
return p_253298_.get();
|
||||
};
|
||||
protected final Button.OnPress onPress;
|
||||
protected final Button.CreateNarration createNarration;
|
||||
|
||||
public static Button.Builder builder(Component p_254439_, Button.OnPress p_254567_) {
|
||||
return new Button.Builder(p_254439_, p_254567_);
|
||||
}
|
||||
|
||||
protected Button(int p_259075_, int p_259271_, int p_260232_, int p_260028_, Component p_259351_, Button.OnPress p_260152_, Button.CreateNarration p_259552_) {
|
||||
super(p_259075_, p_259271_, p_260232_, p_260028_, p_259351_);
|
||||
this.onPress = p_260152_;
|
||||
this.createNarration = p_259552_;
|
||||
}
|
||||
|
||||
protected Button(Builder builder) {
|
||||
this(builder.x, builder.y, builder.width, builder.height, builder.message, builder.onPress, builder.createNarration);
|
||||
setTooltip(builder.tooltip); // Forge: Make use of the Builder tooltip
|
||||
}
|
||||
|
||||
public void onPress() {
|
||||
this.onPress.onPress(this);
|
||||
}
|
||||
|
||||
protected MutableComponent createNarrationMessage() {
|
||||
return this.createNarration.createNarrationMessage(() -> {
|
||||
return super.createNarrationMessage();
|
||||
});
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput p_259196_) {
|
||||
this.defaultButtonNarrationText(p_259196_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Builder {
|
||||
private final Component message;
|
||||
private final Button.OnPress onPress;
|
||||
@Nullable
|
||||
private Tooltip tooltip;
|
||||
private int x;
|
||||
private int y;
|
||||
private int width = 150;
|
||||
private int height = 20;
|
||||
private Button.CreateNarration createNarration = Button.DEFAULT_NARRATION;
|
||||
|
||||
public Builder(Component p_254097_, Button.OnPress p_253761_) {
|
||||
this.message = p_254097_;
|
||||
this.onPress = p_253761_;
|
||||
}
|
||||
|
||||
public Button.Builder pos(int p_254538_, int p_254216_) {
|
||||
this.x = p_254538_;
|
||||
this.y = p_254216_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button.Builder width(int p_254259_) {
|
||||
this.width = p_254259_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button.Builder size(int p_253727_, int p_254457_) {
|
||||
this.width = p_253727_;
|
||||
this.height = p_254457_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button.Builder bounds(int p_254166_, int p_253872_, int p_254522_, int p_253985_) {
|
||||
return this.pos(p_254166_, p_253872_).size(p_254522_, p_253985_);
|
||||
}
|
||||
|
||||
public Button.Builder tooltip(@Nullable Tooltip p_259609_) {
|
||||
this.tooltip = p_259609_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button.Builder createNarration(Button.CreateNarration p_253638_) {
|
||||
this.createNarration = p_253638_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button build() {
|
||||
return build(Button::new);
|
||||
}
|
||||
|
||||
public Button build(java.util.function.Function<Builder, Button> builder) {
|
||||
return builder.apply(this);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface CreateNarration {
|
||||
MutableComponent createNarrationMessage(Supplier<MutableComponent> p_253695_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface OnPress {
|
||||
void onPress(Button p_93751_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,476 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.client.GuiMessage;
|
||||
import net.minecraft.client.GuiMessageTag;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.ChatScreen;
|
||||
import net.minecraft.client.multiplayer.chat.ChatListener;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MessageSignature;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.player.ChatVisiblity;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ChatComponent {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int MAX_CHAT_HISTORY = 100;
|
||||
private static final int MESSAGE_NOT_FOUND = -1;
|
||||
private static final int MESSAGE_INDENT = 4;
|
||||
private static final int MESSAGE_TAG_MARGIN_LEFT = 4;
|
||||
private static final int BOTTOM_MARGIN = 40;
|
||||
private static final int TIME_BEFORE_MESSAGE_DELETION = 60;
|
||||
private static final Component DELETED_CHAT_MESSAGE = Component.translatable("chat.deleted_marker").withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC);
|
||||
private final Minecraft minecraft;
|
||||
private final List<String> recentChat = Lists.newArrayList();
|
||||
private final List<GuiMessage> allMessages = Lists.newArrayList();
|
||||
private final List<GuiMessage.Line> trimmedMessages = Lists.newArrayList();
|
||||
private int chatScrollbarPos;
|
||||
private boolean newMessageSinceScroll;
|
||||
private final List<ChatComponent.DelayedMessageDeletion> messageDeletionQueue = new ArrayList<>();
|
||||
|
||||
public ChatComponent(Minecraft p_93768_) {
|
||||
this.minecraft = p_93768_;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (!this.messageDeletionQueue.isEmpty()) {
|
||||
this.processMessageDeletionQueue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282077_, int p_283491_, int p_282406_, int p_283111_) {
|
||||
if (!this.isChatHidden()) {
|
||||
int i = this.getLinesPerPage();
|
||||
int j = this.trimmedMessages.size();
|
||||
if (j > 0) {
|
||||
boolean flag = this.isChatFocused();
|
||||
float f = (float)this.getScale();
|
||||
int k = Mth.ceil((float)this.getWidth() / f);
|
||||
int l = p_282077_.guiHeight();
|
||||
p_282077_.pose().pushPose();
|
||||
p_282077_.pose().scale(f, f, 1.0F);
|
||||
p_282077_.pose().translate(4.0F, 0.0F, 0.0F);
|
||||
int i1 = Mth.floor((float)(l - 40) / f);
|
||||
int j1 = this.getMessageEndIndexAt(this.screenToChatX((double)p_282406_), this.screenToChatY((double)p_283111_));
|
||||
double d0 = this.minecraft.options.chatOpacity().get() * (double)0.9F + (double)0.1F;
|
||||
double d1 = this.minecraft.options.textBackgroundOpacity().get();
|
||||
double d2 = this.minecraft.options.chatLineSpacing().get();
|
||||
int k1 = this.getLineHeight();
|
||||
int l1 = (int)Math.round(-8.0D * (d2 + 1.0D) + 4.0D * d2);
|
||||
int i2 = 0;
|
||||
|
||||
for(int j2 = 0; j2 + this.chatScrollbarPos < this.trimmedMessages.size() && j2 < i; ++j2) {
|
||||
int k2 = j2 + this.chatScrollbarPos;
|
||||
GuiMessage.Line guimessage$line = this.trimmedMessages.get(k2);
|
||||
if (guimessage$line != null) {
|
||||
int l2 = p_283491_ - guimessage$line.addedTime();
|
||||
if (l2 < 200 || flag) {
|
||||
double d3 = flag ? 1.0D : getTimeFactor(l2);
|
||||
int j3 = (int)(255.0D * d3 * d0);
|
||||
int k3 = (int)(255.0D * d3 * d1);
|
||||
++i2;
|
||||
if (j3 > 3) {
|
||||
int l3 = 0;
|
||||
int i4 = i1 - j2 * k1;
|
||||
int j4 = i4 + l1;
|
||||
p_282077_.pose().pushPose();
|
||||
p_282077_.pose().translate(0.0F, 0.0F, 50.0F);
|
||||
p_282077_.fill(-4, i4 - k1, 0 + k + 4 + 4, i4, k3 << 24);
|
||||
GuiMessageTag guimessagetag = guimessage$line.tag();
|
||||
if (guimessagetag != null) {
|
||||
int k4 = guimessagetag.indicatorColor() | j3 << 24;
|
||||
p_282077_.fill(-4, i4 - k1, -2, i4, k4);
|
||||
if (k2 == j1 && guimessagetag.icon() != null) {
|
||||
int l4 = this.getTagIconLeft(guimessage$line);
|
||||
int i5 = j4 + 9;
|
||||
this.drawTagIcon(p_282077_, l4, i5, guimessagetag.icon());
|
||||
}
|
||||
}
|
||||
|
||||
p_282077_.pose().translate(0.0F, 0.0F, 50.0F);
|
||||
p_282077_.drawString(this.minecraft.font, guimessage$line.content(), 0, j4, 16777215 + (j3 << 24));
|
||||
p_282077_.pose().popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long j5 = this.minecraft.getChatListener().queueSize();
|
||||
if (j5 > 0L) {
|
||||
int k5 = (int)(128.0D * d0);
|
||||
int i6 = (int)(255.0D * d1);
|
||||
p_282077_.pose().pushPose();
|
||||
p_282077_.pose().translate(0.0F, (float)i1, 50.0F);
|
||||
p_282077_.fill(-2, 0, k + 4, 9, i6 << 24);
|
||||
p_282077_.pose().translate(0.0F, 0.0F, 50.0F);
|
||||
p_282077_.drawString(this.minecraft.font, Component.translatable("chat.queue", j5), 0, 1, 16777215 + (k5 << 24));
|
||||
p_282077_.pose().popPose();
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
int l5 = this.getLineHeight();
|
||||
int j6 = j * l5;
|
||||
int k6 = i2 * l5;
|
||||
int i3 = this.chatScrollbarPos * k6 / j - i1;
|
||||
int l6 = k6 * k6 / j6;
|
||||
if (j6 != k6) {
|
||||
int i7 = i3 > 0 ? 170 : 96;
|
||||
int j7 = this.newMessageSinceScroll ? 13382451 : 3355562;
|
||||
int k7 = k + 4;
|
||||
p_282077_.fill(k7, -i3, k7 + 2, -i3 - l6, j7 + (i7 << 24));
|
||||
p_282077_.fill(k7 + 2, -i3, k7 + 1, -i3 - l6, 13421772 + (i7 << 24));
|
||||
}
|
||||
}
|
||||
|
||||
p_282077_.pose().popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawTagIcon(GuiGraphics p_283206_, int p_281677_, int p_281878_, GuiMessageTag.Icon p_282783_) {
|
||||
int i = p_281878_ - p_282783_.height - 1;
|
||||
p_282783_.draw(p_283206_, p_281677_, i);
|
||||
}
|
||||
|
||||
private int getTagIconLeft(GuiMessage.Line p_240622_) {
|
||||
return this.minecraft.font.width(p_240622_.content()) + 4;
|
||||
}
|
||||
|
||||
private boolean isChatHidden() {
|
||||
return this.minecraft.options.chatVisibility().get() == ChatVisiblity.HIDDEN;
|
||||
}
|
||||
|
||||
private static double getTimeFactor(int p_93776_) {
|
||||
double d0 = (double)p_93776_ / 200.0D;
|
||||
d0 = 1.0D - d0;
|
||||
d0 *= 10.0D;
|
||||
d0 = Mth.clamp(d0, 0.0D, 1.0D);
|
||||
return d0 * d0;
|
||||
}
|
||||
|
||||
public void clearMessages(boolean p_93796_) {
|
||||
this.minecraft.getChatListener().clearQueue();
|
||||
this.messageDeletionQueue.clear();
|
||||
this.trimmedMessages.clear();
|
||||
this.allMessages.clear();
|
||||
if (p_93796_) {
|
||||
this.recentChat.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addMessage(Component p_93786_) {
|
||||
this.addMessage(p_93786_, (MessageSignature)null, this.minecraft.isSingleplayer() ? GuiMessageTag.systemSinglePlayer() : GuiMessageTag.system());
|
||||
}
|
||||
|
||||
public void addMessage(Component p_241484_, @Nullable MessageSignature p_241323_, @Nullable GuiMessageTag p_241297_) {
|
||||
this.logChatMessage(p_241484_, p_241297_);
|
||||
this.addMessage(p_241484_, p_241323_, this.minecraft.gui.getGuiTicks(), p_241297_, false);
|
||||
}
|
||||
|
||||
private void logChatMessage(Component p_242919_, @Nullable GuiMessageTag p_242840_) {
|
||||
String s = p_242919_.getString().replaceAll("\r", "\\\\r").replaceAll("\n", "\\\\n");
|
||||
String s1 = Optionull.map(p_242840_, GuiMessageTag::logTag);
|
||||
if (s1 != null) {
|
||||
LOGGER.info("[{}] [CHAT] {}", s1, s);
|
||||
} else {
|
||||
LOGGER.info("[CHAT] {}", (Object)s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addMessage(Component p_240562_, @Nullable MessageSignature p_241566_, int p_240583_, @Nullable GuiMessageTag p_240624_, boolean p_240558_) {
|
||||
int i = Mth.floor((double)this.getWidth() / this.getScale());
|
||||
if (p_240624_ != null && p_240624_.icon() != null) {
|
||||
i -= p_240624_.icon().width + 4 + 2;
|
||||
}
|
||||
|
||||
List<FormattedCharSequence> list = ComponentRenderUtils.wrapComponents(p_240562_, i, this.minecraft.font);
|
||||
boolean flag = this.isChatFocused();
|
||||
|
||||
for(int j = 0; j < list.size(); ++j) {
|
||||
FormattedCharSequence formattedcharsequence = list.get(j);
|
||||
if (flag && this.chatScrollbarPos > 0) {
|
||||
this.newMessageSinceScroll = true;
|
||||
this.scrollChat(1);
|
||||
}
|
||||
|
||||
boolean flag1 = j == list.size() - 1;
|
||||
this.trimmedMessages.add(0, new GuiMessage.Line(p_240583_, formattedcharsequence, p_240624_, flag1));
|
||||
}
|
||||
|
||||
while(this.trimmedMessages.size() > 100) {
|
||||
this.trimmedMessages.remove(this.trimmedMessages.size() - 1);
|
||||
}
|
||||
|
||||
if (!p_240558_) {
|
||||
this.allMessages.add(0, new GuiMessage(p_240583_, p_240562_, p_241566_, p_240624_));
|
||||
|
||||
while(this.allMessages.size() > 100) {
|
||||
this.allMessages.remove(this.allMessages.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void processMessageDeletionQueue() {
|
||||
int i = this.minecraft.gui.getGuiTicks();
|
||||
this.messageDeletionQueue.removeIf((p_250713_) -> {
|
||||
if (i >= p_250713_.deletableAfter()) {
|
||||
return this.deleteMessageOrDelay(p_250713_.signature()) == null;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteMessage(MessageSignature p_241324_) {
|
||||
ChatComponent.DelayedMessageDeletion chatcomponent$delayedmessagedeletion = this.deleteMessageOrDelay(p_241324_);
|
||||
if (chatcomponent$delayedmessagedeletion != null) {
|
||||
this.messageDeletionQueue.add(chatcomponent$delayedmessagedeletion);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ChatComponent.DelayedMessageDeletion deleteMessageOrDelay(MessageSignature p_251812_) {
|
||||
int i = this.minecraft.gui.getGuiTicks();
|
||||
ListIterator<GuiMessage> listiterator = this.allMessages.listIterator();
|
||||
|
||||
while(listiterator.hasNext()) {
|
||||
GuiMessage guimessage = listiterator.next();
|
||||
if (p_251812_.equals(guimessage.signature())) {
|
||||
int j = guimessage.addedTime() + 60;
|
||||
if (i >= j) {
|
||||
listiterator.set(this.createDeletedMarker(guimessage));
|
||||
this.refreshTrimmedMessage();
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ChatComponent.DelayedMessageDeletion(p_251812_, j);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private GuiMessage createDeletedMarker(GuiMessage p_249789_) {
|
||||
return new GuiMessage(p_249789_.addedTime(), DELETED_CHAT_MESSAGE, (MessageSignature)null, GuiMessageTag.system());
|
||||
}
|
||||
|
||||
public void rescaleChat() {
|
||||
this.resetChatScroll();
|
||||
this.refreshTrimmedMessage();
|
||||
}
|
||||
|
||||
private void refreshTrimmedMessage() {
|
||||
this.trimmedMessages.clear();
|
||||
|
||||
for(int i = this.allMessages.size() - 1; i >= 0; --i) {
|
||||
GuiMessage guimessage = this.allMessages.get(i);
|
||||
this.addMessage(guimessage.content(), guimessage.signature(), guimessage.addedTime(), guimessage.tag(), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<String> getRecentChat() {
|
||||
return this.recentChat;
|
||||
}
|
||||
|
||||
public void addRecentChat(String p_93784_) {
|
||||
if (this.recentChat.isEmpty() || !this.recentChat.get(this.recentChat.size() - 1).equals(p_93784_)) {
|
||||
this.recentChat.add(p_93784_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void resetChatScroll() {
|
||||
this.chatScrollbarPos = 0;
|
||||
this.newMessageSinceScroll = false;
|
||||
}
|
||||
|
||||
public void scrollChat(int p_205361_) {
|
||||
this.chatScrollbarPos += p_205361_;
|
||||
int i = this.trimmedMessages.size();
|
||||
if (this.chatScrollbarPos > i - this.getLinesPerPage()) {
|
||||
this.chatScrollbarPos = i - this.getLinesPerPage();
|
||||
}
|
||||
|
||||
if (this.chatScrollbarPos <= 0) {
|
||||
this.chatScrollbarPos = 0;
|
||||
this.newMessageSinceScroll = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean handleChatQueueClicked(double p_93773_, double p_93774_) {
|
||||
if (this.isChatFocused() && !this.minecraft.options.hideGui && !this.isChatHidden()) {
|
||||
ChatListener chatlistener = this.minecraft.getChatListener();
|
||||
if (chatlistener.queueSize() == 0L) {
|
||||
return false;
|
||||
} else {
|
||||
double d0 = p_93773_ - 2.0D;
|
||||
double d1 = (double)this.minecraft.getWindow().getGuiScaledHeight() - p_93774_ - 40.0D;
|
||||
if (d0 <= (double)Mth.floor((double)this.getWidth() / this.getScale()) && d1 < 0.0D && d1 > (double)Mth.floor(-9.0D * this.getScale())) {
|
||||
chatlistener.acceptNextDelayedMessage();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Style getClickedComponentStyleAt(double p_93801_, double p_93802_) {
|
||||
double d0 = this.screenToChatX(p_93801_);
|
||||
double d1 = this.screenToChatY(p_93802_);
|
||||
int i = this.getMessageLineIndexAt(d0, d1);
|
||||
if (i >= 0 && i < this.trimmedMessages.size()) {
|
||||
GuiMessage.Line guimessage$line = this.trimmedMessages.get(i);
|
||||
return this.minecraft.font.getSplitter().componentStyleAtWidth(guimessage$line.content(), Mth.floor(d0));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GuiMessageTag getMessageTagAt(double p_240576_, double p_240554_) {
|
||||
double d0 = this.screenToChatX(p_240576_);
|
||||
double d1 = this.screenToChatY(p_240554_);
|
||||
int i = this.getMessageEndIndexAt(d0, d1);
|
||||
if (i >= 0 && i < this.trimmedMessages.size()) {
|
||||
GuiMessage.Line guimessage$line = this.trimmedMessages.get(i);
|
||||
GuiMessageTag guimessagetag = guimessage$line.tag();
|
||||
if (guimessagetag != null && this.hasSelectedMessageTag(d0, guimessage$line, guimessagetag)) {
|
||||
return guimessagetag;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean hasSelectedMessageTag(double p_240619_, GuiMessage.Line p_240547_, GuiMessageTag p_240637_) {
|
||||
if (p_240619_ < 0.0D) {
|
||||
return true;
|
||||
} else {
|
||||
GuiMessageTag.Icon guimessagetag$icon = p_240637_.icon();
|
||||
if (guimessagetag$icon == null) {
|
||||
return false;
|
||||
} else {
|
||||
int i = this.getTagIconLeft(p_240547_);
|
||||
int j = i + guimessagetag$icon.width;
|
||||
return p_240619_ >= (double)i && p_240619_ <= (double)j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double screenToChatX(double p_240580_) {
|
||||
return p_240580_ / this.getScale() - 4.0D;
|
||||
}
|
||||
|
||||
private double screenToChatY(double p_240548_) {
|
||||
double d0 = (double)this.minecraft.getWindow().getGuiScaledHeight() - p_240548_ - 40.0D;
|
||||
return d0 / (this.getScale() * (double)this.getLineHeight());
|
||||
}
|
||||
|
||||
private int getMessageEndIndexAt(double p_249245_, double p_252282_) {
|
||||
int i = this.getMessageLineIndexAt(p_249245_, p_252282_);
|
||||
if (i == -1) {
|
||||
return -1;
|
||||
} else {
|
||||
while(i >= 0) {
|
||||
if (this.trimmedMessages.get(i).endOfEntry()) {
|
||||
return i;
|
||||
}
|
||||
|
||||
--i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
private int getMessageLineIndexAt(double p_249099_, double p_250008_) {
|
||||
if (this.isChatFocused() && !this.minecraft.options.hideGui && !this.isChatHidden()) {
|
||||
if (!(p_249099_ < -4.0D) && !(p_249099_ > (double)Mth.floor((double)this.getWidth() / this.getScale()))) {
|
||||
int i = Math.min(this.getLinesPerPage(), this.trimmedMessages.size());
|
||||
if (p_250008_ >= 0.0D && p_250008_ < (double)i) {
|
||||
int j = Mth.floor(p_250008_ + (double)this.chatScrollbarPos);
|
||||
if (j >= 0 && j < this.trimmedMessages.size()) {
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isChatFocused() {
|
||||
return this.minecraft.screen instanceof ChatScreen;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return getWidth(this.minecraft.options.chatWidth().get());
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return getHeight(this.isChatFocused() ? this.minecraft.options.chatHeightFocused().get() : this.minecraft.options.chatHeightUnfocused().get());
|
||||
}
|
||||
|
||||
public double getScale() {
|
||||
return this.minecraft.options.chatScale().get();
|
||||
}
|
||||
|
||||
public static int getWidth(double p_93799_) {
|
||||
int i = 320;
|
||||
int j = 40;
|
||||
return Mth.floor(p_93799_ * 280.0D + 40.0D);
|
||||
}
|
||||
|
||||
public static int getHeight(double p_93812_) {
|
||||
int i = 180;
|
||||
int j = 20;
|
||||
return Mth.floor(p_93812_ * 160.0D + 20.0D);
|
||||
}
|
||||
|
||||
public static double defaultUnfocusedPct() {
|
||||
int i = 180;
|
||||
int j = 20;
|
||||
return 70.0D / (double)(getHeight(1.0D) - 20);
|
||||
}
|
||||
|
||||
public int getLinesPerPage() {
|
||||
return this.getHeight() / this.getLineHeight();
|
||||
}
|
||||
|
||||
private int getLineHeight() {
|
||||
return (int)(9.0D * (this.minecraft.options.chatLineSpacing().get() + 1.0D));
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static record DelayedMessageDeletion(MessageSignature signature, int deletableAfter) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Checkbox extends AbstractButton {
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/gui/checkbox.png");
|
||||
private static final int TEXT_COLOR = 14737632;
|
||||
private boolean selected;
|
||||
private final boolean showLabel;
|
||||
|
||||
public Checkbox(int p_93826_, int p_93827_, int p_93828_, int p_93829_, Component p_93830_, boolean p_93831_) {
|
||||
this(p_93826_, p_93827_, p_93828_, p_93829_, p_93830_, p_93831_, true);
|
||||
}
|
||||
|
||||
public Checkbox(int p_93833_, int p_93834_, int p_93835_, int p_93836_, Component p_93837_, boolean p_93838_, boolean p_93839_) {
|
||||
super(p_93833_, p_93834_, p_93835_, p_93836_, p_93837_);
|
||||
this.selected = p_93838_;
|
||||
this.showLabel = p_93839_;
|
||||
}
|
||||
|
||||
public void onPress() {
|
||||
this.selected = !this.selected;
|
||||
}
|
||||
|
||||
public boolean selected() {
|
||||
return this.selected;
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput p_260253_) {
|
||||
p_260253_.add(NarratedElementType.TITLE, this.createNarrationMessage());
|
||||
if (this.active) {
|
||||
if (this.isFocused()) {
|
||||
p_260253_.add(NarratedElementType.USAGE, Component.translatable("narration.checkbox.usage.focused"));
|
||||
} else {
|
||||
p_260253_.add(NarratedElementType.USAGE, Component.translatable("narration.checkbox.usage.hovered"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_283124_, int p_282925_, int p_282705_, float p_282612_) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
RenderSystem.enableDepthTest();
|
||||
Font font = minecraft.font;
|
||||
p_283124_.setColor(1.0F, 1.0F, 1.0F, this.alpha);
|
||||
RenderSystem.enableBlend();
|
||||
p_283124_.blit(TEXTURE, this.getX(), this.getY(), this.isFocused() ? 20.0F : 0.0F, this.selected ? 20.0F : 0.0F, 20, this.height, 64, 64);
|
||||
p_283124_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
if (this.showLabel) {
|
||||
p_283124_.drawString(font, this.getMessage(), this.getX() + 24, this.getY() + (this.height - 8) / 2, 14737632 | Mth.ceil(this.alpha * 255.0F) << 24);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,535 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.Message;
|
||||
import com.mojang.brigadier.ParseResults;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.context.ParsedArgument;
|
||||
import com.mojang.brigadier.context.SuggestionContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestion;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.Rect2i;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.commands.SharedSuggestionProvider;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.ComponentUtils;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class CommandSuggestions {
|
||||
private static final Pattern WHITESPACE_PATTERN = Pattern.compile("(\\s+)");
|
||||
private static final Style UNPARSED_STYLE = Style.EMPTY.withColor(ChatFormatting.RED);
|
||||
private static final Style LITERAL_STYLE = Style.EMPTY.withColor(ChatFormatting.GRAY);
|
||||
private static final List<Style> ARGUMENT_STYLES = Stream.of(ChatFormatting.AQUA, ChatFormatting.YELLOW, ChatFormatting.GREEN, ChatFormatting.LIGHT_PURPLE, ChatFormatting.GOLD).map(Style.EMPTY::withColor).collect(ImmutableList.toImmutableList());
|
||||
final Minecraft minecraft;
|
||||
private final Screen screen;
|
||||
final EditBox input;
|
||||
final Font font;
|
||||
private final boolean commandsOnly;
|
||||
private final boolean onlyShowIfCursorPastError;
|
||||
final int lineStartOffset;
|
||||
final int suggestionLineLimit;
|
||||
final boolean anchorToBottom;
|
||||
final int fillColor;
|
||||
private final List<FormattedCharSequence> commandUsage = Lists.newArrayList();
|
||||
private int commandUsagePosition;
|
||||
private int commandUsageWidth;
|
||||
@Nullable
|
||||
private ParseResults<SharedSuggestionProvider> currentParse;
|
||||
@Nullable
|
||||
private CompletableFuture<Suggestions> pendingSuggestions;
|
||||
@Nullable
|
||||
private CommandSuggestions.SuggestionsList suggestions;
|
||||
private boolean allowSuggestions;
|
||||
boolean keepSuggestions;
|
||||
|
||||
public CommandSuggestions(Minecraft p_93871_, Screen p_93872_, EditBox p_93873_, Font p_93874_, boolean p_93875_, boolean p_93876_, int p_93877_, int p_93878_, boolean p_93879_, int p_93880_) {
|
||||
this.minecraft = p_93871_;
|
||||
this.screen = p_93872_;
|
||||
this.input = p_93873_;
|
||||
this.font = p_93874_;
|
||||
this.commandsOnly = p_93875_;
|
||||
this.onlyShowIfCursorPastError = p_93876_;
|
||||
this.lineStartOffset = p_93877_;
|
||||
this.suggestionLineLimit = p_93878_;
|
||||
this.anchorToBottom = p_93879_;
|
||||
this.fillColor = p_93880_;
|
||||
p_93873_.setFormatter(this::formatChat);
|
||||
}
|
||||
|
||||
public void setAllowSuggestions(boolean p_93923_) {
|
||||
this.allowSuggestions = p_93923_;
|
||||
if (!p_93923_) {
|
||||
this.suggestions = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_93889_, int p_93890_, int p_93891_) {
|
||||
if (this.suggestions != null && this.suggestions.keyPressed(p_93889_, p_93890_, p_93891_)) {
|
||||
return true;
|
||||
} else if (this.screen.getFocused() == this.input && p_93889_ == 258) {
|
||||
this.showSuggestions(true);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double p_93883_) {
|
||||
return this.suggestions != null && this.suggestions.mouseScrolled(Mth.clamp(p_93883_, -1.0D, 1.0D));
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_93885_, double p_93886_, int p_93887_) {
|
||||
return this.suggestions != null && this.suggestions.mouseClicked((int)p_93885_, (int)p_93886_, p_93887_);
|
||||
}
|
||||
|
||||
public void showSuggestions(boolean p_93931_) {
|
||||
if (this.pendingSuggestions != null && this.pendingSuggestions.isDone()) {
|
||||
Suggestions suggestions = this.pendingSuggestions.join();
|
||||
if (!suggestions.isEmpty()) {
|
||||
int i = 0;
|
||||
|
||||
for(Suggestion suggestion : suggestions.getList()) {
|
||||
i = Math.max(i, this.font.width(suggestion.getText()));
|
||||
}
|
||||
|
||||
int j = Mth.clamp(this.input.getScreenX(suggestions.getRange().getStart()), 0, this.input.getScreenX(0) + this.input.getInnerWidth() - i);
|
||||
int k = this.anchorToBottom ? this.screen.height - 12 : 72;
|
||||
this.suggestions = new CommandSuggestions.SuggestionsList(j, k, i, this.sortSuggestions(suggestions), p_93931_);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
this.suggestions = null;
|
||||
}
|
||||
|
||||
private List<Suggestion> sortSuggestions(Suggestions p_93899_) {
|
||||
String s = this.input.getValue().substring(0, this.input.getCursorPosition());
|
||||
int i = getLastWordIndex(s);
|
||||
String s1 = s.substring(i).toLowerCase(Locale.ROOT);
|
||||
List<Suggestion> list = Lists.newArrayList();
|
||||
List<Suggestion> list1 = Lists.newArrayList();
|
||||
|
||||
for(Suggestion suggestion : p_93899_.getList()) {
|
||||
if (!suggestion.getText().startsWith(s1) && !suggestion.getText().startsWith("minecraft:" + s1)) {
|
||||
list1.add(suggestion);
|
||||
} else {
|
||||
list.add(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
list.addAll(list1);
|
||||
return list;
|
||||
}
|
||||
|
||||
public void updateCommandInfo() {
|
||||
String s = this.input.getValue();
|
||||
if (this.currentParse != null && !this.currentParse.getReader().getString().equals(s)) {
|
||||
this.currentParse = null;
|
||||
}
|
||||
|
||||
if (!this.keepSuggestions) {
|
||||
this.input.setSuggestion((String)null);
|
||||
this.suggestions = null;
|
||||
}
|
||||
|
||||
this.commandUsage.clear();
|
||||
StringReader stringreader = new StringReader(s);
|
||||
boolean flag = stringreader.canRead() && stringreader.peek() == '/';
|
||||
if (flag) {
|
||||
stringreader.skip();
|
||||
}
|
||||
|
||||
boolean flag1 = this.commandsOnly || flag;
|
||||
int i = this.input.getCursorPosition();
|
||||
if (flag1) {
|
||||
CommandDispatcher<SharedSuggestionProvider> commanddispatcher = this.minecraft.player.connection.getCommands();
|
||||
if (this.currentParse == null) {
|
||||
this.currentParse = commanddispatcher.parse(stringreader, this.minecraft.player.connection.getSuggestionsProvider());
|
||||
}
|
||||
|
||||
int j = this.onlyShowIfCursorPastError ? stringreader.getCursor() : 1;
|
||||
if (i >= j && (this.suggestions == null || !this.keepSuggestions)) {
|
||||
this.pendingSuggestions = commanddispatcher.getCompletionSuggestions(this.currentParse, i);
|
||||
this.pendingSuggestions.thenRun(() -> {
|
||||
if (this.pendingSuggestions.isDone()) {
|
||||
this.updateUsageInfo();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
String s1 = s.substring(0, i);
|
||||
int k = getLastWordIndex(s1);
|
||||
Collection<String> collection = this.minecraft.player.connection.getSuggestionsProvider().getCustomTabSugggestions();
|
||||
this.pendingSuggestions = SharedSuggestionProvider.suggest(collection, new SuggestionsBuilder(s1, k));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static int getLastWordIndex(String p_93913_) {
|
||||
if (Strings.isNullOrEmpty(p_93913_)) {
|
||||
return 0;
|
||||
} else {
|
||||
int i = 0;
|
||||
|
||||
for(Matcher matcher = WHITESPACE_PATTERN.matcher(p_93913_); matcher.find(); i = matcher.end()) {
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
private static FormattedCharSequence getExceptionMessage(CommandSyntaxException p_93897_) {
|
||||
Component component = ComponentUtils.fromMessage(p_93897_.getRawMessage());
|
||||
String s = p_93897_.getContext();
|
||||
return s == null ? component.getVisualOrderText() : Component.translatable("command.context.parse_error", component, p_93897_.getCursor(), s).getVisualOrderText();
|
||||
}
|
||||
|
||||
private void updateUsageInfo() {
|
||||
boolean flag = false;
|
||||
if (this.input.getCursorPosition() == this.input.getValue().length()) {
|
||||
if (this.pendingSuggestions.join().isEmpty() && !this.currentParse.getExceptions().isEmpty()) {
|
||||
int i = 0;
|
||||
|
||||
for(Map.Entry<CommandNode<SharedSuggestionProvider>, CommandSyntaxException> entry : this.currentParse.getExceptions().entrySet()) {
|
||||
CommandSyntaxException commandsyntaxexception = entry.getValue();
|
||||
if (commandsyntaxexception.getType() == CommandSyntaxException.BUILT_IN_EXCEPTIONS.literalIncorrect()) {
|
||||
++i;
|
||||
} else {
|
||||
this.commandUsage.add(getExceptionMessage(commandsyntaxexception));
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
this.commandUsage.add(getExceptionMessage(CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand().create()));
|
||||
}
|
||||
} else if (this.currentParse.getReader().canRead()) {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.commandUsagePosition = 0;
|
||||
this.commandUsageWidth = this.screen.width;
|
||||
if (this.commandUsage.isEmpty() && !this.fillNodeUsage(ChatFormatting.GRAY) && flag) {
|
||||
this.commandUsage.add(getExceptionMessage(Commands.getParseException(this.currentParse)));
|
||||
}
|
||||
|
||||
this.suggestions = null;
|
||||
if (this.allowSuggestions && this.minecraft.options.autoSuggestions().get()) {
|
||||
this.showSuggestions(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean fillNodeUsage(ChatFormatting p_289002_) {
|
||||
CommandContextBuilder<SharedSuggestionProvider> commandcontextbuilder = this.currentParse.getContext();
|
||||
SuggestionContext<SharedSuggestionProvider> suggestioncontext = commandcontextbuilder.findSuggestionContext(this.input.getCursorPosition());
|
||||
Map<CommandNode<SharedSuggestionProvider>, String> map = this.minecraft.player.connection.getCommands().getSmartUsage(suggestioncontext.parent, this.minecraft.player.connection.getSuggestionsProvider());
|
||||
List<FormattedCharSequence> list = Lists.newArrayList();
|
||||
int i = 0;
|
||||
Style style = Style.EMPTY.withColor(p_289002_);
|
||||
|
||||
for(Map.Entry<CommandNode<SharedSuggestionProvider>, String> entry : map.entrySet()) {
|
||||
if (!(entry.getKey() instanceof LiteralCommandNode)) {
|
||||
list.add(FormattedCharSequence.forward(entry.getValue(), style));
|
||||
i = Math.max(i, this.font.width(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
this.commandUsage.addAll(list);
|
||||
this.commandUsagePosition = Mth.clamp(this.input.getScreenX(suggestioncontext.startPos), 0, this.input.getScreenX(0) + this.input.getInnerWidth() - i);
|
||||
this.commandUsageWidth = i;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private FormattedCharSequence formatChat(String p_93915_, int p_93916_) {
|
||||
return this.currentParse != null ? formatText(this.currentParse, p_93915_, p_93916_) : FormattedCharSequence.forward(p_93915_, Style.EMPTY);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static String calculateSuggestionSuffix(String p_93928_, String p_93929_) {
|
||||
return p_93929_.startsWith(p_93928_) ? p_93929_.substring(p_93928_.length()) : null;
|
||||
}
|
||||
|
||||
private static FormattedCharSequence formatText(ParseResults<SharedSuggestionProvider> p_93893_, String p_93894_, int p_93895_) {
|
||||
List<FormattedCharSequence> list = Lists.newArrayList();
|
||||
int i = 0;
|
||||
int j = -1;
|
||||
CommandContextBuilder<SharedSuggestionProvider> commandcontextbuilder = p_93893_.getContext().getLastChild();
|
||||
|
||||
for(ParsedArgument<SharedSuggestionProvider, ?> parsedargument : commandcontextbuilder.getArguments().values()) {
|
||||
++j;
|
||||
if (j >= ARGUMENT_STYLES.size()) {
|
||||
j = 0;
|
||||
}
|
||||
|
||||
int k = Math.max(parsedargument.getRange().getStart() - p_93895_, 0);
|
||||
if (k >= p_93894_.length()) {
|
||||
break;
|
||||
}
|
||||
|
||||
int l = Math.min(parsedargument.getRange().getEnd() - p_93895_, p_93894_.length());
|
||||
if (l > 0) {
|
||||
list.add(FormattedCharSequence.forward(p_93894_.substring(i, k), LITERAL_STYLE));
|
||||
list.add(FormattedCharSequence.forward(p_93894_.substring(k, l), ARGUMENT_STYLES.get(j)));
|
||||
i = l;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_93893_.getReader().canRead()) {
|
||||
int i1 = Math.max(p_93893_.getReader().getCursor() - p_93895_, 0);
|
||||
if (i1 < p_93894_.length()) {
|
||||
int j1 = Math.min(i1 + p_93893_.getReader().getRemainingLength(), p_93894_.length());
|
||||
list.add(FormattedCharSequence.forward(p_93894_.substring(i, i1), LITERAL_STYLE));
|
||||
list.add(FormattedCharSequence.forward(p_93894_.substring(i1, j1), UNPARSED_STYLE));
|
||||
i = j1;
|
||||
}
|
||||
}
|
||||
|
||||
list.add(FormattedCharSequence.forward(p_93894_.substring(i), LITERAL_STYLE));
|
||||
return FormattedCharSequence.composite(list);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282650_, int p_282266_, int p_281963_) {
|
||||
if (!this.renderSuggestions(p_282650_, p_282266_, p_281963_)) {
|
||||
this.renderUsage(p_282650_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean renderSuggestions(GuiGraphics p_283503_, int p_281628_, int p_282260_) {
|
||||
if (this.suggestions != null) {
|
||||
this.suggestions.render(p_283503_, p_281628_, p_282260_);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void renderUsage(GuiGraphics p_282763_) {
|
||||
int i = 0;
|
||||
|
||||
for(FormattedCharSequence formattedcharsequence : this.commandUsage) {
|
||||
int j = this.anchorToBottom ? this.screen.height - 14 - 13 - 12 * i : 72 + 12 * i;
|
||||
p_282763_.fill(this.commandUsagePosition - 1, j, this.commandUsagePosition + this.commandUsageWidth + 1, j + 12, this.fillColor);
|
||||
p_282763_.drawString(this.font, formattedcharsequence, this.commandUsagePosition, j + 2, -1);
|
||||
++i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
return (Component)(this.suggestions != null ? CommonComponents.NEW_LINE.copy().append(this.suggestions.getNarrationMessage()) : CommonComponents.EMPTY);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class SuggestionsList {
|
||||
private final Rect2i rect;
|
||||
private final String originalContents;
|
||||
private final List<Suggestion> suggestionList;
|
||||
private int offset;
|
||||
private int current;
|
||||
private Vec2 lastMouse = Vec2.ZERO;
|
||||
private boolean tabCycles;
|
||||
private int lastNarratedEntry;
|
||||
|
||||
SuggestionsList(int p_93957_, int p_93958_, int p_93959_, List<Suggestion> p_93960_, boolean p_93961_) {
|
||||
int i = p_93957_ - 1;
|
||||
int j = CommandSuggestions.this.anchorToBottom ? p_93958_ - 3 - Math.min(p_93960_.size(), CommandSuggestions.this.suggestionLineLimit) * 12 : p_93958_;
|
||||
this.rect = new Rect2i(i, j, p_93959_ + 1, Math.min(p_93960_.size(), CommandSuggestions.this.suggestionLineLimit) * 12);
|
||||
this.originalContents = CommandSuggestions.this.input.getValue();
|
||||
this.lastNarratedEntry = p_93961_ ? -1 : 0;
|
||||
this.suggestionList = p_93960_;
|
||||
this.select(0);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282264_, int p_283591_, int p_283236_) {
|
||||
int i = Math.min(this.suggestionList.size(), CommandSuggestions.this.suggestionLineLimit);
|
||||
int j = -5592406;
|
||||
boolean flag = this.offset > 0;
|
||||
boolean flag1 = this.suggestionList.size() > this.offset + i;
|
||||
boolean flag2 = flag || flag1;
|
||||
boolean flag3 = this.lastMouse.x != (float)p_283591_ || this.lastMouse.y != (float)p_283236_;
|
||||
if (flag3) {
|
||||
this.lastMouse = new Vec2((float)p_283591_, (float)p_283236_);
|
||||
}
|
||||
|
||||
if (flag2) {
|
||||
p_282264_.fill(this.rect.getX(), this.rect.getY() - 1, this.rect.getX() + this.rect.getWidth(), this.rect.getY(), CommandSuggestions.this.fillColor);
|
||||
p_282264_.fill(this.rect.getX(), this.rect.getY() + this.rect.getHeight(), this.rect.getX() + this.rect.getWidth(), this.rect.getY() + this.rect.getHeight() + 1, CommandSuggestions.this.fillColor);
|
||||
if (flag) {
|
||||
for(int k = 0; k < this.rect.getWidth(); ++k) {
|
||||
if (k % 2 == 0) {
|
||||
p_282264_.fill(this.rect.getX() + k, this.rect.getY() - 1, this.rect.getX() + k + 1, this.rect.getY(), -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag1) {
|
||||
for(int i1 = 0; i1 < this.rect.getWidth(); ++i1) {
|
||||
if (i1 % 2 == 0) {
|
||||
p_282264_.fill(this.rect.getX() + i1, this.rect.getY() + this.rect.getHeight(), this.rect.getX() + i1 + 1, this.rect.getY() + this.rect.getHeight() + 1, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean flag4 = false;
|
||||
|
||||
for(int l = 0; l < i; ++l) {
|
||||
Suggestion suggestion = this.suggestionList.get(l + this.offset);
|
||||
p_282264_.fill(this.rect.getX(), this.rect.getY() + 12 * l, this.rect.getX() + this.rect.getWidth(), this.rect.getY() + 12 * l + 12, CommandSuggestions.this.fillColor);
|
||||
if (p_283591_ > this.rect.getX() && p_283591_ < this.rect.getX() + this.rect.getWidth() && p_283236_ > this.rect.getY() + 12 * l && p_283236_ < this.rect.getY() + 12 * l + 12) {
|
||||
if (flag3) {
|
||||
this.select(l + this.offset);
|
||||
}
|
||||
|
||||
flag4 = true;
|
||||
}
|
||||
|
||||
p_282264_.drawString(CommandSuggestions.this.font, suggestion.getText(), this.rect.getX() + 1, this.rect.getY() + 2 + 12 * l, l + this.offset == this.current ? -256 : -5592406);
|
||||
}
|
||||
|
||||
if (flag4) {
|
||||
Message message = this.suggestionList.get(this.current).getTooltip();
|
||||
if (message != null) {
|
||||
p_282264_.renderTooltip(CommandSuggestions.this.font, ComponentUtils.fromMessage(message), p_283591_, p_283236_);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean mouseClicked(int p_93976_, int p_93977_, int p_93978_) {
|
||||
if (!this.rect.contains(p_93976_, p_93977_)) {
|
||||
return false;
|
||||
} else {
|
||||
int i = (p_93977_ - this.rect.getY()) / 12 + this.offset;
|
||||
if (i >= 0 && i < this.suggestionList.size()) {
|
||||
this.select(i);
|
||||
this.useSuggestion();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double p_93972_) {
|
||||
int i = (int)(CommandSuggestions.this.minecraft.mouseHandler.xpos() * (double)CommandSuggestions.this.minecraft.getWindow().getGuiScaledWidth() / (double)CommandSuggestions.this.minecraft.getWindow().getScreenWidth());
|
||||
int j = (int)(CommandSuggestions.this.minecraft.mouseHandler.ypos() * (double)CommandSuggestions.this.minecraft.getWindow().getGuiScaledHeight() / (double)CommandSuggestions.this.minecraft.getWindow().getScreenHeight());
|
||||
if (this.rect.contains(i, j)) {
|
||||
this.offset = Mth.clamp((int)((double)this.offset - p_93972_), 0, Math.max(this.suggestionList.size() - CommandSuggestions.this.suggestionLineLimit, 0));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_93989_, int p_93990_, int p_93991_) {
|
||||
if (p_93989_ == 265) {
|
||||
this.cycle(-1);
|
||||
this.tabCycles = false;
|
||||
return true;
|
||||
} else if (p_93989_ == 264) {
|
||||
this.cycle(1);
|
||||
this.tabCycles = false;
|
||||
return true;
|
||||
} else if (p_93989_ == 258) {
|
||||
if (this.tabCycles) {
|
||||
this.cycle(Screen.hasShiftDown() ? -1 : 1);
|
||||
}
|
||||
|
||||
this.useSuggestion();
|
||||
return true;
|
||||
} else if (p_93989_ == 256) {
|
||||
CommandSuggestions.this.hide();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void cycle(int p_93974_) {
|
||||
this.select(this.current + p_93974_);
|
||||
int i = this.offset;
|
||||
int j = this.offset + CommandSuggestions.this.suggestionLineLimit - 1;
|
||||
if (this.current < i) {
|
||||
this.offset = Mth.clamp(this.current, 0, Math.max(this.suggestionList.size() - CommandSuggestions.this.suggestionLineLimit, 0));
|
||||
} else if (this.current > j) {
|
||||
this.offset = Mth.clamp(this.current + CommandSuggestions.this.lineStartOffset - CommandSuggestions.this.suggestionLineLimit, 0, Math.max(this.suggestionList.size() - CommandSuggestions.this.suggestionLineLimit, 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void select(int p_93987_) {
|
||||
this.current = p_93987_;
|
||||
if (this.current < 0) {
|
||||
this.current += this.suggestionList.size();
|
||||
}
|
||||
|
||||
if (this.current >= this.suggestionList.size()) {
|
||||
this.current -= this.suggestionList.size();
|
||||
}
|
||||
|
||||
Suggestion suggestion = this.suggestionList.get(this.current);
|
||||
CommandSuggestions.this.input.setSuggestion(CommandSuggestions.calculateSuggestionSuffix(CommandSuggestions.this.input.getValue(), suggestion.apply(this.originalContents)));
|
||||
if (this.lastNarratedEntry != this.current) {
|
||||
CommandSuggestions.this.minecraft.getNarrator().sayNow(this.getNarrationMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void useSuggestion() {
|
||||
Suggestion suggestion = this.suggestionList.get(this.current);
|
||||
CommandSuggestions.this.keepSuggestions = true;
|
||||
CommandSuggestions.this.input.setValue(suggestion.apply(this.originalContents));
|
||||
int i = suggestion.getRange().getStart() + suggestion.getText().length();
|
||||
CommandSuggestions.this.input.setCursorPosition(i);
|
||||
CommandSuggestions.this.input.setHighlightPos(i);
|
||||
this.select(this.current);
|
||||
CommandSuggestions.this.keepSuggestions = false;
|
||||
this.tabCycles = true;
|
||||
}
|
||||
|
||||
Component getNarrationMessage() {
|
||||
this.lastNarratedEntry = this.current;
|
||||
Suggestion suggestion = this.suggestionList.get(this.current);
|
||||
Message message = suggestion.getTooltip();
|
||||
return message != null ? Component.translatable("narration.suggestion.tooltip", this.current + 1, this.suggestionList.size(), suggestion.getText(), message) : Component.translatable("narration.suggestion", this.current + 1, this.suggestionList.size(), suggestion.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class CommonButtons {
|
||||
public static TextAndImageButton languageTextAndImage(Button.OnPress p_273337_) {
|
||||
return TextAndImageButton.builder(Component.translatable("options.language"), Button.WIDGETS_LOCATION, p_273337_).texStart(3, 109).offset(65, 3).yDiffTex(20).usedTextureSize(14, 14).textureSize(256, 256).build();
|
||||
}
|
||||
|
||||
public static TextAndImageButton accessibilityTextAndImage(Button.OnPress p_273354_) {
|
||||
return TextAndImageButton.builder(Component.translatable("options.accessibility.title"), Button.ACCESSIBILITY_TEXTURE, p_273354_).texStart(3, 2).offset(65, 2).yDiffTex(20).usedTextureSize(14, 16).textureSize(32, 64).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.ComponentCollector;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.locale.Language;
|
||||
import net.minecraft.network.chat.FormattedText;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ComponentRenderUtils {
|
||||
private static final FormattedCharSequence INDENT = FormattedCharSequence.codepoint(32, Style.EMPTY);
|
||||
|
||||
private static String stripColor(String p_94000_) {
|
||||
return Minecraft.getInstance().options.chatColors().get() ? p_94000_ : ChatFormatting.stripFormatting(p_94000_);
|
||||
}
|
||||
|
||||
public static List<FormattedCharSequence> wrapComponents(FormattedText p_94006_, int p_94007_, Font p_94008_) {
|
||||
ComponentCollector componentcollector = new ComponentCollector();
|
||||
p_94006_.visit((p_93997_, p_93998_) -> {
|
||||
componentcollector.append(FormattedText.of(stripColor(p_93998_), p_93997_));
|
||||
return Optional.empty();
|
||||
}, Style.EMPTY);
|
||||
List<FormattedCharSequence> list = Lists.newArrayList();
|
||||
p_94008_.getSplitter().splitLines(componentcollector.getResultOrEmpty(), p_94007_, Style.EMPTY, (p_94003_, p_94004_) -> {
|
||||
FormattedCharSequence formattedcharsequence = Language.getInstance().getVisualOrder(p_94003_);
|
||||
list.add(p_94004_ ? FormattedCharSequence.composite(INDENT, formattedcharsequence) : formattedcharsequence);
|
||||
});
|
||||
return (List<FormattedCharSequence>)(list.isEmpty() ? Lists.newArrayList(FormattedCharSequence.EMPTY) : list);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.ComponentPath;
|
||||
import net.minecraft.client.gui.components.events.ContainerEventHandler;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.gui.navigation.FocusNavigationEvent;
|
||||
import net.minecraft.client.gui.navigation.ScreenAxis;
|
||||
import net.minecraft.client.gui.navigation.ScreenDirection;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class ContainerObjectSelectionList<E extends ContainerObjectSelectionList.Entry<E>> extends AbstractSelectionList<E> {
|
||||
public ContainerObjectSelectionList(Minecraft p_94010_, int p_94011_, int p_94012_, int p_94013_, int p_94014_, int p_94015_) {
|
||||
super(p_94010_, p_94011_, p_94012_, p_94013_, p_94014_, p_94015_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath nextFocusPath(FocusNavigationEvent p_265385_) {
|
||||
if (this.getItemCount() == 0) {
|
||||
return null;
|
||||
} else if (!(p_265385_ instanceof FocusNavigationEvent.ArrowNavigation)) {
|
||||
return super.nextFocusPath(p_265385_);
|
||||
} else {
|
||||
FocusNavigationEvent.ArrowNavigation focusnavigationevent$arrownavigation = (FocusNavigationEvent.ArrowNavigation)p_265385_;
|
||||
E e = this.getFocused();
|
||||
if (focusnavigationevent$arrownavigation.direction().getAxis() == ScreenAxis.HORIZONTAL && e != null) {
|
||||
return ComponentPath.path(this, e.nextFocusPath(p_265385_));
|
||||
} else {
|
||||
int i = -1;
|
||||
ScreenDirection screendirection = focusnavigationevent$arrownavigation.direction();
|
||||
if (e != null) {
|
||||
i = e.children().indexOf(e.getFocused());
|
||||
}
|
||||
|
||||
if (i == -1) {
|
||||
switch (screendirection) {
|
||||
case LEFT:
|
||||
i = Integer.MAX_VALUE;
|
||||
screendirection = ScreenDirection.DOWN;
|
||||
break;
|
||||
case RIGHT:
|
||||
i = 0;
|
||||
screendirection = ScreenDirection.DOWN;
|
||||
break;
|
||||
default:
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
E e1 = e;
|
||||
|
||||
ComponentPath componentpath;
|
||||
do {
|
||||
e1 = this.nextEntry(screendirection, (p_265784_) -> {
|
||||
return !p_265784_.children().isEmpty();
|
||||
}, e1);
|
||||
if (e1 == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
componentpath = e1.focusPathAtIndex(focusnavigationevent$arrownavigation, i);
|
||||
} while(componentpath == null);
|
||||
|
||||
return ComponentPath.path(this, componentpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setFocused(@Nullable GuiEventListener p_265559_) {
|
||||
super.setFocused(p_265559_);
|
||||
if (p_265559_ == null) {
|
||||
this.setSelected((E)null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public NarratableEntry.NarrationPriority narrationPriority() {
|
||||
return this.isFocused() ? NarratableEntry.NarrationPriority.FOCUSED : super.narrationPriority();
|
||||
}
|
||||
|
||||
protected boolean isSelectedItem(int p_94019_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void updateNarration(NarrationElementOutput p_168851_) {
|
||||
E e = this.getHovered();
|
||||
if (e != null) {
|
||||
e.updateNarration(p_168851_.nest());
|
||||
this.narrateListElementPosition(p_168851_, e);
|
||||
} else {
|
||||
E e1 = this.getFocused();
|
||||
if (e1 != null) {
|
||||
e1.updateNarration(p_168851_.nest());
|
||||
this.narrateListElementPosition(p_168851_, e1);
|
||||
}
|
||||
}
|
||||
|
||||
p_168851_.add(NarratedElementType.USAGE, Component.translatable("narration.component_list.usage"));
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract static class Entry<E extends ContainerObjectSelectionList.Entry<E>> extends AbstractSelectionList.Entry<E> implements ContainerEventHandler {
|
||||
@Nullable
|
||||
private GuiEventListener focused;
|
||||
@Nullable
|
||||
private NarratableEntry lastNarratable;
|
||||
private boolean dragging;
|
||||
|
||||
public boolean isDragging() {
|
||||
return this.dragging;
|
||||
}
|
||||
|
||||
public void setDragging(boolean p_94028_) {
|
||||
this.dragging = p_94028_;
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_265453_, double p_265297_, int p_265697_) {
|
||||
return ContainerEventHandler.super.mouseClicked(p_265453_, p_265297_, p_265697_);
|
||||
}
|
||||
|
||||
public void setFocused(@Nullable GuiEventListener p_94024_) {
|
||||
if (this.focused != null) {
|
||||
this.focused.setFocused(false);
|
||||
}
|
||||
|
||||
if (p_94024_ != null) {
|
||||
p_94024_.setFocused(true);
|
||||
}
|
||||
|
||||
this.focused = p_94024_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GuiEventListener getFocused() {
|
||||
return this.focused;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath focusPathAtIndex(FocusNavigationEvent p_265435_, int p_265432_) {
|
||||
if (this.children().isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
ComponentPath componentpath = this.children().get(Math.min(p_265432_, this.children().size() - 1)).nextFocusPath(p_265435_);
|
||||
return ComponentPath.path(this, componentpath);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath nextFocusPath(FocusNavigationEvent p_265672_) {
|
||||
if (p_265672_ instanceof FocusNavigationEvent.ArrowNavigation) {
|
||||
FocusNavigationEvent.ArrowNavigation focusnavigationevent$arrownavigation = (FocusNavigationEvent.ArrowNavigation)p_265672_;
|
||||
byte b0;
|
||||
switch (focusnavigationevent$arrownavigation.direction()) {
|
||||
case LEFT:
|
||||
b0 = -1;
|
||||
break;
|
||||
case RIGHT:
|
||||
b0 = 1;
|
||||
break;
|
||||
case UP:
|
||||
case DOWN:
|
||||
b0 = 0;
|
||||
break;
|
||||
default:
|
||||
throw new IncompatibleClassChangeError();
|
||||
}
|
||||
|
||||
int i = b0;
|
||||
if (i == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int j = Mth.clamp(i + this.children().indexOf(this.getFocused()), 0, this.children().size() - 1);
|
||||
|
||||
for(int k = j; k >= 0 && k < this.children().size(); k += i) {
|
||||
GuiEventListener guieventlistener = this.children().get(k);
|
||||
ComponentPath componentpath = guieventlistener.nextFocusPath(p_265672_);
|
||||
if (componentpath != null) {
|
||||
return ComponentPath.path(this, componentpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ContainerEventHandler.super.nextFocusPath(p_265672_);
|
||||
}
|
||||
|
||||
public abstract List<? extends NarratableEntry> narratables();
|
||||
|
||||
void updateNarration(NarrationElementOutput p_168855_) {
|
||||
List<? extends NarratableEntry> list = this.narratables();
|
||||
Screen.NarratableSearchResult screen$narratablesearchresult = Screen.findNarratableWidget(list, this.lastNarratable);
|
||||
if (screen$narratablesearchresult != null) {
|
||||
if (screen$narratablesearchresult.priority.isTerminal()) {
|
||||
this.lastNarratable = screen$narratablesearchresult.entry;
|
||||
}
|
||||
|
||||
if (list.size() > 1) {
|
||||
p_168855_.add(NarratedElementType.POSITION, Component.translatable("narrator.position.object_list", screen$narratablesearchresult.index + 1, list.size()));
|
||||
if (screen$narratablesearchresult.priority == NarratableEntry.NarrationPriority.FOCUSED) {
|
||||
p_168855_.add(NarratedElementType.USAGE, Component.translatable("narration.component_list.usage"));
|
||||
}
|
||||
}
|
||||
|
||||
screen$narratablesearchresult.entry.updateNarration(p_168855_.nest());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Function;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.OptionInstance;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class CycleButton<T> extends AbstractButton {
|
||||
public static final BooleanSupplier DEFAULT_ALT_LIST_SELECTOR = Screen::hasAltDown;
|
||||
private static final List<Boolean> BOOLEAN_OPTIONS = ImmutableList.of(Boolean.TRUE, Boolean.FALSE);
|
||||
private final Component name;
|
||||
private int index;
|
||||
private T value;
|
||||
private final CycleButton.ValueListSupplier<T> values;
|
||||
private final Function<T, Component> valueStringifier;
|
||||
private final Function<CycleButton<T>, MutableComponent> narrationProvider;
|
||||
private final CycleButton.OnValueChange<T> onValueChange;
|
||||
private final boolean displayOnlyValue;
|
||||
private final OptionInstance.TooltipSupplier<T> tooltipSupplier;
|
||||
|
||||
CycleButton(int p_232484_, int p_232485_, int p_232486_, int p_232487_, Component p_232488_, Component p_232489_, int p_232490_, T p_232491_, CycleButton.ValueListSupplier<T> p_232492_, Function<T, Component> p_232493_, Function<CycleButton<T>, MutableComponent> p_232494_, CycleButton.OnValueChange<T> p_232495_, OptionInstance.TooltipSupplier<T> p_232496_, boolean p_232497_) {
|
||||
super(p_232484_, p_232485_, p_232486_, p_232487_, p_232488_);
|
||||
this.name = p_232489_;
|
||||
this.index = p_232490_;
|
||||
this.value = p_232491_;
|
||||
this.values = p_232492_;
|
||||
this.valueStringifier = p_232493_;
|
||||
this.narrationProvider = p_232494_;
|
||||
this.onValueChange = p_232495_;
|
||||
this.displayOnlyValue = p_232497_;
|
||||
this.tooltipSupplier = p_232496_;
|
||||
this.updateTooltip();
|
||||
}
|
||||
|
||||
private void updateTooltip() {
|
||||
this.setTooltip(this.tooltipSupplier.apply(this.value));
|
||||
}
|
||||
|
||||
public void onPress() {
|
||||
if (Screen.hasShiftDown()) {
|
||||
this.cycleValue(-1);
|
||||
} else {
|
||||
this.cycleValue(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void cycleValue(int p_168909_) {
|
||||
List<T> list = this.values.getSelectedList();
|
||||
this.index = Mth.positiveModulo(this.index + p_168909_, list.size());
|
||||
T t = list.get(this.index);
|
||||
this.updateValue(t);
|
||||
this.onValueChange.onValueChange(this, t);
|
||||
}
|
||||
|
||||
private T getCycledValue(int p_168915_) {
|
||||
List<T> list = this.values.getSelectedList();
|
||||
return list.get(Mth.positiveModulo(this.index + p_168915_, list.size()));
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double p_168885_, double p_168886_, double p_168887_) {
|
||||
if (p_168887_ > 0.0D) {
|
||||
this.cycleValue(-1);
|
||||
} else if (p_168887_ < 0.0D) {
|
||||
this.cycleValue(1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setValue(T p_168893_) {
|
||||
List<T> list = this.values.getSelectedList();
|
||||
int i = list.indexOf(p_168893_);
|
||||
if (i != -1) {
|
||||
this.index = i;
|
||||
}
|
||||
|
||||
this.updateValue(p_168893_);
|
||||
}
|
||||
|
||||
private void updateValue(T p_168906_) {
|
||||
Component component = this.createLabelForValue(p_168906_);
|
||||
this.setMessage(component);
|
||||
this.value = p_168906_;
|
||||
this.updateTooltip();
|
||||
}
|
||||
|
||||
private Component createLabelForValue(T p_168911_) {
|
||||
return (Component)(this.displayOnlyValue ? this.valueStringifier.apply(p_168911_) : this.createFullName(p_168911_));
|
||||
}
|
||||
|
||||
private MutableComponent createFullName(T p_168913_) {
|
||||
return CommonComponents.optionNameValue(this.name, this.valueStringifier.apply(p_168913_));
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
protected MutableComponent createNarrationMessage() {
|
||||
return this.narrationProvider.apply(this);
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput p_168889_) {
|
||||
p_168889_.add(NarratedElementType.TITLE, this.createNarrationMessage());
|
||||
if (this.active) {
|
||||
T t = this.getCycledValue(1);
|
||||
Component component = this.createLabelForValue(t);
|
||||
if (this.isFocused()) {
|
||||
p_168889_.add(NarratedElementType.USAGE, Component.translatable("narration.cycle_button.usage.focused", component));
|
||||
} else {
|
||||
p_168889_.add(NarratedElementType.USAGE, Component.translatable("narration.cycle_button.usage.hovered", component));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public MutableComponent createDefaultNarrationMessage() {
|
||||
return wrapDefaultNarrationMessage((Component)(this.displayOnlyValue ? this.createFullName(this.value) : this.getMessage()));
|
||||
}
|
||||
|
||||
public static <T> CycleButton.Builder<T> builder(Function<T, Component> p_168895_) {
|
||||
return new CycleButton.Builder<>(p_168895_);
|
||||
}
|
||||
|
||||
public static CycleButton.Builder<Boolean> booleanBuilder(Component p_168897_, Component p_168898_) {
|
||||
return (new CycleButton.Builder<Boolean>((p_168902_) -> {
|
||||
return p_168902_ ? p_168897_ : p_168898_;
|
||||
})).withValues(BOOLEAN_OPTIONS);
|
||||
}
|
||||
|
||||
public static CycleButton.Builder<Boolean> onOffBuilder() {
|
||||
return (new CycleButton.Builder<Boolean>((p_168891_) -> {
|
||||
return p_168891_ ? CommonComponents.OPTION_ON : CommonComponents.OPTION_OFF;
|
||||
})).withValues(BOOLEAN_OPTIONS);
|
||||
}
|
||||
|
||||
public static CycleButton.Builder<Boolean> onOffBuilder(boolean p_168917_) {
|
||||
return onOffBuilder().withInitialValue(p_168917_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Builder<T> {
|
||||
private int initialIndex;
|
||||
@Nullable
|
||||
private T initialValue;
|
||||
private final Function<T, Component> valueStringifier;
|
||||
private OptionInstance.TooltipSupplier<T> tooltipSupplier = (p_168964_) -> {
|
||||
return null;
|
||||
};
|
||||
private Function<CycleButton<T>, MutableComponent> narrationProvider = CycleButton::createDefaultNarrationMessage;
|
||||
private CycleButton.ValueListSupplier<T> values = CycleButton.ValueListSupplier.create(ImmutableList.of());
|
||||
private boolean displayOnlyValue;
|
||||
|
||||
public Builder(Function<T, Component> p_168928_) {
|
||||
this.valueStringifier = p_168928_;
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withValues(Collection<T> p_232503_) {
|
||||
return this.withValues(CycleButton.ValueListSupplier.create(p_232503_));
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public final CycleButton.Builder<T> withValues(T... p_168962_) {
|
||||
return this.withValues(ImmutableList.copyOf(p_168962_));
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withValues(List<T> p_168953_, List<T> p_168954_) {
|
||||
return this.withValues(CycleButton.ValueListSupplier.create(CycleButton.DEFAULT_ALT_LIST_SELECTOR, p_168953_, p_168954_));
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withValues(BooleanSupplier p_168956_, List<T> p_168957_, List<T> p_168958_) {
|
||||
return this.withValues(CycleButton.ValueListSupplier.create(p_168956_, p_168957_, p_168958_));
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withValues(CycleButton.ValueListSupplier<T> p_232501_) {
|
||||
this.values = p_232501_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withTooltip(OptionInstance.TooltipSupplier<T> p_232499_) {
|
||||
this.tooltipSupplier = p_232499_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withInitialValue(T p_168949_) {
|
||||
this.initialValue = p_168949_;
|
||||
int i = this.values.getDefaultList().indexOf(p_168949_);
|
||||
if (i != -1) {
|
||||
this.initialIndex = i;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withCustomNarration(Function<CycleButton<T>, MutableComponent> p_168960_) {
|
||||
this.narrationProvider = p_168960_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> displayOnlyValue() {
|
||||
this.displayOnlyValue = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CycleButton<T> create(int p_168931_, int p_168932_, int p_168933_, int p_168934_, Component p_168935_) {
|
||||
return this.create(p_168931_, p_168932_, p_168933_, p_168934_, p_168935_, (p_168946_, p_168947_) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public CycleButton<T> create(int p_168937_, int p_168938_, int p_168939_, int p_168940_, Component p_168941_, CycleButton.OnValueChange<T> p_168942_) {
|
||||
List<T> list = this.values.getDefaultList();
|
||||
if (list.isEmpty()) {
|
||||
throw new IllegalStateException("No values for cycle button");
|
||||
} else {
|
||||
T t = (T)(this.initialValue != null ? this.initialValue : list.get(this.initialIndex));
|
||||
Component component = this.valueStringifier.apply(t);
|
||||
Component component1 = (Component)(this.displayOnlyValue ? component : CommonComponents.optionNameValue(p_168941_, component));
|
||||
return new CycleButton<>(p_168937_, p_168938_, p_168939_, p_168940_, component1, p_168941_, this.initialIndex, t, this.values, this.valueStringifier, this.narrationProvider, p_168942_, this.tooltipSupplier, this.displayOnlyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface OnValueChange<T> {
|
||||
void onValueChange(CycleButton<T> p_168966_, T p_168967_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface ValueListSupplier<T> {
|
||||
List<T> getSelectedList();
|
||||
|
||||
List<T> getDefaultList();
|
||||
|
||||
static <T> CycleButton.ValueListSupplier<T> create(Collection<T> p_232505_) {
|
||||
final List<T> list = ImmutableList.copyOf(p_232505_);
|
||||
return new CycleButton.ValueListSupplier<T>() {
|
||||
public List<T> getSelectedList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<T> getDefaultList() {
|
||||
return list;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static <T> CycleButton.ValueListSupplier<T> create(final BooleanSupplier p_168971_, List<T> p_168972_, List<T> p_168973_) {
|
||||
final List<T> list = ImmutableList.copyOf(p_168972_);
|
||||
final List<T> list1 = ImmutableList.copyOf(p_168973_);
|
||||
return new CycleButton.ValueListSupplier<T>() {
|
||||
public List<T> getSelectedList() {
|
||||
return p_168971_.getAsBoolean() ? list1 : list;
|
||||
}
|
||||
|
||||
public List<T> getDefaultList() {
|
||||
return list;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,548 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.platform.GlUtil;
|
||||
import com.mojang.datafixers.DataFixUtils;
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import it.unimi.dsi.fastutil.longs.LongSets;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.ClientBrandRetriever;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.PostChain;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.server.IntegratedServer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.FrameTimer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
import net.minecraft.world.level.NaturalSpawner;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.RandomState;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class DebugScreenOverlay {
|
||||
private static final int COLOR_GREY = 14737632;
|
||||
private static final int MARGIN_RIGHT = 2;
|
||||
private static final int MARGIN_LEFT = 2;
|
||||
private static final int MARGIN_TOP = 2;
|
||||
private static final Map<Heightmap.Types, String> HEIGHTMAP_NAMES = Util.make(new EnumMap<>(Heightmap.Types.class), (p_94070_) -> {
|
||||
p_94070_.put(Heightmap.Types.WORLD_SURFACE_WG, "SW");
|
||||
p_94070_.put(Heightmap.Types.WORLD_SURFACE, "S");
|
||||
p_94070_.put(Heightmap.Types.OCEAN_FLOOR_WG, "OW");
|
||||
p_94070_.put(Heightmap.Types.OCEAN_FLOOR, "O");
|
||||
p_94070_.put(Heightmap.Types.MOTION_BLOCKING, "M");
|
||||
p_94070_.put(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, "ML");
|
||||
});
|
||||
private final Minecraft minecraft;
|
||||
private final DebugScreenOverlay.AllocationRateCalculator allocationRateCalculator;
|
||||
private final Font font;
|
||||
protected HitResult block;
|
||||
protected HitResult liquid;
|
||||
@Nullable
|
||||
private ChunkPos lastPos;
|
||||
@Nullable
|
||||
private LevelChunk clientChunk;
|
||||
@Nullable
|
||||
private CompletableFuture<LevelChunk> serverChunk;
|
||||
private static final int RED = -65536;
|
||||
private static final int YELLOW = -256;
|
||||
private static final int GREEN = -16711936;
|
||||
|
||||
public DebugScreenOverlay(Minecraft p_94039_) {
|
||||
this.minecraft = p_94039_;
|
||||
this.allocationRateCalculator = new DebugScreenOverlay.AllocationRateCalculator();
|
||||
this.font = p_94039_.font;
|
||||
}
|
||||
|
||||
public void clearChunkCache() {
|
||||
this.serverChunk = null;
|
||||
this.clientChunk = null;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_281427_) {
|
||||
this.minecraft.getProfiler().push("debug");
|
||||
Entity entity = this.minecraft.getCameraEntity();
|
||||
this.block = entity.pick(20.0D, 0.0F, false);
|
||||
this.liquid = entity.pick(20.0D, 0.0F, true);
|
||||
p_281427_.drawManaged(() -> {
|
||||
this.drawGameInformation(p_281427_);
|
||||
this.drawSystemInformation(p_281427_);
|
||||
if (this.minecraft.options.renderFpsChart) {
|
||||
int i = p_281427_.guiWidth();
|
||||
this.drawChart(p_281427_, this.minecraft.getFrameTimer(), 0, i / 2, true);
|
||||
IntegratedServer integratedserver = this.minecraft.getSingleplayerServer();
|
||||
if (integratedserver != null) {
|
||||
this.drawChart(p_281427_, integratedserver.getFrameTimer(), i - Math.min(i / 2, 240), i / 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
this.minecraft.getProfiler().pop();
|
||||
}
|
||||
|
||||
protected void drawGameInformation(GuiGraphics p_281525_) {
|
||||
List<String> list = this.getGameInformation();
|
||||
list.add("");
|
||||
boolean flag = this.minecraft.getSingleplayerServer() != null;
|
||||
list.add("Debug: Pie [shift]: " + (this.minecraft.options.renderDebugCharts ? "visible" : "hidden") + (flag ? " FPS + TPS" : " FPS") + " [alt]: " + (this.minecraft.options.renderFpsChart ? "visible" : "hidden"));
|
||||
list.add("For help: press F3 + Q");
|
||||
this.renderLines(p_281525_, list, true);
|
||||
}
|
||||
|
||||
protected void drawSystemInformation(GuiGraphics p_281261_) {
|
||||
List<String> list = this.getSystemInformation();
|
||||
this.renderLines(p_281261_, list, false);
|
||||
}
|
||||
|
||||
private void renderLines(GuiGraphics p_286519_, List<String> p_286665_, boolean p_286644_) {
|
||||
int i = 9;
|
||||
|
||||
for(int j = 0; j < p_286665_.size(); ++j) {
|
||||
String s = p_286665_.get(j);
|
||||
if (!Strings.isNullOrEmpty(s)) {
|
||||
int k = this.font.width(s);
|
||||
int l = p_286644_ ? 2 : p_286519_.guiWidth() - 2 - k;
|
||||
int i1 = 2 + i * j;
|
||||
p_286519_.fill(l - 1, i1 - 1, l + k + 1, i1 + i - 1, -1873784752);
|
||||
}
|
||||
}
|
||||
|
||||
for(int j1 = 0; j1 < p_286665_.size(); ++j1) {
|
||||
String s1 = p_286665_.get(j1);
|
||||
if (!Strings.isNullOrEmpty(s1)) {
|
||||
int k1 = this.font.width(s1);
|
||||
int l1 = p_286644_ ? 2 : p_286519_.guiWidth() - 2 - k1;
|
||||
int i2 = 2 + i * j1;
|
||||
p_286519_.drawString(this.font, s1, l1, i2, 14737632, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected List<String> getGameInformation() {
|
||||
IntegratedServer integratedserver = this.minecraft.getSingleplayerServer();
|
||||
Connection connection = this.minecraft.getConnection().getConnection();
|
||||
float f = connection.getAverageSentPackets();
|
||||
float f1 = connection.getAverageReceivedPackets();
|
||||
String s;
|
||||
if (integratedserver != null) {
|
||||
s = String.format(Locale.ROOT, "Integrated server @ %.0f ms ticks, %.0f tx, %.0f rx", integratedserver.getAverageTickTime(), f, f1);
|
||||
} else {
|
||||
s = String.format(Locale.ROOT, "\"%s\" server, %.0f tx, %.0f rx", this.minecraft.player.getServerBrand(), f, f1);
|
||||
}
|
||||
|
||||
BlockPos blockpos = this.minecraft.getCameraEntity().blockPosition();
|
||||
if (this.minecraft.showOnlyReducedInfo()) {
|
||||
return Lists.newArrayList("Minecraft " + SharedConstants.getCurrentVersion().getName() + " (" + this.minecraft.getLaunchedVersion() + "/" + ClientBrandRetriever.getClientModName() + ")", this.minecraft.fpsString, s, this.minecraft.levelRenderer.getChunkStatistics(), this.minecraft.levelRenderer.getEntityStatistics(), "P: " + this.minecraft.particleEngine.countParticles() + ". T: " + this.minecraft.level.getEntityCount(), this.minecraft.level.gatherChunkSourceStats(), "", String.format(Locale.ROOT, "Chunk-relative: %d %d %d", blockpos.getX() & 15, blockpos.getY() & 15, blockpos.getZ() & 15));
|
||||
} else {
|
||||
Entity entity = this.minecraft.getCameraEntity();
|
||||
Direction direction = entity.getDirection();
|
||||
String s1;
|
||||
switch (direction) {
|
||||
case NORTH:
|
||||
s1 = "Towards negative Z";
|
||||
break;
|
||||
case SOUTH:
|
||||
s1 = "Towards positive Z";
|
||||
break;
|
||||
case WEST:
|
||||
s1 = "Towards negative X";
|
||||
break;
|
||||
case EAST:
|
||||
s1 = "Towards positive X";
|
||||
break;
|
||||
default:
|
||||
s1 = "Invalid";
|
||||
}
|
||||
|
||||
ChunkPos chunkpos = new ChunkPos(blockpos);
|
||||
if (!Objects.equals(this.lastPos, chunkpos)) {
|
||||
this.lastPos = chunkpos;
|
||||
this.clearChunkCache();
|
||||
}
|
||||
|
||||
Level level = this.getLevel();
|
||||
LongSet longset = (LongSet)(level instanceof ServerLevel ? ((ServerLevel)level).getForcedChunks() : LongSets.EMPTY_SET);
|
||||
List<String> list = Lists.newArrayList("Minecraft " + SharedConstants.getCurrentVersion().getName() + " (" + this.minecraft.getLaunchedVersion() + "/" + ClientBrandRetriever.getClientModName() + ("release".equalsIgnoreCase(this.minecraft.getVersionType()) ? "" : "/" + this.minecraft.getVersionType()) + ")", this.minecraft.fpsString, s, this.minecraft.levelRenderer.getChunkStatistics(), this.minecraft.levelRenderer.getEntityStatistics(), "P: " + this.minecraft.particleEngine.countParticles() + ". T: " + this.minecraft.level.getEntityCount(), this.minecraft.level.gatherChunkSourceStats());
|
||||
String s2 = this.getServerChunkStats();
|
||||
if (s2 != null) {
|
||||
list.add(s2);
|
||||
}
|
||||
|
||||
list.add(this.minecraft.level.dimension().location() + " FC: " + longset.size());
|
||||
list.add("");
|
||||
list.add(String.format(Locale.ROOT, "XYZ: %.3f / %.5f / %.3f", this.minecraft.getCameraEntity().getX(), this.minecraft.getCameraEntity().getY(), this.minecraft.getCameraEntity().getZ()));
|
||||
list.add(String.format(Locale.ROOT, "Block: %d %d %d [%d %d %d]", blockpos.getX(), blockpos.getY(), blockpos.getZ(), blockpos.getX() & 15, blockpos.getY() & 15, blockpos.getZ() & 15));
|
||||
list.add(String.format(Locale.ROOT, "Chunk: %d %d %d [%d %d in r.%d.%d.mca]", chunkpos.x, SectionPos.blockToSectionCoord(blockpos.getY()), chunkpos.z, chunkpos.getRegionLocalX(), chunkpos.getRegionLocalZ(), chunkpos.getRegionX(), chunkpos.getRegionZ()));
|
||||
list.add(String.format(Locale.ROOT, "Facing: %s (%s) (%.1f / %.1f)", direction, s1, Mth.wrapDegrees(entity.getYRot()), Mth.wrapDegrees(entity.getXRot())));
|
||||
LevelChunk levelchunk = this.getClientChunk();
|
||||
if (levelchunk.isEmpty()) {
|
||||
list.add("Waiting for chunk...");
|
||||
} else {
|
||||
int i = this.minecraft.level.getChunkSource().getLightEngine().getRawBrightness(blockpos, 0);
|
||||
int j = this.minecraft.level.getBrightness(LightLayer.SKY, blockpos);
|
||||
int k = this.minecraft.level.getBrightness(LightLayer.BLOCK, blockpos);
|
||||
list.add("Client Light: " + i + " (" + j + " sky, " + k + " block)");
|
||||
LevelChunk levelchunk1 = this.getServerChunk();
|
||||
StringBuilder stringbuilder = new StringBuilder("CH");
|
||||
|
||||
for(Heightmap.Types heightmap$types : Heightmap.Types.values()) {
|
||||
if (heightmap$types.sendToClient()) {
|
||||
stringbuilder.append(" ").append(HEIGHTMAP_NAMES.get(heightmap$types)).append(": ").append(levelchunk.getHeight(heightmap$types, blockpos.getX(), blockpos.getZ()));
|
||||
}
|
||||
}
|
||||
|
||||
list.add(stringbuilder.toString());
|
||||
stringbuilder.setLength(0);
|
||||
stringbuilder.append("SH");
|
||||
|
||||
for(Heightmap.Types heightmap$types1 : Heightmap.Types.values()) {
|
||||
if (heightmap$types1.keepAfterWorldgen()) {
|
||||
stringbuilder.append(" ").append(HEIGHTMAP_NAMES.get(heightmap$types1)).append(": ");
|
||||
if (levelchunk1 != null) {
|
||||
stringbuilder.append(levelchunk1.getHeight(heightmap$types1, blockpos.getX(), blockpos.getZ()));
|
||||
} else {
|
||||
stringbuilder.append("??");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.add(stringbuilder.toString());
|
||||
if (blockpos.getY() >= this.minecraft.level.getMinBuildHeight() && blockpos.getY() < this.minecraft.level.getMaxBuildHeight()) {
|
||||
list.add("Biome: " + printBiome(this.minecraft.level.getBiome(blockpos)));
|
||||
long l = 0L;
|
||||
float f2 = 0.0F;
|
||||
if (levelchunk1 != null) {
|
||||
f2 = level.getMoonBrightness();
|
||||
l = levelchunk1.getInhabitedTime();
|
||||
}
|
||||
|
||||
DifficultyInstance difficultyinstance = new DifficultyInstance(level.getDifficulty(), level.getDayTime(), l, f2);
|
||||
list.add(String.format(Locale.ROOT, "Local Difficulty: %.2f // %.2f (Day %d)", difficultyinstance.getEffectiveDifficulty(), difficultyinstance.getSpecialMultiplier(), this.minecraft.level.getDayTime() / 24000L));
|
||||
}
|
||||
|
||||
if (levelchunk1 != null && levelchunk1.isOldNoiseGeneration()) {
|
||||
list.add("Blending: Old");
|
||||
}
|
||||
}
|
||||
|
||||
ServerLevel serverlevel = this.getServerLevel();
|
||||
if (serverlevel != null) {
|
||||
ServerChunkCache serverchunkcache = serverlevel.getChunkSource();
|
||||
ChunkGenerator chunkgenerator = serverchunkcache.getGenerator();
|
||||
RandomState randomstate = serverchunkcache.randomState();
|
||||
chunkgenerator.addDebugScreenInfo(list, randomstate, blockpos);
|
||||
Climate.Sampler climate$sampler = randomstate.sampler();
|
||||
BiomeSource biomesource = chunkgenerator.getBiomeSource();
|
||||
biomesource.addDebugInfo(list, blockpos, climate$sampler);
|
||||
NaturalSpawner.SpawnState naturalspawner$spawnstate = serverchunkcache.getLastSpawnState();
|
||||
if (naturalspawner$spawnstate != null) {
|
||||
Object2IntMap<MobCategory> object2intmap = naturalspawner$spawnstate.getMobCategoryCounts();
|
||||
int i1 = naturalspawner$spawnstate.getSpawnableChunkCount();
|
||||
list.add("SC: " + i1 + ", " + (String)Stream.of(MobCategory.values()).map((p_94068_) -> {
|
||||
return Character.toUpperCase(p_94068_.getName().charAt(0)) + ": " + object2intmap.getInt(p_94068_);
|
||||
}).collect(Collectors.joining(", ")));
|
||||
} else {
|
||||
list.add("SC: N/A");
|
||||
}
|
||||
}
|
||||
|
||||
PostChain postchain = this.minecraft.gameRenderer.currentEffect();
|
||||
if (postchain != null) {
|
||||
list.add("Shader: " + postchain.getName());
|
||||
}
|
||||
|
||||
list.add(this.minecraft.getSoundManager().getDebugString() + String.format(Locale.ROOT, " (Mood %d%%)", Math.round(this.minecraft.player.getCurrentMood() * 100.0F)));
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
private static String printBiome(Holder<Biome> p_205375_) {
|
||||
return p_205375_.unwrap().map((p_205377_) -> {
|
||||
return p_205377_.location().toString();
|
||||
}, (p_205367_) -> {
|
||||
return "[unregistered " + p_205367_ + "]";
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ServerLevel getServerLevel() {
|
||||
IntegratedServer integratedserver = this.minecraft.getSingleplayerServer();
|
||||
return integratedserver != null ? integratedserver.getLevel(this.minecraft.level.dimension()) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getServerChunkStats() {
|
||||
ServerLevel serverlevel = this.getServerLevel();
|
||||
return serverlevel != null ? serverlevel.gatherChunkSourceStats() : null;
|
||||
}
|
||||
|
||||
private Level getLevel() {
|
||||
return DataFixUtils.orElse(Optional.ofNullable(this.minecraft.getSingleplayerServer()).flatMap((p_288242_) -> {
|
||||
return Optional.ofNullable(p_288242_.getLevel(this.minecraft.level.dimension()));
|
||||
}), this.minecraft.level);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private LevelChunk getServerChunk() {
|
||||
if (this.serverChunk == null) {
|
||||
ServerLevel serverlevel = this.getServerLevel();
|
||||
if (serverlevel != null) {
|
||||
this.serverChunk = serverlevel.getChunkSource().getChunkFuture(this.lastPos.x, this.lastPos.z, ChunkStatus.FULL, false).thenApply((p_205369_) -> {
|
||||
return p_205369_.map((p_205371_) -> {
|
||||
return (LevelChunk)p_205371_;
|
||||
}, (p_205363_) -> {
|
||||
return null;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (this.serverChunk == null) {
|
||||
this.serverChunk = CompletableFuture.completedFuture(this.getClientChunk());
|
||||
}
|
||||
}
|
||||
|
||||
return this.serverChunk.getNow((LevelChunk)null);
|
||||
}
|
||||
|
||||
private LevelChunk getClientChunk() {
|
||||
if (this.clientChunk == null) {
|
||||
this.clientChunk = this.minecraft.level.getChunk(this.lastPos.x, this.lastPos.z);
|
||||
}
|
||||
|
||||
return this.clientChunk;
|
||||
}
|
||||
|
||||
protected List<String> getSystemInformation() {
|
||||
long i = Runtime.getRuntime().maxMemory();
|
||||
long j = Runtime.getRuntime().totalMemory();
|
||||
long k = Runtime.getRuntime().freeMemory();
|
||||
long l = j - k;
|
||||
List<String> list = Lists.newArrayList(String.format(Locale.ROOT, "Java: %s %dbit", System.getProperty("java.version"), this.minecraft.is64Bit() ? 64 : 32), String.format(Locale.ROOT, "Mem: % 2d%% %03d/%03dMB", l * 100L / i, bytesToMegabytes(l), bytesToMegabytes(i)), String.format(Locale.ROOT, "Allocation rate: %03dMB /s", bytesToMegabytes(this.allocationRateCalculator.bytesAllocatedPerSecond(l))), String.format(Locale.ROOT, "Allocated: % 2d%% %03dMB", j * 100L / i, bytesToMegabytes(j)), "", String.format(Locale.ROOT, "CPU: %s", GlUtil.getCpuInfo()), "", String.format(Locale.ROOT, "Display: %dx%d (%s)", Minecraft.getInstance().getWindow().getWidth(), Minecraft.getInstance().getWindow().getHeight(), GlUtil.getVendor()), GlUtil.getRenderer(), GlUtil.getOpenGLVersion());
|
||||
if (this.minecraft.showOnlyReducedInfo()) {
|
||||
return list;
|
||||
} else {
|
||||
if (this.block.getType() == HitResult.Type.BLOCK) {
|
||||
BlockPos blockpos = ((BlockHitResult)this.block).getBlockPos();
|
||||
BlockState blockstate = this.minecraft.level.getBlockState(blockpos);
|
||||
list.add("");
|
||||
list.add(ChatFormatting.UNDERLINE + "Targeted Block: " + blockpos.getX() + ", " + blockpos.getY() + ", " + blockpos.getZ());
|
||||
list.add(String.valueOf((Object)BuiltInRegistries.BLOCK.getKey(blockstate.getBlock())));
|
||||
|
||||
for(Map.Entry<Property<?>, Comparable<?>> entry : blockstate.getValues().entrySet()) {
|
||||
list.add(this.getPropertyValueString(entry));
|
||||
}
|
||||
|
||||
blockstate.getTags().map((p_205365_) -> {
|
||||
return "#" + p_205365_.location();
|
||||
}).forEach(list::add);
|
||||
}
|
||||
|
||||
if (this.liquid.getType() == HitResult.Type.BLOCK) {
|
||||
BlockPos blockpos1 = ((BlockHitResult)this.liquid).getBlockPos();
|
||||
FluidState fluidstate = this.minecraft.level.getFluidState(blockpos1);
|
||||
list.add("");
|
||||
list.add(ChatFormatting.UNDERLINE + "Targeted Fluid: " + blockpos1.getX() + ", " + blockpos1.getY() + ", " + blockpos1.getZ());
|
||||
list.add(String.valueOf((Object)BuiltInRegistries.FLUID.getKey(fluidstate.getType())));
|
||||
|
||||
for(Map.Entry<Property<?>, Comparable<?>> entry1 : fluidstate.getValues().entrySet()) {
|
||||
list.add(this.getPropertyValueString(entry1));
|
||||
}
|
||||
|
||||
fluidstate.getTags().map((p_205379_) -> {
|
||||
return "#" + p_205379_.location();
|
||||
}).forEach(list::add);
|
||||
}
|
||||
|
||||
Entity entity = this.minecraft.crosshairPickEntity;
|
||||
if (entity != null) {
|
||||
list.add("");
|
||||
list.add(ChatFormatting.UNDERLINE + "Targeted Entity");
|
||||
list.add(String.valueOf((Object)BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType())));
|
||||
entity.getType().builtInRegistryHolder().tags().forEach(t -> list.add("#" + t.location()));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
private String getPropertyValueString(Map.Entry<Property<?>, Comparable<?>> p_94072_) {
|
||||
Property<?> property = p_94072_.getKey();
|
||||
Comparable<?> comparable = p_94072_.getValue();
|
||||
String s = Util.getPropertyName(property, comparable);
|
||||
if (Boolean.TRUE.equals(comparable)) {
|
||||
s = ChatFormatting.GREEN + s;
|
||||
} else if (Boolean.FALSE.equals(comparable)) {
|
||||
s = ChatFormatting.RED + s;
|
||||
}
|
||||
|
||||
return property.getName() + ": " + s;
|
||||
}
|
||||
|
||||
private void drawChart(GuiGraphics p_282273_, FrameTimer p_281838_, int p_283392_, int p_282726_, boolean p_282824_) {
|
||||
int i = p_281838_.getLogStart();
|
||||
int j = p_281838_.getLogEnd();
|
||||
long[] along = p_281838_.getLog();
|
||||
int l = p_283392_;
|
||||
int i1 = Math.max(0, along.length - p_282726_);
|
||||
int j1 = along.length - i1;
|
||||
int $$8 = p_281838_.wrapIndex(i + i1);
|
||||
long k1 = 0L;
|
||||
int l1 = Integer.MAX_VALUE;
|
||||
int i2 = Integer.MIN_VALUE;
|
||||
|
||||
for(int j2 = 0; j2 < j1; ++j2) {
|
||||
int k2 = (int)(along[p_281838_.wrapIndex($$8 + j2)] / 1000000L);
|
||||
l1 = Math.min(l1, k2);
|
||||
i2 = Math.max(i2, k2);
|
||||
k1 += (long)k2;
|
||||
}
|
||||
|
||||
int j3 = p_282273_.guiHeight();
|
||||
p_282273_.fill(RenderType.guiOverlay(), p_283392_, j3 - 60, p_283392_ + j1, j3, -1873784752);
|
||||
|
||||
while($$8 != j) {
|
||||
int k3 = p_281838_.scaleSampleTo(along[$$8], p_282824_ ? 30 : 60, p_282824_ ? 60 : 20);
|
||||
int l2 = p_282824_ ? 100 : 60;
|
||||
int i3 = this.getSampleColor(Mth.clamp(k3, 0, l2), 0, l2 / 2, l2);
|
||||
p_282273_.fill(RenderType.guiOverlay(), l, j3 - k3, l + 1, j3, i3);
|
||||
++l;
|
||||
$$8 = p_281838_.wrapIndex($$8 + 1);
|
||||
}
|
||||
|
||||
if (p_282824_) {
|
||||
p_282273_.fill(RenderType.guiOverlay(), p_283392_ + 1, j3 - 30 + 1, p_283392_ + 14, j3 - 30 + 10, -1873784752);
|
||||
p_282273_.drawString(this.font, "60 FPS", p_283392_ + 2, j3 - 30 + 2, 14737632, false);
|
||||
p_282273_.hLine(RenderType.guiOverlay(), p_283392_, p_283392_ + j1 - 1, j3 - 30, -1);
|
||||
p_282273_.fill(RenderType.guiOverlay(), p_283392_ + 1, j3 - 60 + 1, p_283392_ + 14, j3 - 60 + 10, -1873784752);
|
||||
p_282273_.drawString(this.font, "30 FPS", p_283392_ + 2, j3 - 60 + 2, 14737632, false);
|
||||
p_282273_.hLine(RenderType.guiOverlay(), p_283392_, p_283392_ + j1 - 1, j3 - 60, -1);
|
||||
} else {
|
||||
p_282273_.fill(RenderType.guiOverlay(), p_283392_ + 1, j3 - 60 + 1, p_283392_ + 14, j3 - 60 + 10, -1873784752);
|
||||
p_282273_.drawString(this.font, "20 TPS", p_283392_ + 2, j3 - 60 + 2, 14737632, false);
|
||||
p_282273_.hLine(RenderType.guiOverlay(), p_283392_, p_283392_ + j1 - 1, j3 - 60, -1);
|
||||
}
|
||||
|
||||
p_282273_.hLine(RenderType.guiOverlay(), p_283392_, p_283392_ + j1 - 1, j3 - 1, -1);
|
||||
p_282273_.vLine(RenderType.guiOverlay(), p_283392_, j3 - 60, j3, -1);
|
||||
p_282273_.vLine(RenderType.guiOverlay(), p_283392_ + j1 - 1, j3 - 60, j3, -1);
|
||||
int l3 = this.minecraft.options.framerateLimit().get();
|
||||
if (p_282824_ && l3 > 0 && l3 <= 250) {
|
||||
p_282273_.hLine(RenderType.guiOverlay(), p_283392_, p_283392_ + j1 - 1, j3 - 1 - (int)(1800.0D / (double)l3), -16711681);
|
||||
}
|
||||
|
||||
String s1 = l1 + " ms min";
|
||||
String s2 = k1 / (long)j1 + " ms avg";
|
||||
String s = i2 + " ms max";
|
||||
p_282273_.drawString(this.font, s1, p_283392_ + 2, j3 - 60 - 9, 14737632);
|
||||
p_282273_.drawCenteredString(this.font, s2, p_283392_ + j1 / 2, j3 - 60 - 9, 14737632);
|
||||
p_282273_.drawString(this.font, s, p_283392_ + j1 - this.font.width(s), j3 - 60 - 9, 14737632);
|
||||
}
|
||||
|
||||
private int getSampleColor(int p_94046_, int p_94047_, int p_94048_, int p_94049_) {
|
||||
return p_94046_ < p_94048_ ? this.colorLerp(-16711936, -256, (float)p_94046_ / (float)p_94048_) : this.colorLerp(-256, -65536, (float)(p_94046_ - p_94048_) / (float)(p_94049_ - p_94048_));
|
||||
}
|
||||
|
||||
private int colorLerp(int p_94042_, int p_94043_, float p_94044_) {
|
||||
int i = p_94042_ >> 24 & 255;
|
||||
int j = p_94042_ >> 16 & 255;
|
||||
int k = p_94042_ >> 8 & 255;
|
||||
int l = p_94042_ & 255;
|
||||
int i1 = p_94043_ >> 24 & 255;
|
||||
int j1 = p_94043_ >> 16 & 255;
|
||||
int k1 = p_94043_ >> 8 & 255;
|
||||
int l1 = p_94043_ & 255;
|
||||
int i2 = Mth.clamp((int)Mth.lerp(p_94044_, (float)i, (float)i1), 0, 255);
|
||||
int j2 = Mth.clamp((int)Mth.lerp(p_94044_, (float)j, (float)j1), 0, 255);
|
||||
int k2 = Mth.clamp((int)Mth.lerp(p_94044_, (float)k, (float)k1), 0, 255);
|
||||
int l2 = Mth.clamp((int)Mth.lerp(p_94044_, (float)l, (float)l1), 0, 255);
|
||||
return i2 << 24 | j2 << 16 | k2 << 8 | l2;
|
||||
}
|
||||
|
||||
private static long bytesToMegabytes(long p_94051_) {
|
||||
return p_94051_ / 1024L / 1024L;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class AllocationRateCalculator {
|
||||
private static final int UPDATE_INTERVAL_MS = 500;
|
||||
private static final List<GarbageCollectorMXBean> GC_MBEANS = ManagementFactory.getGarbageCollectorMXBeans();
|
||||
private long lastTime = 0L;
|
||||
private long lastHeapUsage = -1L;
|
||||
private long lastGcCounts = -1L;
|
||||
private long lastRate = 0L;
|
||||
|
||||
long bytesAllocatedPerSecond(long p_232517_) {
|
||||
long i = System.currentTimeMillis();
|
||||
if (i - this.lastTime < 500L) {
|
||||
return this.lastRate;
|
||||
} else {
|
||||
long j = gcCounts();
|
||||
if (this.lastTime != 0L && j == this.lastGcCounts) {
|
||||
double d0 = (double)TimeUnit.SECONDS.toMillis(1L) / (double)(i - this.lastTime);
|
||||
long k = p_232517_ - this.lastHeapUsage;
|
||||
this.lastRate = Math.round((double)k * d0);
|
||||
}
|
||||
|
||||
this.lastTime = i;
|
||||
this.lastHeapUsage = p_232517_;
|
||||
this.lastGcCounts = j;
|
||||
return this.lastRate;
|
||||
}
|
||||
}
|
||||
|
||||
private static long gcCounts() {
|
||||
long i = 0L;
|
||||
|
||||
for(GarbageCollectorMXBean garbagecollectormxbean : GC_MBEANS) {
|
||||
i += garbagecollectormxbean.getCollectionCount();
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,565 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.ComponentPath;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.gui.navigation.FocusNavigationEvent;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.sounds.SoundManager;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class EditBox extends AbstractWidget implements Renderable {
|
||||
public static final int BACKWARDS = -1;
|
||||
public static final int FORWARDS = 1;
|
||||
private static final int CURSOR_INSERT_WIDTH = 1;
|
||||
private static final int CURSOR_INSERT_COLOR = -3092272;
|
||||
private static final String CURSOR_APPEND_CHARACTER = "_";
|
||||
public static final int DEFAULT_TEXT_COLOR = 14737632;
|
||||
private static final int BORDER_COLOR_FOCUSED = -1;
|
||||
private static final int BORDER_COLOR = -6250336;
|
||||
private static final int BACKGROUND_COLOR = -16777216;
|
||||
private final Font font;
|
||||
private String value = "";
|
||||
private int maxLength = 32;
|
||||
private int frame;
|
||||
private boolean bordered = true;
|
||||
private boolean canLoseFocus = true;
|
||||
private boolean isEditable = true;
|
||||
private boolean shiftPressed;
|
||||
private int displayPos;
|
||||
private int cursorPos;
|
||||
private int highlightPos;
|
||||
private int textColor = 14737632;
|
||||
private int textColorUneditable = 7368816;
|
||||
@Nullable
|
||||
private String suggestion;
|
||||
@Nullable
|
||||
private Consumer<String> responder;
|
||||
private Predicate<String> filter = Objects::nonNull;
|
||||
private BiFunction<String, Integer, FormattedCharSequence> formatter = (p_94147_, p_94148_) -> {
|
||||
return FormattedCharSequence.forward(p_94147_, Style.EMPTY);
|
||||
};
|
||||
@Nullable
|
||||
private Component hint;
|
||||
|
||||
public EditBox(Font p_94114_, int p_94115_, int p_94116_, int p_94117_, int p_94118_, Component p_94119_) {
|
||||
this(p_94114_, p_94115_, p_94116_, p_94117_, p_94118_, (EditBox)null, p_94119_);
|
||||
}
|
||||
|
||||
public EditBox(Font p_94106_, int p_94107_, int p_94108_, int p_94109_, int p_94110_, @Nullable EditBox p_94111_, Component p_94112_) {
|
||||
super(p_94107_, p_94108_, p_94109_, p_94110_, p_94112_);
|
||||
this.font = p_94106_;
|
||||
if (p_94111_ != null) {
|
||||
this.setValue(p_94111_.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setResponder(Consumer<String> p_94152_) {
|
||||
this.responder = p_94152_;
|
||||
}
|
||||
|
||||
public void setFormatter(BiFunction<String, Integer, FormattedCharSequence> p_94150_) {
|
||||
this.formatter = p_94150_;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
++this.frame;
|
||||
}
|
||||
|
||||
protected MutableComponent createNarrationMessage() {
|
||||
Component component = this.getMessage();
|
||||
return Component.translatable("gui.narrate.editBox", component, this.value);
|
||||
}
|
||||
|
||||
public void setValue(String p_94145_) {
|
||||
if (this.filter.test(p_94145_)) {
|
||||
if (p_94145_.length() > this.maxLength) {
|
||||
this.value = p_94145_.substring(0, this.maxLength);
|
||||
} else {
|
||||
this.value = p_94145_;
|
||||
}
|
||||
|
||||
this.moveCursorToEnd();
|
||||
this.setHighlightPos(this.cursorPos);
|
||||
this.onValueChange(p_94145_);
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getHighlighted() {
|
||||
int i = Math.min(this.cursorPos, this.highlightPos);
|
||||
int j = Math.max(this.cursorPos, this.highlightPos);
|
||||
return this.value.substring(i, j);
|
||||
}
|
||||
|
||||
public void setFilter(Predicate<String> p_94154_) {
|
||||
this.filter = p_94154_;
|
||||
}
|
||||
|
||||
public void insertText(String p_94165_) {
|
||||
int i = Math.min(this.cursorPos, this.highlightPos);
|
||||
int j = Math.max(this.cursorPos, this.highlightPos);
|
||||
int k = this.maxLength - this.value.length() - (i - j);
|
||||
String s = SharedConstants.filterText(p_94165_);
|
||||
int l = s.length();
|
||||
if (k < l) {
|
||||
s = s.substring(0, k);
|
||||
l = k;
|
||||
}
|
||||
|
||||
String s1 = (new StringBuilder(this.value)).replace(i, j, s).toString();
|
||||
if (this.filter.test(s1)) {
|
||||
this.value = s1;
|
||||
this.setCursorPosition(i + l);
|
||||
this.setHighlightPos(this.cursorPos);
|
||||
this.onValueChange(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
private void onValueChange(String p_94175_) {
|
||||
if (this.responder != null) {
|
||||
this.responder.accept(p_94175_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void deleteText(int p_94218_) {
|
||||
if (Screen.hasControlDown()) {
|
||||
this.deleteWords(p_94218_);
|
||||
} else {
|
||||
this.deleteChars(p_94218_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void deleteWords(int p_94177_) {
|
||||
if (!this.value.isEmpty()) {
|
||||
if (this.highlightPos != this.cursorPos) {
|
||||
this.insertText("");
|
||||
} else {
|
||||
this.deleteChars(this.getWordPosition(p_94177_) - this.cursorPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteChars(int p_94181_) {
|
||||
if (!this.value.isEmpty()) {
|
||||
if (this.highlightPos != this.cursorPos) {
|
||||
this.insertText("");
|
||||
} else {
|
||||
int i = this.getCursorPos(p_94181_);
|
||||
int j = Math.min(i, this.cursorPos);
|
||||
int k = Math.max(i, this.cursorPos);
|
||||
if (j != k) {
|
||||
String s = (new StringBuilder(this.value)).delete(j, k).toString();
|
||||
if (this.filter.test(s)) {
|
||||
this.value = s;
|
||||
this.moveCursorTo(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getWordPosition(int p_94185_) {
|
||||
return this.getWordPosition(p_94185_, this.getCursorPosition());
|
||||
}
|
||||
|
||||
private int getWordPosition(int p_94129_, int p_94130_) {
|
||||
return this.getWordPosition(p_94129_, p_94130_, true);
|
||||
}
|
||||
|
||||
private int getWordPosition(int p_94141_, int p_94142_, boolean p_94143_) {
|
||||
int i = p_94142_;
|
||||
boolean flag = p_94141_ < 0;
|
||||
int j = Math.abs(p_94141_);
|
||||
|
||||
for(int k = 0; k < j; ++k) {
|
||||
if (!flag) {
|
||||
int l = this.value.length();
|
||||
i = this.value.indexOf(32, i);
|
||||
if (i == -1) {
|
||||
i = l;
|
||||
} else {
|
||||
while(p_94143_ && i < l && this.value.charAt(i) == ' ') {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while(p_94143_ && i > 0 && this.value.charAt(i - 1) == ' ') {
|
||||
--i;
|
||||
}
|
||||
|
||||
while(i > 0 && this.value.charAt(i - 1) != ' ') {
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public void moveCursor(int p_94189_) {
|
||||
this.moveCursorTo(this.getCursorPos(p_94189_));
|
||||
}
|
||||
|
||||
private int getCursorPos(int p_94221_) {
|
||||
return Util.offsetByCodepoints(this.value, this.cursorPos, p_94221_);
|
||||
}
|
||||
|
||||
public void moveCursorTo(int p_94193_) {
|
||||
this.setCursorPosition(p_94193_);
|
||||
if (!this.shiftPressed) {
|
||||
this.setHighlightPos(this.cursorPos);
|
||||
}
|
||||
|
||||
this.onValueChange(this.value);
|
||||
}
|
||||
|
||||
public void setCursorPosition(int p_94197_) {
|
||||
this.cursorPos = Mth.clamp(p_94197_, 0, this.value.length());
|
||||
}
|
||||
|
||||
public void moveCursorToStart() {
|
||||
this.moveCursorTo(0);
|
||||
}
|
||||
|
||||
public void moveCursorToEnd() {
|
||||
this.moveCursorTo(this.value.length());
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_94132_, int p_94133_, int p_94134_) {
|
||||
if (!this.canConsumeInput()) {
|
||||
return false;
|
||||
} else {
|
||||
this.shiftPressed = Screen.hasShiftDown();
|
||||
if (Screen.isSelectAll(p_94132_)) {
|
||||
this.moveCursorToEnd();
|
||||
this.setHighlightPos(0);
|
||||
return true;
|
||||
} else if (Screen.isCopy(p_94132_)) {
|
||||
Minecraft.getInstance().keyboardHandler.setClipboard(this.getHighlighted());
|
||||
return true;
|
||||
} else if (Screen.isPaste(p_94132_)) {
|
||||
if (this.isEditable) {
|
||||
this.insertText(Minecraft.getInstance().keyboardHandler.getClipboard());
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (Screen.isCut(p_94132_)) {
|
||||
Minecraft.getInstance().keyboardHandler.setClipboard(this.getHighlighted());
|
||||
if (this.isEditable) {
|
||||
this.insertText("");
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
switch (p_94132_) {
|
||||
case 259:
|
||||
if (this.isEditable) {
|
||||
this.shiftPressed = false;
|
||||
this.deleteText(-1);
|
||||
this.shiftPressed = Screen.hasShiftDown();
|
||||
}
|
||||
|
||||
return true;
|
||||
case 260:
|
||||
case 264:
|
||||
case 265:
|
||||
case 266:
|
||||
case 267:
|
||||
default:
|
||||
return false;
|
||||
case 261:
|
||||
if (this.isEditable) {
|
||||
this.shiftPressed = false;
|
||||
this.deleteText(1);
|
||||
this.shiftPressed = Screen.hasShiftDown();
|
||||
}
|
||||
|
||||
return true;
|
||||
case 262:
|
||||
if (Screen.hasControlDown()) {
|
||||
this.moveCursorTo(this.getWordPosition(1));
|
||||
} else {
|
||||
this.moveCursor(1);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 263:
|
||||
if (Screen.hasControlDown()) {
|
||||
this.moveCursorTo(this.getWordPosition(-1));
|
||||
} else {
|
||||
this.moveCursor(-1);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 268:
|
||||
this.moveCursorToStart();
|
||||
return true;
|
||||
case 269:
|
||||
this.moveCursorToEnd();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canConsumeInput() {
|
||||
return this.isVisible() && this.isFocused() && this.isEditable();
|
||||
}
|
||||
|
||||
public boolean charTyped(char p_94122_, int p_94123_) {
|
||||
if (!this.canConsumeInput()) {
|
||||
return false;
|
||||
} else if (SharedConstants.isAllowedChatCharacter(p_94122_)) {
|
||||
if (this.isEditable) {
|
||||
this.insertText(Character.toString(p_94122_));
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void onClick(double p_279417_, double p_279437_) {
|
||||
int i = Mth.floor(p_279417_) - this.getX();
|
||||
if (this.bordered) {
|
||||
i -= 4;
|
||||
}
|
||||
|
||||
String s = this.font.plainSubstrByWidth(this.value.substring(this.displayPos), this.getInnerWidth());
|
||||
this.moveCursorTo(this.font.plainSubstrByWidth(s, i).length() + this.displayPos);
|
||||
}
|
||||
|
||||
public void playDownSound(SoundManager p_279245_) {
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_283252_, int p_281594_, int p_282100_, float p_283101_) {
|
||||
if (this.isVisible()) {
|
||||
if (this.isBordered()) {
|
||||
int i = this.isFocused() ? -1 : -6250336;
|
||||
p_283252_.fill(this.getX() - 1, this.getY() - 1, this.getX() + this.width + 1, this.getY() + this.height + 1, i);
|
||||
p_283252_.fill(this.getX(), this.getY(), this.getX() + this.width, this.getY() + this.height, -16777216);
|
||||
}
|
||||
|
||||
int i2 = this.isEditable ? this.textColor : this.textColorUneditable;
|
||||
int j = this.cursorPos - this.displayPos;
|
||||
int k = this.highlightPos - this.displayPos;
|
||||
String s = this.font.plainSubstrByWidth(this.value.substring(this.displayPos), this.getInnerWidth());
|
||||
boolean flag = j >= 0 && j <= s.length();
|
||||
boolean flag1 = this.isFocused() && this.frame / 6 % 2 == 0 && flag;
|
||||
int l = this.bordered ? this.getX() + 4 : this.getX();
|
||||
int i1 = this.bordered ? this.getY() + (this.height - 8) / 2 : this.getY();
|
||||
int j1 = l;
|
||||
if (k > s.length()) {
|
||||
k = s.length();
|
||||
}
|
||||
|
||||
if (!s.isEmpty()) {
|
||||
String s1 = flag ? s.substring(0, j) : s;
|
||||
j1 = p_283252_.drawString(this.font, this.formatter.apply(s1, this.displayPos), l, i1, i2);
|
||||
}
|
||||
|
||||
boolean flag2 = this.cursorPos < this.value.length() || this.value.length() >= this.getMaxLength();
|
||||
int k1 = j1;
|
||||
if (!flag) {
|
||||
k1 = j > 0 ? l + this.width : l;
|
||||
} else if (flag2) {
|
||||
k1 = j1 - 1;
|
||||
--j1;
|
||||
}
|
||||
|
||||
if (!s.isEmpty() && flag && j < s.length()) {
|
||||
p_283252_.drawString(this.font, this.formatter.apply(s.substring(j), this.cursorPos), j1, i1, i2);
|
||||
}
|
||||
|
||||
if (this.hint != null && s.isEmpty() && !this.isFocused()) {
|
||||
p_283252_.drawString(this.font, this.hint, j1, i1, i2);
|
||||
}
|
||||
|
||||
if (!flag2 && this.suggestion != null) {
|
||||
p_283252_.drawString(this.font, this.suggestion, k1 - 1, i1, -8355712);
|
||||
}
|
||||
|
||||
if (flag1) {
|
||||
if (flag2) {
|
||||
p_283252_.fill(RenderType.guiOverlay(), k1, i1 - 1, k1 + 1, i1 + 1 + 9, -3092272);
|
||||
} else {
|
||||
p_283252_.drawString(this.font, "_", k1, i1, i2);
|
||||
}
|
||||
}
|
||||
|
||||
if (k != j) {
|
||||
int l1 = l + this.font.width(s.substring(0, k));
|
||||
this.renderHighlight(p_283252_, k1, i1 - 1, l1 - 1, i1 + 1 + 9);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void renderHighlight(GuiGraphics p_281400_, int p_265338_, int p_265693_, int p_265618_, int p_265584_) {
|
||||
if (p_265338_ < p_265618_) {
|
||||
int i = p_265338_;
|
||||
p_265338_ = p_265618_;
|
||||
p_265618_ = i;
|
||||
}
|
||||
|
||||
if (p_265693_ < p_265584_) {
|
||||
int j = p_265693_;
|
||||
p_265693_ = p_265584_;
|
||||
p_265584_ = j;
|
||||
}
|
||||
|
||||
if (p_265618_ > this.getX() + this.width) {
|
||||
p_265618_ = this.getX() + this.width;
|
||||
}
|
||||
|
||||
if (p_265338_ > this.getX() + this.width) {
|
||||
p_265338_ = this.getX() + this.width;
|
||||
}
|
||||
|
||||
p_281400_.fill(RenderType.guiTextHighlight(), p_265338_, p_265693_, p_265618_, p_265584_, -16776961);
|
||||
}
|
||||
|
||||
public void setMaxLength(int p_94200_) {
|
||||
this.maxLength = p_94200_;
|
||||
if (this.value.length() > p_94200_) {
|
||||
this.value = this.value.substring(0, p_94200_);
|
||||
this.onValueChange(this.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int getMaxLength() {
|
||||
return this.maxLength;
|
||||
}
|
||||
|
||||
public int getCursorPosition() {
|
||||
return this.cursorPos;
|
||||
}
|
||||
|
||||
private boolean isBordered() {
|
||||
return this.bordered;
|
||||
}
|
||||
|
||||
public void setBordered(boolean p_94183_) {
|
||||
this.bordered = p_94183_;
|
||||
}
|
||||
|
||||
public void setTextColor(int p_94203_) {
|
||||
this.textColor = p_94203_;
|
||||
}
|
||||
|
||||
public void setTextColorUneditable(int p_94206_) {
|
||||
this.textColorUneditable = p_94206_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath nextFocusPath(FocusNavigationEvent p_265216_) {
|
||||
return this.visible && this.isEditable ? super.nextFocusPath(p_265216_) : null;
|
||||
}
|
||||
|
||||
public boolean isMouseOver(double p_94157_, double p_94158_) {
|
||||
return this.visible && p_94157_ >= (double)this.getX() && p_94157_ < (double)(this.getX() + this.width) && p_94158_ >= (double)this.getY() && p_94158_ < (double)(this.getY() + this.height);
|
||||
}
|
||||
|
||||
public void setFocused(boolean p_265520_) {
|
||||
if (this.canLoseFocus || p_265520_) {
|
||||
super.setFocused(p_265520_);
|
||||
if (p_265520_) {
|
||||
this.frame = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEditable() {
|
||||
return this.isEditable;
|
||||
}
|
||||
|
||||
public void setEditable(boolean p_94187_) {
|
||||
this.isEditable = p_94187_;
|
||||
}
|
||||
|
||||
public int getInnerWidth() {
|
||||
return this.isBordered() ? this.width - 8 : this.width;
|
||||
}
|
||||
|
||||
public void setHighlightPos(int p_94209_) {
|
||||
int i = this.value.length();
|
||||
this.highlightPos = Mth.clamp(p_94209_, 0, i);
|
||||
if (this.font != null) {
|
||||
if (this.displayPos > i) {
|
||||
this.displayPos = i;
|
||||
}
|
||||
|
||||
int j = this.getInnerWidth();
|
||||
String s = this.font.plainSubstrByWidth(this.value.substring(this.displayPos), j);
|
||||
int k = s.length() + this.displayPos;
|
||||
if (this.highlightPos == this.displayPos) {
|
||||
this.displayPos -= this.font.plainSubstrByWidth(this.value, j, true).length();
|
||||
}
|
||||
|
||||
if (this.highlightPos > k) {
|
||||
this.displayPos += this.highlightPos - k;
|
||||
} else if (this.highlightPos <= this.displayPos) {
|
||||
this.displayPos -= this.displayPos - this.highlightPos;
|
||||
}
|
||||
|
||||
this.displayPos = Mth.clamp(this.displayPos, 0, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setCanLoseFocus(boolean p_94191_) {
|
||||
this.canLoseFocus = p_94191_;
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
public void setVisible(boolean p_94195_) {
|
||||
this.visible = p_94195_;
|
||||
}
|
||||
|
||||
public void setSuggestion(@Nullable String p_94168_) {
|
||||
this.suggestion = p_94168_;
|
||||
}
|
||||
|
||||
public int getScreenX(int p_94212_) {
|
||||
return p_94212_ > this.value.length() ? this.getX() : this.getX() + this.font.width(this.value.substring(0, p_94212_));
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput p_259237_) {
|
||||
p_259237_.add(NarratedElementType.TITLE, this.createNarrationMessage());
|
||||
}
|
||||
|
||||
public void setHint(Component p_259584_) {
|
||||
this.hint = p_259584_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class FittingMultiLineTextWidget extends AbstractScrollWidget {
|
||||
private final Font font;
|
||||
private final MultiLineTextWidget multilineWidget;
|
||||
|
||||
public FittingMultiLineTextWidget(int p_289785_, int p_289777_, int p_289760_, int p_289801_, Component p_289788_, Font p_289781_) {
|
||||
super(p_289785_, p_289777_, p_289760_, p_289801_, p_289788_);
|
||||
this.font = p_289781_;
|
||||
this.multilineWidget = (new MultiLineTextWidget(0, 0, p_289788_, p_289781_)).setMaxWidth(this.getWidth() - this.totalInnerPadding());
|
||||
}
|
||||
|
||||
public FittingMultiLineTextWidget setColor(int p_289780_) {
|
||||
this.multilineWidget.setColor(p_289780_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setWidth(int p_289765_) {
|
||||
super.setWidth(p_289765_);
|
||||
this.multilineWidget.setMaxWidth(this.getWidth() - this.totalInnerPadding());
|
||||
}
|
||||
|
||||
protected int getInnerHeight() {
|
||||
return this.multilineWidget.getHeight();
|
||||
}
|
||||
|
||||
protected double scrollRate() {
|
||||
return 9.0D;
|
||||
}
|
||||
|
||||
protected void renderBackground(GuiGraphics p_289758_) {
|
||||
if (this.scrollbarVisible()) {
|
||||
super.renderBackground(p_289758_);
|
||||
} else if (this.isFocused()) {
|
||||
this.renderBorder(p_289758_, this.getX() - this.innerPadding(), this.getY() - this.innerPadding(), this.getWidth() + this.totalInnerPadding(), this.getHeight() + this.totalInnerPadding());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_289802_, int p_289778_, int p_289798_, float p_289804_) {
|
||||
if (this.visible) {
|
||||
if (!this.scrollbarVisible()) {
|
||||
this.renderBackground(p_289802_);
|
||||
p_289802_.pose().pushPose();
|
||||
p_289802_.pose().translate((float)this.getX(), (float)this.getY(), 0.0F);
|
||||
this.multilineWidget.render(p_289802_, p_289778_, p_289798_, p_289804_);
|
||||
p_289802_.pose().popPose();
|
||||
} else {
|
||||
super.renderWidget(p_289802_, p_289778_, p_289798_, p_289804_);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderContents(GuiGraphics p_289766_, int p_289790_, int p_289786_, float p_289767_) {
|
||||
p_289766_.pose().pushPose();
|
||||
p_289766_.pose().translate((float)(this.getX() + this.innerPadding()), (float)(this.getY() + this.innerPadding()), 0.0F);
|
||||
this.multilineWidget.render(p_289766_, p_289790_, p_289786_, p_289767_);
|
||||
p_289766_.pose().popPose();
|
||||
}
|
||||
|
||||
protected void updateWidgetNarration(NarrationElementOutput p_289784_) {
|
||||
p_289784_.add(NarratedElementType.TITLE, this.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ImageButton extends Button {
|
||||
protected final ResourceLocation resourceLocation;
|
||||
protected final int xTexStart;
|
||||
protected final int yTexStart;
|
||||
protected final int yDiffTex;
|
||||
protected final int textureWidth;
|
||||
protected final int textureHeight;
|
||||
|
||||
public ImageButton(int p_169011_, int p_169012_, int p_169013_, int p_169014_, int p_169015_, int p_169016_, ResourceLocation p_169017_, Button.OnPress p_169018_) {
|
||||
this(p_169011_, p_169012_, p_169013_, p_169014_, p_169015_, p_169016_, p_169014_, p_169017_, 256, 256, p_169018_);
|
||||
}
|
||||
|
||||
public ImageButton(int p_94269_, int p_94270_, int p_94271_, int p_94272_, int p_94273_, int p_94274_, int p_94275_, ResourceLocation p_94276_, Button.OnPress p_94277_) {
|
||||
this(p_94269_, p_94270_, p_94271_, p_94272_, p_94273_, p_94274_, p_94275_, p_94276_, 256, 256, p_94277_);
|
||||
}
|
||||
|
||||
public ImageButton(int p_94230_, int p_94231_, int p_94232_, int p_94233_, int p_94234_, int p_94235_, int p_94236_, ResourceLocation p_94237_, int p_94238_, int p_94239_, Button.OnPress p_94240_) {
|
||||
this(p_94230_, p_94231_, p_94232_, p_94233_, p_94234_, p_94235_, p_94236_, p_94237_, p_94238_, p_94239_, p_94240_, CommonComponents.EMPTY);
|
||||
}
|
||||
|
||||
public ImageButton(int p_94256_, int p_94257_, int p_94258_, int p_94259_, int p_94260_, int p_94261_, int p_94262_, ResourceLocation p_94263_, int p_94264_, int p_94265_, Button.OnPress p_94266_, Component p_94267_) {
|
||||
super(p_94256_, p_94257_, p_94258_, p_94259_, p_94267_, p_94266_, DEFAULT_NARRATION);
|
||||
this.textureWidth = p_94264_;
|
||||
this.textureHeight = p_94265_;
|
||||
this.xTexStart = p_94260_;
|
||||
this.yTexStart = p_94261_;
|
||||
this.yDiffTex = p_94262_;
|
||||
this.resourceLocation = p_94263_;
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_283502_, int p_281473_, int p_283021_, float p_282518_) {
|
||||
this.renderTexture(p_283502_, this.resourceLocation, this.getX(), this.getY(), this.xTexStart, this.yTexStart, this.yDiffTex, this.width, this.height, this.textureWidth, this.textureHeight);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ImageWidget extends AbstractWidget {
|
||||
private final ResourceLocation imageLocation;
|
||||
|
||||
public ImageWidget(int p_275550_, int p_275723_, ResourceLocation p_275649_) {
|
||||
this(0, 0, p_275550_, p_275723_, p_275649_);
|
||||
}
|
||||
|
||||
public ImageWidget(int p_275421_, int p_275294_, int p_275403_, int p_275631_, ResourceLocation p_275648_) {
|
||||
super(p_275421_, p_275294_, p_275403_, p_275631_, Component.empty());
|
||||
this.imageLocation = p_275648_;
|
||||
}
|
||||
|
||||
protected void updateWidgetNarration(NarrationElementOutput p_275454_) {
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_283475_, int p_281265_, int p_281555_, float p_282690_) {
|
||||
int i = this.getWidth();
|
||||
int j = this.getHeight();
|
||||
p_283475_.blit(this.imageLocation, this.getX(), this.getY(), 0.0F, 0.0F, i, j, i, j);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import java.util.UUID;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.BossEvent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class LerpingBossEvent extends BossEvent {
|
||||
private static final long LERP_MILLISECONDS = 100L;
|
||||
protected float targetPercent;
|
||||
protected long setTime;
|
||||
|
||||
public LerpingBossEvent(UUID p_169021_, Component p_169022_, float p_169023_, BossEvent.BossBarColor p_169024_, BossEvent.BossBarOverlay p_169025_, boolean p_169026_, boolean p_169027_, boolean p_169028_) {
|
||||
super(p_169021_, p_169022_, p_169024_, p_169025_);
|
||||
this.targetPercent = p_169023_;
|
||||
this.progress = p_169023_;
|
||||
this.setTime = Util.getMillis();
|
||||
this.setDarkenScreen(p_169026_);
|
||||
this.setPlayBossMusic(p_169027_);
|
||||
this.setCreateWorldFog(p_169028_);
|
||||
}
|
||||
|
||||
public void setProgress(float p_169030_) {
|
||||
this.progress = this.getProgress();
|
||||
this.targetPercent = p_169030_;
|
||||
this.setTime = Util.getMillis();
|
||||
}
|
||||
|
||||
public float getProgress() {
|
||||
long i = Util.getMillis() - this.setTime;
|
||||
float f = Mth.clamp((float)i / 100.0F, 0.0F, 1.0F);
|
||||
return Mth.lerp(f, this.progress, this.targetPercent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class LockIconButton extends Button {
|
||||
private boolean locked;
|
||||
|
||||
public LockIconButton(int p_94299_, int p_94300_, Button.OnPress p_94301_) {
|
||||
super(p_94299_, p_94300_, 20, 20, Component.translatable("narrator.button.difficulty_lock"), p_94301_, DEFAULT_NARRATION);
|
||||
}
|
||||
|
||||
protected MutableComponent createNarrationMessage() {
|
||||
return CommonComponents.joinForNarration(super.createNarrationMessage(), this.isLocked() ? Component.translatable("narrator.button.difficulty_lock.locked") : Component.translatable("narrator.button.difficulty_lock.unlocked"));
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return this.locked;
|
||||
}
|
||||
|
||||
public void setLocked(boolean p_94310_) {
|
||||
this.locked = p_94310_;
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_282701_, int p_282638_, int p_283565_, float p_282549_) {
|
||||
LockIconButton.Icon lockiconbutton$icon;
|
||||
if (!this.active) {
|
||||
lockiconbutton$icon = this.locked ? LockIconButton.Icon.LOCKED_DISABLED : LockIconButton.Icon.UNLOCKED_DISABLED;
|
||||
} else if (this.isHoveredOrFocused()) {
|
||||
lockiconbutton$icon = this.locked ? LockIconButton.Icon.LOCKED_HOVER : LockIconButton.Icon.UNLOCKED_HOVER;
|
||||
} else {
|
||||
lockiconbutton$icon = this.locked ? LockIconButton.Icon.LOCKED : LockIconButton.Icon.UNLOCKED;
|
||||
}
|
||||
|
||||
p_282701_.blit(Button.WIDGETS_LOCATION, this.getX(), this.getY(), lockiconbutton$icon.getX(), lockiconbutton$icon.getY(), this.width, this.height);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static enum Icon {
|
||||
LOCKED(0, 146),
|
||||
LOCKED_HOVER(0, 166),
|
||||
LOCKED_DISABLED(0, 186),
|
||||
UNLOCKED(20, 146),
|
||||
UNLOCKED_HOVER(20, 166),
|
||||
UNLOCKED_DISABLED(20, 186);
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
private Icon(int p_94324_, int p_94325_) {
|
||||
this.x = p_94324_;
|
||||
this.y = p_94325_;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class LogoRenderer {
|
||||
public static final ResourceLocation MINECRAFT_LOGO = new ResourceLocation("textures/gui/title/minecraft.png");
|
||||
public static final ResourceLocation EASTER_EGG_LOGO = new ResourceLocation("textures/gui/title/minceraft.png");
|
||||
public static final ResourceLocation MINECRAFT_EDITION = new ResourceLocation("textures/gui/title/edition.png");
|
||||
public static final int LOGO_WIDTH = 256;
|
||||
public static final int LOGO_HEIGHT = 44;
|
||||
private static final int LOGO_TEXTURE_WIDTH = 256;
|
||||
private static final int LOGO_TEXTURE_HEIGHT = 64;
|
||||
private static final int EDITION_WIDTH = 128;
|
||||
private static final int EDITION_HEIGHT = 14;
|
||||
private static final int EDITION_TEXTURE_WIDTH = 128;
|
||||
private static final int EDITION_TEXTURE_HEIGHT = 16;
|
||||
public static final int DEFAULT_HEIGHT_OFFSET = 30;
|
||||
private static final int EDITION_LOGO_OVERLAP = 7;
|
||||
private final boolean showEasterEgg = (double)RandomSource.create().nextFloat() < 1.0E-4D;
|
||||
private final boolean keepLogoThroughFade;
|
||||
|
||||
public LogoRenderer(boolean p_265300_) {
|
||||
this.keepLogoThroughFade = p_265300_;
|
||||
}
|
||||
|
||||
public void renderLogo(GuiGraphics p_282217_, int p_283270_, float p_282051_) {
|
||||
this.renderLogo(p_282217_, p_283270_, p_282051_, 30);
|
||||
}
|
||||
|
||||
public void renderLogo(GuiGraphics p_281856_, int p_281512_, float p_281290_, int p_282296_) {
|
||||
p_281856_.setColor(1.0F, 1.0F, 1.0F, this.keepLogoThroughFade ? 1.0F : p_281290_);
|
||||
int i = p_281512_ / 2 - 128;
|
||||
p_281856_.blit(this.showEasterEgg ? EASTER_EGG_LOGO : MINECRAFT_LOGO, i, p_282296_, 0.0F, 0.0F, 256, 44, 256, 64);
|
||||
int j = p_281512_ / 2 - 64;
|
||||
int k = p_282296_ + 44 - 7;
|
||||
p_281856_.blit(MINECRAFT_EDITION, j, k, 0.0F, 0.0F, 128, 14, 128, 16);
|
||||
p_281856_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class MultiLineEditBox extends AbstractScrollWidget {
|
||||
private static final int CURSOR_INSERT_WIDTH = 1;
|
||||
private static final int CURSOR_INSERT_COLOR = -3092272;
|
||||
private static final String CURSOR_APPEND_CHARACTER = "_";
|
||||
private static final int TEXT_COLOR = -2039584;
|
||||
private static final int PLACEHOLDER_TEXT_COLOR = -857677600;
|
||||
private final Font font;
|
||||
private final Component placeholder;
|
||||
private final MultilineTextField textField;
|
||||
private int frame;
|
||||
|
||||
public MultiLineEditBox(Font p_239008_, int p_239009_, int p_239010_, int p_239011_, int p_239012_, Component p_239013_, Component p_239014_) {
|
||||
super(p_239009_, p_239010_, p_239011_, p_239012_, p_239014_);
|
||||
this.font = p_239008_;
|
||||
this.placeholder = p_239013_;
|
||||
this.textField = new MultilineTextField(p_239008_, p_239011_ - this.totalInnerPadding());
|
||||
this.textField.setCursorListener(this::scrollToCursor);
|
||||
}
|
||||
|
||||
public void setCharacterLimit(int p_239314_) {
|
||||
this.textField.setCharacterLimit(p_239314_);
|
||||
}
|
||||
|
||||
public void setValueListener(Consumer<String> p_239274_) {
|
||||
this.textField.setValueListener(p_239274_);
|
||||
}
|
||||
|
||||
public void setValue(String p_240160_) {
|
||||
this.textField.setValue(p_240160_);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.textField.value();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
++this.frame;
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput p_259393_) {
|
||||
p_259393_.add(NarratedElementType.TITLE, Component.translatable("gui.narrate.editBox", this.getMessage(), this.getValue()));
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_239101_, double p_239102_, int p_239103_) {
|
||||
if (super.mouseClicked(p_239101_, p_239102_, p_239103_)) {
|
||||
return true;
|
||||
} else if (this.withinContentAreaPoint(p_239101_, p_239102_) && p_239103_ == 0) {
|
||||
this.textField.setSelecting(Screen.hasShiftDown());
|
||||
this.seekCursorScreen(p_239101_, p_239102_);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseDragged(double p_238978_, double p_238979_, int p_238980_, double p_238981_, double p_238982_) {
|
||||
if (super.mouseDragged(p_238978_, p_238979_, p_238980_, p_238981_, p_238982_)) {
|
||||
return true;
|
||||
} else if (this.withinContentAreaPoint(p_238978_, p_238979_) && p_238980_ == 0) {
|
||||
this.textField.setSelecting(true);
|
||||
this.seekCursorScreen(p_238978_, p_238979_);
|
||||
this.textField.setSelecting(Screen.hasShiftDown());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_239433_, int p_239434_, int p_239435_) {
|
||||
return this.textField.keyPressed(p_239433_);
|
||||
}
|
||||
|
||||
public boolean charTyped(char p_239387_, int p_239388_) {
|
||||
if (this.visible && this.isFocused() && SharedConstants.isAllowedChatCharacter(p_239387_)) {
|
||||
this.textField.insertText(Character.toString(p_239387_));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderContents(GuiGraphics p_283676_, int p_281538_, int p_283033_, float p_281767_) {
|
||||
String s = this.textField.value();
|
||||
if (s.isEmpty() && !this.isFocused()) {
|
||||
p_283676_.drawWordWrap(this.font, this.placeholder, this.getX() + this.innerPadding(), this.getY() + this.innerPadding(), this.width - this.totalInnerPadding(), -857677600);
|
||||
} else {
|
||||
int i = this.textField.cursor();
|
||||
boolean flag = this.isFocused() && this.frame / 6 % 2 == 0;
|
||||
boolean flag1 = i < s.length();
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
int l = this.getY() + this.innerPadding();
|
||||
|
||||
for(MultilineTextField.StringView multilinetextfield$stringview : this.textField.iterateLines()) {
|
||||
boolean flag2 = this.withinContentAreaTopBottom(l, l + 9);
|
||||
if (flag && flag1 && i >= multilinetextfield$stringview.beginIndex() && i <= multilinetextfield$stringview.endIndex()) {
|
||||
if (flag2) {
|
||||
j = p_283676_.drawString(this.font, s.substring(multilinetextfield$stringview.beginIndex(), i), this.getX() + this.innerPadding(), l, -2039584) - 1;
|
||||
p_283676_.fill(j, l - 1, j + 1, l + 1 + 9, -3092272);
|
||||
p_283676_.drawString(this.font, s.substring(i, multilinetextfield$stringview.endIndex()), j, l, -2039584);
|
||||
}
|
||||
} else {
|
||||
if (flag2) {
|
||||
j = p_283676_.drawString(this.font, s.substring(multilinetextfield$stringview.beginIndex(), multilinetextfield$stringview.endIndex()), this.getX() + this.innerPadding(), l, -2039584) - 1;
|
||||
}
|
||||
|
||||
k = l;
|
||||
}
|
||||
|
||||
l += 9;
|
||||
}
|
||||
|
||||
if (flag && !flag1 && this.withinContentAreaTopBottom(k, k + 9)) {
|
||||
p_283676_.drawString(this.font, "_", j, k, -3092272);
|
||||
}
|
||||
|
||||
if (this.textField.hasSelection()) {
|
||||
MultilineTextField.StringView multilinetextfield$stringview2 = this.textField.getSelected();
|
||||
int k1 = this.getX() + this.innerPadding();
|
||||
l = this.getY() + this.innerPadding();
|
||||
|
||||
for(MultilineTextField.StringView multilinetextfield$stringview1 : this.textField.iterateLines()) {
|
||||
if (multilinetextfield$stringview2.beginIndex() > multilinetextfield$stringview1.endIndex()) {
|
||||
l += 9;
|
||||
} else {
|
||||
if (multilinetextfield$stringview1.beginIndex() > multilinetextfield$stringview2.endIndex()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.withinContentAreaTopBottom(l, l + 9)) {
|
||||
int i1 = this.font.width(s.substring(multilinetextfield$stringview1.beginIndex(), Math.max(multilinetextfield$stringview2.beginIndex(), multilinetextfield$stringview1.beginIndex())));
|
||||
int j1;
|
||||
if (multilinetextfield$stringview2.endIndex() > multilinetextfield$stringview1.endIndex()) {
|
||||
j1 = this.width - this.innerPadding();
|
||||
} else {
|
||||
j1 = this.font.width(s.substring(multilinetextfield$stringview1.beginIndex(), multilinetextfield$stringview2.endIndex()));
|
||||
}
|
||||
|
||||
this.renderHighlight(p_283676_, k1 + i1, l, k1 + j1, l + 9);
|
||||
}
|
||||
|
||||
l += 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderDecorations(GuiGraphics p_282551_) {
|
||||
super.renderDecorations(p_282551_);
|
||||
if (this.textField.hasCharacterLimit()) {
|
||||
int i = this.textField.characterLimit();
|
||||
Component component = Component.translatable("gui.multiLineEditBox.character_limit", this.textField.value().length(), i);
|
||||
p_282551_.drawString(this.font, component, this.getX() + this.width - this.font.width(component), this.getY() + this.height + 4, 10526880);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getInnerHeight() {
|
||||
return 9 * this.textField.getLineCount();
|
||||
}
|
||||
|
||||
protected boolean scrollbarVisible() {
|
||||
return (double)this.textField.getLineCount() > this.getDisplayableLineCount();
|
||||
}
|
||||
|
||||
protected double scrollRate() {
|
||||
return 9.0D / 2.0D;
|
||||
}
|
||||
|
||||
private void renderHighlight(GuiGraphics p_282092_, int p_282814_, int p_282908_, int p_281451_, int p_281765_) {
|
||||
p_282092_.fill(RenderType.guiTextHighlight(), p_282814_, p_282908_, p_281451_, p_281765_, -16776961);
|
||||
}
|
||||
|
||||
private void scrollToCursor() {
|
||||
double d0 = this.scrollAmount();
|
||||
MultilineTextField.StringView multilinetextfield$stringview = this.textField.getLineView((int)(d0 / 9.0D));
|
||||
if (this.textField.cursor() <= multilinetextfield$stringview.beginIndex()) {
|
||||
d0 = (double)(this.textField.getLineAtCursor() * 9);
|
||||
} else {
|
||||
MultilineTextField.StringView multilinetextfield$stringview1 = this.textField.getLineView((int)((d0 + (double)this.height) / 9.0D) - 1);
|
||||
if (this.textField.cursor() > multilinetextfield$stringview1.endIndex()) {
|
||||
d0 = (double)(this.textField.getLineAtCursor() * 9 - this.height + 9 + this.totalInnerPadding());
|
||||
}
|
||||
}
|
||||
|
||||
this.setScrollAmount(d0);
|
||||
}
|
||||
|
||||
private double getDisplayableLineCount() {
|
||||
return (double)(this.height - this.totalInnerPadding()) / 9.0D;
|
||||
}
|
||||
|
||||
private void seekCursorScreen(double p_239276_, double p_239277_) {
|
||||
double d0 = p_239276_ - (double)this.getX() - (double)this.innerPadding();
|
||||
double d1 = p_239277_ - (double)this.getY() - (double)this.innerPadding() + this.scrollAmount();
|
||||
this.textField.seekCursorToPoint(d0, d1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.FormattedText;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface MultiLineLabel {
|
||||
MultiLineLabel EMPTY = new MultiLineLabel() {
|
||||
public int renderCentered(GuiGraphics p_283287_, int p_94383_, int p_94384_) {
|
||||
return p_94384_;
|
||||
}
|
||||
|
||||
public int renderCentered(GuiGraphics p_283384_, int p_94395_, int p_94396_, int p_94397_, int p_94398_) {
|
||||
return p_94396_;
|
||||
}
|
||||
|
||||
public int renderLeftAligned(GuiGraphics p_283077_, int p_94379_, int p_94380_, int p_282157_, int p_282742_) {
|
||||
return p_94380_;
|
||||
}
|
||||
|
||||
public int renderLeftAlignedNoShadow(GuiGraphics p_283645_, int p_94389_, int p_94390_, int p_94391_, int p_94392_) {
|
||||
return p_94390_;
|
||||
}
|
||||
|
||||
public void renderBackgroundCentered(GuiGraphics p_283208_, int p_210825_, int p_210826_, int p_210827_, int p_210828_, int p_210829_) {
|
||||
}
|
||||
|
||||
public int getLineCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
static MultiLineLabel create(Font p_94342_, FormattedText p_94343_, int p_94344_) {
|
||||
return createFixed(p_94342_, p_94342_.split(p_94343_, p_94344_).stream().map((p_94374_) -> {
|
||||
return new MultiLineLabel.TextWithWidth(p_94374_, p_94342_.width(p_94374_));
|
||||
}).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
|
||||
static MultiLineLabel create(Font p_94346_, FormattedText p_94347_, int p_94348_, int p_94349_) {
|
||||
return createFixed(p_94346_, p_94346_.split(p_94347_, p_94348_).stream().limit((long)p_94349_).map((p_94371_) -> {
|
||||
return new MultiLineLabel.TextWithWidth(p_94371_, p_94346_.width(p_94371_));
|
||||
}).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
|
||||
static MultiLineLabel create(Font p_94351_, Component... p_94352_) {
|
||||
return createFixed(p_94351_, Arrays.stream(p_94352_).map(Component::getVisualOrderText).map((p_94360_) -> {
|
||||
return new MultiLineLabel.TextWithWidth(p_94360_, p_94351_.width(p_94360_));
|
||||
}).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
|
||||
static MultiLineLabel create(Font p_169037_, List<Component> p_169038_) {
|
||||
return createFixed(p_169037_, p_169038_.stream().map(Component::getVisualOrderText).map((p_169035_) -> {
|
||||
return new MultiLineLabel.TextWithWidth(p_169035_, p_169037_.width(p_169035_));
|
||||
}).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
|
||||
static MultiLineLabel createFixed(final Font p_94362_, final List<MultiLineLabel.TextWithWidth> p_94363_) {
|
||||
return p_94363_.isEmpty() ? EMPTY : new MultiLineLabel() {
|
||||
private final int width = p_94363_.stream().mapToInt((p_232527_) -> {
|
||||
return p_232527_.width;
|
||||
}).max().orElse(0);
|
||||
|
||||
public int renderCentered(GuiGraphics p_283492_, int p_283184_, int p_282078_) {
|
||||
return this.renderCentered(p_283492_, p_283184_, p_282078_, 9, 16777215);
|
||||
}
|
||||
|
||||
public int renderCentered(GuiGraphics p_281603_, int p_281267_, int p_281819_, int p_281545_, int p_282780_) {
|
||||
int i = p_281819_;
|
||||
|
||||
for(MultiLineLabel.TextWithWidth multilinelabel$textwithwidth : p_94363_) {
|
||||
p_281603_.drawString(p_94362_, multilinelabel$textwithwidth.text, p_281267_ - multilinelabel$textwithwidth.width / 2, i, p_282780_);
|
||||
i += p_281545_;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public int renderLeftAligned(GuiGraphics p_282318_, int p_283665_, int p_283416_, int p_281919_, int p_281686_) {
|
||||
int i = p_283416_;
|
||||
|
||||
for(MultiLineLabel.TextWithWidth multilinelabel$textwithwidth : p_94363_) {
|
||||
p_282318_.drawString(p_94362_, multilinelabel$textwithwidth.text, p_283665_, i, p_281686_);
|
||||
i += p_281919_;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public int renderLeftAlignedNoShadow(GuiGraphics p_281782_, int p_282841_, int p_283554_, int p_282768_, int p_283499_) {
|
||||
int i = p_283554_;
|
||||
|
||||
for(MultiLineLabel.TextWithWidth multilinelabel$textwithwidth : p_94363_) {
|
||||
p_281782_.drawString(p_94362_, multilinelabel$textwithwidth.text, p_282841_, i, p_283499_, false);
|
||||
i += p_282768_;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public void renderBackgroundCentered(GuiGraphics p_281633_, int p_210832_, int p_210833_, int p_210834_, int p_210835_, int p_210836_) {
|
||||
int i = p_94363_.stream().mapToInt((p_232524_) -> {
|
||||
return p_232524_.width;
|
||||
}).max().orElse(0);
|
||||
if (i > 0) {
|
||||
p_281633_.fill(p_210832_ - i / 2 - p_210835_, p_210833_ - p_210835_, p_210832_ + i / 2 + p_210835_, p_210833_ + p_94363_.size() * p_210834_ + p_210835_, p_210836_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getLineCount() {
|
||||
return p_94363_.size();
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int renderCentered(GuiGraphics p_281749_, int p_94334_, int p_94335_);
|
||||
|
||||
int renderCentered(GuiGraphics p_281785_, int p_94337_, int p_94338_, int p_94339_, int p_94340_);
|
||||
|
||||
int renderLeftAligned(GuiGraphics p_282655_, int p_94365_, int p_94366_, int p_94367_, int p_94368_);
|
||||
|
||||
int renderLeftAlignedNoShadow(GuiGraphics p_281982_, int p_94354_, int p_94355_, int p_94356_, int p_94357_);
|
||||
|
||||
void renderBackgroundCentered(GuiGraphics p_282120_, int p_210818_, int p_210819_, int p_210820_, int p_210821_, int p_210822_);
|
||||
|
||||
int getLineCount();
|
||||
|
||||
int getWidth();
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class TextWithWidth {
|
||||
final FormattedCharSequence text;
|
||||
final int width;
|
||||
|
||||
TextWithWidth(FormattedCharSequence p_94430_, int p_94431_) {
|
||||
this.text = p_94430_;
|
||||
this.width = p_94431_;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.SingleKeyCache;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class MultiLineTextWidget extends AbstractStringWidget {
|
||||
private OptionalInt maxWidth = OptionalInt.empty();
|
||||
private OptionalInt maxRows = OptionalInt.empty();
|
||||
private final SingleKeyCache<MultiLineTextWidget.CacheKey, MultiLineLabel> cache;
|
||||
private boolean centered = false;
|
||||
|
||||
public MultiLineTextWidget(Component p_270532_, Font p_270639_) {
|
||||
this(0, 0, p_270532_, p_270639_);
|
||||
}
|
||||
|
||||
public MultiLineTextWidget(int p_270325_, int p_270355_, Component p_270069_, Font p_270673_) {
|
||||
super(p_270325_, p_270355_, 0, 0, p_270069_, p_270673_);
|
||||
this.cache = Util.singleKeyCache((p_270516_) -> {
|
||||
return p_270516_.maxRows.isPresent() ? MultiLineLabel.create(p_270673_, p_270516_.message, p_270516_.maxWidth, p_270516_.maxRows.getAsInt()) : MultiLineLabel.create(p_270673_, p_270516_.message, p_270516_.maxWidth);
|
||||
});
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
public MultiLineTextWidget setColor(int p_270378_) {
|
||||
super.setColor(p_270378_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MultiLineTextWidget setMaxWidth(int p_270776_) {
|
||||
this.maxWidth = OptionalInt.of(p_270776_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MultiLineTextWidget setMaxRows(int p_270085_) {
|
||||
this.maxRows = OptionalInt.of(p_270085_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MultiLineTextWidget setCentered(boolean p_270493_) {
|
||||
this.centered = p_270493_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.cache.getValue(this.getFreshCacheKey()).getWidth();
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.cache.getValue(this.getFreshCacheKey()).getLineCount() * 9;
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_282535_, int p_261774_, int p_261640_, float p_261514_) {
|
||||
MultiLineLabel multilinelabel = this.cache.getValue(this.getFreshCacheKey());
|
||||
int i = this.getX();
|
||||
int j = this.getY();
|
||||
int k = 9;
|
||||
int l = this.getColor();
|
||||
if (this.centered) {
|
||||
multilinelabel.renderCentered(p_282535_, i + this.getWidth() / 2, j, k, l);
|
||||
} else {
|
||||
multilinelabel.renderLeftAligned(p_282535_, i, j, k, l);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private MultiLineTextWidget.CacheKey getFreshCacheKey() {
|
||||
return new MultiLineTextWidget.CacheKey(this.getMessage(), this.maxWidth.orElse(Integer.MAX_VALUE), this.maxRows);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static record CacheKey(Component message, int maxWidth, OptionalInt maxRows) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.StringUtil;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class MultilineTextField {
|
||||
public static final int NO_CHARACTER_LIMIT = Integer.MAX_VALUE;
|
||||
private static final int LINE_SEEK_PIXEL_BIAS = 2;
|
||||
private final Font font;
|
||||
private final List<MultilineTextField.StringView> displayLines = Lists.newArrayList();
|
||||
private String value;
|
||||
private int cursor;
|
||||
private int selectCursor;
|
||||
private boolean selecting;
|
||||
private int characterLimit = Integer.MAX_VALUE;
|
||||
private final int width;
|
||||
private Consumer<String> valueListener = (p_239235_) -> {
|
||||
};
|
||||
private Runnable cursorListener = () -> {
|
||||
};
|
||||
|
||||
public MultilineTextField(Font p_239611_, int p_239612_) {
|
||||
this.font = p_239611_;
|
||||
this.width = p_239612_;
|
||||
this.setValue("");
|
||||
}
|
||||
|
||||
public int characterLimit() {
|
||||
return this.characterLimit;
|
||||
}
|
||||
|
||||
public void setCharacterLimit(int p_240163_) {
|
||||
if (p_240163_ < 0) {
|
||||
throw new IllegalArgumentException("Character limit cannot be negative");
|
||||
} else {
|
||||
this.characterLimit = p_240163_;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasCharacterLimit() {
|
||||
return this.characterLimit != Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public void setValueListener(Consumer<String> p_239920_) {
|
||||
this.valueListener = p_239920_;
|
||||
}
|
||||
|
||||
public void setCursorListener(Runnable p_239258_) {
|
||||
this.cursorListener = p_239258_;
|
||||
}
|
||||
|
||||
public void setValue(String p_239678_) {
|
||||
this.value = this.truncateFullText(p_239678_);
|
||||
this.cursor = this.value.length();
|
||||
this.selectCursor = this.cursor;
|
||||
this.onValueChange();
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void insertText(String p_240016_) {
|
||||
if (!p_240016_.isEmpty() || this.hasSelection()) {
|
||||
String s = this.truncateInsertionText(SharedConstants.filterText(p_240016_, true));
|
||||
MultilineTextField.StringView multilinetextfield$stringview = this.getSelected();
|
||||
this.value = (new StringBuilder(this.value)).replace(multilinetextfield$stringview.beginIndex, multilinetextfield$stringview.endIndex, s).toString();
|
||||
this.cursor = multilinetextfield$stringview.beginIndex + s.length();
|
||||
this.selectCursor = this.cursor;
|
||||
this.onValueChange();
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteText(int p_239475_) {
|
||||
if (!this.hasSelection()) {
|
||||
this.selectCursor = Mth.clamp(this.cursor + p_239475_, 0, this.value.length());
|
||||
}
|
||||
|
||||
this.insertText("");
|
||||
}
|
||||
|
||||
public int cursor() {
|
||||
return this.cursor;
|
||||
}
|
||||
|
||||
public void setSelecting(boolean p_239951_) {
|
||||
this.selecting = p_239951_;
|
||||
}
|
||||
|
||||
public MultilineTextField.StringView getSelected() {
|
||||
return new MultilineTextField.StringView(Math.min(this.selectCursor, this.cursor), Math.max(this.selectCursor, this.cursor));
|
||||
}
|
||||
|
||||
public int getLineCount() {
|
||||
return this.displayLines.size();
|
||||
}
|
||||
|
||||
public int getLineAtCursor() {
|
||||
for(int i = 0; i < this.displayLines.size(); ++i) {
|
||||
MultilineTextField.StringView multilinetextfield$stringview = this.displayLines.get(i);
|
||||
if (this.cursor >= multilinetextfield$stringview.beginIndex && this.cursor <= multilinetextfield$stringview.endIndex) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public MultilineTextField.StringView getLineView(int p_239145_) {
|
||||
return this.displayLines.get(Mth.clamp(p_239145_, 0, this.displayLines.size() - 1));
|
||||
}
|
||||
|
||||
public void seekCursor(Whence p_239798_, int p_239799_) {
|
||||
switch (p_239798_) {
|
||||
case ABSOLUTE:
|
||||
this.cursor = p_239799_;
|
||||
break;
|
||||
case RELATIVE:
|
||||
this.cursor += p_239799_;
|
||||
break;
|
||||
case END:
|
||||
this.cursor = this.value.length() + p_239799_;
|
||||
}
|
||||
|
||||
this.cursor = Mth.clamp(this.cursor, 0, this.value.length());
|
||||
this.cursorListener.run();
|
||||
if (!this.selecting) {
|
||||
this.selectCursor = this.cursor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void seekCursorLine(int p_239394_) {
|
||||
if (p_239394_ != 0) {
|
||||
int i = this.font.width(this.value.substring(this.getCursorLineView().beginIndex, this.cursor)) + 2;
|
||||
MultilineTextField.StringView multilinetextfield$stringview = this.getCursorLineView(p_239394_);
|
||||
int j = this.font.plainSubstrByWidth(this.value.substring(multilinetextfield$stringview.beginIndex, multilinetextfield$stringview.endIndex), i).length();
|
||||
this.seekCursor(Whence.ABSOLUTE, multilinetextfield$stringview.beginIndex + j);
|
||||
}
|
||||
}
|
||||
|
||||
public void seekCursorToPoint(double p_239579_, double p_239580_) {
|
||||
int i = Mth.floor(p_239579_);
|
||||
int j = Mth.floor(p_239580_ / 9.0D);
|
||||
MultilineTextField.StringView multilinetextfield$stringview = this.displayLines.get(Mth.clamp(j, 0, this.displayLines.size() - 1));
|
||||
int k = this.font.plainSubstrByWidth(this.value.substring(multilinetextfield$stringview.beginIndex, multilinetextfield$stringview.endIndex), i).length();
|
||||
this.seekCursor(Whence.ABSOLUTE, multilinetextfield$stringview.beginIndex + k);
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_239712_) {
|
||||
this.selecting = Screen.hasShiftDown();
|
||||
if (Screen.isSelectAll(p_239712_)) {
|
||||
this.cursor = this.value.length();
|
||||
this.selectCursor = 0;
|
||||
return true;
|
||||
} else if (Screen.isCopy(p_239712_)) {
|
||||
Minecraft.getInstance().keyboardHandler.setClipboard(this.getSelectedText());
|
||||
return true;
|
||||
} else if (Screen.isPaste(p_239712_)) {
|
||||
this.insertText(Minecraft.getInstance().keyboardHandler.getClipboard());
|
||||
return true;
|
||||
} else if (Screen.isCut(p_239712_)) {
|
||||
Minecraft.getInstance().keyboardHandler.setClipboard(this.getSelectedText());
|
||||
this.insertText("");
|
||||
return true;
|
||||
} else {
|
||||
switch (p_239712_) {
|
||||
case 257:
|
||||
case 335:
|
||||
this.insertText("\n");
|
||||
return true;
|
||||
case 259:
|
||||
if (Screen.hasControlDown()) {
|
||||
MultilineTextField.StringView multilinetextfield$stringview3 = this.getPreviousWord();
|
||||
this.deleteText(multilinetextfield$stringview3.beginIndex - this.cursor);
|
||||
} else {
|
||||
this.deleteText(-1);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 261:
|
||||
if (Screen.hasControlDown()) {
|
||||
MultilineTextField.StringView multilinetextfield$stringview2 = this.getNextWord();
|
||||
this.deleteText(multilinetextfield$stringview2.beginIndex - this.cursor);
|
||||
} else {
|
||||
this.deleteText(1);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 262:
|
||||
if (Screen.hasControlDown()) {
|
||||
MultilineTextField.StringView multilinetextfield$stringview1 = this.getNextWord();
|
||||
this.seekCursor(Whence.ABSOLUTE, multilinetextfield$stringview1.beginIndex);
|
||||
} else {
|
||||
this.seekCursor(Whence.RELATIVE, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 263:
|
||||
if (Screen.hasControlDown()) {
|
||||
MultilineTextField.StringView multilinetextfield$stringview = this.getPreviousWord();
|
||||
this.seekCursor(Whence.ABSOLUTE, multilinetextfield$stringview.beginIndex);
|
||||
} else {
|
||||
this.seekCursor(Whence.RELATIVE, -1);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 264:
|
||||
if (!Screen.hasControlDown()) {
|
||||
this.seekCursorLine(1);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 265:
|
||||
if (!Screen.hasControlDown()) {
|
||||
this.seekCursorLine(-1);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 266:
|
||||
this.seekCursor(Whence.ABSOLUTE, 0);
|
||||
return true;
|
||||
case 267:
|
||||
this.seekCursor(Whence.END, 0);
|
||||
return true;
|
||||
case 268:
|
||||
if (Screen.hasControlDown()) {
|
||||
this.seekCursor(Whence.ABSOLUTE, 0);
|
||||
} else {
|
||||
this.seekCursor(Whence.ABSOLUTE, this.getCursorLineView().beginIndex);
|
||||
}
|
||||
|
||||
return true;
|
||||
case 269:
|
||||
if (Screen.hasControlDown()) {
|
||||
this.seekCursor(Whence.END, 0);
|
||||
} else {
|
||||
this.seekCursor(Whence.ABSOLUTE, this.getCursorLineView().endIndex);
|
||||
}
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Iterable<MultilineTextField.StringView> iterateLines() {
|
||||
return this.displayLines;
|
||||
}
|
||||
|
||||
public boolean hasSelection() {
|
||||
return this.selectCursor != this.cursor;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public String getSelectedText() {
|
||||
MultilineTextField.StringView multilinetextfield$stringview = this.getSelected();
|
||||
return this.value.substring(multilinetextfield$stringview.beginIndex, multilinetextfield$stringview.endIndex);
|
||||
}
|
||||
|
||||
private MultilineTextField.StringView getCursorLineView() {
|
||||
return this.getCursorLineView(0);
|
||||
}
|
||||
|
||||
private MultilineTextField.StringView getCursorLineView(int p_239855_) {
|
||||
int i = this.getLineAtCursor();
|
||||
if (i < 0) {
|
||||
throw new IllegalStateException("Cursor is not within text (cursor = " + this.cursor + ", length = " + this.value.length() + ")");
|
||||
} else {
|
||||
return this.displayLines.get(Mth.clamp(i + p_239855_, 0, this.displayLines.size() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public MultilineTextField.StringView getPreviousWord() {
|
||||
if (this.value.isEmpty()) {
|
||||
return MultilineTextField.StringView.EMPTY;
|
||||
} else {
|
||||
int i;
|
||||
for(i = Mth.clamp(this.cursor, 0, this.value.length() - 1); i > 0 && Character.isWhitespace(this.value.charAt(i - 1)); --i) {
|
||||
}
|
||||
|
||||
while(i > 0 && !Character.isWhitespace(this.value.charAt(i - 1))) {
|
||||
--i;
|
||||
}
|
||||
|
||||
return new MultilineTextField.StringView(i, this.getWordEndPosition(i));
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public MultilineTextField.StringView getNextWord() {
|
||||
if (this.value.isEmpty()) {
|
||||
return MultilineTextField.StringView.EMPTY;
|
||||
} else {
|
||||
int i;
|
||||
for(i = Mth.clamp(this.cursor, 0, this.value.length() - 1); i < this.value.length() && !Character.isWhitespace(this.value.charAt(i)); ++i) {
|
||||
}
|
||||
|
||||
while(i < this.value.length() && Character.isWhitespace(this.value.charAt(i))) {
|
||||
++i;
|
||||
}
|
||||
|
||||
return new MultilineTextField.StringView(i, this.getWordEndPosition(i));
|
||||
}
|
||||
}
|
||||
|
||||
private int getWordEndPosition(int p_240093_) {
|
||||
int i;
|
||||
for(i = p_240093_; i < this.value.length() && !Character.isWhitespace(this.value.charAt(i)); ++i) {
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private void onValueChange() {
|
||||
this.reflowDisplayLines();
|
||||
this.valueListener.accept(this.value);
|
||||
this.cursorListener.run();
|
||||
}
|
||||
|
||||
private void reflowDisplayLines() {
|
||||
this.displayLines.clear();
|
||||
if (this.value.isEmpty()) {
|
||||
this.displayLines.add(MultilineTextField.StringView.EMPTY);
|
||||
} else {
|
||||
this.font.getSplitter().splitLines(this.value, this.width, Style.EMPTY, false, (p_239846_, p_239847_, p_239848_) -> {
|
||||
this.displayLines.add(new MultilineTextField.StringView(p_239847_, p_239848_));
|
||||
});
|
||||
if (this.value.charAt(this.value.length() - 1) == '\n') {
|
||||
this.displayLines.add(new MultilineTextField.StringView(this.value.length(), this.value.length()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private String truncateFullText(String p_239843_) {
|
||||
return this.hasCharacterLimit() ? StringUtil.truncateStringIfNecessary(p_239843_, this.characterLimit, false) : p_239843_;
|
||||
}
|
||||
|
||||
private String truncateInsertionText(String p_239418_) {
|
||||
if (this.hasCharacterLimit()) {
|
||||
int i = this.characterLimit - this.value.length();
|
||||
return StringUtil.truncateStringIfNecessary(p_239418_, i, false);
|
||||
} else {
|
||||
return p_239418_;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected static record StringView(int beginIndex, int endIndex) {
|
||||
static final MultilineTextField.StringView EMPTY = new MultilineTextField.StringView(0, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.ComponentPath;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.gui.narration.NarrationSupplier;
|
||||
import net.minecraft.client.gui.navigation.FocusNavigationEvent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class ObjectSelectionList<E extends ObjectSelectionList.Entry<E>> extends AbstractSelectionList<E> {
|
||||
private static final Component USAGE_NARRATION = Component.translatable("narration.selection.usage");
|
||||
|
||||
public ObjectSelectionList(Minecraft p_94442_, int p_94443_, int p_94444_, int p_94445_, int p_94446_, int p_94447_) {
|
||||
super(p_94442_, p_94443_, p_94444_, p_94445_, p_94446_, p_94447_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath nextFocusPath(FocusNavigationEvent p_265150_) {
|
||||
if (this.getItemCount() == 0) {
|
||||
return null;
|
||||
} else if (this.isFocused() && p_265150_ instanceof FocusNavigationEvent.ArrowNavigation) {
|
||||
FocusNavigationEvent.ArrowNavigation focusnavigationevent$arrownavigation = (FocusNavigationEvent.ArrowNavigation)p_265150_;
|
||||
E e1 = this.nextEntry(focusnavigationevent$arrownavigation.direction());
|
||||
return e1 != null ? ComponentPath.path(this, ComponentPath.leaf(e1)) : null;
|
||||
} else if (!this.isFocused()) {
|
||||
E e = this.getSelected();
|
||||
if (e == null) {
|
||||
e = this.nextEntry(p_265150_.getVerticalDirectionForInitialFocus());
|
||||
}
|
||||
|
||||
return e == null ? null : ComponentPath.path(this, ComponentPath.leaf(e));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateNarration(NarrationElementOutput p_169042_) {
|
||||
E e = this.getHovered();
|
||||
if (e != null) {
|
||||
this.narrateListElementPosition(p_169042_.nest(), e);
|
||||
e.updateNarration(p_169042_);
|
||||
} else {
|
||||
E e1 = this.getSelected();
|
||||
if (e1 != null) {
|
||||
this.narrateListElementPosition(p_169042_.nest(), e1);
|
||||
e1.updateNarration(p_169042_);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isFocused()) {
|
||||
p_169042_.add(NarratedElementType.USAGE, USAGE_NARRATION);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract static class Entry<E extends ObjectSelectionList.Entry<E>> extends AbstractSelectionList.Entry<E> implements NarrationSupplier {
|
||||
public abstract Component getNarration();
|
||||
|
||||
public void updateNarration(NarrationElementOutput p_169044_) {
|
||||
p_169044_.add(NarratedElementType.TITLE, this.getNarration());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.OptionInstance;
|
||||
import net.minecraft.client.Options;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class OptionsList extends ContainerObjectSelectionList<OptionsList.Entry> {
|
||||
public OptionsList(Minecraft p_94465_, int p_94466_, int p_94467_, int p_94468_, int p_94469_, int p_94470_) {
|
||||
super(p_94465_, p_94466_, p_94467_, p_94468_, p_94469_, p_94470_);
|
||||
this.centerListVertically = false;
|
||||
}
|
||||
|
||||
public int addBig(OptionInstance<?> p_232529_) {
|
||||
return this.addEntry(OptionsList.Entry.big(this.minecraft.options, this.width, p_232529_));
|
||||
}
|
||||
|
||||
public void addSmall(OptionInstance<?> p_232531_, @Nullable OptionInstance<?> p_232532_) {
|
||||
this.addEntry(OptionsList.Entry.small(this.minecraft.options, this.width, p_232531_, p_232532_));
|
||||
}
|
||||
|
||||
public void addSmall(OptionInstance<?>[] p_232534_) {
|
||||
for(int i = 0; i < p_232534_.length; i += 2) {
|
||||
this.addSmall(p_232534_[i], i < p_232534_.length - 1 ? p_232534_[i + 1] : null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getRowWidth() {
|
||||
return 400;
|
||||
}
|
||||
|
||||
protected int getScrollbarPosition() {
|
||||
return super.getScrollbarPosition() + 32;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AbstractWidget findOption(OptionInstance<?> p_232536_) {
|
||||
for(OptionsList.Entry optionslist$entry : this.children()) {
|
||||
AbstractWidget abstractwidget = optionslist$entry.options.get(p_232536_);
|
||||
if (abstractwidget != null) {
|
||||
return abstractwidget;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Optional<AbstractWidget> getMouseOver(double p_94481_, double p_94482_) {
|
||||
for(OptionsList.Entry optionslist$entry : this.children()) {
|
||||
for(AbstractWidget abstractwidget : optionslist$entry.children) {
|
||||
if (abstractwidget.isMouseOver(p_94481_, p_94482_)) {
|
||||
return Optional.of(abstractwidget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected static class Entry extends ContainerObjectSelectionList.Entry<OptionsList.Entry> {
|
||||
final Map<OptionInstance<?>, AbstractWidget> options;
|
||||
final List<AbstractWidget> children;
|
||||
|
||||
private Entry(Map<OptionInstance<?>, AbstractWidget> p_169047_) {
|
||||
this.options = p_169047_;
|
||||
this.children = ImmutableList.copyOf(p_169047_.values());
|
||||
}
|
||||
|
||||
public static OptionsList.Entry big(Options p_232538_, int p_232539_, OptionInstance<?> p_232540_) {
|
||||
return new OptionsList.Entry(ImmutableMap.of(p_232540_, p_232540_.createButton(p_232538_, p_232539_ / 2 - 155, 0, 310)));
|
||||
}
|
||||
|
||||
public static OptionsList.Entry small(Options p_232542_, int p_232543_, OptionInstance<?> p_232544_, @Nullable OptionInstance<?> p_232545_) {
|
||||
AbstractWidget abstractwidget = p_232544_.createButton(p_232542_, p_232543_ / 2 - 155, 0, 150);
|
||||
return p_232545_ == null ? new OptionsList.Entry(ImmutableMap.of(p_232544_, abstractwidget)) : new OptionsList.Entry(ImmutableMap.of(p_232544_, abstractwidget, p_232545_, p_232545_.createButton(p_232542_, p_232543_ / 2 - 155 + 160, 0, 150)));
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_281311_, int p_94497_, int p_94498_, int p_94499_, int p_94500_, int p_94501_, int p_94502_, int p_94503_, boolean p_94504_, float p_94505_) {
|
||||
this.children.forEach((p_280776_) -> {
|
||||
p_280776_.setY(p_94498_);
|
||||
p_280776_.render(p_281311_, p_94502_, p_94503_, p_94505_);
|
||||
});
|
||||
}
|
||||
|
||||
public List<? extends GuiEventListener> children() {
|
||||
return this.children;
|
||||
}
|
||||
|
||||
public List<? extends NarratableEntry> narratables() {
|
||||
return this.children;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.ComponentUtils;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PlainTextButton extends Button {
|
||||
private final Font font;
|
||||
private final Component message;
|
||||
private final Component underlinedMessage;
|
||||
|
||||
public PlainTextButton(int p_211755_, int p_211756_, int p_211757_, int p_211758_, Component p_211759_, Button.OnPress p_211760_, Font p_211761_) {
|
||||
super(p_211755_, p_211756_, p_211757_, p_211758_, p_211759_, p_211760_, DEFAULT_NARRATION);
|
||||
this.font = p_211761_;
|
||||
this.message = p_211759_;
|
||||
this.underlinedMessage = ComponentUtils.mergeStyles(p_211759_.copy(), Style.EMPTY.withUnderlined(true));
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_283309_, int p_282710_, int p_282486_, float p_281727_) {
|
||||
Component component = this.isHoveredOrFocused() ? this.underlinedMessage : this.message;
|
||||
p_283309_.drawString(this.font, component, this.getX(), this.getY(), 16777215 | Mth.ceil(this.alpha * 255.0F) << 24);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PlayerFaceRenderer {
|
||||
public static final int SKIN_HEAD_U = 8;
|
||||
public static final int SKIN_HEAD_V = 8;
|
||||
public static final int SKIN_HEAD_WIDTH = 8;
|
||||
public static final int SKIN_HEAD_HEIGHT = 8;
|
||||
public static final int SKIN_HAT_U = 40;
|
||||
public static final int SKIN_HAT_V = 8;
|
||||
public static final int SKIN_HAT_WIDTH = 8;
|
||||
public static final int SKIN_HAT_HEIGHT = 8;
|
||||
public static final int SKIN_TEX_WIDTH = 64;
|
||||
public static final int SKIN_TEX_HEIGHT = 64;
|
||||
|
||||
public static void draw(GuiGraphics p_281827_, ResourceLocation p_281637_, int p_282126_, int p_281693_, int p_281565_) {
|
||||
draw(p_281827_, p_281637_, p_282126_, p_281693_, p_281565_, true, false);
|
||||
}
|
||||
|
||||
public static void draw(GuiGraphics p_283244_, ResourceLocation p_281495_, int p_282035_, int p_282441_, int p_281801_, boolean p_283149_, boolean p_283555_) {
|
||||
int i = 8 + (p_283555_ ? 8 : 0);
|
||||
int j = 8 * (p_283555_ ? -1 : 1);
|
||||
p_283244_.blit(p_281495_, p_282035_, p_282441_, p_281801_, p_281801_, 8.0F, (float)i, 8, j, 64, 64);
|
||||
if (p_283149_) {
|
||||
drawHat(p_283244_, p_281495_, p_282035_, p_282441_, p_281801_, p_283555_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void drawHat(GuiGraphics p_282228_, ResourceLocation p_282835_, int p_282585_, int p_282234_, int p_282576_, boolean p_281523_) {
|
||||
int i = 8 + (p_281523_ ? 8 : 0);
|
||||
int j = 8 * (p_281523_ ? -1 : 1);
|
||||
RenderSystem.enableBlend();
|
||||
p_282228_.blit(p_282835_, p_282585_, p_282234_, p_282576_, p_282576_, 40.0F, (float)i, 8, j, 64, 64);
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.multiplayer.PlayerInfo;
|
||||
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.ComponentUtils;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.player.PlayerModelPart;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.scores.Objective;
|
||||
import net.minecraft.world.scores.PlayerTeam;
|
||||
import net.minecraft.world.scores.Scoreboard;
|
||||
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PlayerTabOverlay {
|
||||
private static final Comparator<PlayerInfo> PLAYER_COMPARATOR = Comparator.<PlayerInfo>comparingInt((p_253306_) -> {
|
||||
return p_253306_.getGameMode() == GameType.SPECTATOR ? 1 : 0;
|
||||
}).thenComparing((p_269613_) -> {
|
||||
return Optionull.mapOrDefault(p_269613_.getTeam(), PlayerTeam::getName, "");
|
||||
}).thenComparing((p_253305_) -> {
|
||||
return p_253305_.getProfile().getName();
|
||||
}, String::compareToIgnoreCase);
|
||||
private static final ResourceLocation GUI_ICONS_LOCATION = new ResourceLocation("textures/gui/icons.png");
|
||||
public static final int MAX_ROWS_PER_COL = 20;
|
||||
public static final int HEART_EMPTY_CONTAINER = 16;
|
||||
public static final int HEART_EMPTY_CONTAINER_BLINKING = 25;
|
||||
public static final int HEART_FULL = 52;
|
||||
public static final int HEART_HALF_FULL = 61;
|
||||
public static final int HEART_GOLDEN_FULL = 160;
|
||||
public static final int HEART_GOLDEN_HALF_FULL = 169;
|
||||
public static final int HEART_GHOST_FULL = 70;
|
||||
public static final int HEART_GHOST_HALF_FULL = 79;
|
||||
private final Minecraft minecraft;
|
||||
private final Gui gui;
|
||||
@Nullable
|
||||
private Component footer;
|
||||
@Nullable
|
||||
private Component header;
|
||||
private boolean visible;
|
||||
private final Map<UUID, PlayerTabOverlay.HealthState> healthStates = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
public PlayerTabOverlay(Minecraft p_94527_, Gui p_94528_) {
|
||||
this.minecraft = p_94527_;
|
||||
this.gui = p_94528_;
|
||||
}
|
||||
|
||||
public Component getNameForDisplay(PlayerInfo p_94550_) {
|
||||
return p_94550_.getTabListDisplayName() != null ? this.decorateName(p_94550_, p_94550_.getTabListDisplayName().copy()) : this.decorateName(p_94550_, PlayerTeam.formatNameForTeam(p_94550_.getTeam(), Component.literal(p_94550_.getProfile().getName())));
|
||||
}
|
||||
|
||||
private Component decorateName(PlayerInfo p_94552_, MutableComponent p_94553_) {
|
||||
return p_94552_.getGameMode() == GameType.SPECTATOR ? p_94553_.withStyle(ChatFormatting.ITALIC) : p_94553_;
|
||||
}
|
||||
|
||||
public void setVisible(boolean p_94557_) {
|
||||
if (this.visible != p_94557_) {
|
||||
this.healthStates.clear();
|
||||
this.visible = p_94557_;
|
||||
if (p_94557_) {
|
||||
Component component = ComponentUtils.formatList(this.getPlayerInfos(), Component.literal(", "), this::getNameForDisplay);
|
||||
this.minecraft.getNarrator().sayNow(Component.translatable("multiplayer.player.list.narration", component));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<PlayerInfo> getPlayerInfos() {
|
||||
return this.minecraft.player.connection.getListedOnlinePlayers().stream().sorted(PLAYER_COMPARATOR).limit(80L).toList();
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_281484_, int p_283602_, Scoreboard p_282338_, @Nullable Objective p_282369_) {
|
||||
List<PlayerInfo> list = this.getPlayerInfos();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
for(PlayerInfo playerinfo : list) {
|
||||
int k = this.minecraft.font.width(this.getNameForDisplay(playerinfo));
|
||||
i = Math.max(i, k);
|
||||
if (p_282369_ != null && p_282369_.getRenderType() != ObjectiveCriteria.RenderType.HEARTS) {
|
||||
k = this.minecraft.font.width(" " + p_282338_.getOrCreatePlayerScore(playerinfo.getProfile().getName(), p_282369_).getScore());
|
||||
j = Math.max(j, k);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.healthStates.isEmpty()) {
|
||||
Set<UUID> set = list.stream().map((p_250472_) -> {
|
||||
return p_250472_.getProfile().getId();
|
||||
}).collect(Collectors.toSet());
|
||||
this.healthStates.keySet().removeIf((p_248583_) -> {
|
||||
return !set.contains(p_248583_);
|
||||
});
|
||||
}
|
||||
|
||||
int i3 = list.size();
|
||||
int j3 = i3;
|
||||
|
||||
int k3;
|
||||
for(k3 = 1; j3 > 20; j3 = (i3 + k3 - 1) / k3) {
|
||||
++k3;
|
||||
}
|
||||
|
||||
boolean flag = this.minecraft.isLocalServer() || this.minecraft.getConnection().getConnection().isEncrypted();
|
||||
int l;
|
||||
if (p_282369_ != null) {
|
||||
if (p_282369_.getRenderType() == ObjectiveCriteria.RenderType.HEARTS) {
|
||||
l = 90;
|
||||
} else {
|
||||
l = j;
|
||||
}
|
||||
} else {
|
||||
l = 0;
|
||||
}
|
||||
|
||||
int i1 = Math.min(k3 * ((flag ? 9 : 0) + i + l + 13), p_283602_ - 50) / k3;
|
||||
int j1 = p_283602_ / 2 - (i1 * k3 + (k3 - 1) * 5) / 2;
|
||||
int k1 = 10;
|
||||
int l1 = i1 * k3 + (k3 - 1) * 5;
|
||||
List<FormattedCharSequence> list1 = null;
|
||||
if (this.header != null) {
|
||||
list1 = this.minecraft.font.split(this.header, p_283602_ - 50);
|
||||
|
||||
for(FormattedCharSequence formattedcharsequence : list1) {
|
||||
l1 = Math.max(l1, this.minecraft.font.width(formattedcharsequence));
|
||||
}
|
||||
}
|
||||
|
||||
List<FormattedCharSequence> list2 = null;
|
||||
if (this.footer != null) {
|
||||
list2 = this.minecraft.font.split(this.footer, p_283602_ - 50);
|
||||
|
||||
for(FormattedCharSequence formattedcharsequence1 : list2) {
|
||||
l1 = Math.max(l1, this.minecraft.font.width(formattedcharsequence1));
|
||||
}
|
||||
}
|
||||
|
||||
if (list1 != null) {
|
||||
p_281484_.fill(p_283602_ / 2 - l1 / 2 - 1, k1 - 1, p_283602_ / 2 + l1 / 2 + 1, k1 + list1.size() * 9, Integer.MIN_VALUE);
|
||||
|
||||
for(FormattedCharSequence formattedcharsequence2 : list1) {
|
||||
int i2 = this.minecraft.font.width(formattedcharsequence2);
|
||||
p_281484_.drawString(this.minecraft.font, formattedcharsequence2, p_283602_ / 2 - i2 / 2, k1, -1);
|
||||
k1 += 9;
|
||||
}
|
||||
|
||||
++k1;
|
||||
}
|
||||
|
||||
p_281484_.fill(p_283602_ / 2 - l1 / 2 - 1, k1 - 1, p_283602_ / 2 + l1 / 2 + 1, k1 + j3 * 9, Integer.MIN_VALUE);
|
||||
int l3 = this.minecraft.options.getBackgroundColor(553648127);
|
||||
|
||||
for(int i4 = 0; i4 < i3; ++i4) {
|
||||
int j4 = i4 / j3;
|
||||
int j2 = i4 % j3;
|
||||
int k2 = j1 + j4 * i1 + j4 * 5;
|
||||
int l2 = k1 + j2 * 9;
|
||||
p_281484_.fill(k2, l2, k2 + i1, l2 + 8, l3);
|
||||
RenderSystem.enableBlend();
|
||||
if (i4 < list.size()) {
|
||||
PlayerInfo playerinfo1 = list.get(i4);
|
||||
GameProfile gameprofile = playerinfo1.getProfile();
|
||||
if (flag) {
|
||||
Player player = this.minecraft.level.getPlayerByUUID(gameprofile.getId());
|
||||
boolean flag1 = player != null && LivingEntityRenderer.isEntityUpsideDown(player);
|
||||
boolean flag2 = player != null && player.isModelPartShown(PlayerModelPart.HAT);
|
||||
PlayerFaceRenderer.draw(p_281484_, playerinfo1.getSkinLocation(), k2, l2, 8, flag2, flag1);
|
||||
k2 += 9;
|
||||
}
|
||||
|
||||
p_281484_.drawString(this.minecraft.font, this.getNameForDisplay(playerinfo1), k2, l2, playerinfo1.getGameMode() == GameType.SPECTATOR ? -1862270977 : -1);
|
||||
if (p_282369_ != null && playerinfo1.getGameMode() != GameType.SPECTATOR) {
|
||||
int l4 = k2 + i + 1;
|
||||
int i5 = l4 + l;
|
||||
if (i5 - l4 > 5) {
|
||||
this.renderTablistScore(p_282369_, l2, gameprofile.getName(), l4, i5, gameprofile.getId(), p_281484_);
|
||||
}
|
||||
}
|
||||
|
||||
this.renderPingIcon(p_281484_, i1, k2 - (flag ? 9 : 0), l2, playerinfo1);
|
||||
}
|
||||
}
|
||||
|
||||
if (list2 != null) {
|
||||
k1 += j3 * 9 + 1;
|
||||
p_281484_.fill(p_283602_ / 2 - l1 / 2 - 1, k1 - 1, p_283602_ / 2 + l1 / 2 + 1, k1 + list2.size() * 9, Integer.MIN_VALUE);
|
||||
|
||||
for(FormattedCharSequence formattedcharsequence3 : list2) {
|
||||
int k4 = this.minecraft.font.width(formattedcharsequence3);
|
||||
p_281484_.drawString(this.minecraft.font, formattedcharsequence3, p_283602_ / 2 - k4 / 2, k1, -1);
|
||||
k1 += 9;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void renderPingIcon(GuiGraphics p_283286_, int p_281809_, int p_282801_, int p_282223_, PlayerInfo p_282986_) {
|
||||
int i = 0;
|
||||
int j;
|
||||
if (p_282986_.getLatency() < 0) {
|
||||
j = 5;
|
||||
} else if (p_282986_.getLatency() < 150) {
|
||||
j = 0;
|
||||
} else if (p_282986_.getLatency() < 300) {
|
||||
j = 1;
|
||||
} else if (p_282986_.getLatency() < 600) {
|
||||
j = 2;
|
||||
} else if (p_282986_.getLatency() < 1000) {
|
||||
j = 3;
|
||||
} else {
|
||||
j = 4;
|
||||
}
|
||||
|
||||
p_283286_.pose().pushPose();
|
||||
p_283286_.pose().translate(0.0F, 0.0F, 100.0F);
|
||||
p_283286_.blit(GUI_ICONS_LOCATION, p_282801_ + p_281809_ - 11, p_282223_, 0, 176 + j * 8, 10, 8);
|
||||
p_283286_.pose().popPose();
|
||||
}
|
||||
|
||||
private void renderTablistScore(Objective p_283381_, int p_282557_, String p_283058_, int p_283533_, int p_281254_, UUID p_283099_, GuiGraphics p_282280_) {
|
||||
int i = p_283381_.getScoreboard().getOrCreatePlayerScore(p_283058_, p_283381_).getScore();
|
||||
if (p_283381_.getRenderType() == ObjectiveCriteria.RenderType.HEARTS) {
|
||||
this.renderTablistHearts(p_282557_, p_283533_, p_281254_, p_283099_, p_282280_, i);
|
||||
} else {
|
||||
String s = "" + ChatFormatting.YELLOW + i;
|
||||
p_282280_.drawString(this.minecraft.font, s, p_281254_ - this.minecraft.font.width(s), p_282557_, 16777215);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTablistHearts(int p_282904_, int p_283173_, int p_282149_, UUID p_283348_, GuiGraphics p_281723_, int p_281354_) {
|
||||
PlayerTabOverlay.HealthState playertaboverlay$healthstate = this.healthStates.computeIfAbsent(p_283348_, (p_249546_) -> {
|
||||
return new PlayerTabOverlay.HealthState(p_281354_);
|
||||
});
|
||||
playertaboverlay$healthstate.update(p_281354_, (long)this.gui.getGuiTicks());
|
||||
int i = Mth.positiveCeilDiv(Math.max(p_281354_, playertaboverlay$healthstate.displayedValue()), 2);
|
||||
int j = Math.max(p_281354_, Math.max(playertaboverlay$healthstate.displayedValue(), 20)) / 2;
|
||||
boolean flag = playertaboverlay$healthstate.isBlinking((long)this.gui.getGuiTicks());
|
||||
if (i > 0) {
|
||||
int k = Mth.floor(Math.min((float)(p_282149_ - p_283173_ - 4) / (float)j, 9.0F));
|
||||
if (k <= 3) {
|
||||
float f = Mth.clamp((float)p_281354_ / 20.0F, 0.0F, 1.0F);
|
||||
int i1 = (int)((1.0F - f) * 255.0F) << 16 | (int)(f * 255.0F) << 8;
|
||||
String s = "" + (float)p_281354_ / 2.0F;
|
||||
if (p_282149_ - this.minecraft.font.width(s + "hp") >= p_283173_) {
|
||||
s = s + "hp";
|
||||
}
|
||||
|
||||
p_281723_.drawString(this.minecraft.font, s, (p_282149_ + p_283173_ - this.minecraft.font.width(s)) / 2, p_282904_, i1);
|
||||
} else {
|
||||
for(int l = i; l < j; ++l) {
|
||||
p_281723_.blit(GUI_ICONS_LOCATION, p_283173_ + l * k, p_282904_, flag ? 25 : 16, 0, 9, 9);
|
||||
}
|
||||
|
||||
for(int j1 = 0; j1 < i; ++j1) {
|
||||
p_281723_.blit(GUI_ICONS_LOCATION, p_283173_ + j1 * k, p_282904_, flag ? 25 : 16, 0, 9, 9);
|
||||
if (flag) {
|
||||
if (j1 * 2 + 1 < playertaboverlay$healthstate.displayedValue()) {
|
||||
p_281723_.blit(GUI_ICONS_LOCATION, p_283173_ + j1 * k, p_282904_, 70, 0, 9, 9);
|
||||
}
|
||||
|
||||
if (j1 * 2 + 1 == playertaboverlay$healthstate.displayedValue()) {
|
||||
p_281723_.blit(GUI_ICONS_LOCATION, p_283173_ + j1 * k, p_282904_, 79, 0, 9, 9);
|
||||
}
|
||||
}
|
||||
|
||||
if (j1 * 2 + 1 < p_281354_) {
|
||||
p_281723_.blit(GUI_ICONS_LOCATION, p_283173_ + j1 * k, p_282904_, j1 >= 10 ? 160 : 52, 0, 9, 9);
|
||||
}
|
||||
|
||||
if (j1 * 2 + 1 == p_281354_) {
|
||||
p_281723_.blit(GUI_ICONS_LOCATION, p_283173_ + j1 * k, p_282904_, j1 >= 10 ? 169 : 61, 0, 9, 9);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setFooter(@Nullable Component p_94555_) {
|
||||
this.footer = p_94555_;
|
||||
}
|
||||
|
||||
public void setHeader(@Nullable Component p_94559_) {
|
||||
this.header = p_94559_;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.header = null;
|
||||
this.footer = null;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class HealthState {
|
||||
private static final long DISPLAY_UPDATE_DELAY = 20L;
|
||||
private static final long DECREASE_BLINK_DURATION = 20L;
|
||||
private static final long INCREASE_BLINK_DURATION = 10L;
|
||||
private int lastValue;
|
||||
private int displayedValue;
|
||||
private long lastUpdateTick;
|
||||
private long blinkUntilTick;
|
||||
|
||||
public HealthState(int p_250562_) {
|
||||
this.displayedValue = p_250562_;
|
||||
this.lastValue = p_250562_;
|
||||
}
|
||||
|
||||
public void update(int p_251066_, long p_251460_) {
|
||||
if (p_251066_ != this.lastValue) {
|
||||
long i = p_251066_ < this.lastValue ? 20L : 10L;
|
||||
this.blinkUntilTick = p_251460_ + i;
|
||||
this.lastValue = p_251066_;
|
||||
this.lastUpdateTick = p_251460_;
|
||||
}
|
||||
|
||||
if (p_251460_ - this.lastUpdateTick > 20L) {
|
||||
this.displayedValue = p_251066_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int displayedValue() {
|
||||
return this.displayedValue;
|
||||
}
|
||||
|
||||
public boolean isBlinking(long p_251847_) {
|
||||
return this.blinkUntilTick > p_251847_ && (this.blinkUntilTick - p_251847_) % 6L >= 3L;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface Renderable {
|
||||
void render(GuiGraphics p_281245_, int p_253973_, int p_254325_, float p_254004_);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.mojang.math.Axis;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class SplashRenderer {
|
||||
public static final SplashRenderer CHRISTMAS = new SplashRenderer("Merry X-mas!");
|
||||
public static final SplashRenderer NEW_YEAR = new SplashRenderer("Happy new year!");
|
||||
public static final SplashRenderer HALLOWEEN = new SplashRenderer("OOoooOOOoooo! Spooky!");
|
||||
private static final int WIDTH_OFFSET = 123;
|
||||
private static final int HEIGH_OFFSET = 69;
|
||||
private final String splash;
|
||||
|
||||
public SplashRenderer(String p_283500_) {
|
||||
this.splash = p_283500_;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282218_, int p_281824_, Font p_281962_, int p_282586_) {
|
||||
p_282218_.pose().pushPose();
|
||||
p_282218_.pose().translate((float)p_281824_ / 2.0F + 123.0F, 69.0F, 0.0F);
|
||||
p_282218_.pose().mulPose(Axis.ZP.rotationDegrees(-20.0F));
|
||||
float f = 1.8F - Mth.abs(Mth.sin((float)(Util.getMillis() % 1000L) / 1000.0F * ((float)Math.PI * 2F)) * 0.1F);
|
||||
f = f * 100.0F / (float)(p_281962_.width(this.splash) + 32);
|
||||
p_282218_.pose().scale(f, f, f);
|
||||
p_282218_.drawCenteredString(p_281962_, this.splash, 0, -8, 16776960 | p_282586_);
|
||||
p_282218_.pose().popPose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class StateSwitchingButton extends AbstractWidget {
|
||||
protected ResourceLocation resourceLocation;
|
||||
protected boolean isStateTriggered;
|
||||
protected int xTexStart;
|
||||
protected int yTexStart;
|
||||
protected int xDiffTex;
|
||||
protected int yDiffTex;
|
||||
|
||||
public StateSwitchingButton(int p_94615_, int p_94616_, int p_94617_, int p_94618_, boolean p_94619_) {
|
||||
super(p_94615_, p_94616_, p_94617_, p_94618_, CommonComponents.EMPTY);
|
||||
this.isStateTriggered = p_94619_;
|
||||
}
|
||||
|
||||
public void initTextureValues(int p_94625_, int p_94626_, int p_94627_, int p_94628_, ResourceLocation p_94629_) {
|
||||
this.xTexStart = p_94625_;
|
||||
this.yTexStart = p_94626_;
|
||||
this.xDiffTex = p_94627_;
|
||||
this.yDiffTex = p_94628_;
|
||||
this.resourceLocation = p_94629_;
|
||||
}
|
||||
|
||||
public void setStateTriggered(boolean p_94636_) {
|
||||
this.isStateTriggered = p_94636_;
|
||||
}
|
||||
|
||||
public boolean isStateTriggered() {
|
||||
return this.isStateTriggered;
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput p_259073_) {
|
||||
this.defaultButtonNarrationText(p_259073_);
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_283051_, int p_283010_, int p_281379_, float p_283453_) {
|
||||
RenderSystem.disableDepthTest();
|
||||
int i = this.xTexStart;
|
||||
int j = this.yTexStart;
|
||||
if (this.isStateTriggered) {
|
||||
i += this.xDiffTex;
|
||||
}
|
||||
|
||||
if (this.isHoveredOrFocused()) {
|
||||
j += this.yDiffTex;
|
||||
}
|
||||
|
||||
p_283051_.blit(this.resourceLocation, this.getX(), this.getY(), i, j, this.width, this.height);
|
||||
RenderSystem.enableDepthTest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class StringWidget extends AbstractStringWidget {
|
||||
private float alignX = 0.5F;
|
||||
|
||||
public StringWidget(Component p_268211_, Font p_267963_) {
|
||||
this(0, 0, p_267963_.width(p_268211_.getVisualOrderText()), 9, p_268211_, p_267963_);
|
||||
}
|
||||
|
||||
public StringWidget(int p_268183_, int p_268082_, Component p_268069_, Font p_268121_) {
|
||||
this(0, 0, p_268183_, p_268082_, p_268069_, p_268121_);
|
||||
}
|
||||
|
||||
public StringWidget(int p_268199_, int p_268137_, int p_268178_, int p_268169_, Component p_268285_, Font p_268047_) {
|
||||
super(p_268199_, p_268137_, p_268178_, p_268169_, p_268285_, p_268047_);
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
public StringWidget setColor(int p_270680_) {
|
||||
super.setColor(p_270680_);
|
||||
return this;
|
||||
}
|
||||
|
||||
private StringWidget horizontalAlignment(float p_267947_) {
|
||||
this.alignX = p_267947_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StringWidget alignLeft() {
|
||||
return this.horizontalAlignment(0.0F);
|
||||
}
|
||||
|
||||
public StringWidget alignCenter() {
|
||||
return this.horizontalAlignment(0.5F);
|
||||
}
|
||||
|
||||
public StringWidget alignRight() {
|
||||
return this.horizontalAlignment(1.0F);
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_281367_, int p_268221_, int p_268001_, float p_268214_) {
|
||||
Component component = this.getMessage();
|
||||
Font font = this.getFont();
|
||||
int i = this.getX() + Math.round(this.alignX * (float)(this.getWidth() - font.width(component)));
|
||||
int j = this.getY() + (this.getHeight() - 9) / 2;
|
||||
p_281367_.drawString(font, component, i, j, this.getColor());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.client.sounds.SoundEventListener;
|
||||
import net.minecraft.client.sounds.WeighedSoundEvents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class SubtitleOverlay implements SoundEventListener {
|
||||
private static final long DISPLAY_TIME = 3000L;
|
||||
private final Minecraft minecraft;
|
||||
private final List<SubtitleOverlay.Subtitle> subtitles = Lists.newArrayList();
|
||||
private boolean isListening;
|
||||
|
||||
public SubtitleOverlay(Minecraft p_94641_) {
|
||||
this.minecraft = p_94641_;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282562_) {
|
||||
if (!this.isListening && this.minecraft.options.showSubtitles().get()) {
|
||||
this.minecraft.getSoundManager().addListener(this);
|
||||
this.isListening = true;
|
||||
} else if (this.isListening && !this.minecraft.options.showSubtitles().get()) {
|
||||
this.minecraft.getSoundManager().removeListener(this);
|
||||
this.isListening = false;
|
||||
}
|
||||
|
||||
if (this.isListening && !this.subtitles.isEmpty()) {
|
||||
Vec3 vec3 = new Vec3(this.minecraft.player.getX(), this.minecraft.player.getEyeY(), this.minecraft.player.getZ());
|
||||
Vec3 vec31 = (new Vec3(0.0D, 0.0D, -1.0D)).xRot(-this.minecraft.player.getXRot() * ((float)Math.PI / 180F)).yRot(-this.minecraft.player.getYRot() * ((float)Math.PI / 180F));
|
||||
Vec3 vec32 = (new Vec3(0.0D, 1.0D, 0.0D)).xRot(-this.minecraft.player.getXRot() * ((float)Math.PI / 180F)).yRot(-this.minecraft.player.getYRot() * ((float)Math.PI / 180F));
|
||||
Vec3 vec33 = vec31.cross(vec32);
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
double d0 = this.minecraft.options.notificationDisplayTime().get();
|
||||
Iterator<SubtitleOverlay.Subtitle> iterator = this.subtitles.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
SubtitleOverlay.Subtitle subtitleoverlay$subtitle = iterator.next();
|
||||
if ((double)subtitleoverlay$subtitle.getTime() + 3000.0D * d0 <= (double)Util.getMillis()) {
|
||||
iterator.remove();
|
||||
} else {
|
||||
j = Math.max(j, this.minecraft.font.width(subtitleoverlay$subtitle.getText()));
|
||||
}
|
||||
}
|
||||
|
||||
j += this.minecraft.font.width("<") + this.minecraft.font.width(" ") + this.minecraft.font.width(">") + this.minecraft.font.width(" ");
|
||||
|
||||
for(SubtitleOverlay.Subtitle subtitleoverlay$subtitle1 : this.subtitles) {
|
||||
int k = 255;
|
||||
Component component = subtitleoverlay$subtitle1.getText();
|
||||
Vec3 vec34 = subtitleoverlay$subtitle1.getLocation().subtract(vec3).normalize();
|
||||
double d1 = -vec33.dot(vec34);
|
||||
double d2 = -vec31.dot(vec34);
|
||||
boolean flag = d2 > 0.5D;
|
||||
int l = j / 2;
|
||||
int i1 = 9;
|
||||
int j1 = i1 / 2;
|
||||
float f = 1.0F;
|
||||
int k1 = this.minecraft.font.width(component);
|
||||
int l1 = Mth.floor(Mth.clampedLerp(255.0F, 75.0F, (float)(Util.getMillis() - subtitleoverlay$subtitle1.getTime()) / (float)(3000.0D * d0)));
|
||||
int i2 = l1 << 16 | l1 << 8 | l1;
|
||||
p_282562_.pose().pushPose();
|
||||
p_282562_.pose().translate((float)p_282562_.guiWidth() - (float)l * 1.0F - 2.0F, (float)(p_282562_.guiHeight() - 35) - (float)(i * (i1 + 1)) * 1.0F, 0.0F);
|
||||
p_282562_.pose().scale(1.0F, 1.0F, 1.0F);
|
||||
p_282562_.fill(-l - 1, -j1 - 1, l + 1, j1 + 1, this.minecraft.options.getBackgroundColor(0.8F));
|
||||
int j2 = i2 + -16777216;
|
||||
if (!flag) {
|
||||
if (d1 > 0.0D) {
|
||||
p_282562_.drawString(this.minecraft.font, ">", l - this.minecraft.font.width(">"), -j1, j2);
|
||||
} else if (d1 < 0.0D) {
|
||||
p_282562_.drawString(this.minecraft.font, "<", -l, -j1, j2);
|
||||
}
|
||||
}
|
||||
|
||||
p_282562_.drawString(this.minecraft.font, component, -k1 / 2, -j1, j2);
|
||||
p_282562_.pose().popPose();
|
||||
++i;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void onPlaySound(SoundInstance p_94645_, WeighedSoundEvents p_94646_) {
|
||||
if (p_94646_.getSubtitle() != null) {
|
||||
Component component = p_94646_.getSubtitle();
|
||||
if (!this.subtitles.isEmpty()) {
|
||||
for(SubtitleOverlay.Subtitle subtitleoverlay$subtitle : this.subtitles) {
|
||||
if (subtitleoverlay$subtitle.getText().equals(component)) {
|
||||
subtitleoverlay$subtitle.refresh(new Vec3(p_94645_.getX(), p_94645_.getY(), p_94645_.getZ()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.subtitles.add(new SubtitleOverlay.Subtitle(component, new Vec3(p_94645_.getX(), p_94645_.getY(), p_94645_.getZ())));
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Subtitle {
|
||||
private final Component text;
|
||||
private long time;
|
||||
private Vec3 location;
|
||||
|
||||
public Subtitle(Component p_169072_, Vec3 p_169073_) {
|
||||
this.text = p_169072_;
|
||||
this.location = p_169073_;
|
||||
this.time = Util.getMillis();
|
||||
}
|
||||
|
||||
public Component getText() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return this.time;
|
||||
}
|
||||
|
||||
public Vec3 getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public void refresh(Vec3 p_94657_) {
|
||||
this.location = p_94657_;
|
||||
this.time = Util.getMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.tabs.Tab;
|
||||
import net.minecraft.client.gui.components.tabs.TabManager;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.sounds.SoundManager;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class TabButton extends AbstractWidget {
|
||||
private static final ResourceLocation TEXTURE_LOCATION = new ResourceLocation("textures/gui/tab_button.png");
|
||||
private static final int TEXTURE_WIDTH = 130;
|
||||
private static final int TEXTURE_HEIGHT = 24;
|
||||
private static final int TEXTURE_BORDER = 2;
|
||||
private static final int TEXTURE_BORDER_BOTTOM = 0;
|
||||
private static final int SELECTED_OFFSET = 3;
|
||||
private static final int TEXT_MARGIN = 1;
|
||||
private static final int UNDERLINE_HEIGHT = 1;
|
||||
private static final int UNDERLINE_MARGIN_X = 4;
|
||||
private static final int UNDERLINE_MARGIN_BOTTOM = 2;
|
||||
private final TabManager tabManager;
|
||||
private final Tab tab;
|
||||
|
||||
public TabButton(TabManager p_275399_, Tab p_275391_, int p_275340_, int p_275364_) {
|
||||
super(0, 0, p_275340_, p_275364_, p_275391_.getTabTitle());
|
||||
this.tabManager = p_275399_;
|
||||
this.tab = p_275391_;
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_283350_, int p_283437_, int p_281595_, float p_282117_) {
|
||||
p_283350_.blitNineSliced(TEXTURE_LOCATION, this.getX(), this.getY(), this.width, this.height, 2, 2, 2, 0, 130, 24, 0, this.getTextureY());
|
||||
Font font = Minecraft.getInstance().font;
|
||||
int i = this.active ? -1 : -6250336;
|
||||
this.renderString(p_283350_, font, i);
|
||||
if (this.isSelected()) {
|
||||
this.renderFocusUnderline(p_283350_, font, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void renderString(GuiGraphics p_282917_, Font p_275208_, int p_275293_) {
|
||||
int i = this.getX() + 1;
|
||||
int j = this.getY() + (this.isSelected() ? 0 : 3);
|
||||
int k = this.getX() + this.getWidth() - 1;
|
||||
int l = this.getY() + this.getHeight();
|
||||
renderScrollingString(p_282917_, p_275208_, this.getMessage(), i, j, k, l, p_275293_);
|
||||
}
|
||||
|
||||
private void renderFocusUnderline(GuiGraphics p_282383_, Font p_275475_, int p_275367_) {
|
||||
int i = Math.min(p_275475_.width(this.getMessage()), this.getWidth() - 4);
|
||||
int j = this.getX() + (this.getWidth() - i) / 2;
|
||||
int k = this.getY() + this.getHeight() - 2;
|
||||
p_282383_.fill(j, k, j + i, k + 1, p_275367_);
|
||||
}
|
||||
|
||||
protected int getTextureY() {
|
||||
int i = 2;
|
||||
if (this.isSelected() && this.isHoveredOrFocused()) {
|
||||
i = 1;
|
||||
} else if (this.isSelected()) {
|
||||
i = 0;
|
||||
} else if (this.isHoveredOrFocused()) {
|
||||
i = 3;
|
||||
}
|
||||
|
||||
return i * 24;
|
||||
}
|
||||
|
||||
protected void updateWidgetNarration(NarrationElementOutput p_275465_) {
|
||||
p_275465_.add(NarratedElementType.TITLE, Component.translatable("gui.narrate.tab", this.tab.getTabTitle()));
|
||||
}
|
||||
|
||||
public void playDownSound(SoundManager p_276302_) {
|
||||
}
|
||||
|
||||
public Tab tab() {
|
||||
return this.tab;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return this.tabManager.getCurrentTab() == this.tab;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface TabOrderedElement {
|
||||
default int getTabOrderGroup() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class TextAndImageButton extends Button {
|
||||
protected final ResourceLocation resourceLocation;
|
||||
protected final int xTexStart;
|
||||
protected final int yTexStart;
|
||||
protected final int yDiffTex;
|
||||
protected final int textureWidth;
|
||||
protected final int textureHeight;
|
||||
private final int xOffset;
|
||||
private final int yOffset;
|
||||
private final int usedTextureWidth;
|
||||
private final int usedTextureHeight;
|
||||
|
||||
TextAndImageButton(Component p_268357_, int p_268106_, int p_268141_, int p_268331_, int p_268045_, int p_268300_, int p_268151_, int p_267955_, int p_268114_, int p_268103_, ResourceLocation p_268067_, Button.OnPress p_268052_) {
|
||||
super(0, 0, 150, 20, p_268357_, p_268052_, DEFAULT_NARRATION);
|
||||
this.textureWidth = p_268114_;
|
||||
this.textureHeight = p_268103_;
|
||||
this.xTexStart = p_268106_;
|
||||
this.yTexStart = p_268141_;
|
||||
this.yDiffTex = p_268300_;
|
||||
this.resourceLocation = p_268067_;
|
||||
this.xOffset = p_268331_;
|
||||
this.yOffset = p_268045_;
|
||||
this.usedTextureWidth = p_268151_;
|
||||
this.usedTextureHeight = p_267955_;
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_282062_, int p_283189_, int p_283584_, float p_283402_) {
|
||||
super.renderWidget(p_282062_, p_283189_, p_283584_, p_283402_);
|
||||
this.renderTexture(p_282062_, this.resourceLocation, this.getXOffset(), this.getYOffset(), this.xTexStart, this.yTexStart, this.yDiffTex, this.usedTextureWidth, this.usedTextureHeight, this.textureWidth, this.textureHeight);
|
||||
}
|
||||
|
||||
public void renderString(GuiGraphics p_281792_, Font p_283239_, int p_283135_) {
|
||||
int i = this.getX() + 2;
|
||||
int j = this.getX() + this.getWidth() - this.usedTextureWidth - 6;
|
||||
renderScrollingString(p_281792_, p_283239_, this.getMessage(), i, this.getY(), j, this.getY() + this.getHeight(), p_283135_);
|
||||
}
|
||||
|
||||
private int getXOffset() {
|
||||
return this.getX() + (this.width / 2 - this.usedTextureWidth / 2) + this.xOffset;
|
||||
}
|
||||
|
||||
private int getYOffset() {
|
||||
return this.getY() + this.yOffset;
|
||||
}
|
||||
|
||||
public static TextAndImageButton.Builder builder(Component p_268304_, ResourceLocation p_268277_, Button.OnPress p_268297_) {
|
||||
return new TextAndImageButton.Builder(p_268304_, p_268277_, p_268297_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Builder {
|
||||
private final Component message;
|
||||
private final ResourceLocation resourceLocation;
|
||||
private final Button.OnPress onPress;
|
||||
private int xTexStart;
|
||||
private int yTexStart;
|
||||
private int yDiffTex;
|
||||
private int usedTextureWidth;
|
||||
private int usedTextureHeight;
|
||||
private int textureWidth;
|
||||
private int textureHeight;
|
||||
private int xOffset;
|
||||
private int yOffset;
|
||||
|
||||
public Builder(Component p_267988_, ResourceLocation p_268260_, Button.OnPress p_268075_) {
|
||||
this.message = p_267988_;
|
||||
this.resourceLocation = p_268260_;
|
||||
this.onPress = p_268075_;
|
||||
}
|
||||
|
||||
public TextAndImageButton.Builder texStart(int p_267995_, int p_268187_) {
|
||||
this.xTexStart = p_267995_;
|
||||
this.yTexStart = p_268187_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextAndImageButton.Builder offset(int p_268306_, int p_268207_) {
|
||||
this.xOffset = p_268306_;
|
||||
this.yOffset = p_268207_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextAndImageButton.Builder yDiffTex(int p_268008_) {
|
||||
this.yDiffTex = p_268008_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextAndImageButton.Builder usedTextureSize(int p_268087_, int p_268011_) {
|
||||
this.usedTextureWidth = p_268087_;
|
||||
this.usedTextureHeight = p_268011_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextAndImageButton.Builder textureSize(int p_268166_, int p_268310_) {
|
||||
this.textureWidth = p_268166_;
|
||||
this.textureHeight = p_268310_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextAndImageButton build() {
|
||||
return new TextAndImageButton(this.message, this.xTexStart, this.yTexStart, this.xOffset, this.yOffset, this.yDiffTex, this.usedTextureWidth, this.usedTextureHeight, this.textureWidth, this.textureHeight, this.resourceLocation, this.onPress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.narration.NarratedElementType;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.gui.narration.NarrationSupplier;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Tooltip implements NarrationSupplier {
|
||||
private static final int MAX_WIDTH = 170;
|
||||
private final Component message;
|
||||
@Nullable
|
||||
private List<FormattedCharSequence> cachedTooltip;
|
||||
@Nullable
|
||||
private final Component narration;
|
||||
|
||||
private Tooltip(Component p_260262_, @Nullable Component p_260005_) {
|
||||
this.message = p_260262_;
|
||||
this.narration = p_260005_;
|
||||
}
|
||||
|
||||
public static Tooltip create(Component p_259571_, @Nullable Component p_259174_) {
|
||||
return new Tooltip(p_259571_, p_259174_);
|
||||
}
|
||||
|
||||
public static Tooltip create(Component p_259142_) {
|
||||
return new Tooltip(p_259142_, p_259142_);
|
||||
}
|
||||
|
||||
public void updateNarration(NarrationElementOutput p_260330_) {
|
||||
if (this.narration != null) {
|
||||
p_260330_.add(NarratedElementType.HINT, this.narration);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<FormattedCharSequence> toCharSequence(Minecraft p_260243_) {
|
||||
if (this.cachedTooltip == null) {
|
||||
this.cachedTooltip = splitTooltip(p_260243_, this.message);
|
||||
}
|
||||
|
||||
return this.cachedTooltip;
|
||||
}
|
||||
|
||||
public static List<FormattedCharSequence> splitTooltip(Minecraft p_259133_, Component p_260172_) {
|
||||
return p_259133_.font.split(p_260172_, 170);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package net.minecraft.client.gui.components;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum Whence {
|
||||
ABSOLUTE,
|
||||
RELATIVE,
|
||||
END;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package net.minecraft.client.gui.components.events;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class AbstractContainerEventHandler implements ContainerEventHandler {
|
||||
@Nullable
|
||||
private GuiEventListener focused;
|
||||
private boolean isDragging;
|
||||
|
||||
public final boolean isDragging() {
|
||||
return this.isDragging;
|
||||
}
|
||||
|
||||
public final void setDragging(boolean p_94681_) {
|
||||
this.isDragging = p_94681_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GuiEventListener getFocused() {
|
||||
return this.focused;
|
||||
}
|
||||
|
||||
public void setFocused(@Nullable GuiEventListener p_94677_) {
|
||||
if (this.focused != null) {
|
||||
this.focused.setFocused(false);
|
||||
}
|
||||
|
||||
if (p_94677_ != null) {
|
||||
p_94677_.setFocused(true);
|
||||
}
|
||||
|
||||
this.focused = p_94677_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
package net.minecraft.client.gui.components.events;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.ComponentPath;
|
||||
import net.minecraft.client.gui.navigation.FocusNavigationEvent;
|
||||
import net.minecraft.client.gui.navigation.ScreenAxis;
|
||||
import net.minecraft.client.gui.navigation.ScreenDirection;
|
||||
import net.minecraft.client.gui.navigation.ScreenPosition;
|
||||
import net.minecraft.client.gui.navigation.ScreenRectangle;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface ContainerEventHandler extends GuiEventListener {
|
||||
List<? extends GuiEventListener> children();
|
||||
|
||||
default Optional<GuiEventListener> getChildAt(double p_94730_, double p_94731_) {
|
||||
for(GuiEventListener guieventlistener : this.children()) {
|
||||
if (guieventlistener.isMouseOver(p_94730_, p_94731_)) {
|
||||
return Optional.of(guieventlistener);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
default boolean mouseClicked(double p_94695_, double p_94696_, int p_94697_) {
|
||||
for(GuiEventListener guieventlistener : this.children()) {
|
||||
if (guieventlistener.mouseClicked(p_94695_, p_94696_, p_94697_)) {
|
||||
this.setFocused(guieventlistener);
|
||||
if (p_94697_ == 0) {
|
||||
this.setDragging(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean mouseReleased(double p_94722_, double p_94723_, int p_94724_) {
|
||||
this.setDragging(false);
|
||||
return this.getChildAt(p_94722_, p_94723_).filter((p_94708_) -> {
|
||||
return p_94708_.mouseReleased(p_94722_, p_94723_, p_94724_);
|
||||
}).isPresent();
|
||||
}
|
||||
|
||||
default boolean mouseDragged(double p_94699_, double p_94700_, int p_94701_, double p_94702_, double p_94703_) {
|
||||
return this.getFocused() != null && this.isDragging() && p_94701_ == 0 ? this.getFocused().mouseDragged(p_94699_, p_94700_, p_94701_, p_94702_, p_94703_) : false;
|
||||
}
|
||||
|
||||
boolean isDragging();
|
||||
|
||||
void setDragging(boolean p_94720_);
|
||||
|
||||
default boolean mouseScrolled(double p_94686_, double p_94687_, double p_94688_) {
|
||||
return this.getChildAt(p_94686_, p_94687_).filter((p_94693_) -> {
|
||||
return p_94693_.mouseScrolled(p_94686_, p_94687_, p_94688_);
|
||||
}).isPresent();
|
||||
}
|
||||
|
||||
default boolean keyPressed(int p_94710_, int p_94711_, int p_94712_) {
|
||||
return this.getFocused() != null && this.getFocused().keyPressed(p_94710_, p_94711_, p_94712_);
|
||||
}
|
||||
|
||||
default boolean keyReleased(int p_94715_, int p_94716_, int p_94717_) {
|
||||
return this.getFocused() != null && this.getFocused().keyReleased(p_94715_, p_94716_, p_94717_);
|
||||
}
|
||||
|
||||
default boolean charTyped(char p_94683_, int p_94684_) {
|
||||
return this.getFocused() != null && this.getFocused().charTyped(p_94683_, p_94684_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
GuiEventListener getFocused();
|
||||
|
||||
void setFocused(@Nullable GuiEventListener p_94713_);
|
||||
|
||||
default void setFocused(boolean p_265504_) {
|
||||
}
|
||||
|
||||
default boolean isFocused() {
|
||||
return this.getFocused() != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default ComponentPath getCurrentFocusPath() {
|
||||
GuiEventListener guieventlistener = this.getFocused();
|
||||
return guieventlistener != null ? ComponentPath.path(this, guieventlistener.getCurrentFocusPath()) : null;
|
||||
}
|
||||
|
||||
default void magicalSpecialHackyFocus(@Nullable GuiEventListener p_94726_) {
|
||||
this.setFocused(p_94726_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default ComponentPath nextFocusPath(FocusNavigationEvent p_265668_) {
|
||||
GuiEventListener guieventlistener = this.getFocused();
|
||||
if (guieventlistener != null) {
|
||||
ComponentPath componentpath = guieventlistener.nextFocusPath(p_265668_);
|
||||
if (componentpath != null) {
|
||||
return ComponentPath.path(this, componentpath);
|
||||
}
|
||||
}
|
||||
|
||||
if (p_265668_ instanceof FocusNavigationEvent.TabNavigation focusnavigationevent$tabnavigation) {
|
||||
return this.handleTabNavigation(focusnavigationevent$tabnavigation);
|
||||
} else if (p_265668_ instanceof FocusNavigationEvent.ArrowNavigation focusnavigationevent$arrownavigation) {
|
||||
return this.handleArrowNavigation(focusnavigationevent$arrownavigation);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ComponentPath handleTabNavigation(FocusNavigationEvent.TabNavigation p_265354_) {
|
||||
boolean flag = p_265354_.forward();
|
||||
GuiEventListener guieventlistener = this.getFocused();
|
||||
List<? extends GuiEventListener> list = new ArrayList<>(this.children());
|
||||
Collections.sort(list, Comparator.comparingInt((p_289623_) -> {
|
||||
return p_289623_.getTabOrderGroup();
|
||||
}));
|
||||
int j = list.indexOf(guieventlistener);
|
||||
int i;
|
||||
if (guieventlistener != null && j >= 0) {
|
||||
i = j + (flag ? 1 : 0);
|
||||
} else if (flag) {
|
||||
i = 0;
|
||||
} else {
|
||||
i = list.size();
|
||||
}
|
||||
|
||||
ListIterator<? extends GuiEventListener> listiterator = list.listIterator(i);
|
||||
BooleanSupplier booleansupplier = flag ? listiterator::hasNext : listiterator::hasPrevious;
|
||||
Supplier<? extends GuiEventListener> supplier = flag ? listiterator::next : listiterator::previous;
|
||||
|
||||
while(booleansupplier.getAsBoolean()) {
|
||||
GuiEventListener guieventlistener1 = supplier.get();
|
||||
ComponentPath componentpath = guieventlistener1.nextFocusPath(p_265354_);
|
||||
if (componentpath != null) {
|
||||
return ComponentPath.path(this, componentpath);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ComponentPath handleArrowNavigation(FocusNavigationEvent.ArrowNavigation p_265760_) {
|
||||
GuiEventListener guieventlistener = this.getFocused();
|
||||
if (guieventlistener == null) {
|
||||
ScreenDirection screendirection = p_265760_.direction();
|
||||
ScreenRectangle screenrectangle1 = this.getRectangle().getBorder(screendirection.getOpposite());
|
||||
return ComponentPath.path(this, this.nextFocusPathInDirection(screenrectangle1, screendirection, (GuiEventListener)null, p_265760_));
|
||||
} else {
|
||||
ScreenRectangle screenrectangle = guieventlistener.getRectangle();
|
||||
return ComponentPath.path(this, this.nextFocusPathInDirection(screenrectangle, p_265760_.direction(), guieventlistener, p_265760_));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ComponentPath nextFocusPathInDirection(ScreenRectangle p_265054_, ScreenDirection p_265167_, @Nullable GuiEventListener p_265476_, FocusNavigationEvent p_265762_) {
|
||||
ScreenAxis screenaxis = p_265167_.getAxis();
|
||||
ScreenAxis screenaxis1 = screenaxis.orthogonal();
|
||||
ScreenDirection screendirection = screenaxis1.getPositive();
|
||||
int i = p_265054_.getBoundInDirection(p_265167_.getOpposite());
|
||||
List<GuiEventListener> list = new ArrayList<>();
|
||||
|
||||
for(GuiEventListener guieventlistener : this.children()) {
|
||||
if (guieventlistener != p_265476_) {
|
||||
ScreenRectangle screenrectangle = guieventlistener.getRectangle();
|
||||
if (screenrectangle.overlapsInAxis(p_265054_, screenaxis1)) {
|
||||
int j = screenrectangle.getBoundInDirection(p_265167_.getOpposite());
|
||||
if (p_265167_.isAfter(j, i)) {
|
||||
list.add(guieventlistener);
|
||||
} else if (j == i && p_265167_.isAfter(screenrectangle.getBoundInDirection(p_265167_), p_265054_.getBoundInDirection(p_265167_))) {
|
||||
list.add(guieventlistener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Comparator<GuiEventListener> comparator = Comparator.comparing((p_264674_) -> {
|
||||
return p_264674_.getRectangle().getBoundInDirection(p_265167_.getOpposite());
|
||||
}, p_265167_.coordinateValueComparator());
|
||||
Comparator<GuiEventListener> comparator1 = Comparator.comparing((p_264676_) -> {
|
||||
return p_264676_.getRectangle().getBoundInDirection(screendirection.getOpposite());
|
||||
}, screendirection.coordinateValueComparator());
|
||||
list.sort(comparator.thenComparing(comparator1));
|
||||
|
||||
for(GuiEventListener guieventlistener1 : list) {
|
||||
ComponentPath componentpath = guieventlistener1.nextFocusPath(p_265762_);
|
||||
if (componentpath != null) {
|
||||
return componentpath;
|
||||
}
|
||||
}
|
||||
|
||||
return this.nextFocusPathVaguelyInDirection(p_265054_, p_265167_, p_265476_, p_265762_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ComponentPath nextFocusPathVaguelyInDirection(ScreenRectangle p_265390_, ScreenDirection p_265687_, @Nullable GuiEventListener p_265498_, FocusNavigationEvent p_265048_) {
|
||||
ScreenAxis screenaxis = p_265687_.getAxis();
|
||||
ScreenAxis screenaxis1 = screenaxis.orthogonal();
|
||||
List<Pair<GuiEventListener, Long>> list = new ArrayList<>();
|
||||
ScreenPosition screenposition = ScreenPosition.of(screenaxis, p_265390_.getBoundInDirection(p_265687_), p_265390_.getCenterInAxis(screenaxis1));
|
||||
|
||||
for(GuiEventListener guieventlistener : this.children()) {
|
||||
if (guieventlistener != p_265498_) {
|
||||
ScreenRectangle screenrectangle = guieventlistener.getRectangle();
|
||||
ScreenPosition screenposition1 = ScreenPosition.of(screenaxis, screenrectangle.getBoundInDirection(p_265687_.getOpposite()), screenrectangle.getCenterInAxis(screenaxis1));
|
||||
if (p_265687_.isAfter(screenposition1.getCoordinate(screenaxis), screenposition.getCoordinate(screenaxis))) {
|
||||
long i = Vector2i.distanceSquared(screenposition.x(), screenposition.y(), screenposition1.x(), screenposition1.y());
|
||||
list.add(Pair.of(guieventlistener, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.sort(Comparator.comparingDouble(Pair::getSecond));
|
||||
|
||||
for(Pair<GuiEventListener, Long> pair : list) {
|
||||
ComponentPath componentpath = pair.getFirst().nextFocusPath(p_265048_);
|
||||
if (componentpath != null) {
|
||||
return componentpath;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user