Initial Commit
This commit is contained in:
1 parent
377b32db6e
commit
2d9a5eecba
14134 files changed
+1160982
No files matched your search
+35
@@ -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 pId, String pKey) {
|
||||
this.id = pId;
|
||||
this.key = pKey;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public static AttackIndicatorStatus byId(int pId) {
|
||||
return BY_ID.apply(pId);
|
||||
}
|
||||
}
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
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 pLevel, Entity pEntity, boolean pDetached, boolean pThirdPersonReverse, float pPartialTick) {
|
||||
this.initialized = true;
|
||||
this.level = pLevel;
|
||||
this.entity = pEntity;
|
||||
this.detached = pDetached;
|
||||
this.setRotation(pEntity.getViewYRot(pPartialTick), pEntity.getViewXRot(pPartialTick));
|
||||
this.setPosition(Mth.lerp((double)pPartialTick, pEntity.xo, pEntity.getX()), Mth.lerp((double)pPartialTick, pEntity.yo, pEntity.getY()) + (double)Mth.lerp(pPartialTick, this.eyeHeightOld, this.eyeHeight), Mth.lerp((double)pPartialTick, pEntity.zo, pEntity.getZ()));
|
||||
if (pDetached) {
|
||||
if (pThirdPersonReverse) {
|
||||
this.setRotation(this.yRot + 180.0F, -this.xRot);
|
||||
}
|
||||
|
||||
this.move(-this.getMaxZoom(4.0D), 0.0D, 0.0D);
|
||||
} else if (pEntity instanceof LivingEntity && ((LivingEntity)pEntity).isSleeping()) {
|
||||
Direction direction = ((LivingEntity)pEntity).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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for collision of the third person camera and returns the distance
|
||||
*/
|
||||
private double getMaxZoom(double pStartingDistance) {
|
||||
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() * pStartingDistance + (double)f, this.position.y - (double)this.forwards.y() * pStartingDistance + (double)f1, this.position.z - (double)this.forwards.z() * pStartingDistance + (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 < pStartingDistance) {
|
||||
pStartingDistance = d0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pStartingDistance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the render position relative to the view direction, for third person camera
|
||||
*/
|
||||
protected void move(double pDistanceOffset, double pVerticalOffset, double pHorizontalOffset) {
|
||||
double d0 = (double)this.forwards.x() * pDistanceOffset + (double)this.up.x() * pVerticalOffset + (double)this.left.x() * pHorizontalOffset;
|
||||
double d1 = (double)this.forwards.y() * pDistanceOffset + (double)this.up.y() * pVerticalOffset + (double)this.left.y() * pHorizontalOffset;
|
||||
double d2 = (double)this.forwards.z() * pDistanceOffset + (double)this.up.z() * pVerticalOffset + (double)this.left.z() * pHorizontalOffset;
|
||||
this.setPosition(new Vec3(this.position.x + d0, this.position.y + d1, this.position.z + d2));
|
||||
}
|
||||
|
||||
protected void setRotation(float pYRot, float pXRot) {
|
||||
this.xRot = pXRot;
|
||||
this.yRot = pYRot;
|
||||
this.rotation.rotationYXZ(-pYRot * ((float)Math.PI / 180F), pXRot * ((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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position and blockpos of the active render
|
||||
*/
|
||||
protected void setPosition(double pX, double pY, double pZ) {
|
||||
this.setPosition(new Vec3(pX, pY, pZ));
|
||||
}
|
||||
|
||||
protected void setPosition(Vec3 pPos) {
|
||||
this.position = pPos;
|
||||
this.blockPosition.set(pPos.x, pPos.y, pPos.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 pForward, Vec3 pLeft, Vec3 pUp) {
|
||||
this.forward = pForward;
|
||||
this.left = pLeft;
|
||||
this.up = pUp;
|
||||
}
|
||||
|
||||
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 pLeftScale, float pUpScale) {
|
||||
return this.forward.add(this.up.scale((double)pUpScale)).subtract(this.left.scale((double)pLeftScale));
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -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 pFirstPerson, boolean pMirrored) {
|
||||
this.firstPerson = pFirstPerson;
|
||||
this.mirrored = pMirrored;
|
||||
}
|
||||
|
||||
public boolean isFirstPerson() {
|
||||
return this.firstPerson;
|
||||
}
|
||||
|
||||
public boolean isMirrored() {
|
||||
return this.mirrored;
|
||||
}
|
||||
|
||||
public CameraType cycle() {
|
||||
return VALUES[(this.ordinal() + 1) % VALUES.length];
|
||||
}
|
||||
}
|
||||
+15
@@ -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();
|
||||
}
|
||||
}
|
||||
+161
@@ -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<?>> pRecipes, RegistryAccess pRegistryAccess) {
|
||||
Map<RecipeBookCategories, List<List<Recipe<?>>>> map = categorizeAndGroupRecipes(pRecipes);
|
||||
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(pRegistryAccess, 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<?>> pRecipes) {
|
||||
Map<RecipeBookCategories, List<List<Recipe<?>>>> map = Maps.newHashMap();
|
||||
Table<RecipeBookCategories, String, List<Recipe<?>>> table = HashBasedTable.create();
|
||||
|
||||
for(Recipe<?> recipe : pRecipes) {
|
||||
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<?> pRecipe) {
|
||||
if (pRecipe instanceof CraftingRecipe) {
|
||||
CraftingRecipe craftingrecipe = (CraftingRecipe)pRecipe;
|
||||
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 = pRecipe.getType();
|
||||
if (pRecipe instanceof AbstractCookingRecipe) {
|
||||
AbstractCookingRecipe abstractcookingrecipe = (AbstractCookingRecipe)pRecipe;
|
||||
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, pRecipe);
|
||||
if (categories != null) return categories;
|
||||
LOGGER.warn("Unknown recipe category: {}/{}", LogUtils.defer(() -> {
|
||||
return BuiltInRegistries.RECIPE_TYPE.getKey(pRecipe.getType());
|
||||
}), LogUtils.defer(pRecipe::getId));
|
||||
return RecipeBookCategories.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<RecipeCollection> getCollections() {
|
||||
return this.allCollections;
|
||||
}
|
||||
|
||||
public List<RecipeCollection> getCollection(RecipeBookCategories pCategories) {
|
||||
return this.collectionsByTab.getOrDefault(pCategories, Collections.emptyList());
|
||||
}
|
||||
}
|
||||
+28
@@ -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 pId, String pKey) {
|
||||
this.id = pId;
|
||||
this.key = pKey;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
}
|
||||
+35
@@ -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 pPart) {
|
||||
this.parts.add(pPart);
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
+48
@@ -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 pConnection) {
|
||||
this.connection = pConnection;
|
||||
}
|
||||
|
||||
public boolean handleResponse(int pTransactionId, @Nullable CompoundTag pTag) {
|
||||
if (this.transactionId == pTransactionId && this.callback != null) {
|
||||
this.callback.accept(pTag);
|
||||
this.callback = null;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private int startTransaction(Consumer<CompoundTag> pCallback) {
|
||||
this.callback = pCallback;
|
||||
return ++this.transactionId;
|
||||
}
|
||||
|
||||
public void queryEntityTag(int pEntId, Consumer<CompoundTag> pTag) {
|
||||
int i = this.startTransaction(pTag);
|
||||
this.connection.send(new ServerboundEntityTagQuery(i, pEntId));
|
||||
}
|
||||
|
||||
public void queryBlockEntityTag(BlockPos pPos, Consumer<CompoundTag> pTag) {
|
||||
int i = this.startTransaction(pTag);
|
||||
this.connection.send(new ServerboundBlockEntityTagQuery(i, pPos));
|
||||
}
|
||||
}
|
||||
+113
@@ -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 pMinecraft) {
|
||||
this.minecraft = pMinecraft;
|
||||
}
|
||||
|
||||
public void sayChat(Component pMessage) {
|
||||
if (this.getStatus().shouldNarrateChat()) {
|
||||
String s = pMessage.getString();
|
||||
this.logNarratedMessage(s);
|
||||
this.narrator.say(s, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void say(Component pMessage) {
|
||||
String s = pMessage.getString();
|
||||
if (this.getStatus().shouldNarrateSystem() && !s.isEmpty()) {
|
||||
this.logNarratedMessage(s);
|
||||
this.narrator.say(s, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void sayNow(Component pMessage) {
|
||||
this.sayNow(pMessage.getString());
|
||||
}
|
||||
|
||||
public void sayNow(String pMessage) {
|
||||
if (this.getStatus().shouldNarrateSystem() && !pMessage.isEmpty()) {
|
||||
this.logNarratedMessage(pMessage);
|
||||
if (this.narrator.active()) {
|
||||
this.narrator.clear();
|
||||
this.narrator.say(pMessage, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private NarratorStatus getStatus() {
|
||||
return this.minecraft.options.narrator().get();
|
||||
}
|
||||
|
||||
private void logNarratedMessage(String pMessage) {
|
||||
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
||||
LOGGER.debug("Narrating: {}", (Object)pMessage.replaceAll("\n", "\\\\n"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void updateNarratorStatus(NarratorStatus pStatus) {
|
||||
this.clear();
|
||||
this.narrator.say(Component.translatable("options.narrator").append(" : ").append(pStatus.getName()).getString(), true);
|
||||
ToastComponent toastcomponent = Minecraft.getInstance().getToasts();
|
||||
if (this.narrator.active()) {
|
||||
if (pStatus == 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"), pStatus.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 pNarratorEnabled) {
|
||||
if (pNarratorEnabled && !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_);
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
@@ -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 pId, String pKey) {
|
||||
this.id = pId;
|
||||
this.key = pKey;
|
||||
}
|
||||
|
||||
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 pId) {
|
||||
return BY_ID.apply(pId);
|
||||
}
|
||||
}
|
||||
+15
@@ -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) {
|
||||
}
|
||||
}
|
||||
+63
@@ -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 pOriginalText) {
|
||||
Component component = Component.literal(pOriginalText).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 pU, int pV, int pWidth, int pHeight) {
|
||||
this.u = pU;
|
||||
this.v = pV;
|
||||
this.width = pWidth;
|
||||
this.height = pHeight;
|
||||
}
|
||||
|
||||
public void draw(GuiGraphics pGuiGraphics, int pX, int pY) {
|
||||
pGuiGraphics.blit(GuiMessageTag.TEXTURE_LOCATION, pX, pY, (float)this.u, (float)this.v, this.width, this.height, 32, 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
+76
@@ -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 pGameDirectory, DataFixer pFixerUpper) {
|
||||
this.optionsFile = new File(pGameDirectory, "hotbar.nbt");
|
||||
this.fixerUpper = pFixerUpper;
|
||||
|
||||
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 pIndex) {
|
||||
if (!this.loaded) {
|
||||
this.load();
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
return this.hotbars[pIndex];
|
||||
}
|
||||
}
|
||||
+20
@@ -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;
|
||||
}
|
||||
}
|
||||
+319
@@ -0,0 +1,319 @@
|
||||
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 pKey) {
|
||||
for (KeyMapping keymapping : MAP.getAll(pKey))
|
||||
if (keymapping != null) {
|
||||
++keymapping.clickCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void set(InputConstants.Key pKey, boolean pHeld) {
|
||||
for (KeyMapping keymapping : MAP.getAll(pKey))
|
||||
if (keymapping != null) {
|
||||
keymapping.setDown(pHeld);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely recalculates whether any keybinds are held, from scratch.
|
||||
*/
|
||||
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 pName, int pKeyCode, String pCategory) {
|
||||
this(pName, InputConstants.Type.KEYSYM, pKeyCode, pCategory);
|
||||
}
|
||||
|
||||
public KeyMapping(String pName, InputConstants.Type pType, int pKeyCode, String pCategory) {
|
||||
this.name = pName;
|
||||
this.key = pType.getOrCreate(pKeyCode);
|
||||
this.defaultKey = this.key;
|
||||
this.category = pCategory;
|
||||
ALL.put(pName, this);
|
||||
MAP.put(this.key, this);
|
||||
CATEGORIES.add(pCategory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the key is pressed (used for continuous querying). Should be used in tickers.
|
||||
*/
|
||||
public boolean isDown() {
|
||||
return this.isDown && isConflictContextAndModifierActive();
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return this.category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} on the initial key press. For continuous querying use {@link isKeyDown()}. Should be used in
|
||||
* key events.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a new KeyCode to this
|
||||
*/
|
||||
public void setKey(InputConstants.Key pKey) {
|
||||
this.key = pKey;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a supplier which gets a keybind's current binding (eg, <code>key.forward</code> returns <samp>W</samp> by
|
||||
* default), or the keybind's name if no such keybind exists (eg, <code>key.invalid</code> returns
|
||||
* <samp>key.invalid</samp>)
|
||||
*/
|
||||
public static Supplier<Component> createNameSupplier(String pKey) {
|
||||
KeyMapping keymapping = ALL.get(pKey);
|
||||
return keymapping == null ? () -> {
|
||||
return Component.translatable(pKey);
|
||||
} : keymapping::getTranslatedKeyMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the supplied {@code KeyMapping} conflicts with this
|
||||
*/
|
||||
public boolean same(KeyMapping pBinding) {
|
||||
if (getKeyConflictContext().conflicts(pBinding.getKeyConflictContext()) || pBinding.getKeyConflictContext().conflicts(getKeyConflictContext())) {
|
||||
net.minecraftforge.client.settings.KeyModifier keyModifier = getKeyModifier();
|
||||
net.minecraftforge.client.settings.KeyModifier otherKeyModifier = pBinding.getKeyModifier();
|
||||
if (keyModifier.matches(pBinding.getKey()) || otherKeyModifier.matches(getKey())) {
|
||||
return true;
|
||||
} else if (getKey().equals(pBinding.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(pBinding.key);
|
||||
}
|
||||
|
||||
public boolean isUnbound() {
|
||||
return this.key.equals(InputConstants.UNKNOWN);
|
||||
}
|
||||
|
||||
public boolean matches(int pKeysym, int pScancode) {
|
||||
if (pKeysym == InputConstants.UNKNOWN.getValue()) {
|
||||
return this.key.getType() == InputConstants.Type.SCANCODE && this.key.getValue() == pScancode;
|
||||
} else {
|
||||
return this.key.getType() == InputConstants.Type.KEYSYM && this.key.getValue() == pKeysym;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the {@code KeyMapping} is set to a mouse key and the key matches.
|
||||
*/
|
||||
public boolean matchesMouse(int pKey) {
|
||||
return this.key.getType() == InputConstants.Type.MOUSE && this.key.getValue() == pKey;
|
||||
}
|
||||
|
||||
public Component getTranslatedKeyMessage() {
|
||||
return getKeyModifier().getCombinedName(key, () -> {
|
||||
return this.key.getDisplayName();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the {@code KeyMapping} is using the default key and key modifier
|
||||
*/
|
||||
public boolean isDefault() {
|
||||
return this.key.equals(this.defaultKey) && getKeyModifier() == getDefaultKeyModifier();
|
||||
}
|
||||
|
||||
public String saveString() {
|
||||
return this.key.getName();
|
||||
}
|
||||
|
||||
public void setDown(boolean pValue) {
|
||||
this.isDown = pValue;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
+517
@@ -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 pMinecraft) {
|
||||
this.minecraft = pMinecraft;
|
||||
}
|
||||
|
||||
private boolean handleChunkDebugKeys(int pKeyCode) {
|
||||
switch (pKeyCode) {
|
||||
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 pFormatting, Component pMessage) {
|
||||
this.minecraft.gui.getChat().addMessage(Component.empty().append(Component.translatable("debug.prefix").withStyle(pFormatting, ChatFormatting.BOLD)).append(CommonComponents.SPACE).append(pMessage));
|
||||
}
|
||||
|
||||
private void debugFeedbackComponent(Component p_167823_) {
|
||||
this.debugComponent(ChatFormatting.YELLOW, p_167823_);
|
||||
}
|
||||
|
||||
private void debugFeedbackTranslated(String pMessage, Object... pArgs) {
|
||||
this.debugFeedbackComponent(Component.translatable(pMessage, pArgs));
|
||||
}
|
||||
|
||||
private void debugWarningTranslated(String pMessage, Object... pArgs) {
|
||||
this.debugComponent(ChatFormatting.RED, Component.translatable(pMessage, pArgs));
|
||||
}
|
||||
|
||||
private void debugFeedback(String pMessage, Object... pArgs) {
|
||||
this.debugFeedbackComponent(Component.literal(MessageFormat.format(pMessage, pArgs)));
|
||||
}
|
||||
|
||||
private boolean handleDebugKeys(int pKey) {
|
||||
if (this.debugCrashKeyTime > 0L && this.debugCrashKeyTime < Util.getMillis() - 100L) {
|
||||
return true;
|
||||
} else {
|
||||
switch (pKey) {
|
||||
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 pPrivileged, boolean pAskServer) {
|
||||
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 (pPrivileged) {
|
||||
if (pAskServer) {
|
||||
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 (pPrivileged) {
|
||||
if (pAskServer) {
|
||||
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 pState, BlockPos pPos, @Nullable CompoundTag pCompound) {
|
||||
StringBuilder stringbuilder = new StringBuilder(BlockStateParser.serialize(pState));
|
||||
if (pCompound != null) {
|
||||
stringbuilder.append((Object)pCompound);
|
||||
}
|
||||
|
||||
String s = String.format(Locale.ROOT, "/setblock %d %d %d %s", pPos.getX(), pPos.getY(), pPos.getZ(), stringbuilder);
|
||||
this.setClipboard(s);
|
||||
}
|
||||
|
||||
private void copyCreateEntityCommand(ResourceLocation pEntityId, Vec3 pPos, @Nullable CompoundTag pCompound) {
|
||||
String s;
|
||||
if (pCompound != null) {
|
||||
pCompound.remove("UUID");
|
||||
pCompound.remove("Pos");
|
||||
pCompound.remove("Dimension");
|
||||
String s1 = NbtUtils.toPrettyComponent(pCompound).getString();
|
||||
s = String.format(Locale.ROOT, "/summon %s %.2f %.2f %.2f %s", pEntityId.toString(), pPos.x, pPos.y, pPos.z, s1);
|
||||
} else {
|
||||
s = String.format(Locale.ROOT, "/summon %s %.2f %.2f %.2f", pEntityId.toString(), pPos.x, pPos.y, pPos.z);
|
||||
}
|
||||
|
||||
this.setClipboard(s);
|
||||
}
|
||||
|
||||
public void keyPress(long pWindowPointer, int pKey, int pScanCode, int pAction, int pModifiers) {
|
||||
if (pWindowPointer == 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 (pKey) {
|
||||
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 (pAction == 1 && (!(this.minecraft.screen instanceof KeyBindsScreen) || ((KeyBindsScreen)screen).lastKeySelection <= Util.getMillis() - 20L)) {
|
||||
if (this.minecraft.options.keyFullscreen.matches(pKey, pScanCode)) {
|
||||
this.minecraft.getWindow().toggleFullScreen();
|
||||
this.minecraft.options.fullscreen().set(this.minecraft.getWindow().isFullscreen());
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.minecraft.options.keyScreenshot.matches(pKey, pScanCode)) {
|
||||
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 (pAction != 0 && pKey == 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 (pAction != 1 && pAction != 2) {
|
||||
if (pAction == 0) {
|
||||
aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyReleasedPre(screen, pKey, pScanCode, pModifiers);
|
||||
if (!aboolean[0]) aboolean[0] = screen.keyReleased(pKey, pScanCode, pModifiers);
|
||||
if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyReleasedPost(screen, pKey, pScanCode, pModifiers);
|
||||
}
|
||||
} else {
|
||||
screen.afterKeyboardAction();
|
||||
aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyPressedPre(screen, pKey, pScanCode, pModifiers);
|
||||
if (!aboolean[0]) aboolean[0] = screen.keyPressed(pKey, pScanCode, pModifiers);
|
||||
if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyPressedPost(screen, pKey, pScanCode, pModifiers);
|
||||
}
|
||||
|
||||
}, "keyPressed event handler", screen.getClass().getCanonicalName());
|
||||
if (aboolean[0]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.minecraft.screen == null) {
|
||||
InputConstants.Key inputconstants$key = InputConstants.getKey(pKey, pScanCode);
|
||||
if (pAction == 0) {
|
||||
KeyMapping.set(inputconstants$key, false);
|
||||
if (pKey == 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 (pKey == 293 && this.minecraft.gameRenderer != null) {
|
||||
this.minecraft.gameRenderer.togglePostEffect();
|
||||
}
|
||||
|
||||
boolean flag3 = false;
|
||||
if (pKey == 256) {
|
||||
boolean flag2 = InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 292);
|
||||
this.minecraft.pauseGame(flag2);
|
||||
}
|
||||
|
||||
flag3 = InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 292) && this.handleDebugKeys(pKey);
|
||||
this.handledDebugKey |= flag3;
|
||||
if (pKey == 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 && pKey >= 48 && pKey <= 57) {
|
||||
this.minecraft.debugFpsMeterKeyPress(pKey - 48);
|
||||
}
|
||||
}
|
||||
}
|
||||
net.minecraftforge.client.ForgeHooksClient.onKeyInput(pKey, pScanCode, pAction, pModifiers);
|
||||
}
|
||||
}
|
||||
|
||||
private void charTyped(long pWindowPointer, int pCodePoint, int pModifiers) {
|
||||
if (pWindowPointer == this.minecraft.getWindow().getWindow()) {
|
||||
Screen guieventlistener = this.minecraft.screen;
|
||||
if (guieventlistener != null && this.minecraft.getOverlay() == null) {
|
||||
if (Character.charCount(pCodePoint) == 1) {
|
||||
Screen.wrapScreenError(() -> {
|
||||
if (net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPre(guieventlistener, (char)pCodePoint, pModifiers)) return;
|
||||
if (guieventlistener.charTyped((char)pCodePoint, pModifiers)) return;
|
||||
net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPost(guieventlistener, (char)pCodePoint, pModifiers);
|
||||
}, "charTyped event handler", guieventlistener.getClass().getCanonicalName());
|
||||
} else {
|
||||
for(char c0 : Character.toChars(pCodePoint)) {
|
||||
Screen.wrapScreenError(() -> {
|
||||
if (net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPre(guieventlistener, c0, pModifiers)) return;
|
||||
if (guieventlistener.charTyped(c0, pModifiers)) return;
|
||||
net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPost(guieventlistener, c0, pModifiers);
|
||||
}, "charTyped event handler", guieventlistener.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setup(long pWindow) {
|
||||
InputConstants.setupKeyboardCallbacks(pWindow, (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 pString) {
|
||||
if (!pString.isEmpty()) {
|
||||
this.clipboardManager.setClipboard(this.minecraft.getWindow().getWindow(), pString);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+2989
File diff suppressed because it is too large.
Load diff
+389
@@ -0,0 +1,389 @@
|
||||
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 pMinecraft) {
|
||||
this.minecraft = pMinecraft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be called when a mouse button is pressed or released.
|
||||
*
|
||||
* @see GLFWMouseButtonCallbackI
|
||||
*/
|
||||
private void onPress(long pWindowPointer, int pButton, int pAction, int pModifiers) {
|
||||
if (pWindowPointer == this.minecraft.getWindow().getWindow()) {
|
||||
if (this.minecraft.screen != null) {
|
||||
this.minecraft.setLastInputType(InputType.MOUSE);
|
||||
}
|
||||
|
||||
boolean flag = pAction == 1;
|
||||
if (Minecraft.ON_OSX && pButton == 0) {
|
||||
if (flag) {
|
||||
if ((pModifiers & 2) == 2) {
|
||||
pButton = 1;
|
||||
++this.fakeRightMouse;
|
||||
}
|
||||
} else if (this.fakeRightMouse > 0) {
|
||||
pButton = 1;
|
||||
--this.fakeRightMouse;
|
||||
}
|
||||
}
|
||||
|
||||
int i = pButton;
|
||||
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(pButton, pAction, pModifiers)) 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(pButton, pAction, pModifiers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be called when a scrolling device is used, such as a mouse wheel or scrolling area of a touchpad.
|
||||
*
|
||||
* @see GLFWScrollCallbackI
|
||||
*/
|
||||
private void onScroll(long pWindowPointer, double pXOffset, double pYOffset) {
|
||||
if (pWindowPointer == Minecraft.getInstance().getWindow().getWindow()) {
|
||||
// FORGE: Allows for Horizontal Scroll to be recognized as Vertical Scroll - Fixes MC-121772
|
||||
double offset = pYOffset;
|
||||
if (Minecraft.ON_OSX && pYOffset == 0) {
|
||||
offset = pXOffset;
|
||||
}
|
||||
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 pWindow, List<Path> pPaths) {
|
||||
if (this.minecraft.screen != null) {
|
||||
this.minecraft.screen.onFilesDrop(pPaths);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setup(long pWindowPointer) {
|
||||
InputConstants.setupMouseCallbacks(pWindowPointer, (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));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be called when the cursor is moved.
|
||||
*
|
||||
* <p>The callback function receives the cursor position, measured in screen coordinates but relative to the top-left
|
||||
* corner of the window client area. On platforms that provide it, the full sub-pixel cursor position is passed
|
||||
* on.</p>
|
||||
*
|
||||
* @see GLFWCursorPosCallbackI
|
||||
*/
|
||||
private void onMove(long pWindowPointer, double pXpos, double pYpos) {
|
||||
if (pWindowPointer == Minecraft.getInstance().getWindow().getWindow()) {
|
||||
if (this.ignoreFirstMove) {
|
||||
this.xpos = pXpos;
|
||||
this.ypos = pYpos;
|
||||
this.ignoreFirstMove = false;
|
||||
}
|
||||
|
||||
Screen screen = this.minecraft.screen;
|
||||
if (screen != null && this.minecraft.getOverlay() == null) {
|
||||
double d0 = pXpos * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getScreenWidth();
|
||||
double d1 = pYpos * (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 = (pXpos - this.xpos) * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getScreenWidth();
|
||||
double d3 = (pYpos - 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 += pXpos - this.xpos;
|
||||
this.accumulatedDY += pYpos - this.ypos;
|
||||
}
|
||||
|
||||
this.turnPlayer();
|
||||
this.xpos = pXpos;
|
||||
this.ypos = pYpos;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the mouse is grabbed.
|
||||
*/
|
||||
public boolean isMouseGrabbed() {
|
||||
return this.mouseGrabbed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will set the focus to ingame if the Minecraft window is the active with focus. Also clears any GUI screen
|
||||
* currently displayed
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the player keystate, disables the ingame focus, and ungrabs the mouse cursor.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
+44
@@ -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 pId, String pName) {
|
||||
this.id = pId;
|
||||
this.name = Component.translatable(pName);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Component getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public static NarratorStatus byId(int pId) {
|
||||
return BY_ID.apply(pId);
|
||||
}
|
||||
|
||||
public boolean shouldNarrateChat() {
|
||||
return this == ALL || this == CHAT;
|
||||
}
|
||||
|
||||
public boolean shouldNarrateSystem() {
|
||||
return this == ALL || this == SYSTEM;
|
||||
}
|
||||
}
|
||||
+425
@@ -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 pKey, boolean pInitialValue, Consumer<Boolean> pOnValueUpdate) {
|
||||
return createBoolean(pKey, noTooltip(), pInitialValue, pOnValueUpdate);
|
||||
}
|
||||
|
||||
public static OptionInstance<Boolean> createBoolean(String pKey, boolean pInitialValue) {
|
||||
return createBoolean(pKey, noTooltip(), pInitialValue, (p_231548_) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public static OptionInstance<Boolean> createBoolean(String pCaption, OptionInstance.TooltipSupplier<Boolean> pTooltip, boolean pInitialValue) {
|
||||
return createBoolean(pCaption, pTooltip, pInitialValue, (p_231513_) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public static OptionInstance<Boolean> createBoolean(String pCaption, OptionInstance.TooltipSupplier<Boolean> pTooltip, boolean pInitialValue, Consumer<Boolean> pOnValueUpdate) {
|
||||
return createBoolean(pCaption, pTooltip, BOOLEAN_TO_STRING, pInitialValue, pOnValueUpdate);
|
||||
}
|
||||
|
||||
public static OptionInstance<Boolean> createBoolean(String pCaption, OptionInstance.TooltipSupplier<Boolean> pTooltip, OptionInstance.CaptionBasedToString<Boolean> pValueStringifier, boolean pInitialValue, Consumer<Boolean> pOnValueUpdate) {
|
||||
return new OptionInstance<>(pCaption, pTooltip, pValueStringifier, BOOLEAN_VALUES, pInitialValue, pOnValueUpdate);
|
||||
}
|
||||
|
||||
public OptionInstance(String pCaption, OptionInstance.TooltipSupplier<T> pTooltip, OptionInstance.CaptionBasedToString<T> pValueStringifier, OptionInstance.ValueSet<T> pValues, T pInitialValue, Consumer<T> pOnValueUpdate) {
|
||||
this(pCaption, pTooltip, pValueStringifier, pValues, pValues.codec(), pInitialValue, pOnValueUpdate);
|
||||
}
|
||||
|
||||
public OptionInstance(String pCaption, OptionInstance.TooltipSupplier<T> pTooltip, OptionInstance.CaptionBasedToString<T> pValueStringifier, OptionInstance.ValueSet<T> pValues, Codec<T> pCodec, T pInitialValue, Consumer<T> pOnValueUpdate) {
|
||||
this.caption = Component.translatable(pCaption);
|
||||
this.tooltip = pTooltip;
|
||||
this.toString = (p_231506_) -> {
|
||||
return pValueStringifier.toString(this.caption, p_231506_);
|
||||
};
|
||||
this.values = pValues;
|
||||
this.codec = pCodec;
|
||||
this.initialValue = pInitialValue;
|
||||
this.onValueUpdate = pOnValueUpdate;
|
||||
this.value = this.initialValue;
|
||||
}
|
||||
|
||||
public static <T> OptionInstance.TooltipSupplier<T> noTooltip() {
|
||||
return (p_258114_) -> {
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> OptionInstance.TooltipSupplier<T> cachedConstantTooltip(Component pMessage) {
|
||||
return (p_258116_) -> {
|
||||
return Tooltip.create(pMessage);
|
||||
};
|
||||
}
|
||||
|
||||
public static <T extends OptionEnum> OptionInstance.CaptionBasedToString<T> forOptionEnum() {
|
||||
return (p_231538_, p_231539_) -> {
|
||||
return p_231539_.getCaption();
|
||||
};
|
||||
}
|
||||
|
||||
public AbstractWidget createButton(Options pOptions, int pX, int pY, int pWidth) {
|
||||
return this.createButton(pOptions, pX, pY, pWidth, (p_261336_) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public AbstractWidget createButton(Options pOptions, int pX, int pY, int pWidth, Consumer<T> pOnValueChanged) {
|
||||
return this.values.createButton(this.tooltip, pOptions, pX, pY, pWidth, pOnValueChanged).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 pValue) {
|
||||
T t = this.values.validateValue(pValue).orElseGet(() -> {
|
||||
LOGGER.error("Illegal option value " + pValue + " 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 pCaption, T pValue);
|
||||
}
|
||||
|
||||
@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> pTooltipSupplier, Options pOptions, int pX, int pY, int pWidth, Consumer<T> pOnValueChanged) {
|
||||
return (p_261343_) -> {
|
||||
return CycleButton.builder(p_261343_.toString).withValues(this.valueListSupplier()).withTooltip(pTooltipSupplier).withInitialValue(p_261343_.value).create(pX, pY, pWidth, 20, p_261343_.caption, (p_261347_, p_261348_) -> {
|
||||
this.valueSetter().set(p_261343_, p_261348_);
|
||||
pOptions.save();
|
||||
pOnValueChanged.accept(p_261348_);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface ValueSetter<T> {
|
||||
void set(OptionInstance<T> pInstance, T pValue);
|
||||
}
|
||||
}
|
||||
|
||||
@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 pOptions, int pX, int pY, int pWidth, int pHeight, OptionInstance<N> pInstance, OptionInstance.SliderableValueSet<N> pValues, OptionInstance.TooltipSupplier<N> pTooltipSupplier, Consumer<N> pOnValueChanged) {
|
||||
super(pOptions, pX, pY, pWidth, pHeight, pValues.toSliderValue(pInstance.get()));
|
||||
this.instance = pInstance;
|
||||
this.values = pValues;
|
||||
this.tooltipSupplier = pTooltipSupplier;
|
||||
this.onValueChanged = pOnValueChanged;
|
||||
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 pValue);
|
||||
|
||||
T fromSliderValue(double pValue);
|
||||
|
||||
default Function<OptionInstance<T>, AbstractWidget> createButton(OptionInstance.TooltipSupplier<T> pTooltipSupplier, Options pOptions, int pX, int pY, int pWidth, Consumer<T> pOnValueChanged) {
|
||||
return (p_261355_) -> {
|
||||
return new OptionInstance.OptionInstanceSliderButton<>(pOptions, pX, pY, pWidth, 20, p_261355_, this, pTooltipSupplier, pOnValueChanged);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@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> pTooltipSupplier, Options pOptions, int pX, int pY, int pWidth, Consumer<T> pOnValueChanged);
|
||||
|
||||
Optional<T> validateValue(T pValue);
|
||||
|
||||
Codec<T> codec();
|
||||
}
|
||||
}
|
||||
+1381
File diff suppressed because it is too large.
Load diff
+35
@@ -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 pId, String pKey) {
|
||||
this.id = pId;
|
||||
this.key = pKey;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public static ParticleStatus byId(int pId) {
|
||||
return BY_ID.apply(pId);
|
||||
}
|
||||
}
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
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 pNotifications, Object2BooleanFunction<String> pSelector) {
|
||||
this.notifications = pNotifications;
|
||||
this.selector = pSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs any reloading that can be done off-thread, such as file IO
|
||||
*/
|
||||
protected Map<String, List<PeriodicNotificationManager.Notification>> prepare(ResourceManager pResourceManager, ProfilerFiller pProfiler) {
|
||||
try (Reader reader = pResourceManager.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>> pObject, ResourceManager pResourceManager, ProfilerFiller pProfiler) {
|
||||
List<PeriodicNotificationManager.Notification> list = pObject.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> pNotifications, long pDelay) {
|
||||
return pNotifications.stream().mapToLong((p_205298_) -> {
|
||||
long i = p_205298_.delay - pDelay;
|
||||
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> pNotifications) {
|
||||
return pNotifications.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> pNotifications, long pElapsed, long pPeriod) {
|
||||
this.notifications = pNotifications;
|
||||
this.period = pPeriod;
|
||||
this.elapsed = new AtomicLong(pElapsed);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+35
@@ -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 pId, String pKey) {
|
||||
this.id = pId;
|
||||
this.key = pKey;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public static PrioritizeChunkUpdates byId(int pId) {
|
||||
return BY_ID.apply(pId);
|
||||
}
|
||||
}
|
||||
+59
@@ -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 pMinecraft) {
|
||||
this.minecraft = pMinecraft;
|
||||
}
|
||||
|
||||
public void showRealms32BitWarningIfNeeded(Screen pLastScreen) {
|
||||
if (!this.minecraft.is64Bit() && !this.minecraft.options.skipRealms32bitWarning && !this.warningScreenShown && this.checkForRealmsSubscription()) {
|
||||
this.minecraft.setScreen(new Realms32bitWarningScreen(pLastScreen));
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
@@ -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... pItemIcons) {
|
||||
this.itemIcons = ImmutableList.copyOf(pItemIcons);
|
||||
}
|
||||
|
||||
public static List<RecipeBookCategories> getCategories(RecipeBookType pRecipeBookType) {
|
||||
List list;
|
||||
switch (pRecipeBookType) {
|
||||
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(pRecipeBookType);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<ItemStack> getIconItems() {
|
||||
return this.itemIcons;
|
||||
}
|
||||
|
||||
public static RecipeBookCategories create(String name, ItemStack... icons) {
|
||||
throw new IllegalStateException("Enum not extended");
|
||||
}
|
||||
}
|
||||
+115
@@ -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 pReloadReason, List<PackResources> pPacks) {
|
||||
++this.reloadCount;
|
||||
if (this.reloadState != null && !this.reloadState.finished) {
|
||||
LOGGER.warn("Reload already ongoing, replacing");
|
||||
}
|
||||
|
||||
this.reloadState = new ResourceLoadStateTracker.ReloadState(pReloadReason, pPacks.stream().map(PackResources::packId).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
|
||||
public void startRecovery(Throwable pError) {
|
||||
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(pError);
|
||||
}
|
||||
|
||||
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 pReport) {
|
||||
CrashReportCategory crashreportcategory = pReport.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 pError) {
|
||||
this.error = pError;
|
||||
}
|
||||
|
||||
public void fillCrashInfo(CrashReportCategory pCrash) {
|
||||
pCrash.setDetail("Recovery", "Yes");
|
||||
pCrash.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 pName) {
|
||||
this.name = pName;
|
||||
}
|
||||
}
|
||||
|
||||
@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 pReloadReason, List<String> pPacks) {
|
||||
this.reloadReason = pReloadReason;
|
||||
this.packs = pPacks;
|
||||
}
|
||||
|
||||
public void fillCrashInfo(CrashReportCategory pCrash) {
|
||||
pCrash.setDetail("Reload reason", this.reloadReason.name);
|
||||
pCrash.setDetail("Finished", this.finished ? "Yes" : "No");
|
||||
pCrash.setDetail("Packs", () -> {
|
||||
return String.join(", ", this.packs);
|
||||
});
|
||||
if (this.recoveryReloadInfo != null) {
|
||||
this.recoveryReloadInfo.fillCrashInfo(pCrash);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* Saves a screenshot in the game directory with a time-stamped filename.
|
||||
*/
|
||||
public static void grab(File pGameDirectory, RenderTarget pBuffer, Consumer<Component> pMessageConsumer) {
|
||||
grab(pGameDirectory, (String)null, pBuffer, pMessageConsumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a screenshot in the game directory with the given file name (or null to generate a time-stamped name).
|
||||
*/
|
||||
public static void grab(File pGameDirectory, @Nullable String pScreenshotName, RenderTarget pBuffer, Consumer<Component> pMessageConsumer) {
|
||||
if (!RenderSystem.isOnRenderThread()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
_grab(pGameDirectory, pScreenshotName, pBuffer, pMessageConsumer);
|
||||
});
|
||||
} else {
|
||||
_grab(pGameDirectory, pScreenshotName, pBuffer, pMessageConsumer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void _grab(File pGameDirectory, @Nullable String pScreenshotName, RenderTarget pBuffer, Consumer<Component> pMessageConsumer) {
|
||||
NativeImage nativeimage = takeScreenshot(pBuffer);
|
||||
File file1 = new File(pGameDirectory, "screenshots");
|
||||
file1.mkdir();
|
||||
File file2;
|
||||
if (pScreenshotName == null) {
|
||||
file2 = getFile(file1);
|
||||
} else {
|
||||
file2 = new File(file1, pScreenshotName);
|
||||
}
|
||||
|
||||
net.minecraftforge.client.event.ScreenshotEvent event = net.minecraftforge.client.ForgeHooksClient.onScreenshot(nativeimage, file2);
|
||||
if (event.isCanceled()) {
|
||||
pMessageConsumer.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)
|
||||
pMessageConsumer.accept(event.getResultMessage());
|
||||
else
|
||||
pMessageConsumer.accept(Component.translatable("screenshot.success", component));
|
||||
} catch (Exception exception) {
|
||||
LOGGER.warn("Couldn't save screenshot", (Throwable)exception);
|
||||
pMessageConsumer.accept(Component.translatable("screenshot.failure", exception.getMessage()));
|
||||
} finally {
|
||||
nativeimage.close();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public static NativeImage takeScreenshot(RenderTarget pFramebuffer) {
|
||||
int i = pFramebuffer.width;
|
||||
int j = pFramebuffer.height;
|
||||
NativeImage nativeimage = new NativeImage(i, j, false);
|
||||
RenderSystem.bindTexture(pFramebuffer.getColorTextureId());
|
||||
nativeimage.downloadTexture(0, true);
|
||||
nativeimage.flipY();
|
||||
return nativeimage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a unique PNG file in the given directory named by a timestamp. Handles cases where the timestamp alone is
|
||||
* not enough to create a uniquely named file, though it still might suffer from an unlikely race condition where the
|
||||
* filename was unique when this method was called, but another process or thread created a file at the same path
|
||||
* immediately after this method returned.
|
||||
*/
|
||||
private static File getFile(File pGameDirectory) {
|
||||
String s = Util.getFilenameFormattedDateTime();
|
||||
int i = 1;
|
||||
|
||||
while(true) {
|
||||
File file1 = new File(pGameDirectory, s + (i == 1 ? "" : "_" + i) + ".png");
|
||||
if (!file1.exists()) {
|
||||
return file1;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
public Screenshot(File pGameDirectory, int pWidth, int pHeight, int pRowHeight) throws IOException {
|
||||
this.width = pWidth;
|
||||
this.height = pHeight;
|
||||
this.rowHeight = pRowHeight;
|
||||
File file1 = new File(pGameDirectory, "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)(pWidth % 256);
|
||||
abyte[13] = (byte)(pWidth / 256);
|
||||
abyte[14] = (byte)(pHeight % 256);
|
||||
abyte[15] = (byte)(pHeight / 256);
|
||||
abyte[16] = 24;
|
||||
this.bytes = new byte[pWidth * pRowHeight * 3];
|
||||
this.outputStream = new DataOutputStream(new FileOutputStream(this.file));
|
||||
this.outputStream.write(abyte);
|
||||
}
|
||||
|
||||
public void addRegion(ByteBuffer pBuffer, int pWidth, int pHeight, int pRowWidth, int pRowHeight) {
|
||||
int i = pRowWidth;
|
||||
int j = pRowHeight;
|
||||
if (pRowWidth > this.width - pWidth) {
|
||||
i = this.width - pWidth;
|
||||
}
|
||||
|
||||
if (pRowHeight > this.height - pHeight) {
|
||||
j = this.height - pHeight;
|
||||
}
|
||||
|
||||
this.rowHeight = j;
|
||||
|
||||
for(int k = 0; k < j; ++k) {
|
||||
pBuffer.position((pRowHeight - j) * pRowWidth * 3 + k * pRowWidth * 3);
|
||||
int l = (pWidth + k * this.width) * 3;
|
||||
pBuffer.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;
|
||||
}
|
||||
}
|
||||
+486
@@ -0,0 +1,486 @@
|
||||
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 pWidthProvider) {
|
||||
this.widthProvider = pWidthProvider;
|
||||
}
|
||||
|
||||
public float stringWidth(@Nullable String pContent) {
|
||||
if (pContent == null) {
|
||||
return 0.0F;
|
||||
} else {
|
||||
MutableFloat mutablefloat = new MutableFloat();
|
||||
StringDecomposer.iterateFormatted(pContent, 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 pContent) {
|
||||
MutableFloat mutablefloat = new MutableFloat();
|
||||
StringDecomposer.iterateFormatted(pContent, 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 pContent) {
|
||||
MutableFloat mutablefloat = new MutableFloat();
|
||||
pContent.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 pContent, int pMaxWidth, Style pStyle) {
|
||||
StringSplitter.WidthLimitedCharSink stringsplitter$widthlimitedcharsink = new StringSplitter.WidthLimitedCharSink((float)pMaxWidth);
|
||||
StringDecomposer.iterate(pContent, pStyle, stringsplitter$widthlimitedcharsink);
|
||||
return stringsplitter$widthlimitedcharsink.getPosition();
|
||||
}
|
||||
|
||||
public String plainHeadByWidth(String pContent, int pMaxWidth, Style pStyle) {
|
||||
return pContent.substring(0, this.plainIndexAtWidth(pContent, pMaxWidth, pStyle));
|
||||
}
|
||||
|
||||
public String plainTailByWidth(String pContent, int pMaxWidth, Style pStyle) {
|
||||
MutableFloat mutablefloat = new MutableFloat();
|
||||
MutableInt mutableint = new MutableInt(pContent.length());
|
||||
StringDecomposer.iterateBackwards(pContent, pStyle, (p_92407_, p_92408_, p_92409_) -> {
|
||||
float f = mutablefloat.addAndGet(this.widthProvider.getWidth(p_92409_, p_92408_));
|
||||
if (f > (float)pMaxWidth) {
|
||||
return false;
|
||||
} else {
|
||||
mutableint.setValue(p_92407_);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return pContent.substring(mutableint.intValue());
|
||||
}
|
||||
|
||||
public int formattedIndexByWidth(String pContent, int pMaxWidth, Style pStyle) {
|
||||
StringSplitter.WidthLimitedCharSink stringsplitter$widthlimitedcharsink = new StringSplitter.WidthLimitedCharSink((float)pMaxWidth);
|
||||
StringDecomposer.iterateFormatted(pContent, pStyle, stringsplitter$widthlimitedcharsink);
|
||||
return stringsplitter$widthlimitedcharsink.getPosition();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Style componentStyleAtWidth(FormattedText pContent, int pMaxWidth) {
|
||||
StringSplitter.WidthLimitedCharSink stringsplitter$widthlimitedcharsink = new StringSplitter.WidthLimitedCharSink((float)pMaxWidth);
|
||||
return pContent.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 pContent, int pMaxWidth) {
|
||||
StringSplitter.WidthLimitedCharSink stringsplitter$widthlimitedcharsink = new StringSplitter.WidthLimitedCharSink((float)pMaxWidth);
|
||||
MutableObject<Style> mutableobject = new MutableObject<>();
|
||||
pContent.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 pContent, int pMaxWidth, Style pStyle) {
|
||||
return pContent.substring(0, this.formattedIndexByWidth(pContent, pMaxWidth, pStyle));
|
||||
}
|
||||
|
||||
public FormattedText headByWidth(FormattedText pContent, int pMaxWidth, Style pStyle) {
|
||||
final StringSplitter.WidthLimitedCharSink stringsplitter$widthlimitedcharsink = new StringSplitter.WidthLimitedCharSink((float)pMaxWidth);
|
||||
return pContent.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();
|
||||
}
|
||||
}
|
||||
}, pStyle).orElse(pContent);
|
||||
}
|
||||
|
||||
public int findLineBreak(String pContent, int pMaxWidth, Style pStyle) {
|
||||
StringSplitter.LineBreakFinder stringsplitter$linebreakfinder = new StringSplitter.LineBreakFinder((float)pMaxWidth);
|
||||
StringDecomposer.iterateFormatted(pContent, pStyle, stringsplitter$linebreakfinder);
|
||||
return stringsplitter$linebreakfinder.getSplitPosition();
|
||||
}
|
||||
|
||||
public static int getWordPosition(String pContent, int pSkipCount, int pCursorPoint, boolean pIncludeWhitespace) {
|
||||
int i = pCursorPoint;
|
||||
boolean flag = pSkipCount < 0;
|
||||
int j = Math.abs(pSkipCount);
|
||||
|
||||
for(int k = 0; k < j; ++k) {
|
||||
if (flag) {
|
||||
while(pIncludeWhitespace && i > 0 && (pContent.charAt(i - 1) == ' ' || pContent.charAt(i - 1) == '\n')) {
|
||||
--i;
|
||||
}
|
||||
|
||||
while(i > 0 && pContent.charAt(i - 1) != ' ' && pContent.charAt(i - 1) != '\n') {
|
||||
--i;
|
||||
}
|
||||
} else {
|
||||
int l = pContent.length();
|
||||
int i1 = pContent.indexOf(32, i);
|
||||
int j1 = pContent.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(pIncludeWhitespace && i < l && (pContent.charAt(i) == ' ' || pContent.charAt(i) == '\n')) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public void splitLines(String pContent, int pMaxWidth, Style pStyle, boolean pWithNewLines, StringSplitter.LinePosConsumer pLinePos) {
|
||||
int i = 0;
|
||||
int j = pContent.length();
|
||||
|
||||
StringSplitter.LineBreakFinder stringsplitter$linebreakfinder;
|
||||
for(Style style = pStyle; i < j; style = stringsplitter$linebreakfinder.getSplitStyle()) {
|
||||
stringsplitter$linebreakfinder = new StringSplitter.LineBreakFinder((float)pMaxWidth);
|
||||
boolean flag = StringDecomposer.iterateFormatted(pContent, i, style, pStyle, stringsplitter$linebreakfinder);
|
||||
if (flag) {
|
||||
pLinePos.accept(style, i, j);
|
||||
break;
|
||||
}
|
||||
|
||||
int k = stringsplitter$linebreakfinder.getSplitPosition();
|
||||
char c0 = pContent.charAt(k);
|
||||
int l = c0 != '\n' && c0 != ' ' ? k : k + 1;
|
||||
pLinePos.accept(style, i, pWithNewLines ? l : k);
|
||||
i = l;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<FormattedText> splitLines(String pContent, int pMaxWidth, Style pStyle) {
|
||||
List<FormattedText> list = Lists.newArrayList();
|
||||
this.splitLines(pContent, pMaxWidth, pStyle, false, (p_92373_, p_92374_, p_92375_) -> {
|
||||
list.add(FormattedText.of(pContent.substring(p_92374_, p_92375_), p_92373_));
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<FormattedText> splitLines(FormattedText pContent, int pMaxWidth, Style pStyle) {
|
||||
List<FormattedText> list = Lists.newArrayList();
|
||||
this.splitLines(pContent, pMaxWidth, pStyle, (p_92378_, p_92379_) -> {
|
||||
list.add(p_92378_);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<FormattedText> splitLines(FormattedText pContent, int pMaxWidth, Style pStyle, FormattedText pPrefix) {
|
||||
List<FormattedText> list = Lists.newArrayList();
|
||||
this.splitLines(pContent, pMaxWidth, pStyle, (p_168619_, p_168620_) -> {
|
||||
list.add(p_168620_ ? FormattedText.composite(pPrefix, p_168619_) : p_168619_);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public void splitLines(FormattedText pContent, int pMaxWidth, Style pStyle, BiConsumer<FormattedText, Boolean> pSplitifier) {
|
||||
List<StringSplitter.LineComponent> list = Lists.newArrayList();
|
||||
pContent.visit((p_92382_, p_92383_) -> {
|
||||
if (!p_92383_.isEmpty()) {
|
||||
list.add(new StringSplitter.LineComponent(p_92383_, p_92382_));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}, pStyle);
|
||||
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)pMaxWidth);
|
||||
|
||||
for(StringSplitter.LineComponent stringsplitter$linecomponent : stringsplitter$flatcomponents.parts) {
|
||||
boolean flag3 = StringDecomposer.iterateFormatted(stringsplitter$linecomponent.contents, 0, stringsplitter$linecomponent.style, pStyle, 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);
|
||||
pSplitifier.accept(formattedtext, flag2);
|
||||
flag2 = !flag4;
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
|
||||
stringsplitter$linebreakfinder.addToOffset(stringsplitter$linecomponent.contents.length());
|
||||
}
|
||||
}
|
||||
|
||||
FormattedText formattedtext1 = stringsplitter$flatcomponents.getRemainder();
|
||||
if (formattedtext1 != null) {
|
||||
pSplitifier.accept(formattedtext1, flag2);
|
||||
} else if (flag1) {
|
||||
pSplitifier.accept(FormattedText.EMPTY, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class FlatComponents {
|
||||
final List<StringSplitter.LineComponent> parts;
|
||||
private String flatParts;
|
||||
|
||||
public FlatComponents(List<StringSplitter.LineComponent> pParts) {
|
||||
this.parts = pParts;
|
||||
this.flatParts = pParts.stream().map((p_92459_) -> {
|
||||
return p_92459_.contents;
|
||||
}).collect(Collectors.joining());
|
||||
}
|
||||
|
||||
public char charAt(int pCodePoint) {
|
||||
return this.flatParts.charAt(pCodePoint);
|
||||
}
|
||||
|
||||
public FormattedText splitAt(int pBegin, int pEnd, Style pStyle) {
|
||||
ComponentCollector componentcollector = new ComponentCollector();
|
||||
ListIterator<StringSplitter.LineComponent> listiterator = this.parts.listIterator();
|
||||
int i = pBegin;
|
||||
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 += pEnd;
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
if (i <= j) {
|
||||
String s2 = s.substring(i);
|
||||
if (s2.isEmpty()) {
|
||||
listiterator.remove();
|
||||
} else {
|
||||
listiterator.set(new StringSplitter.LineComponent(s2, pStyle));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
listiterator.remove();
|
||||
i -= j;
|
||||
}
|
||||
}
|
||||
|
||||
this.flatParts = this.flatParts.substring(pBegin + pEnd);
|
||||
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 pMaxWidth) {
|
||||
this.maxWidth = Math.max(pMaxWidth, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a single code point from a {@link net.minecraft.util.FormattedCharSequence}.
|
||||
* @return {@code true} to accept more characters, {@code false} to stop traversing the sequence.
|
||||
* @param pPositionInCurrentSequence Contains the relative position of the character in the current sub-sequence.
|
||||
* If multiple formatted char sequences have been combined, this value will reset to {@code 0} after each sequence
|
||||
* has been fully consumed.
|
||||
*/
|
||||
public boolean accept(int pPositionInCurrentSequence, Style pStyle, int pCodePoint) {
|
||||
int i = pPositionInCurrentSequence + this.offset;
|
||||
switch (pCodePoint) {
|
||||
case 10:
|
||||
return this.finishIteration(i, pStyle);
|
||||
case 32:
|
||||
this.lastSpace = i;
|
||||
this.lastSpaceStyle = pStyle;
|
||||
default:
|
||||
float f = StringSplitter.this.widthProvider.getWidth(pCodePoint, pStyle);
|
||||
this.width += f;
|
||||
if (this.hadNonZeroWidthChar && this.width > this.maxWidth) {
|
||||
return this.lastSpace != -1 ? this.finishIteration(this.lastSpace, this.lastSpaceStyle) : this.finishIteration(i, pStyle);
|
||||
} else {
|
||||
this.hadNonZeroWidthChar |= f != 0.0F;
|
||||
this.nextChar = i + Character.charCount(pCodePoint);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean finishIteration(int pLineBreak, Style pLineBreakStyle) {
|
||||
this.lineBreak = pLineBreak;
|
||||
this.lineBreakStyle = pLineBreakStyle;
|
||||
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 pOffset) {
|
||||
this.offset += pOffset;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class LineComponent implements FormattedText {
|
||||
final String contents;
|
||||
final Style style;
|
||||
|
||||
public LineComponent(String pContents, Style pStyle) {
|
||||
this.contents = pContents;
|
||||
this.style = pStyle;
|
||||
}
|
||||
|
||||
public <T> Optional<T> visit(FormattedText.ContentConsumer<T> pAcceptor) {
|
||||
return pAcceptor.accept(this.contents);
|
||||
}
|
||||
|
||||
public <T> Optional<T> visit(FormattedText.StyledContentConsumer<T> pAcceptor, Style pStyle) {
|
||||
return pAcceptor.accept(this.style.applyTo(pStyle), this.contents);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface LinePosConsumer {
|
||||
void accept(Style pStyle, int pCurrentPos, int pContentWidth);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class WidthLimitedCharSink implements FormattedCharSink {
|
||||
private float maxWidth;
|
||||
private int position;
|
||||
|
||||
public WidthLimitedCharSink(float pMaxWidth) {
|
||||
this.maxWidth = pMaxWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a single code point from a {@link net.minecraft.util.FormattedCharSequence}.
|
||||
* @return {@code true} to accept more characters, {@code false} to stop traversing the sequence.
|
||||
* @param pPositionInCurrentSequence Contains the relative position of the character in the current sub-sequence.
|
||||
* If multiple formatted char sequences have been combined, this value will reset to {@code 0} after each sequence
|
||||
* has been fully consumed.
|
||||
*/
|
||||
public boolean accept(int pPositionInCurrentSequence, Style pStyle, int pCodePoint) {
|
||||
this.maxWidth -= StringSplitter.this.widthProvider.getWidth(pCodePoint, pStyle);
|
||||
if (this.maxWidth >= 0.0F) {
|
||||
this.position = pPositionInCurrentSequence + Character.charCount(pCodePoint);
|
||||
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 pCodePoint, Style pStyle);
|
||||
}
|
||||
}
|
||||
+26
@@ -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 pTicksPerSecond, long pLastMs) {
|
||||
this.msPerTick = 1000.0F / pTicksPerSecond;
|
||||
this.lastMs = pLastMs;
|
||||
}
|
||||
|
||||
public int advanceTime(long pGameTime) {
|
||||
this.tickDelta = (float)(pGameTime - this.lastMs) / this.msPerTick;
|
||||
this.lastMs = pGameTime;
|
||||
this.partialTick += this.tickDelta;
|
||||
int i = (int)this.partialTick;
|
||||
this.partialTick -= (float)i;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
+32
@@ -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 pName, int pKeyCode, String pCategory, BooleanSupplier pNeedsToggle) {
|
||||
super(pName, InputConstants.Type.KEYSYM, pKeyCode, pCategory);
|
||||
this.needsToggle = pNeedsToggle;
|
||||
}
|
||||
|
||||
public void setDown(boolean pValue) {
|
||||
if (this.needsToggle.getAsBoolean()) {
|
||||
if (pValue && isConflictContextAndModifierActive()) {
|
||||
super.setDown(!this.isDown());
|
||||
}
|
||||
} else {
|
||||
super.setDown(pValue);
|
||||
}
|
||||
|
||||
}
|
||||
@Override public boolean isDown() { return this.isDown && (isConflictContextAndModifierActive() || needsToggle.getAsBoolean()); }
|
||||
|
||||
protected void reset() {
|
||||
super.setDown(false);
|
||||
}
|
||||
}
|
||||
+127
@@ -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 pName, String pUuid, String pAccessToken, Optional<String> pXuid, Optional<String> pClientId, User.Type pType) {
|
||||
if (pName == null || pName.isEmpty()) {
|
||||
pName = "MissingName";
|
||||
pUuid = pAccessToken = "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 = pName;
|
||||
this.uuid = pUuid;
|
||||
this.accessToken = pAccessToken;
|
||||
this.xuid = pXuid;
|
||||
this.clientId = pClientId;
|
||||
this.type = pType;
|
||||
}
|
||||
|
||||
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 pName) {
|
||||
this.name = pName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static User.Type byName(String pTypeName) {
|
||||
return BY_NAME.get(pTypeName.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
@@ -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 pAnimationVecCache, float pKeyframeDelta, Keyframe[] pKeyframes, int pCurrentKeyframeIdx, int pNextKeyframeIdx, float pScale);
|
||||
}
|
||||
|
||||
@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 pModelPart, Vector3f pAnimationVector);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
+42
@@ -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 pLengthInSeconds) {
|
||||
return new AnimationDefinition.Builder(pLengthInSeconds);
|
||||
}
|
||||
|
||||
private Builder(float pLengthInSeconds) {
|
||||
this.length = pLengthInSeconds;
|
||||
}
|
||||
|
||||
public AnimationDefinition.Builder looping() {
|
||||
this.looping = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnimationDefinition.Builder addAnimation(String pBone, AnimationChannel pAnimationChannel) {
|
||||
this.animationByBone.computeIfAbsent(pBone, (p_232278_) -> {
|
||||
return Lists.newArrayList();
|
||||
}).add(pAnimationChannel);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnimationDefinition build() {
|
||||
return new AnimationDefinition(this.length, this.looping, this.animationByBone);
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -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) {
|
||||
}
|
||||
+62
@@ -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<?> pModel, AnimationDefinition pAnimationDefinition, long pAccumulatedTime, float pScale, Vector3f pAnimationVecCache) {
|
||||
float f = getElapsedSeconds(pAnimationDefinition, pAccumulatedTime);
|
||||
|
||||
for(Map.Entry<String, List<AnimationChannel>> entry : pAnimationDefinition.boneAnimations().entrySet()) {
|
||||
Optional<ModelPart> optional = pModel.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(pAnimationVecCache, f2, akeyframe, i, j, pScale);
|
||||
p_288241_.target().apply(p_232330_, pAnimationVecCache);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static float getElapsedSeconds(AnimationDefinition pAnimationDefinition, long pAccumulatedTime) {
|
||||
float f = (float)pAccumulatedTime / 1000.0F;
|
||||
return pAnimationDefinition.looping() ? f % pAnimationDefinition.lengthInSeconds() : f;
|
||||
}
|
||||
|
||||
public static Vector3f posVec(float pX, float pY, float pZ) {
|
||||
return new Vector3f(pX, -pY, pZ);
|
||||
}
|
||||
|
||||
public static Vector3f degreeVec(float pXDegrees, float pYDegrees, float pZDegrees) {
|
||||
return new Vector3f(pXDegrees * ((float)Math.PI / 180F), pYDegrees * ((float)Math.PI / 180F), pZDegrees * ((float)Math.PI / 180F));
|
||||
}
|
||||
|
||||
public static Vector3f scaleVec(double pXScale, double pYScale, double pZScale) {
|
||||
return new Vector3f((float)(pXScale - 1.0D), (float)(pYScale - 1.0D), (float)(pZScale - 1.0D));
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package net.minecraft.client.animation.definitions;
|
||||
|
||||
import net.minecraft.client.animation.AnimationChannel;
|
||||
import net.minecraft.client.animation.AnimationDefinition;
|
||||
import net.minecraft.client.animation.Keyframe;
|
||||
import net.minecraft.client.animation.KeyframeAnimations;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class CamelAnimation {
|
||||
public static final AnimationDefinition CAMEL_WALK = AnimationDefinition.Builder.withLength(1.5F).looping().addAnimation("root", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 2.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -2.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 2.5F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.375F, KeyframeAnimations.degreeVec(-2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.75F, KeyframeAnimations.degreeVec(2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.125F, KeyframeAnimations.degreeVec(-2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.degreeVec(2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.75F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.4583F, KeyframeAnimations.posVec(0.0F, 4.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.75F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.75F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.75F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.2083F, KeyframeAnimations.posVec(0.0F, 4.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-20.4F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.75F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.375F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.degreeVec(-20.4F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_hind_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -0.21F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.75F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0833F, KeyframeAnimations.posVec(0.0F, 4.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.375F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.posVec(0.0F, -0.21F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.625F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.375F, KeyframeAnimations.posVec(0.0F, 4.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), newLine truncated
|
||||
public static final AnimationDefinition CAMEL_SIT = AnimationDefinition.Builder.withLength(2.0F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.3F, KeyframeAnimations.degreeVec(30.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.8F, KeyframeAnimations.degreeVec(24.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.3F, KeyframeAnimations.posVec(0.0F, 0.0F, 1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.8F, KeyframeAnimations.posVec(0.0F, -6.0F, 1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.posVec(0.0F, -19.9F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(-30.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.degreeVec(-30.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(-90.0F, 10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, -2.0F, 11.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.posVec(0.0F, -2.0F, 11.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.7F, KeyframeAnimations.posVec(0.0F, -8.4F, 11.4F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.posVec(0.0F, -20.6F, 12.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(-30.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.degreeVec(-30.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(-90.0F, -10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, -2.0F, 11.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.posVec(0.0F, -2.0F, 11.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.7F, KeyframeAnimations.posVec(0.0F, -8.4F, 11.4F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.posVec(0.0F, -20.6F, 12.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.degreeVec(-10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.7F, KeyframeAnimations.degreeVec(-15.0F, -3.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.9F, KeyframeAnimations.degreeVec(-65.0F, -9.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(-90.0F, -15.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_hind_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.7F, KeyframeAnimations.posVec(1.0F, -0.62F, 0.25F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.9F, KeyframeAnimations.posVec(0.5F, -11.25F, 2.5F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.posVec(1.0F, -20.5F, 5.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframLine truncated
|
||||
public static final AnimationDefinition CAMEL_SIT_POSE = AnimationDefinition.Builder.withLength(1.0F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -19.9F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, -19.9F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.0F, 10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(-90.0F, 10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -20.6F, 12.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, -20.6F, 12.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.0F, -10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(-90.0F, -10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -20.6F, 12.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, -20.6F, 12.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.0F, -15.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(-90.0F, -15.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_hind_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(1.0F, -20.5F, 5.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(1.0F, -20.5F, 5.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.0F, 15.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(-90.0F, 15.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(-1.0F, -20.5F, 5.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(-1.0F, -20.5F, 5.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("tail", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(50.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(50.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).build();
|
||||
public static final AnimationDefinition CAMEL_STANDUP = AnimationDefinition.Builder.withLength(2.6F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.7F, KeyframeAnimations.degreeVec(-17.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.8F, KeyframeAnimations.degreeVec(-17.83F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.3F, KeyframeAnimations.degreeVec(-5.83F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.6F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -19.9F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.7F, KeyframeAnimations.posVec(0.0F, -19.9F, -3.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.4F, KeyframeAnimations.posVec(0.0F, -12.76F, -4.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.8F, KeyframeAnimations.posVec(0.0F, -10.1F, -4.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.3F, KeyframeAnimations.posVec(0.0F, -2.9F, -2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.6F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.0F, 10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(-90.0F, 10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1F, KeyframeAnimations.degreeVec(-49.06F, 10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.8F, KeyframeAnimations.degreeVec(-22.5F, 10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.3F, KeyframeAnimations.degreeVec(-25.0F, 10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.6F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -20.6F, 12.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, -20.6F, 8.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1F, KeyframeAnimations.posVec(0.0F, -7.14F, 4.42F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.8F, KeyframeAnimations.posVec(0.0F, -1.27F, -1.33F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.3F, KeyframeAnimations.posVec(0.0F, -1.27F, -0.33F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.6F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.0F, -10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(-90.0F, -10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1F, KeyframeAnimations.degreeVec(-49.06F, -10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.8F, KeyframeAnimations.degreeVec(-22.5F, -10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.3F, KeyframeAnimations.degreeVec(-25.0F, -10.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.6F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -20.6F, 12.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, -20.6F, 8.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1F, KeyframeAnimations.posVec(0.0F, -7.14F, 4.42F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.8F, KeyframeAnimations.posVec(0.0F, -1.27F, -1.33F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.3F, KeyframeAnimations.posVec(0.0F, -1.27F, -0.33F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.6F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.0F, -15.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.3F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.6F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1F, KeyframeAnimations.degreeVec(-60.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.9F, KeyfraLine truncated
|
||||
public static final AnimationDefinition CAMEL_DASH = AnimationDefinition.Builder.withLength(0.5F).looping().addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(5.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(5.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("tail", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(67.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.125F, KeyframeAnimations.degreeVec(112.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.degreeVec(67.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.375F, KeyframeAnimations.degreeVec(112.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.5F, KeyframeAnimations.degreeVec(67.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.degreeVec(10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.375F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.5F, KeyframeAnimations.degreeVec(10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(44.97272F, 1.76749F, -1.76833F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.125F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.degreeVec(44.97272F, 1.76749F, -1.76833F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.375F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.5F, KeyframeAnimations.degreeVec(44.97272F, 1.76749F, -1.76833F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.125F, KeyframeAnimations.degreeVec(44.97272F, -1.76749F, 1.76833F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.375F, KeyframeAnimations.degreeVec(44.97272F, -1.76749F, 1.76833F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.5F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.125F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.degreeVec(90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.375F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.5F, KeyframeAnimations.degreeVec(90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.125F, KeyframeAnimations.degreeVec(90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.375F, KeyframeAnimations.degreeVec(90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.5F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, -67.5F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, -67.5F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 67.5F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, 67.5F, 0.0F), AnimationChannel.InterpolationLine truncated
|
||||
public static final AnimationDefinition CAMEL_IDLE = AnimationDefinition.Builder.withLength(4.0F).addAnimation("tail", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(5.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0F, KeyframeAnimations.degreeVec(4.98107F, 0.43523F, -4.98107F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.degreeVec(4.9872F, -0.29424F, 3.36745F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.0F, KeyframeAnimations.degreeVec(5.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.0F, KeyframeAnimations.degreeVec(-2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(2.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -45.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.625F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.75F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -45.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.875F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -45.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(2.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 45.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.625F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.75F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 45.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.875F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 45.0F), AnimationChannel.Interpolations.CATMULLROM))).build();
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package net.minecraft.client.animation.definitions;
|
||||
|
||||
import net.minecraft.client.animation.AnimationChannel;
|
||||
import net.minecraft.client.animation.AnimationDefinition;
|
||||
import net.minecraft.client.animation.Keyframe;
|
||||
import net.minecraft.client.animation.KeyframeAnimations;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class FrogAnimation {
|
||||
public static final AnimationDefinition FROG_CROAK = AnimationDefinition.Builder.withLength(3.0F).addAnimation("croaking_body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.375F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.4167F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.4583F, KeyframeAnimations.posVec(0.0F, 1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.9583F, KeyframeAnimations.posVec(0.0F, 1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(3.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("croaking_body", new AnimationChannel(AnimationChannel.Targets.SCALE, new Keyframe(0.0F, KeyframeAnimations.scaleVec(0.0D, 0.0D, 0.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.375F, KeyframeAnimations.scaleVec(0.0D, 0.0D, 0.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.4167F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.4583F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5417F, KeyframeAnimations.scaleVec((double)1.3F, (double)2.1F, (double)1.6F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.625F, KeyframeAnimations.scaleVec((double)1.3F, (double)2.1F, (double)1.6F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.7083F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.25F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.3333F, KeyframeAnimations.scaleVec((double)1.3F, (double)2.1F, (double)1.6F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.4167F, KeyframeAnimations.scaleVec((double)1.3F, (double)2.1F, (double)1.6F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.5F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.5833F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.6667F, KeyframeAnimations.scaleVec((double)1.3F, (double)2.1F, (double)1.6F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.875F, KeyframeAnimations.scaleVec((double)1.3F, (double)2.1F, (double)1.6F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.9583F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(3.0F, KeyframeAnimations.scaleVec(0.0D, 0.0D, 0.0D), AnimationChannel.Interpolations.LINEAR))).build();
|
||||
public static final AnimationDefinition FROG_WALK = AnimationDefinition.Builder.withLength(1.25F).looping().addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, -5.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.2917F, KeyframeAnimations.degreeVec(7.5F, -2.67F, -7.5F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.625F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.7917F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.125F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.25F, KeyframeAnimations.degreeVec(0.0F, -5.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.1F, -2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.2917F, KeyframeAnimations.posVec(-0.5F, -0.25F, -0.13F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.625F, KeyframeAnimations.posVec(-0.5F, 0.1F, 2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.9583F, KeyframeAnimations.posVec(0.5F, 1.0F, -0.11F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.25F, KeyframeAnimations.posVec(0.0F, 0.1F, -2.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.125F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.4583F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.625F, KeyframeAnimations.degreeVec(0.0F, 5.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.9583F, KeyframeAnimations.degreeVec(7.5F, 2.33F, 7.5F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.5F, 0.1F, 2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.2917F, KeyframeAnimations.posVec(-0.5F, 1.0F, 0.12F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.625F, KeyframeAnimations.posVec(0.0F, 0.1F, -2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.9583F, KeyframeAnimations.posVec(0.5F, -0.25F, -0.13F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.25F, KeyframeAnimations.posVec(0.5F, 0.1F, 2.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.1667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.2917F, KeyframeAnimations.degreeVec(45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.625F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.7917F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.1F, 1.2F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.1667F, KeyframeAnimations.posVec(0.0F, 0.1F, 2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.4583F, KeyframeAnimations.posVec(0.0F, 2.0F, 1.06F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.7917F, KeyframeAnimations.posVec(0.0F, 0.1F, -1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.25F, KeyframeAnimations.posVec(0.0F, 0.1F, 1.2F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-33.75F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.0417F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.1667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.7917F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.9583F, KeyframeAnimations.degreeVec(45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.25F, KeyframeAnimations.degreeVec(-33.75F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_leg", Line truncated
|
||||
public static final AnimationDefinition FROG_JUMP = AnimationDefinition.Builder.withLength(0.5F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-56.14F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(-56.14F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-56.14F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(-56.14F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).build();
|
||||
public static final AnimationDefinition FROG_TONGUE = AnimationDefinition.Builder.withLength(0.5F).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.0833F, KeyframeAnimations.degreeVec(-60.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.4167F, KeyframeAnimations.degreeVec(-60.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.SCALE, new Keyframe(0.0F, KeyframeAnimations.degreeVec(1.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.0833F, KeyframeAnimations.degreeVec(0.998F, 1.0F, 1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.4167F, KeyframeAnimations.degreeVec(0.998F, 1.0F, 1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(1.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("tongue", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.0833F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.4167F, KeyframeAnimations.degreeVec(-18.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("tongue", new AnimationChannel(AnimationChannel.Targets.SCALE, new Keyframe(0.0833F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.1667F, KeyframeAnimations.scaleVec(0.5D, 1.0D, 5.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.4167F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR))).build();
|
||||
public static final AnimationDefinition FROG_SWIM = AnimationDefinition.Builder.withLength(1.04167F).looping().addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.3333F, KeyframeAnimations.degreeVec(10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.6667F, KeyframeAnimations.degreeVec(-10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0417F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(90.0F, 22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.4583F, KeyframeAnimations.degreeVec(45.0F, 22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.6667F, KeyframeAnimations.degreeVec(-22.5F, -22.5F, -22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.875F, KeyframeAnimations.degreeVec(-45.0F, -22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.9583F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0417F, KeyframeAnimations.degreeVec(90.0F, 22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -0.64F, 2.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.4583F, KeyframeAnimations.posVec(0.0F, -0.64F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.6667F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.875F, KeyframeAnimations.posVec(0.0F, -0.27F, -1.14F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.9583F, KeyframeAnimations.posVec(0.0F, -1.45F, 0.43F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0417F, KeyframeAnimations.posVec(0.0F, -0.64F, 2.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(90.0F, -22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.4583F, KeyframeAnimations.degreeVec(45.0F, -22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.6667F, KeyframeAnimations.degreeVec(-22.5F, 22.5F, 22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.875F, KeyframeAnimations.degreeVec(-45.0F, 22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.9583F, KeyframeAnimations.degreeVec(22.5F, 0.0F, -22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0417F, KeyframeAnimations.degreeVec(90.0F, -22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -0.64F, 2.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.4583F, KeyframeAnimations.posVec(0.0F, -0.64F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.6667F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.875F, KeyframeAnimations.posVec(0.0F, -0.27F, -1.14F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.9583F, KeyframeAnimations.posVec(0.0F, -1.45F, 0.43F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0417F, KeyframeAnimations.posVec(0.0F, -0.64F, 2.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.degreeVec(90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.4583F, KeyframeAnimations.degreeVec(67.5F, -45.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.7917F, KeyframeAnimations.degreeVec(90.0F, 45.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.9583F, KeyframeAnimations.degreeVec(90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0417F, KeyframeAnimations.degreeVec(90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(-2.5F, 0.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.posVec(-2.0F, 0.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.4583F, KeyframeAnimations.posVec(1.0F, -2.0F, -1.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.7917F, KeyframeAnimations.posVec(0.58F,Line truncated
|
||||
public static final AnimationDefinition FROG_IDLE_WATER = AnimationDefinition.Builder.withLength(3.0F).looping().addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.625F, KeyframeAnimations.degreeVec(-10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.2083F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -45.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -22.5F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(-1.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.2083F, KeyframeAnimations.posVec(-1.0F, -0.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.posVec(-1.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.2083F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 45.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 22.5F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(1.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.2083F, KeyframeAnimations.posVec(1.0F, -0.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.posVec(1.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(22.5F, -22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0F, KeyframeAnimations.degreeVec(22.5F, -22.5F, -45.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.degreeVec(22.5F, -22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, -1.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(22.5F, 22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0F, KeyframeAnimations.degreeVec(22.5F, 22.5F, 45.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.degreeVec(22.5F, 22.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, -1.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM))).build();
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package net.minecraft.client.animation.definitions;
|
||||
|
||||
import net.minecraft.client.animation.AnimationChannel;
|
||||
import net.minecraft.client.animation.AnimationDefinition;
|
||||
import net.minecraft.client.animation.Keyframe;
|
||||
import net.minecraft.client.animation.KeyframeAnimations;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class SnifferAnimation {
|
||||
public static final AnimationDefinition BABY_TRANSFORM = AnimationDefinition.Builder.withLength(0.0F).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.SCALE, new Keyframe(0.0F, KeyframeAnimations.scaleVec((double)1.2F, (double)1.2F, (double)1.2F), AnimationChannel.Interpolations.LINEAR))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.LINEAR))).build();
|
||||
public static final AnimationDefinition SNIFFER_SNIFFSNIFF = AnimationDefinition.Builder.withLength(8.0F).looping().addAnimation("nose", new AnimationChannel(AnimationChannel.Targets.SCALE, new Keyframe(0.0F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5417F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5833F, KeyframeAnimations.scaleVec(1.0D, 0.5D, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.6667F, KeyframeAnimations.scaleVec(1.0D, 2.5D, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.7917F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.9167F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0F, KeyframeAnimations.scaleVec(1.0D, 3.0D, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.125F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR))).build();
|
||||
public static final AnimationDefinition SNIFFER_LONGSNIFF = AnimationDefinition.Builder.withLength(1.0F).addAnimation("nose", new AnimationChannel(AnimationChannel.Targets.SCALE, new Keyframe(0.0F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.0833F, KeyframeAnimations.scaleVec(1.0D, (double)0.7F, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.125F, KeyframeAnimations.scaleVec(1.0D, 3.0D, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.scaleVec(1.0D, 3.0D, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.7083F, KeyframeAnimations.scaleVec(1.0D, 4.0D, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.8333F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.125F, KeyframeAnimations.degreeVec(-5.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.875F, KeyframeAnimations.degreeVec(-20.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).build();
|
||||
public static final AnimationDefinition SNIFFER_WALK = AnimationDefinition.Builder.withLength(2.0F).looping().addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5833F, KeyframeAnimations.degreeVec(35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(-35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 3.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.75F, KeyframeAnimations.posVec(0.0F, 4.0F, -1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1667F, KeyframeAnimations.posVec(0.0F, 0.0F, -1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 3.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_mid_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-7.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.1667F, KeyframeAnimations.degreeVec(-35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.3333F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.75F, KeyframeAnimations.degreeVec(35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(-7.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_mid_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 2.67F, -0.67F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.1667F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.3333F, KeyframeAnimations.posVec(0.0F, 0.0F, -2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1667F, KeyframeAnimations.posVec(0.0F, 0.0F, 3.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.9167F, KeyframeAnimations.posVec(0.0F, 4.0F, -1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.posVec(0.0F, 2.67F, -0.67F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5833F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(25.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1667F, KeyframeAnimations.degreeVec(35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5833F, KeyframeAnimations.degreeVec(-35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.75F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, -0.5F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5833F, KeyframeAnimations.posVec(0.0F, 0.0F, 2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, 2.22F, 0.78F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.3333F, KeyframeAnimations.posVec(0.0F, 4.0F, -1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5833F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.75F, KeyframeAnimations.posVec(0.0F, 0.0F, -2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.posVec(0.0F, 0.0F, -0.5F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.1667F, KeyframeAnimLine truncated
|
||||
public static final AnimationDefinition SNIFFER_SNIFF_SEARCH = AnimationDefinition.Builder.withLength(2.0F).looping().addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5833F, KeyframeAnimations.degreeVec(35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(-35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 3.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.75F, KeyframeAnimations.posVec(0.0F, 4.0F, -1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1667F, KeyframeAnimations.posVec(0.0F, 0.0F, -1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 3.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_mid_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-7.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.1667F, KeyframeAnimations.degreeVec(-35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.3333F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.75F, KeyframeAnimations.degreeVec(35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(-7.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_mid_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 2.67F, -0.67F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.1667F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.3333F, KeyframeAnimations.posVec(0.0F, 0.0F, -2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1667F, KeyframeAnimations.posVec(0.0F, 0.0F, 3.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.9167F, KeyframeAnimations.posVec(0.0F, 4.0F, -1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.posVec(0.0F, 2.67F, -0.67F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5833F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(25.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.1667F, KeyframeAnimations.degreeVec(35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5833F, KeyframeAnimations.degreeVec(-35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.75F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, -0.5F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5833F, KeyframeAnimations.posVec(0.0F, 0.0F, 2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, 2.22F, 0.78F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.3333F, KeyframeAnimations.posVec(0.0F, 4.0F, -1.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5833F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.75F, KeyframeAnimations.posVec(0.0F, 0.0F, -2.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.posVec(0.0F, 0.0F, -0.5F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(-35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.1667F, KeyfLine truncated
|
||||
public static final AnimationDefinition SNIFFER_DIG = AnimationDefinition.Builder.withLength(8.0F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(1.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.3333F, KeyframeAnimations.degreeVec(-5.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.5F, KeyframeAnimations.degreeVec(2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(3.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(3.5F, KeyframeAnimations.degreeVec(2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(4.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(4.5F, KeyframeAnimations.degreeVec(2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(5.6667F, KeyframeAnimations.degreeVec(5.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(5.8333F, KeyframeAnimations.degreeVec(-2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(6.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.3333F, KeyframeAnimations.posVec(0.0F, 1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.posVec(0.0F, -7.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.SCALE, new Keyframe(0.0F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5417F, KeyframeAnimations.scaleVec((double)1.04F, (double)0.98F, (double)1.02F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5833F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.1667F, KeyframeAnimations.degreeVec(10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.4167F, KeyframeAnimations.degreeVec(-10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5833F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.875F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.0833F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.5F, KeyframeAnimations.degreeVec(47.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.6667F, KeyframeAnimations.degreeVec(38.44F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.875F, KeyframeAnimations.degreeVec(10.95951F, 13.57454F, -14.93501F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.2083F, KeyframeAnimations.degreeVec(47.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.5833F, KeyframeAnimations.degreeVec(55.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.7917F, KeyframeAnimations.degreeVec(4.2932F, -16.187F, 10.90042F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.125F, KeyframeAnimations.degreeVec(47.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.4167F, KeyframeAnimations.degreeVec(54.71135F, 7.98009F, -5.56662F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.5F, KeyframeAnimations.degreeVec(55.72895F, -6.77684F, 4.46197F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.5833F, KeyframeAnimations.degreeVec(54.71135F, 7.98009F, -5.56662F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.6667F, KeyframeAnimations.degreeVec(55.72895F, -6.77684F, 4.46197F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.75F, KeyframeAnimations.degreeVec(54.71135F, 7.98009F, -5.56662F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.8333F, KeyframeAnimations.degreeVec(55.72895F, -6.77684F, 4.46197F), AnimationChannel.Interpolations.CATLine truncated
|
||||
public static final AnimationDefinition SNIFFER_STAND_UP = AnimationDefinition.Builder.withLength(3.0F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.75F, KeyframeAnimations.degreeVec(2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.degreeVec(-2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.7083F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.25F, KeyframeAnimations.posVec(0.0F, -7.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.75F, KeyframeAnimations.posVec(0.0F, -7.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.7083F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.3333F, KeyframeAnimations.degreeVec(-5.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.7083F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.0F, KeyframeAnimations.degreeVec(10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.375F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.375F, KeyframeAnimations.posVec(0.0F, 1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -30.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.9167F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -30.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.2083F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -5.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 30.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.9167F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 30.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.2083F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 5.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 90.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.4583F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(-4.0F, -5.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.2083F, KeyframeAnimations.posVec(6.0F, -5.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.4583F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_mid_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0833F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 90.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.5833F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_mid_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0833F, KeyframeAnimations.posVec(-4.0F, -5.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.3333F, KeyframeAnimations.posVec(6.0F, -5.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.5833F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.1667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 90.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.6667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_hind_leg", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.1667F, KeyframeAnimations.posVec(-4.0F, -5.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.4167F, KeyframeAnimations.posVec(6.0F, -5.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), neLine truncated
|
||||
public static final AnimationDefinition SNIFFER_BABY_FALL = AnimationDefinition.Builder.withLength(4.0F).addAnimation("bone", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(1.0F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.degreeVec(-98.91F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.9583F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.7083F, KeyframeAnimations.degreeVec(-68.28F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.9583F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("bone", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, 20.0F, 17.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.posVec(0.0F, 25.19F, 20.37F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.9583F, KeyframeAnimations.posVec(0.0F, 20.0F, 17.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.7083F, KeyframeAnimations.posVec(0.0F, 17.06F, 11.25F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.8333F, KeyframeAnimations.posVec(0.0F, 9.85F, 2.2F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.9583F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.SCALE, new Keyframe(1.0F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.9583F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.9167F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR), new Keyframe(3.0F, KeyframeAnimations.scaleVec((double)1.05F, (double)0.95F, (double)1.05F), AnimationChannel.Interpolations.LINEAR), new Keyframe(3.0833F, KeyframeAnimations.scaleVec(1.0D, 1.0D, 1.0D), AnimationChannel.Interpolations.LINEAR))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.2917F, KeyframeAnimations.degreeVec(17.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.9583F, KeyframeAnimations.degreeVec(-10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.75F, KeyframeAnimations.degreeVec(35.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.9167F, KeyframeAnimations.degreeVec(-30.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(3.0417F, KeyframeAnimations.degreeVec(7.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(3.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, 7.0F, 19.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.5F, KeyframeAnimations.posVec(0.0F, 7.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.9583F, KeyframeAnimations.posVec(0.0F, 7.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.75F, KeyframeAnimations.posVec(0.0F, 7.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.9583F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("left_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -5.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.9583F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -5.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.7083F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -5.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.9167F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -90.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -5.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 5.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(1.9583F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 5.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.7083F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 5.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(2.9167F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 90.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 5.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_front_leg", new AnimationChannel(AnimationChannel.TargeLine truncated
|
||||
public static final AnimationDefinition SNIFFER_HAPPY = AnimationDefinition.Builder.withLength(2.0F).looping().addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), new Keyframe(0.5F, KeyframeAnimations.degreeVec(-32.00206F, 19.3546F, -11.70092F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5F, KeyframeAnimations.degreeVec(-32.00206F, -19.3546F, 11.70092F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.75F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -67.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.9583F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -67.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.2917F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.75F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 67.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.9583F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 67.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.2917F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).build();
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package net.minecraft.client.animation.definitions;
|
||||
|
||||
import net.minecraft.client.animation.AnimationChannel;
|
||||
import net.minecraft.client.animation.AnimationDefinition;
|
||||
import net.minecraft.client.animation.Keyframe;
|
||||
import net.minecraft.client.animation.KeyframeAnimations;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class WardenAnimation {
|
||||
public static final AnimationDefinition WARDEN_EMERGE = AnimationDefinition.Builder.withLength(6.68F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.52F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -22.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.2F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -7.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.68F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 10.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.8F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 10.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.28F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 10.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.88F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 10.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.76F, KeyframeAnimations.degreeVec(25.0F, 0.0F, -7.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.92F, KeyframeAnimations.degreeVec(35.0F, 0.0F, -7.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.08F, KeyframeAnimations.degreeVec(25.0F, 0.0F, -7.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.44F, KeyframeAnimations.degreeVec(47.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.56F, KeyframeAnimations.degreeVec(47.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.68F, KeyframeAnimations.degreeVec(47.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(5.0F, KeyframeAnimations.degreeVec(70.0F, 0.0F, 2.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(5.8F, KeyframeAnimations.degreeVec(70.0F, 0.0F, 2.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(6.64F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -63.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.52F, KeyframeAnimations.posVec(0.0F, -56.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.2F, KeyframeAnimations.posVec(0.0F, -32.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.68F, KeyframeAnimations.posVec(0.0F, -32.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.8F, KeyframeAnimations.posVec(0.0F, -32.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.28F, KeyframeAnimations.posVec(0.0F, -32.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.88F, KeyframeAnimations.posVec(0.0F, -32.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.16F, KeyframeAnimations.posVec(0.0F, -27.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.76F, KeyframeAnimations.posVec(0.0F, -14.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.92F, KeyframeAnimations.posVec(0.0F, -11.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.08F, KeyframeAnimations.posVec(0.0F, -14.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.44F, KeyframeAnimations.posVec(0.0F, -6.0F, -3.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.56F, KeyframeAnimations.posVec(0.0F, -4.0F, -3.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.68F, KeyframeAnimations.posVec(0.0F, -6.0F, -3.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(5.0F, KeyframeAnimations.posVec(0.0F, -3.0F, -4.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(5.8F, KeyframeAnimations.posVec(0.0F, -3.0F, -4.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(6.64F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.52F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.92F, KeyframeAnimations.degreeVec(0.74F, 0.0F, -40.38F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.16F, KeyframeAnimations.degreeVec(-67.5F, 0.0F, -2.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.24F, KeyframeAnimations.degreeVec(-67.5F, 0.0F, -2.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.32F, KeyframeAnimations.degreeVec(-47.5F, 0.0F, -2.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.4F, KeyframeAnimations.degreeVec(-67.5F, 0.0F, -2.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.68F, KeyframeAnimations.degreeVec(-67.5F, 0.0F, 15.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.76F, KeLine truncated
|
||||
public static final AnimationDefinition WARDEN_DIG = AnimationDefinition.Builder.withLength(5.0F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.degreeVec(4.13441F, 0.94736F, 1.2694F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.5F, KeyframeAnimations.degreeVec(50.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.7083F, KeyframeAnimations.degreeVec(54.45407F, -13.53935F, -18.14183F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0417F, KeyframeAnimations.degreeVec(59.46442F, -10.8885F, 35.7954F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.3333F, KeyframeAnimations.degreeVec(82.28261F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.625F, KeyframeAnimations.degreeVec(53.23606F, 10.04715F, -29.72932F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.2083F, KeyframeAnimations.degreeVec(-17.71739F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.5417F, KeyframeAnimations.degreeVec(112.28261F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.6667F, KeyframeAnimations.degreeVec(116.06889F, 5.11581F, -24.50117F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.8333F, KeyframeAnimations.degreeVec(121.56244F, -4.17248F, 19.57737F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0417F, KeyframeAnimations.degreeVec(138.5689F, 5.11581F, -24.50117F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.25F, KeyframeAnimations.degreeVec(144.06244F, -4.17248F, 19.57737F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.375F, KeyframeAnimations.degreeVec(147.28261F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.625F, KeyframeAnimations.degreeVec(147.28261F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.875F, KeyframeAnimations.degreeVec(134.36221F, 8.81113F, -8.90172F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.0417F, KeyframeAnimations.degreeVec(132.05966F, -8.35927F, 9.70506F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.25F, KeyframeAnimations.degreeVec(134.36221F, 8.81113F, -8.90172F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.5F, KeyframeAnimations.degreeVec(147.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, -16.48454F, -6.5784F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.7083F, KeyframeAnimations.posVec(0.0F, -16.48454F, -6.5784F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0417F, KeyframeAnimations.posVec(0.0F, -16.97F, -7.11F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.625F, KeyframeAnimations.posVec(0.0F, -13.97F, -7.11F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.2083F, KeyframeAnimations.posVec(0.0F, -11.48454F, -0.5784F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.5417F, KeyframeAnimations.posVec(0.0F, -16.48454F, -6.5784F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.6667F, KeyframeAnimations.posVec(0.0F, -20.27F, -5.42F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.375F, KeyframeAnimations.posVec(0.0F, -21.48454F, -5.5784F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.0417F, KeyframeAnimations.posVec(0.0F, -22.48454F, -5.5784F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.5F, KeyframeAnimations.posVec(0.0F, -40.0F, -8.0F), AnimationChannel.Interpolations.LINEAR))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.6667F, KeyframeAnimations.degreeVec(12.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.2083F, KeyframeAnimations.degreeVec(12.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.75F, KeyframeAnimations.degreeVec(45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.375F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.5417F, KeyframeAnimations.degreeVec(67.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.375F, KeyframeAnimations.degreeVec(67.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.375Line truncated
|
||||
public static final AnimationDefinition WARDEN_ROAR = AnimationDefinition.Builder.withLength(4.2F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.24F, KeyframeAnimations.degreeVec(-25.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.6F, KeyframeAnimations.degreeVec(32.5F, 0.0F, -7.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.84F, KeyframeAnimations.degreeVec(38.33F, 0.0F, 2.99F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.08F, KeyframeAnimations.degreeVec(40.97F, 0.0F, -4.3F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.36F, KeyframeAnimations.degreeVec(44.41F, 0.0F, 6.29F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.degreeVec(47.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.2F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.24F, KeyframeAnimations.posVec(0.0F, -1.0F, 3.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.6F, KeyframeAnimations.posVec(0.0F, -3.0F, -6.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.posVec(0.0F, -3.0F, -6.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.2F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.24F, KeyframeAnimations.degreeVec(-32.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.6F, KeyframeAnimations.degreeVec(-32.5F, 0.0F, -27.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.8F, KeyframeAnimations.degreeVec(-32.5F, 0.0F, 26.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.04F, KeyframeAnimations.degreeVec(-32.5F, 0.0F, -27.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.44F, KeyframeAnimations.degreeVec(-32.5F, 0.0F, 26.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.84F, KeyframeAnimations.degreeVec(-5.0F, 0.0F, -12.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.2F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.24F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.6F, KeyframeAnimations.posVec(0.0F, -2.0F, -6.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.2F, KeyframeAnimations.posVec(0.0F, -2.0F, -6.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.48F, KeyframeAnimations.posVec(0.0F, -2.0F, -6.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.2F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.24F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.76F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -10.85F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.08F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 12.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.4F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -10.85F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.72F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 12.5F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -10.85F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(4.2F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_ear", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.24F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.76F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -15.85F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.08F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 12.5F), AnimationChannel.Interpolations.CATMULLROM), new KeyfrLine truncated
|
||||
public static final AnimationDefinition WARDEN_SNIFF = AnimationDefinition.Builder.withLength(4.16F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.56F, KeyframeAnimations.degreeVec(17.5F, 32.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.96F, KeyframeAnimations.degreeVec(0.0F, 32.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.2F, KeyframeAnimations.degreeVec(10.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.8F, KeyframeAnimations.degreeVec(10.0F, -30.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.32F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.68F, KeyframeAnimations.degreeVec(0.0F, 40.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.96F, KeyframeAnimations.degreeVec(-22.5F, 40.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.24F, KeyframeAnimations.degreeVec(0.0F, 20.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.52F, KeyframeAnimations.degreeVec(-35.0F, 20.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.76F, KeyframeAnimations.degreeVec(0.0F, 20.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.28F, KeyframeAnimations.degreeVec(0.0F, -20.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.88F, KeyframeAnimations.degreeVec(0.0F, -20.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.32F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.96F, KeyframeAnimations.degreeVec(17.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.2F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.76F, KeyframeAnimations.degreeVec(-15.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.32F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.96F, KeyframeAnimations.degreeVec(-15.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.2F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.76F, KeyframeAnimations.degreeVec(17.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(3.32F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).build();
|
||||
public static final AnimationDefinition WARDEN_ATTACK = AnimationDefinition.Builder.withLength(0.33333F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.0417F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.2083F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.3333F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.0417F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.2083F, KeyframeAnimations.posVec(0.0F, -1.0F, -2.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.3333F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.0417F, KeyframeAnimations.degreeVec(22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.degreeVec(-30.17493F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.3333F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.0417F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.25F, KeyframeAnimations.posVec(0.0F, -2.0F, -2.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.3333F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.0417F, KeyframeAnimations.degreeVec(-120.36119F, 40.78947F, -20.94102F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.1667F, KeyframeAnimations.degreeVec(-90.0F, -45.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.3333F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.0417F, KeyframeAnimations.posVec(4.0F, 0.0F, 5.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.1667F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.3333F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.0417F, KeyframeAnimations.degreeVec(-120.36119F, -40.78947F, 20.94102F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.1667F, KeyframeAnimations.degreeVec(-61.1632F, 42.85882F, 11.52421F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.3333F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.0417F, KeyframeAnimations.posVec(-4.0F, 0.0F, 5.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.1667F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(0.3333F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).build();
|
||||
public static final AnimationDefinition WARDEN_SONIC_BOOM = AnimationDefinition.Builder.withLength(3.0F).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0833F, KeyframeAnimations.degreeVec(47.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.625F, KeyframeAnimations.degreeVec(55.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.9167F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.0F, KeyframeAnimations.degreeVec(-32.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.4583F, KeyframeAnimations.degreeVec(-32.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.7083F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.875F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0833F, KeyframeAnimations.posVec(0.0F, -3.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.625F, KeyframeAnimations.posVec(0.0F, -4.0F, -1.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.9167F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.7083F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.875F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_ribcage", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5417F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.7917F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.875F, KeyframeAnimations.degreeVec(0.0F, 125.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.5F, KeyframeAnimations.degreeVec(0.0F, 125.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.6667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("left_ribcage", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.5417F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.7917F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.875F, KeyframeAnimations.degreeVec(0.0F, -125.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.5F, KeyframeAnimations.degreeVec(0.0F, -125.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.6667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.0F, KeyframeAnimations.degreeVec(67.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.75F, KeyframeAnimations.degreeVec(80.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.9167F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.5F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.7083F, KeyframeAnimations.degreeVec(-45.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.875F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("head", new AnimationChannel(AnimationChannel.Targets.POSITION, new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(1.9167F, KeyframeAnimations.posVec(0.0F, 0.0F, -3.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.5F, KeyframeAnimations.posVec(0.0F, 0.0F, -3.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.7083F, KeyframeAnimations.posVec(0.0F, 0.0F, -3.0F), AnimationChannel.Interpolations.CATMULLROM), new Keyframe(2.875F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM))).addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, newLine truncated
|
||||
}
|
||||
+11
@@ -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;
|
||||
+11
@@ -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;
|
||||
+13
@@ -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 pState, @Nullable BlockAndTintGetter pLevel, @Nullable BlockPos pPos, int pTintIndex);
|
||||
}
|
||||
+126
@@ -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 pState, Level pLevel, BlockPos pPos) {
|
||||
BlockColor blockcolor = this.blockColors.get(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(pState.getBlock()));
|
||||
if (blockcolor != null) {
|
||||
return blockcolor.getColor(pState, (BlockAndTintGetter)null, (BlockPos)null, 0);
|
||||
} else {
|
||||
MapColor mapcolor = pState.getMapColor(pLevel, pPos);
|
||||
return mapcolor != null ? mapcolor.col : -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getColor(BlockState pState, @Nullable BlockAndTintGetter pLevel, @Nullable BlockPos pPos, int pTintIndex) {
|
||||
BlockColor blockcolor = this.blockColors.get(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(pState.getBlock()));
|
||||
return blockcolor == null ? -1 : blockcolor.getColor(pState, pLevel, pPos, pTintIndex);
|
||||
}
|
||||
|
||||
/** @deprecated Register via {@link net.minecraftforge.client.event.RegisterColorHandlersEvent.Block} */
|
||||
@Deprecated
|
||||
public void register(BlockColor pBlockColor, Block... pBlocks) {
|
||||
for(Block block : pBlocks) {
|
||||
this.blockColors.put(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(block), pBlockColor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addColoringStates(Set<Property<?>> pProperties, Block... pBlocks) {
|
||||
for(Block block : pBlocks) {
|
||||
this.coloringStates.put(block, pProperties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addColoringState(Property<?> pProperty, Block... pBlocks) {
|
||||
this.addColoringStates(ImmutableSet.of(pProperty), pBlocks);
|
||||
}
|
||||
|
||||
public Set<Property<?>> getColoringProperties(Block pBlock) {
|
||||
return this.coloringStates.getOrDefault(pBlock, ImmutableSet.of());
|
||||
}
|
||||
}
|
||||
+179
@@ -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> pSource) {
|
||||
this.source = pSource;
|
||||
}
|
||||
|
||||
public int getColor(BlockPos pPos) {
|
||||
int i = SectionPos.blockToSectionCoord(pPos.getX());
|
||||
int j = SectionPos.blockToSectionCoord(pPos.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(pPos.getY());
|
||||
int k = pPos.getX() & 15;
|
||||
int l = pPos.getZ() & 15;
|
||||
int i1 = l << 4 | k;
|
||||
int j1 = aint[i1];
|
||||
if (j1 != -1) {
|
||||
return j1;
|
||||
} else {
|
||||
int k1 = this.source.applyAsInt(pPos);
|
||||
aint[i1] = k1;
|
||||
return k1;
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidateForChunk(int pChunkX, int pChunkZ) {
|
||||
try {
|
||||
this.lock.writeLock().lock();
|
||||
|
||||
for(int i = -1; i <= 1; ++i) {
|
||||
for(int j = -1; j <= 1; ++j) {
|
||||
long k = ChunkPos.asLong(pChunkX + i, pChunkZ + 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 pChunkX, int pChunkZ) {
|
||||
long i = ChunkPos.asLong(pChunkX, pChunkZ);
|
||||
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 pHeight) {
|
||||
this.lock.readLock().lock();
|
||||
|
||||
try {
|
||||
int[] aint = this.cache.get(pHeight);
|
||||
if (aint != null) {
|
||||
return aint;
|
||||
}
|
||||
} finally {
|
||||
this.lock.readLock().unlock();
|
||||
}
|
||||
|
||||
this.lock.writeLock().lock();
|
||||
|
||||
int[] aint1;
|
||||
try {
|
||||
aint1 = this.cache.computeIfAbsent(pHeight, (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() {
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -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;
|
||||
+10
@@ -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 pStack, int pTintIndex);
|
||||
}
|
||||
+109
@@ -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 pColors) {
|
||||
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 pColors.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, pColors);
|
||||
return itemcolors;
|
||||
}
|
||||
|
||||
public int getColor(ItemStack pStack, int pTintIndex) {
|
||||
ItemColor itemcolor = this.itemColors.get(net.minecraftforge.registries.ForgeRegistries.ITEMS.getDelegateOrThrow(pStack.getItem()));
|
||||
return itemcolor == null ? -1 : itemcolor.getColor(pStack, pTintIndex);
|
||||
}
|
||||
|
||||
/** @deprecated Register via {@link net.minecraftforge.client.event.RegisterColorHandlersEvent.Item} */
|
||||
@Deprecated
|
||||
public void register(ItemColor pItemColor, ItemLike... pItems) {
|
||||
for(ItemLike itemlike : pItems) {
|
||||
this.itemColors.put(net.minecraftforge.registries.ForgeRegistries.ITEMS.getDelegateOrThrow(itemlike.asItem()), pItemColor);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+11
@@ -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;
|
||||
+61
@@ -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 pComponent) {
|
||||
return new ComponentPath.Leaf(pComponent);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static ComponentPath path(ContainerEventHandler pComponent, @Nullable ComponentPath pChildPath) {
|
||||
return pChildPath == null ? null : new ComponentPath.Path(pComponent, pChildPath);
|
||||
}
|
||||
|
||||
static ComponentPath path(GuiEventListener pComponent, ContainerEventHandler... pChildren) {
|
||||
ComponentPath componentpath = leaf(pComponent);
|
||||
|
||||
for(ContainerEventHandler containereventhandler : pChildren) {
|
||||
componentpath = path(containereventhandler, componentpath);
|
||||
}
|
||||
|
||||
return componentpath;
|
||||
}
|
||||
|
||||
GuiEventListener component();
|
||||
|
||||
void applyFocus(boolean pFocused);
|
||||
|
||||
@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 pFocused) {
|
||||
if (!pFocused) {
|
||||
this.component.setFocused((GuiEventListener)null);
|
||||
} else {
|
||||
this.component.setFocused(this.childPath.component());
|
||||
}
|
||||
|
||||
this.childPath.applyFocus(pFocused);
|
||||
}
|
||||
|
||||
public ContainerEventHandler component() {
|
||||
return this.component;
|
||||
}
|
||||
}
|
||||
}
|
||||
+337
@@ -0,0 +1,337 @@
|
||||
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> pFonts, boolean pFilterFishyGlyphs) {
|
||||
this.fonts = pFonts;
|
||||
this.filterFishyGlyphs = pFilterFishyGlyphs;
|
||||
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 pFontLocation) {
|
||||
return this.fonts.apply(pFontLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply Unicode Bidirectional Algorithm to string and return a new possibly reordered string for visual rendering.
|
||||
*/
|
||||
public String bidirectionalShaping(String pText) {
|
||||
try {
|
||||
Bidi bidi = new Bidi((new ArabicShaping(8)).shape(pText), 127);
|
||||
bidi.setReorderingMode(0);
|
||||
return bidi.writeReordered(2);
|
||||
} catch (ArabicShapingException arabicshapingexception) {
|
||||
return pText;
|
||||
}
|
||||
}
|
||||
|
||||
public int drawInBatch(String pText, float pX, float pY, int pColor, boolean pDropShadow, Matrix4f pMatrix, MultiBufferSource pBuffer, Font.DisplayMode pDisplayMode, int pBackgroundColor, int pPackedLightCoords) {
|
||||
return this.drawInBatch(pText, pX, pY, pColor, pDropShadow, pMatrix, pBuffer, pDisplayMode, pBackgroundColor, pPackedLightCoords, this.isBidirectional());
|
||||
}
|
||||
|
||||
public int drawInBatch(String pText, float pX, float pY, int pColor, boolean pDropShadow, Matrix4f pMatrix, MultiBufferSource pBuffer, Font.DisplayMode pDisplayMode, int pBackgroundColor, int pPackedLightCoords, boolean pBidirectional) {
|
||||
return this.drawInternal(pText, pX, pY, pColor, pDropShadow, pMatrix, pBuffer, pDisplayMode, pBackgroundColor, pPackedLightCoords, pBidirectional);
|
||||
}
|
||||
|
||||
public int drawInBatch(Component pText, float pX, float pY, int pColor, boolean pDropShadow, Matrix4f pMatrix, MultiBufferSource pBuffer, Font.DisplayMode pDisplayMode, int pBackgroundColor, int pPackedLightCoords) {
|
||||
return this.drawInBatch(pText.getVisualOrderText(), pX, pY, pColor, pDropShadow, pMatrix, pBuffer, pDisplayMode, pBackgroundColor, pPackedLightCoords);
|
||||
}
|
||||
|
||||
public int drawInBatch(FormattedCharSequence pText, float pX, float pY, int pColor, boolean pDropShadow, Matrix4f pMatrix, MultiBufferSource pBuffer, Font.DisplayMode pDisplayMode, int pBackgroundColor, int pPackedLightCoords) {
|
||||
return this.drawInternal(pText, pX, pY, pColor, pDropShadow, pMatrix, pBuffer, pDisplayMode, pBackgroundColor, pPackedLightCoords);
|
||||
}
|
||||
|
||||
public void drawInBatch8xOutline(FormattedCharSequence pText, float pX, float pY, int pColor, int pBackgroundColor, Matrix4f pMatrix, MultiBufferSource pBufferSource, int pPackedLightCoords) {
|
||||
int i = adjustColor(pBackgroundColor);
|
||||
Font.StringRenderOutput font$stringrenderoutput = new Font.StringRenderOutput(pBufferSource, 0.0F, 0.0F, i, false, pMatrix, Font.DisplayMode.NORMAL, pPackedLightCoords);
|
||||
|
||||
for(int j = -1; j <= 1; ++j) {
|
||||
for(int k = -1; k <= 1; ++k) {
|
||||
if (j != 0 || k != 0) {
|
||||
float[] afloat = new float[]{pX};
|
||||
int l = j;
|
||||
int i1 = k;
|
||||
pText.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 = pY + (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(pBufferSource, pX, pY, adjustColor(pColor), false, pMatrix, Font.DisplayMode.POLYGON_OFFSET, pPackedLightCoords);
|
||||
pText.accept(font$stringrenderoutput1);
|
||||
font$stringrenderoutput1.finish(0, pX);
|
||||
}
|
||||
|
||||
private static int adjustColor(int pColor) {
|
||||
return (pColor & -67108864) == 0 ? pColor | -16777216 : pColor;
|
||||
}
|
||||
|
||||
private int drawInternal(String pText, float pX, float pY, int pColor, boolean pDropShadow, Matrix4f pMatrix, MultiBufferSource pBuffer, Font.DisplayMode pDisplayMode, int pBackgroundColor, int pPackedLightCoords, boolean pBidirectional) {
|
||||
if (pBidirectional) {
|
||||
pText = this.bidirectionalShaping(pText);
|
||||
}
|
||||
|
||||
pColor = adjustColor(pColor);
|
||||
Matrix4f matrix4f = new Matrix4f(pMatrix);
|
||||
if (pDropShadow) {
|
||||
this.renderText(pText, pX, pY, pColor, true, pMatrix, pBuffer, pDisplayMode, pBackgroundColor, pPackedLightCoords);
|
||||
matrix4f.translate(SHADOW_OFFSET);
|
||||
}
|
||||
|
||||
pX = this.renderText(pText, pX, pY, pColor, false, matrix4f, pBuffer, pDisplayMode, pBackgroundColor, pPackedLightCoords);
|
||||
return (int)pX + (pDropShadow ? 1 : 0);
|
||||
}
|
||||
|
||||
private int drawInternal(FormattedCharSequence pText, float pX, float pY, int pColor, boolean pDropShadow, Matrix4f pMatrix, MultiBufferSource pBuffer, Font.DisplayMode pDisplayMode, int pBackgroundColor, int pPackedLightCoords) {
|
||||
pColor = adjustColor(pColor);
|
||||
Matrix4f matrix4f = new Matrix4f(pMatrix);
|
||||
if (pDropShadow) {
|
||||
this.renderText(pText, pX, pY, pColor, true, pMatrix, pBuffer, pDisplayMode, pBackgroundColor, pPackedLightCoords);
|
||||
matrix4f.translate(SHADOW_OFFSET);
|
||||
}
|
||||
|
||||
pX = this.renderText(pText, pX, pY, pColor, false, matrix4f, pBuffer, pDisplayMode, pBackgroundColor, pPackedLightCoords);
|
||||
return (int)pX + (pDropShadow ? 1 : 0);
|
||||
}
|
||||
|
||||
private float renderText(String pText, float pX, float pY, int pColor, boolean pDropShadow, Matrix4f pMatrix, MultiBufferSource pBuffer, Font.DisplayMode pDisplayMode, int pBackgroundColor, int pPackedLightCoords) {
|
||||
Font.StringRenderOutput font$stringrenderoutput = new Font.StringRenderOutput(pBuffer, pX, pY, pColor, pDropShadow, pMatrix, pDisplayMode, pPackedLightCoords);
|
||||
StringDecomposer.iterateFormatted(pText, Style.EMPTY, font$stringrenderoutput);
|
||||
return font$stringrenderoutput.finish(pBackgroundColor, pX);
|
||||
}
|
||||
|
||||
private float renderText(FormattedCharSequence pText, float pX, float pY, int pColor, boolean pDropShadow, Matrix4f pMatrix, MultiBufferSource pBuffer, Font.DisplayMode pDisplayMode, int pBackgroundColor, int pPackedLightCoords) {
|
||||
Font.StringRenderOutput font$stringrenderoutput = new Font.StringRenderOutput(pBuffer, pX, pY, pColor, pDropShadow, pMatrix, pDisplayMode, pPackedLightCoords);
|
||||
pText.accept(font$stringrenderoutput);
|
||||
return font$stringrenderoutput.finish(pBackgroundColor, pX);
|
||||
}
|
||||
|
||||
void renderChar(BakedGlyph pGlyph, boolean pBold, boolean pItalic, float pBoldOffset, float pX, float pY, Matrix4f pMatrix, VertexConsumer pBuffer, float pRed, float pGreen, float pBlue, float pAlpha, int pPackedLight) {
|
||||
pGlyph.render(pItalic, pX, pY, pMatrix, pBuffer, pRed, pGreen, pBlue, pAlpha, pPackedLight);
|
||||
if (pBold) {
|
||||
pGlyph.render(pItalic, pX + pBoldOffset, pY, pMatrix, pBuffer, pRed, pGreen, pBlue, pAlpha, pPackedLight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of this string. Equivalent of FontMetrics.stringWidth(String s).
|
||||
*/
|
||||
public int width(String pText) {
|
||||
return Mth.ceil(this.splitter.stringWidth(pText));
|
||||
}
|
||||
|
||||
public int width(FormattedText pText) {
|
||||
return Mth.ceil(this.splitter.stringWidth(pText));
|
||||
}
|
||||
|
||||
public int width(FormattedCharSequence pText) {
|
||||
return Mth.ceil(this.splitter.stringWidth(pText));
|
||||
}
|
||||
|
||||
public String plainSubstrByWidth(String pText, int pMaxWidth, boolean pTail) {
|
||||
return pTail ? this.splitter.plainTailByWidth(pText, pMaxWidth, Style.EMPTY) : this.splitter.plainHeadByWidth(pText, pMaxWidth, Style.EMPTY);
|
||||
}
|
||||
|
||||
public String plainSubstrByWidth(String pText, int pMaxWidth) {
|
||||
return this.splitter.plainHeadByWidth(pText, pMaxWidth, Style.EMPTY);
|
||||
}
|
||||
|
||||
public FormattedText substrByWidth(FormattedText pText, int pMaxWidth) {
|
||||
return this.splitter.headByWidth(pText, pMaxWidth, Style.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height (in pixels) of the given string if it is wordwrapped to the given max width.
|
||||
*/
|
||||
public int wordWrapHeight(String pText, int pMaxWidth) {
|
||||
return 9 * this.splitter.splitLines(pText, pMaxWidth, Style.EMPTY).size();
|
||||
}
|
||||
|
||||
public int wordWrapHeight(FormattedText pText, int pMaxWidth) {
|
||||
return 9 * this.splitter.splitLines(pText, pMaxWidth, Style.EMPTY).size();
|
||||
}
|
||||
|
||||
public List<FormattedCharSequence> split(FormattedText pText, int pMaxWidth) {
|
||||
return Language.getInstance().getVisualOrder(this.splitter.splitLines(pText, pMaxWidth, Style.EMPTY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bidiFlag that controls if the Unicode Bidirectional Algorithm should be run before rendering any string
|
||||
*/
|
||||
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 pEffect) {
|
||||
if (this.effects == null) {
|
||||
this.effects = Lists.newArrayList();
|
||||
}
|
||||
|
||||
this.effects.add(pEffect);
|
||||
}
|
||||
|
||||
public StringRenderOutput(MultiBufferSource pBufferSource, float pX, float pY, int pColor, boolean pDropShadow, Matrix4f pPose, Font.DisplayMode pMode, int pPackedLightCoords) {
|
||||
this.bufferSource = pBufferSource;
|
||||
this.x = pX;
|
||||
this.y = pY;
|
||||
this.dropShadow = pDropShadow;
|
||||
this.dimFactor = pDropShadow ? 0.25F : 1.0F;
|
||||
this.r = (float)(pColor >> 16 & 255) / 255.0F * this.dimFactor;
|
||||
this.g = (float)(pColor >> 8 & 255) / 255.0F * this.dimFactor;
|
||||
this.b = (float)(pColor & 255) / 255.0F * this.dimFactor;
|
||||
this.a = (float)(pColor >> 24 & 255) / 255.0F;
|
||||
this.pose = pPose;
|
||||
this.mode = pMode;
|
||||
this.packedLightCoords = pPackedLightCoords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a single code point from a {@link net.minecraft.util.FormattedCharSequence}.
|
||||
* @return {@code true} to accept more characters, {@code false} to stop traversing the sequence.
|
||||
* @param pPositionInCurrentSequence Contains the relative position of the character in the current sub-sequence.
|
||||
* If multiple formatted char sequences have been combined, this value will reset to {@code 0} after each sequence
|
||||
* has been fully consumed.
|
||||
*/
|
||||
public boolean accept(int pPositionInCurrentSequence, Style pStyle, int pCodePoint) {
|
||||
FontSet fontset = Font.this.getFontSet(pStyle.getFont());
|
||||
GlyphInfo glyphinfo = fontset.getGlyphInfo(pCodePoint, Font.this.filterFishyGlyphs);
|
||||
BakedGlyph bakedglyph = pStyle.isObfuscated() && pCodePoint != 32 ? fontset.getRandomGlyph(glyphinfo) : fontset.getGlyph(pCodePoint);
|
||||
boolean flag = pStyle.isBold();
|
||||
float f3 = this.a;
|
||||
TextColor textcolor = pStyle.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, pStyle.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 (pStyle.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 (pStyle.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 pBackgroundColor, float pX) {
|
||||
if (pBackgroundColor != 0) {
|
||||
float f = (float)(pBackgroundColor >> 24 & 255) / 255.0F;
|
||||
float f1 = (float)(pBackgroundColor >> 16 & 255) / 255.0F;
|
||||
float f2 = (float)(pBackgroundColor >> 8 & 255) / 255.0F;
|
||||
float f3 = (float)(pBackgroundColor & 255) / 255.0F;
|
||||
this.addEffect(new BakedGlyph.Effect(pX - 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1248
File diff suppressed because it is too large.
Load diff
+685
@@ -0,0 +1,685 @@
|
||||
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 pMinecraft, PoseStack pPose, MultiBufferSource.BufferSource pBufferSource) {
|
||||
this.minecraft = pMinecraft;
|
||||
this.pose = pPose;
|
||||
this.bufferSource = pBufferSource;
|
||||
}
|
||||
|
||||
public GuiGraphics(Minecraft pMinecraft, MultiBufferSource.BufferSource pBufferSource) {
|
||||
this(pMinecraft, new PoseStack(), pBufferSource);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
public void drawManaged(Runnable pRunnable) {
|
||||
this.flush();
|
||||
this.managed = true;
|
||||
pRunnable.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 pMinX, int pMaxX, int pY, int pColor) {
|
||||
this.hLine(RenderType.gui(), pMinX, pMaxX, pY, pColor);
|
||||
}
|
||||
|
||||
public void hLine(RenderType pRenderType, int pMinX, int pMaxX, int pY, int pColor) {
|
||||
if (pMaxX < pMinX) {
|
||||
int i = pMinX;
|
||||
pMinX = pMaxX;
|
||||
pMaxX = i;
|
||||
}
|
||||
|
||||
this.fill(pRenderType, pMinX, pY, pMaxX + 1, pY + 1, pColor);
|
||||
}
|
||||
|
||||
public void vLine(int pX, int pMinY, int pMaxY, int pColor) {
|
||||
this.vLine(RenderType.gui(), pX, pMinY, pMaxY, pColor);
|
||||
}
|
||||
|
||||
public void vLine(RenderType pRenderType, int pX, int pMinY, int pMaxY, int pColor) {
|
||||
if (pMaxY < pMinY) {
|
||||
int i = pMinY;
|
||||
pMinY = pMaxY;
|
||||
pMaxY = i;
|
||||
}
|
||||
|
||||
this.fill(pRenderType, pX, pMinY + 1, pX + 1, pMaxY, pColor);
|
||||
}
|
||||
|
||||
public void enableScissor(int pMinX, int pMinY, int pMaxX, int pMaxY) {
|
||||
this.applyScissor(this.scissorStack.push(new ScreenRectangle(pMinX, pMinY, pMaxX - pMinX, pMaxY - pMinY)));
|
||||
}
|
||||
|
||||
public void disableScissor() {
|
||||
this.applyScissor(this.scissorStack.pop());
|
||||
}
|
||||
|
||||
private void applyScissor(@Nullable ScreenRectangle pRectangle) {
|
||||
this.flushIfManaged();
|
||||
if (pRectangle != null) {
|
||||
Window window = Minecraft.getInstance().getWindow();
|
||||
int i = window.getHeight();
|
||||
double d0 = window.getGuiScale();
|
||||
double d1 = (double)pRectangle.left() * d0;
|
||||
double d2 = (double)i - (double)pRectangle.bottom() * d0;
|
||||
double d3 = (double)pRectangle.width() * d0;
|
||||
double d4 = (double)pRectangle.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 pRed, float pGreen, float pBlue, float pAlpha) {
|
||||
this.flushIfManaged();
|
||||
RenderSystem.setShaderColor(pRed, pGreen, pBlue, pAlpha);
|
||||
}
|
||||
|
||||
public void fill(int pMinX, int pMinY, int pMaxX, int pMaxY, int pColor) {
|
||||
this.fill(pMinX, pMinY, pMaxX, pMaxY, 0, pColor);
|
||||
}
|
||||
|
||||
public void fill(int pMinX, int pMinY, int pMaxX, int pMaxY, int pZ, int pColor) {
|
||||
this.fill(RenderType.gui(), pMinX, pMinY, pMaxX, pMaxY, pZ, pColor);
|
||||
}
|
||||
|
||||
public void fill(RenderType pRenderType, int pMinX, int pMinY, int pMaxX, int pMaxY, int pColor) {
|
||||
this.fill(pRenderType, pMinX, pMinY, pMaxX, pMaxY, 0, pColor);
|
||||
}
|
||||
|
||||
public void fill(RenderType pRenderType, int pMinX, int pMinY, int pMaxX, int pMaxY, int pZ, int pColor) {
|
||||
Matrix4f matrix4f = this.pose.last().pose();
|
||||
if (pMinX < pMaxX) {
|
||||
int i = pMinX;
|
||||
pMinX = pMaxX;
|
||||
pMaxX = i;
|
||||
}
|
||||
|
||||
if (pMinY < pMaxY) {
|
||||
int j = pMinY;
|
||||
pMinY = pMaxY;
|
||||
pMaxY = j;
|
||||
}
|
||||
|
||||
float f3 = (float)FastColor.ARGB32.alpha(pColor) / 255.0F;
|
||||
float f = (float)FastColor.ARGB32.red(pColor) / 255.0F;
|
||||
float f1 = (float)FastColor.ARGB32.green(pColor) / 255.0F;
|
||||
float f2 = (float)FastColor.ARGB32.blue(pColor) / 255.0F;
|
||||
VertexConsumer vertexconsumer = this.bufferSource.getBuffer(pRenderType);
|
||||
vertexconsumer.vertex(matrix4f, (float)pMinX, (float)pMinY, (float)pZ).color(f, f1, f2, f3).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, (float)pMinX, (float)pMaxY, (float)pZ).color(f, f1, f2, f3).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, (float)pMaxX, (float)pMaxY, (float)pZ).color(f, f1, f2, f3).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, (float)pMaxX, (float)pMinY, (float)pZ).color(f, f1, f2, f3).endVertex();
|
||||
this.flushIfUnmanaged();
|
||||
}
|
||||
|
||||
public void fillGradient(int pX1, int pY1, int pX2, int pY2, int pColorFrom, int pColorTo) {
|
||||
this.fillGradient(pX1, pY1, pX2, pY2, 0, pColorFrom, pColorTo);
|
||||
}
|
||||
|
||||
public void fillGradient(int pX1, int pY1, int pX2, int pY2, int pZ, int pColorFrom, int pColorTo) {
|
||||
this.fillGradient(RenderType.gui(), pX1, pY1, pX2, pY2, pColorFrom, pColorTo, pZ);
|
||||
}
|
||||
|
||||
public void fillGradient(RenderType pRenderType, int pX1, int pY1, int pX2, int pY2, int pColorFrom, int pColorTo, int pZ) {
|
||||
VertexConsumer vertexconsumer = this.bufferSource.getBuffer(pRenderType);
|
||||
this.fillGradient(vertexconsumer, pX1, pY1, pX2, pY2, pZ, pColorFrom, pColorTo);
|
||||
this.flushIfUnmanaged();
|
||||
}
|
||||
|
||||
private void fillGradient(VertexConsumer pConsumer, int pX1, int pY1, int pX2, int pY2, int pZ, int pColorFrom, int pColorTo) {
|
||||
float f = (float)FastColor.ARGB32.alpha(pColorFrom) / 255.0F;
|
||||
float f1 = (float)FastColor.ARGB32.red(pColorFrom) / 255.0F;
|
||||
float f2 = (float)FastColor.ARGB32.green(pColorFrom) / 255.0F;
|
||||
float f3 = (float)FastColor.ARGB32.blue(pColorFrom) / 255.0F;
|
||||
float f4 = (float)FastColor.ARGB32.alpha(pColorTo) / 255.0F;
|
||||
float f5 = (float)FastColor.ARGB32.red(pColorTo) / 255.0F;
|
||||
float f6 = (float)FastColor.ARGB32.green(pColorTo) / 255.0F;
|
||||
float f7 = (float)FastColor.ARGB32.blue(pColorTo) / 255.0F;
|
||||
Matrix4f matrix4f = this.pose.last().pose();
|
||||
pConsumer.vertex(matrix4f, (float)pX1, (float)pY1, (float)pZ).color(f1, f2, f3, f).endVertex();
|
||||
pConsumer.vertex(matrix4f, (float)pX1, (float)pY2, (float)pZ).color(f5, f6, f7, f4).endVertex();
|
||||
pConsumer.vertex(matrix4f, (float)pX2, (float)pY2, (float)pZ).color(f5, f6, f7, f4).endVertex();
|
||||
pConsumer.vertex(matrix4f, (float)pX2, (float)pY1, (float)pZ).color(f1, f2, f3, f).endVertex();
|
||||
}
|
||||
|
||||
public void drawCenteredString(Font pFont, String pText, int pX, int pY, int pColor) {
|
||||
this.drawString(pFont, pText, pX - pFont.width(pText) / 2, pY, pColor);
|
||||
}
|
||||
|
||||
public void drawCenteredString(Font pFont, Component pText, int pX, int pY, int pColor) {
|
||||
FormattedCharSequence formattedcharsequence = pText.getVisualOrderText();
|
||||
this.drawString(pFont, formattedcharsequence, pX - pFont.width(formattedcharsequence) / 2, pY, pColor);
|
||||
}
|
||||
|
||||
public void drawCenteredString(Font pFont, FormattedCharSequence pText, int pX, int pY, int pColor) {
|
||||
this.drawString(pFont, pText, pX - pFont.width(pText) / 2, pY, pColor);
|
||||
}
|
||||
|
||||
public int drawString(Font pFont, @Nullable String pText, int pX, int pY, int pColor) {
|
||||
return this.drawString(pFont, pText, pX, pY, pColor, true);
|
||||
}
|
||||
|
||||
public int drawString(Font pFont, @Nullable String pText, int pX, int pY, int pColor, boolean pDropShadow) {
|
||||
return this.drawString(pFont, pText, (float)pX, (float)pY, pColor, pDropShadow);
|
||||
}
|
||||
|
||||
// Forge: Add float variant for x,y coordinates
|
||||
public int drawString(Font pFont, @Nullable String pText, float pX, float pY, int pColor, boolean pDropShadow) {
|
||||
if (pText == null) {
|
||||
return 0;
|
||||
} else {
|
||||
int i = pFont.drawInBatch(pText, (float)pX, (float)pY, pColor, pDropShadow, this.pose.last().pose(), this.bufferSource, Font.DisplayMode.NORMAL, 0, 15728880, pFont.isBidirectional());
|
||||
this.flushIfUnmanaged();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
public int drawString(Font pFont, FormattedCharSequence pText, int pX, int pY, int pColor) {
|
||||
return this.drawString(pFont, pText, pX, pY, pColor, true);
|
||||
}
|
||||
|
||||
public int drawString(Font pFont, FormattedCharSequence pText, int pX, int pY, int pColor, boolean pDropShadow) {
|
||||
return this.drawString(pFont, pText, (float)pX, (float)pY, pColor, pDropShadow);
|
||||
}
|
||||
|
||||
// Forge: Add float variant for x,y coordinates
|
||||
public int drawString(Font pFont, FormattedCharSequence pText, float pX, float pY, int pColor, boolean pDropShadow) {
|
||||
int i = pFont.drawInBatch(pText, (float)pX, (float)pY, pColor, pDropShadow, this.pose.last().pose(), this.bufferSource, Font.DisplayMode.NORMAL, 0, 15728880);
|
||||
this.flushIfUnmanaged();
|
||||
return i;
|
||||
}
|
||||
|
||||
public int drawString(Font pFont, Component pText, int pX, int pY, int pColor) {
|
||||
return this.drawString(pFont, pText, pX, pY, pColor, true);
|
||||
}
|
||||
|
||||
public int drawString(Font pFont, Component pText, int pX, int pY, int pColor, boolean pDropShadow) {
|
||||
return this.drawString(pFont, pText.getVisualOrderText(), pX, pY, pColor, pDropShadow);
|
||||
}
|
||||
|
||||
public void drawWordWrap(Font pFont, FormattedText pText, int pX, int pY, int pLineWidth, int pColor) {
|
||||
for(FormattedCharSequence formattedcharsequence : pFont.split(pText, pLineWidth)) {
|
||||
this.drawString(pFont, formattedcharsequence, pX, pY, pColor, false);
|
||||
pY += 9;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void blit(int pX, int pY, int pBlitOffset, int pWidth, int pHeight, TextureAtlasSprite pSprite) {
|
||||
this.innerBlit(pSprite.atlasLocation(), pX, pX + pWidth, pY, pY + pHeight, pBlitOffset, pSprite.getU0(), pSprite.getU1(), pSprite.getV0(), pSprite.getV1());
|
||||
}
|
||||
|
||||
public void blit(int pX, int pY, int pBlitOffset, int pWidth, int pHeight, TextureAtlasSprite pSprite, float pRed, float pGreen, float pBlue, float pAlpha) {
|
||||
this.innerBlit(pSprite.atlasLocation(), pX, pX + pWidth, pY, pY + pHeight, pBlitOffset, pSprite.getU0(), pSprite.getU1(), pSprite.getV0(), pSprite.getV1(), pRed, pGreen, pBlue, pAlpha);
|
||||
}
|
||||
|
||||
public void renderOutline(int pX, int pY, int pWidth, int pHeight, int pColor) {
|
||||
this.fill(pX, pY, pX + pWidth, pY + 1, pColor);
|
||||
this.fill(pX, pY + pHeight - 1, pX + pWidth, pY + pHeight, pColor);
|
||||
this.fill(pX, pY + 1, pX + 1, pY + pHeight - 1, pColor);
|
||||
this.fill(pX + pWidth - 1, pY + 1, pX + pWidth, pY + pHeight - 1, pColor);
|
||||
}
|
||||
|
||||
public void blit(ResourceLocation pAtlasLocation, int pX, int pY, int pUOffset, int pVOffset, int pUWidth, int pVHeight) {
|
||||
this.blit(pAtlasLocation, pX, pY, 0, (float)pUOffset, (float)pVOffset, pUWidth, pVHeight, 256, 256);
|
||||
}
|
||||
|
||||
public void blit(ResourceLocation pAtlasLocation, int pX, int pY, int pBlitOffset, float pUOffset, float pVOffset, int pUWidth, int pVHeight, int pTextureWidth, int pTextureHeight) {
|
||||
this.blit(pAtlasLocation, pX, pX + pUWidth, pY, pY + pVHeight, pBlitOffset, pUWidth, pVHeight, pUOffset, pVOffset, pTextureWidth, pTextureHeight);
|
||||
}
|
||||
|
||||
public void blit(ResourceLocation pAtlasLocation, int pX, int pY, int pWidth, int pHeight, float pUWidth, float pVHeight, int pUOffset, int pVOffset, int pTextureWidth, int pTextureHeight) {
|
||||
this.blit(pAtlasLocation, pX, pX + pWidth, pY, pY + pHeight, 0, pUOffset, pVOffset, pUWidth, pVHeight, pTextureWidth, pTextureHeight);
|
||||
}
|
||||
|
||||
public void blit(ResourceLocation pAtlasLocation, int pX, int pY, float pUOffset, float pVOffset, int pWidth, int pHeight, int pTextureWidth, int pTextureHeight) {
|
||||
this.blit(pAtlasLocation, pX, pY, pWidth, pHeight, pUOffset, pVOffset, pWidth, pHeight, pTextureWidth, pTextureHeight);
|
||||
}
|
||||
|
||||
void blit(ResourceLocation pAtlasLocation, int pX1, int pX2, int pY1, int pY2, int pBlitOffset, int pUWidth, int pVHeight, float pUOffset, float pVOffset, int pTextureWidth, int pTextureHeight) {
|
||||
this.innerBlit(pAtlasLocation, pX1, pX2, pY1, pY2, pBlitOffset, (pUOffset + 0.0F) / (float)pTextureWidth, (pUOffset + (float)pUWidth) / (float)pTextureWidth, (pVOffset + 0.0F) / (float)pTextureHeight, (pVOffset + (float)pVHeight) / (float)pTextureHeight);
|
||||
}
|
||||
|
||||
void innerBlit(ResourceLocation pAtlasLocation, int pX1, int pX2, int pY1, int pY2, int pBlitOffset, float pMinU, float pMaxU, float pMinV, float pMaxV) {
|
||||
RenderSystem.setShaderTexture(0, pAtlasLocation);
|
||||
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)pX1, (float)pY1, (float)pBlitOffset).uv(pMinU, pMinV).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)pX1, (float)pY2, (float)pBlitOffset).uv(pMinU, pMaxV).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)pX2, (float)pY2, (float)pBlitOffset).uv(pMaxU, pMaxV).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)pX2, (float)pY1, (float)pBlitOffset).uv(pMaxU, pMinV).endVertex();
|
||||
BufferUploader.drawWithShader(bufferbuilder.end());
|
||||
}
|
||||
|
||||
void innerBlit(ResourceLocation pAtlasLocation, int pX1, int pX2, int pY1, int pY2, int pBlitOffset, float pMinU, float pMaxU, float pMinV, float pMaxV, float pRed, float pGreen, float pBlue, float pAlpha) {
|
||||
RenderSystem.setShaderTexture(0, pAtlasLocation);
|
||||
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)pX1, (float)pY1, (float)pBlitOffset).color(pRed, pGreen, pBlue, pAlpha).uv(pMinU, pMinV).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)pX1, (float)pY2, (float)pBlitOffset).color(pRed, pGreen, pBlue, pAlpha).uv(pMinU, pMaxV).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)pX2, (float)pY2, (float)pBlitOffset).color(pRed, pGreen, pBlue, pAlpha).uv(pMaxU, pMaxV).endVertex();
|
||||
bufferbuilder.vertex(matrix4f, (float)pX2, (float)pY1, (float)pBlitOffset).color(pRed, pGreen, pBlue, pAlpha).uv(pMaxU, pMinV).endVertex();
|
||||
BufferUploader.drawWithShader(bufferbuilder.end());
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
public void blitNineSliced(ResourceLocation pAtlasLocation, int pTargetX, int pTargetY, int pTargetWidth, int pTargetHeight, int pSliceSize, int pSourceWidth, int pSourceHeight, int pSourceX, int pSourceY) {
|
||||
this.blitNineSliced(pAtlasLocation, pTargetX, pTargetY, pTargetWidth, pTargetHeight, pSliceSize, pSliceSize, pSliceSize, pSliceSize, pSourceWidth, pSourceHeight, pSourceX, pSourceY);
|
||||
}
|
||||
|
||||
public void blitNineSliced(ResourceLocation pAtlasLocation, int pTargetX, int pTargetY, int pTargetWidth, int pTargetHeight, int pSliceWidth, int pSliceHeight, int pSourceWidth, int pSourceHeight, int pSourceX, int pSourceY) {
|
||||
this.blitNineSliced(pAtlasLocation, pTargetX, pTargetY, pTargetWidth, pTargetHeight, pSliceWidth, pSliceHeight, pSliceWidth, pSliceHeight, pSourceWidth, pSourceHeight, pSourceX, pSourceY);
|
||||
}
|
||||
|
||||
public void blitNineSliced(ResourceLocation pAtlasLocation, int pTargetX, int pTargetY, int pTargetWidth, int pTargetHeight, int pCornerWidth, int pCornerHeight, int pEdgeWidth, int pEdgeHeight, int pSourceWidth, int pSourceHeight, int pSourceX, int pSourceY) {
|
||||
pCornerWidth = Math.min(pCornerWidth, pTargetWidth / 2);
|
||||
pEdgeWidth = Math.min(pEdgeWidth, pTargetWidth / 2);
|
||||
pCornerHeight = Math.min(pCornerHeight, pTargetHeight / 2);
|
||||
pEdgeHeight = Math.min(pEdgeHeight, pTargetHeight / 2);
|
||||
if (pTargetWidth == pSourceWidth && pTargetHeight == pSourceHeight) {
|
||||
this.blit(pAtlasLocation, pTargetX, pTargetY, pSourceX, pSourceY, pTargetWidth, pTargetHeight);
|
||||
} else if (pTargetHeight == pSourceHeight) {
|
||||
this.blit(pAtlasLocation, pTargetX, pTargetY, pSourceX, pSourceY, pCornerWidth, pTargetHeight);
|
||||
this.blitRepeating(pAtlasLocation, pTargetX + pCornerWidth, pTargetY, pTargetWidth - pEdgeWidth - pCornerWidth, pTargetHeight, pSourceX + pCornerWidth, pSourceY, pSourceWidth - pEdgeWidth - pCornerWidth, pSourceHeight);
|
||||
this.blit(pAtlasLocation, pTargetX + pTargetWidth - pEdgeWidth, pTargetY, pSourceX + pSourceWidth - pEdgeWidth, pSourceY, pEdgeWidth, pTargetHeight);
|
||||
} else if (pTargetWidth == pSourceWidth) {
|
||||
this.blit(pAtlasLocation, pTargetX, pTargetY, pSourceX, pSourceY, pTargetWidth, pCornerHeight);
|
||||
this.blitRepeating(pAtlasLocation, pTargetX, pTargetY + pCornerHeight, pTargetWidth, pTargetHeight - pEdgeHeight - pCornerHeight, pSourceX, pSourceY + pCornerHeight, pSourceWidth, pSourceHeight - pEdgeHeight - pCornerHeight);
|
||||
this.blit(pAtlasLocation, pTargetX, pTargetY + pTargetHeight - pEdgeHeight, pSourceX, pSourceY + pSourceHeight - pEdgeHeight, pTargetWidth, pEdgeHeight);
|
||||
} else {
|
||||
this.blit(pAtlasLocation, pTargetX, pTargetY, pSourceX, pSourceY, pCornerWidth, pCornerHeight);
|
||||
this.blitRepeating(pAtlasLocation, pTargetX + pCornerWidth, pTargetY, pTargetWidth - pEdgeWidth - pCornerWidth, pCornerHeight, pSourceX + pCornerWidth, pSourceY, pSourceWidth - pEdgeWidth - pCornerWidth, pCornerHeight);
|
||||
this.blit(pAtlasLocation, pTargetX + pTargetWidth - pEdgeWidth, pTargetY, pSourceX + pSourceWidth - pEdgeWidth, pSourceY, pEdgeWidth, pCornerHeight);
|
||||
this.blit(pAtlasLocation, pTargetX, pTargetY + pTargetHeight - pEdgeHeight, pSourceX, pSourceY + pSourceHeight - pEdgeHeight, pCornerWidth, pEdgeHeight);
|
||||
this.blitRepeating(pAtlasLocation, pTargetX + pCornerWidth, pTargetY + pTargetHeight - pEdgeHeight, pTargetWidth - pEdgeWidth - pCornerWidth, pEdgeHeight, pSourceX + pCornerWidth, pSourceY + pSourceHeight - pEdgeHeight, pSourceWidth - pEdgeWidth - pCornerWidth, pEdgeHeight);
|
||||
this.blit(pAtlasLocation, pTargetX + pTargetWidth - pEdgeWidth, pTargetY + pTargetHeight - pEdgeHeight, pSourceX + pSourceWidth - pEdgeWidth, pSourceY + pSourceHeight - pEdgeHeight, pEdgeWidth, pEdgeHeight);
|
||||
this.blitRepeating(pAtlasLocation, pTargetX, pTargetY + pCornerHeight, pCornerWidth, pTargetHeight - pEdgeHeight - pCornerHeight, pSourceX, pSourceY + pCornerHeight, pCornerWidth, pSourceHeight - pEdgeHeight - pCornerHeight);
|
||||
this.blitRepeating(pAtlasLocation, pTargetX + pCornerWidth, pTargetY + pCornerHeight, pTargetWidth - pEdgeWidth - pCornerWidth, pTargetHeight - pEdgeHeight - pCornerHeight, pSourceX + pCornerWidth, pSourceY + pCornerHeight, pSourceWidth - pEdgeWidth - pCornerWidth, pSourceHeight - pEdgeHeight - pCornerHeight);
|
||||
this.blitRepeating(pAtlasLocation, pTargetX + pTargetWidth - pEdgeWidth, pTargetY + pCornerHeight, pCornerWidth, pTargetHeight - pEdgeHeight - pCornerHeight, pSourceX + pSourceWidth - pEdgeWidth, pSourceY + pCornerHeight, pEdgeWidth, pSourceHeight - pEdgeHeight - pCornerHeight);
|
||||
}
|
||||
}
|
||||
|
||||
public void blitRepeating(ResourceLocation pAtlasLocation, int pTargetX, int pTargetY, int pTargetWidth, int pTargetHeight, int pSourceX, int pSourceY, int pSourceWidth, int pSourceHeight) {
|
||||
blitRepeating(pAtlasLocation, pTargetX, pTargetY, pTargetWidth, pTargetHeight, pSourceX, pSourceY, pSourceWidth, pSourceHeight, 256, 256);
|
||||
}
|
||||
|
||||
public void blitRepeating(ResourceLocation pAtlasLocation, int pTargetX, int pTargetY, int pTargetWidth, int pTargetHeight, int pSourceX, int pSourceY, int pSourceWidth, int pSourceHeight, int textureWidth, int textureHeight) {
|
||||
int i = pTargetX;
|
||||
|
||||
int j;
|
||||
for(IntIterator intiterator = slices(pTargetWidth, pSourceWidth); intiterator.hasNext(); i += j) {
|
||||
j = intiterator.nextInt();
|
||||
int k = (pSourceWidth - j) / 2;
|
||||
int l = pTargetY;
|
||||
|
||||
int i1;
|
||||
for(IntIterator intiterator1 = slices(pTargetHeight, pSourceHeight); intiterator1.hasNext(); l += i1) {
|
||||
i1 = intiterator1.nextInt();
|
||||
int j1 = (pSourceHeight - i1) / 2;
|
||||
this.blit(pAtlasLocation, i, l, pSourceX + k, pSourceY + 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 pStack, int pX, int pY) {
|
||||
this.renderItem(this.minecraft.player, this.minecraft.level, pStack, pX, pY, 0);
|
||||
}
|
||||
|
||||
public void renderItem(ItemStack pStack, int pX, int pY, int pSeed) {
|
||||
this.renderItem(this.minecraft.player, this.minecraft.level, pStack, pX, pY, pSeed);
|
||||
}
|
||||
|
||||
public void renderItem(ItemStack pStack, int pX, int pY, int pSeed, int p_282314_) {
|
||||
this.renderItem(this.minecraft.player, this.minecraft.level, pStack, pX, pY, pSeed, p_282314_);
|
||||
}
|
||||
|
||||
public void renderFakeItem(ItemStack pStack, int pX, int pY) {
|
||||
this.renderItem((LivingEntity)null, this.minecraft.level, pStack, pX, pY, 0);
|
||||
}
|
||||
|
||||
public void renderItem(LivingEntity pEntity, ItemStack pStack, int pX, int pY, int pSeed) {
|
||||
this.renderItem(pEntity, pEntity.level(), pStack, pX, pY, pSeed);
|
||||
}
|
||||
|
||||
private void renderItem(@Nullable LivingEntity pEntity, @Nullable Level pLevel, ItemStack pStack, int pX, int pY, int pSeed) {
|
||||
this.renderItem(pEntity, pLevel, pStack, pX, pY, pSeed, 0);
|
||||
}
|
||||
|
||||
private void renderItem(@Nullable LivingEntity pEntity, @Nullable Level pLevel, ItemStack pStack, int pX, int pY, int pSeed, int p_281995_) {
|
||||
if (!pStack.isEmpty()) {
|
||||
BakedModel bakedmodel = this.minecraft.getItemRenderer().getModel(pStack, pLevel, pEntity, pSeed);
|
||||
this.pose.pushPose();
|
||||
this.pose.translate((float)(pX + 8), (float)(pY + 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(pStack, 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)pStack.getItem());
|
||||
});
|
||||
crashreportcategory.setDetail("Registry Name", () -> String.valueOf(net.minecraftforge.registries.ForgeRegistries.ITEMS.getKey(pStack.getItem())));
|
||||
crashreportcategory.setDetail("Item Damage", () -> {
|
||||
return String.valueOf(pStack.getDamageValue());
|
||||
});
|
||||
crashreportcategory.setDetail("Item NBT", () -> {
|
||||
return String.valueOf((Object)pStack.getTag());
|
||||
});
|
||||
crashreportcategory.setDetail("Item Foil", () -> {
|
||||
return String.valueOf(pStack.hasFoil());
|
||||
});
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
|
||||
this.pose.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
public void renderItemDecorations(Font pFont, ItemStack pStack, int pX, int pY) {
|
||||
this.renderItemDecorations(pFont, pStack, pX, pY, (String)null);
|
||||
}
|
||||
|
||||
public void renderItemDecorations(Font pFont, ItemStack pStack, int pX, int pY, @Nullable String pText) {
|
||||
if (!pStack.isEmpty()) {
|
||||
this.pose.pushPose();
|
||||
if (pStack.getCount() != 1 || pText != null) {
|
||||
String s = pText == null ? String.valueOf(pStack.getCount()) : pText;
|
||||
this.pose.translate(0.0F, 0.0F, 200.0F);
|
||||
this.drawString(pFont, s, pX + 19 - 2 - pFont.width(s), pY + 6 + 3, 16777215, true);
|
||||
}
|
||||
|
||||
if (pStack.isBarVisible()) {
|
||||
int l = pStack.getBarWidth();
|
||||
int i = pStack.getBarColor();
|
||||
int j = pX + 2;
|
||||
int k = pY + 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(pStack.getItem(), this.minecraft.getFrameTime());
|
||||
if (f > 0.0F) {
|
||||
int i1 = pY + Mth.floor(16.0F * (1.0F - f));
|
||||
int j1 = i1 + Mth.ceil(16.0F * f);
|
||||
this.fill(RenderType.guiOverlay(), pX, i1, pX + 16, j1, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
this.pose.popPose();
|
||||
net.minecraftforge.client.ItemDecoratorHandler.of(pStack).render(this, pFont, pStack, pX, pY);
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack tooltipStack = ItemStack.EMPTY;
|
||||
|
||||
public void renderTooltip(Font pFont, ItemStack pStack, int pMouseX, int pMouseY) {
|
||||
this.tooltipStack = pStack;
|
||||
this.renderTooltip(pFont, Screen.getTooltipFromItem(this.minecraft, pStack), pStack.getTooltipImage(), pMouseX, pMouseY);
|
||||
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 pFont, List<Component> pTooltipLines, Optional<TooltipComponent> pVisualTooltipComponent, int pMouseX, int pMouseY) {
|
||||
List<ClientTooltipComponent> list = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, pTooltipLines, pVisualTooltipComponent, pMouseX, guiWidth(), guiHeight(), pFont);
|
||||
this.renderTooltipInternal(pFont, list, pMouseX, pMouseY, DefaultTooltipPositioner.INSTANCE);
|
||||
}
|
||||
|
||||
public void renderTooltip(Font pFont, Component pText, int pMouseX, int pMouseY) {
|
||||
this.renderTooltip(pFont, List.of(pText.getVisualOrderText()), pMouseX, pMouseY);
|
||||
}
|
||||
|
||||
public void renderComponentTooltip(Font pFont, List<Component> pTooltipLines, int pMouseX, int pMouseY) {
|
||||
List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, pTooltipLines, pMouseX, guiWidth(), guiHeight(), pFont);
|
||||
this.renderTooltipInternal(pFont, components, pMouseX, pMouseY, 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 renderTooltip(Font pFont, List<? extends FormattedCharSequence> pTooltipLines, int pMouseX, int pMouseY) {
|
||||
this.renderTooltipInternal(pFont, pTooltipLines.stream().map(ClientTooltipComponent::create).collect(Collectors.toList()), pMouseX, pMouseY, DefaultTooltipPositioner.INSTANCE);
|
||||
}
|
||||
|
||||
public void renderTooltip(Font pFont, List<FormattedCharSequence> pTooltipLines, ClientTooltipPositioner pTooltipPositioner, int pMouseX, int pMouseY) {
|
||||
this.renderTooltipInternal(pFont, pTooltipLines.stream().map(ClientTooltipComponent::create).collect(Collectors.toList()), pMouseX, pMouseY, pTooltipPositioner);
|
||||
}
|
||||
|
||||
private void renderTooltipInternal(Font pFont, List<ClientTooltipComponent> pComponents, int pMouseX, int pMouseY, ClientTooltipPositioner pTooltipPositioner) {
|
||||
if (!pComponents.isEmpty()) {
|
||||
net.minecraftforge.client.event.RenderTooltipEvent.Pre preEvent = net.minecraftforge.client.ForgeHooksClient.onRenderTooltipPre(this.tooltipStack, this, pMouseX, pMouseY, guiWidth(), guiHeight(), pComponents, pFont, pTooltipPositioner);
|
||||
if (preEvent.isCanceled()) return;
|
||||
int i = 0;
|
||||
int j = pComponents.size() == 1 ? -2 : 0;
|
||||
|
||||
for(ClientTooltipComponent clienttooltipcomponent : pComponents) {
|
||||
int k = clienttooltipcomponent.getWidth(preEvent.getFont());
|
||||
if (k > i) {
|
||||
i = k;
|
||||
}
|
||||
|
||||
j += clienttooltipcomponent.getHeight();
|
||||
}
|
||||
|
||||
int i2 = i;
|
||||
int j2 = j;
|
||||
Vector2ic vector2ic = pTooltipPositioner.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(), pComponents);
|
||||
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 < pComponents.size(); ++l1) {
|
||||
ClientTooltipComponent clienttooltipcomponent1 = pComponents.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 < pComponents.size(); ++k2) {
|
||||
ClientTooltipComponent clienttooltipcomponent2 = pComponents.get(k2);
|
||||
clienttooltipcomponent2.renderImage(preEvent.getFont(), l, k1, this);
|
||||
k1 += clienttooltipcomponent2.getHeight() + (k2 == 0 ? 2 : 0);
|
||||
}
|
||||
|
||||
this.pose.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
public void renderComponentHoverEffect(Font pFont, @Nullable Style pStyle, int pMouseX, int pMouseY) {
|
||||
if (pStyle != null && pStyle.getHoverEvent() != null) {
|
||||
HoverEvent hoverevent = pStyle.getHoverEvent();
|
||||
HoverEvent.ItemStackInfo hoverevent$itemstackinfo = hoverevent.getValue(HoverEvent.Action.SHOW_ITEM);
|
||||
if (hoverevent$itemstackinfo != null) {
|
||||
this.renderTooltip(pFont, hoverevent$itemstackinfo.getItemStack(), pMouseX, pMouseY);
|
||||
} else {
|
||||
HoverEvent.EntityTooltipInfo hoverevent$entitytooltipinfo = hoverevent.getValue(HoverEvent.Action.SHOW_ENTITY);
|
||||
if (hoverevent$entitytooltipinfo != null) {
|
||||
if (this.minecraft.options.advancedItemTooltips) {
|
||||
this.renderComponentTooltip(pFont, hoverevent$entitytooltipinfo.getTooltipLines(), pMouseX, pMouseY);
|
||||
}
|
||||
} else {
|
||||
Component component = hoverevent.getValue(HoverEvent.Action.SHOW_TEXT);
|
||||
if (component != null) {
|
||||
this.renderTooltip(pFont, pFont.split(component, Math.max(this.guiWidth() / 2, 200)), pMouseX, pMouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class ScissorStack {
|
||||
private final Deque<ScreenRectangle> stack = new ArrayDeque<>();
|
||||
|
||||
public ScreenRectangle push(ScreenRectangle pSciccor) {
|
||||
ScreenRectangle screenrectangle = this.stack.peekLast();
|
||||
if (screenrectangle != null) {
|
||||
ScreenRectangle screenrectangle1 = Objects.requireNonNullElse(pSciccor.intersection(screenrectangle), ScreenRectangle.empty());
|
||||
this.stack.addLast(screenrectangle1);
|
||||
return screenrectangle1;
|
||||
} else {
|
||||
this.stack.addLast(pSciccor);
|
||||
return pSciccor;
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable ScreenRectangle pop() {
|
||||
if (this.stack.isEmpty()) {
|
||||
throw new IllegalStateException("Scissor stack underflow");
|
||||
} else {
|
||||
this.stack.removeLast();
|
||||
return this.stack.peekLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
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 pTextureManager) {
|
||||
this.textureManager = pTextureManager;
|
||||
}
|
||||
|
||||
public void update(int pMapId, MapItemSavedData pMapData) {
|
||||
this.getOrCreateMapInstance(pMapId, pMapData).forceUpload();
|
||||
}
|
||||
|
||||
public void render(PoseStack pPoseStack, MultiBufferSource pBufferSource, int pMapId, MapItemSavedData pMapData, boolean pActive, int pPackedLight) {
|
||||
this.getOrCreateMapInstance(pMapId, pMapData).draw(pPoseStack, pBufferSource, pActive, pPackedLight);
|
||||
}
|
||||
|
||||
private MapRenderer.MapInstance getOrCreateMapInstance(int pMapId, MapItemSavedData pMapData) {
|
||||
return this.maps.compute(pMapId, (p_182563_, p_182564_) -> {
|
||||
if (p_182564_ == null) {
|
||||
return new MapRenderer.MapInstance(p_182563_, pMapData);
|
||||
} else {
|
||||
p_182564_.replaceMapData(pMapData);
|
||||
return p_182564_;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the currently loaded maps and removes their corresponding textures
|
||||
*/
|
||||
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 pId, MapItemSavedData pData) {
|
||||
this.data = pData;
|
||||
this.texture = new DynamicTexture(128, 128, true);
|
||||
ResourceLocation resourcelocation = MapRenderer.this.textureManager.register("map/" + pId, this.texture);
|
||||
this.renderType = RenderType.text(resourcelocation);
|
||||
}
|
||||
|
||||
void replaceMapData(MapItemSavedData pData) {
|
||||
boolean flag = this.data != pData;
|
||||
this.data = pData;
|
||||
this.requiresUpload |= flag;
|
||||
}
|
||||
|
||||
public void forceUpload() {
|
||||
this.requiresUpload = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a map texture.
|
||||
*/
|
||||
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 pPoseStack, MultiBufferSource pBufferSource, boolean pActive, int pPackedLight) {
|
||||
if (this.requiresUpload) {
|
||||
this.updateTexture();
|
||||
this.requiresUpload = false;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
float f = 0.0F;
|
||||
Matrix4f matrix4f = pPoseStack.last().pose();
|
||||
VertexConsumer vertexconsumer = pBufferSource.getBuffer(this.renderType);
|
||||
vertexconsumer.vertex(matrix4f, 0.0F, 128.0F, -0.01F).color(255, 255, 255, 255).uv(0.0F, 1.0F).uv2(pPackedLight).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, 128.0F, 128.0F, -0.01F).color(255, 255, 255, 255).uv(1.0F, 1.0F).uv2(pPackedLight).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, 128.0F, 0.0F, -0.01F).color(255, 255, 255, 255).uv(1.0F, 0.0F).uv2(pPackedLight).endVertex();
|
||||
vertexconsumer.vertex(matrix4f, 0.0F, 0.0F, -0.01F).color(255, 255, 255, 255).uv(0.0F, 0.0F).uv2(pPackedLight).endVertex();
|
||||
int k = 0;
|
||||
|
||||
for(MapDecoration mapdecoration : this.data.getDecorations()) {
|
||||
if (!pActive || mapdecoration.renderOnFrame()) {
|
||||
if (mapdecoration.render(k)) { k++; continue; }
|
||||
pPoseStack.pushPose();
|
||||
pPoseStack.translate(0.0F + (float)mapdecoration.getX() / 2.0F + 64.0F, 0.0F + (float)mapdecoration.getY() / 2.0F + 64.0F, -0.02F);
|
||||
pPoseStack.mulPose(Axis.ZP.rotationDegrees((float)(mapdecoration.getRot() * 360) / 16.0F));
|
||||
pPoseStack.scale(4.0F, 4.0F, 3.0F);
|
||||
pPoseStack.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 = pPoseStack.last().pose();
|
||||
float f5 = -0.001F;
|
||||
VertexConsumer vertexconsumer1 = pBufferSource.getBuffer(MapRenderer.MAP_ICONS);
|
||||
vertexconsumer1.vertex(matrix4f1, -1.0F, 1.0F, (float)k * -0.001F).color(255, 255, 255, 255).uv(f1, f2).uv2(pPackedLight).endVertex();
|
||||
vertexconsumer1.vertex(matrix4f1, 1.0F, 1.0F, (float)k * -0.001F).color(255, 255, 255, 255).uv(f3, f2).uv2(pPackedLight).endVertex();
|
||||
vertexconsumer1.vertex(matrix4f1, 1.0F, -1.0F, (float)k * -0.001F).color(255, 255, 255, 255).uv(f3, f4).uv2(pPackedLight).endVertex();
|
||||
vertexconsumer1.vertex(matrix4f1, -1.0F, -1.0F, (float)k * -0.001F).color(255, 255, 255, 255).uv(f1, f4).uv2(pPackedLight).endVertex();
|
||||
pPoseStack.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);
|
||||
pPoseStack.pushPose();
|
||||
pPoseStack.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);
|
||||
pPoseStack.scale(f7, f7, 1.0F);
|
||||
pPoseStack.translate(0.0F, 0.0F, -0.1F);
|
||||
font.drawInBatch(component, 0.0F, 0.0F, -1, false, pPoseStack.last().pose(), pBufferSource, Font.DisplayMode.NORMAL, Integer.MIN_VALUE, pPackedLight);
|
||||
pPoseStack.popPose();
|
||||
}
|
||||
|
||||
++k;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.texture.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
+71
@@ -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 pX, int pY, int pWidth, int pHeight, Component pMessage) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage);
|
||||
}
|
||||
|
||||
public abstract void onPress();
|
||||
|
||||
protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
pGuiGraphics.setColor(1.0F, 1.0F, 1.0F, this.alpha);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.enableDepthTest();
|
||||
pGuiGraphics.blitNineSliced(WIDGETS_LOCATION, this.getX(), this.getY(), this.getWidth(), this.getHeight(), 20, 4, 200, 20, 0, this.getTextureY());
|
||||
pGuiGraphics.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
int i = getFGColor();
|
||||
this.renderString(pGuiGraphics, minecraft.font, i | Mth.ceil(this.alpha * 255.0F) << 24);
|
||||
}
|
||||
|
||||
public void renderString(GuiGraphics pGuiGraphics, Font pFont, int pColor) {
|
||||
this.renderScrollingString(pGuiGraphics, pFont, 2, pColor);
|
||||
}
|
||||
|
||||
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 pMouseX, double pMouseY) {
|
||||
this.onPress();
|
||||
}
|
||||
|
||||
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
if (this.active && this.visible) {
|
||||
if (CommonInputs.selected(pKeyCode)) {
|
||||
this.playDownSound(Minecraft.getInstance().getSoundManager());
|
||||
this.onPress();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -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 pOptions, int pX, int pY, int pWidth, int pHeight, double pValue) {
|
||||
super(pX, pY, pWidth, pHeight, CommonComponents.EMPTY, pValue);
|
||||
this.options = pOptions;
|
||||
}
|
||||
}
|
||||
+172
@@ -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 pX, int pY, int pWidth, int pHeight, Component pMessage) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage);
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
|
||||
if (!this.visible) {
|
||||
return false;
|
||||
} else {
|
||||
boolean flag = this.withinContentAreaPoint(pMouseX, pMouseY);
|
||||
boolean flag1 = this.scrollbarVisible() && pMouseX >= (double)(this.getX() + this.width) && pMouseX <= (double)(this.getX() + this.width + 8) && pMouseY >= (double)this.getY() && pMouseY < (double)(this.getY() + this.height);
|
||||
if (flag1 && pButton == 0) {
|
||||
this.scrolling = true;
|
||||
return true;
|
||||
} else {
|
||||
return flag || flag1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseReleased(double pMouseX, double pMouseY, int pButton) {
|
||||
if (pButton == 0) {
|
||||
this.scrolling = false;
|
||||
}
|
||||
|
||||
return super.mouseReleased(pMouseX, pMouseY, pButton);
|
||||
}
|
||||
|
||||
public boolean mouseDragged(double pMouseX, double pMouseY, int pButton, double pDragX, double pDragY) {
|
||||
if (this.visible && this.isFocused() && this.scrolling) {
|
||||
if (pMouseY < (double)this.getY()) {
|
||||
this.setScrollAmount(0.0D);
|
||||
} else if (pMouseY > (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 + pDragY * d0);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double pMouseX, double pMouseY, double pDelta) {
|
||||
if (!this.visible) {
|
||||
return false;
|
||||
} else {
|
||||
this.setScrollAmount(this.scrollAmount - pDelta * this.scrollRate());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
boolean flag = pKeyCode == 265;
|
||||
boolean flag1 = pKeyCode == 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(pKeyCode, pScanCode, pModifiers);
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
if (this.visible) {
|
||||
this.renderBackground(pGuiGraphics);
|
||||
pGuiGraphics.enableScissor(this.getX() + 1, this.getY() + 1, this.getX() + this.width - 1, this.getY() + this.height - 1);
|
||||
pGuiGraphics.pose().pushPose();
|
||||
pGuiGraphics.pose().translate(0.0D, -this.scrollAmount, 0.0D);
|
||||
this.renderContents(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
|
||||
pGuiGraphics.pose().popPose();
|
||||
pGuiGraphics.disableScissor();
|
||||
this.renderDecorations(pGuiGraphics);
|
||||
}
|
||||
}
|
||||
|
||||
private int getScrollBarHeight() {
|
||||
return Mth.clamp((int)((float)(this.height * this.height) / (float)this.getContentHeight()), 32, this.height);
|
||||
}
|
||||
|
||||
protected void renderDecorations(GuiGraphics pGuiGraphics) {
|
||||
if (this.scrollbarVisible()) {
|
||||
this.renderScrollBar(pGuiGraphics);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected int innerPadding() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected int totalInnerPadding() {
|
||||
return this.innerPadding() * 2;
|
||||
}
|
||||
|
||||
protected double scrollAmount() {
|
||||
return this.scrollAmount;
|
||||
}
|
||||
|
||||
protected void setScrollAmount(double pScrollAmount) {
|
||||
this.scrollAmount = Mth.clamp(pScrollAmount, 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 pGuiGraphics) {
|
||||
this.renderBorder(pGuiGraphics, this.getX(), this.getY(), this.getWidth(), this.getHeight());
|
||||
}
|
||||
|
||||
protected void renderBorder(GuiGraphics pGuiGraphics, int pX, int pY, int pWidth, int pHeight) {
|
||||
int i = this.isFocused() ? -1 : -6250336;
|
||||
pGuiGraphics.fill(pX, pY, pX + pWidth, pY + pHeight, i);
|
||||
pGuiGraphics.fill(pX + 1, pY + 1, pX + pWidth - 1, pY + pHeight - 1, -16777216);
|
||||
}
|
||||
|
||||
private void renderScrollBar(GuiGraphics pGuiGraphics) {
|
||||
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;
|
||||
pGuiGraphics.fill(j, l, k, i1, -8355712);
|
||||
pGuiGraphics.fill(j, l, k - 1, i1 - 1, -4144960);
|
||||
}
|
||||
|
||||
protected boolean withinContentAreaTopBottom(int pTop, int pBottom) {
|
||||
return (double)pBottom - this.scrollAmount >= (double)this.getY() && (double)pTop - this.scrollAmount <= (double)(this.getY() + this.height);
|
||||
}
|
||||
|
||||
protected boolean withinContentAreaPoint(double pX, double pY) {
|
||||
return pX >= (double)this.getX() && pX < (double)(this.getX() + this.width) && pY >= (double)this.getY() && pY < (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 pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick);
|
||||
}
|
||||
+574
@@ -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 pMinecraft, int pWidth, int pHeight, int pY0, int pY1, int pItemHeight) {
|
||||
this.minecraft = pMinecraft;
|
||||
this.width = pWidth;
|
||||
this.height = pHeight;
|
||||
this.y0 = pY0;
|
||||
this.y1 = pY1;
|
||||
this.itemHeight = pItemHeight;
|
||||
this.x0 = 0;
|
||||
this.x1 = pWidth;
|
||||
}
|
||||
|
||||
public void setRenderSelection(boolean pRenderSelection) {
|
||||
this.renderSelection = pRenderSelection;
|
||||
}
|
||||
|
||||
protected void setRenderHeader(boolean pRenderHeader, int pHeaderHeight) {
|
||||
this.renderHeader = pRenderHeader;
|
||||
this.headerHeight = pHeaderHeight;
|
||||
if (!pRenderHeader) {
|
||||
this.headerHeight = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getRowWidth() {
|
||||
return 220;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public E getSelected() {
|
||||
return this.selected;
|
||||
}
|
||||
|
||||
public void setSelected(@Nullable E pSelected) {
|
||||
this.selected = pSelected;
|
||||
}
|
||||
|
||||
public E getFirstElement() {
|
||||
return this.children.get(0);
|
||||
}
|
||||
|
||||
public void setRenderBackground(boolean pRenderBackground) {
|
||||
this.renderBackground = pRenderBackground;
|
||||
}
|
||||
|
||||
public void setRenderTopAndBottom(boolean pRenderTopAndButton) {
|
||||
this.renderTopAndBottom = pRenderTopAndButton;
|
||||
}
|
||||
|
||||
@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> pEntries) {
|
||||
this.clearEntries();
|
||||
this.children.addAll(pEntries);
|
||||
}
|
||||
|
||||
protected E getEntry(int pIndex) {
|
||||
return this.children().get(pIndex);
|
||||
}
|
||||
|
||||
protected int addEntry(E pEntry) {
|
||||
this.children.add(pEntry);
|
||||
return this.children.size() - 1;
|
||||
}
|
||||
|
||||
protected void addEntryToTop(E pEntry) {
|
||||
double d0 = (double)this.getMaxScroll() - this.getScrollAmount();
|
||||
this.children.add(0, pEntry);
|
||||
this.setScrollAmount((double)this.getMaxScroll() - d0);
|
||||
}
|
||||
|
||||
protected boolean removeEntryFromTop(E pEntry) {
|
||||
double d0 = (double)this.getMaxScroll() - this.getScrollAmount();
|
||||
boolean flag = this.removeEntry(pEntry);
|
||||
this.setScrollAmount((double)this.getMaxScroll() - d0);
|
||||
return flag;
|
||||
}
|
||||
|
||||
protected int getItemCount() {
|
||||
return this.children().size();
|
||||
}
|
||||
|
||||
protected boolean isSelectedItem(int pIndex) {
|
||||
return Objects.equals(this.getSelected(), this.children().get(pIndex));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected final E getEntryAtPosition(double pMouseX, double pMouseY) {
|
||||
int i = this.getRowWidth() / 2;
|
||||
int j = this.x0 + this.width / 2;
|
||||
int k = j - i;
|
||||
int l = j + i;
|
||||
int i1 = Mth.floor(pMouseY - (double)this.y0) - this.headerHeight + (int)this.getScrollAmount() - 4;
|
||||
int j1 = i1 / this.itemHeight;
|
||||
return (E)(pMouseX < (double)this.getScrollbarPosition() && pMouseX >= (double)k && pMouseX <= (double)l && j1 >= 0 && i1 >= 0 && j1 < this.getItemCount() ? this.children().get(j1) : null);
|
||||
}
|
||||
|
||||
public void updateSize(int pWidth, int pHeight, int pY0, int pY1) {
|
||||
this.width = pWidth;
|
||||
this.height = pHeight;
|
||||
this.y0 = pY0;
|
||||
this.y1 = pY1;
|
||||
this.x0 = 0;
|
||||
this.x1 = pWidth;
|
||||
}
|
||||
|
||||
public void setLeftPos(int pX0) {
|
||||
this.x0 = pX0;
|
||||
this.x1 = pX0 + this.width;
|
||||
}
|
||||
|
||||
protected int getMaxPosition() {
|
||||
return this.getItemCount() * this.itemHeight + this.headerHeight;
|
||||
}
|
||||
|
||||
protected void clickedHeader(int pMouseX, int pMouseY) {
|
||||
}
|
||||
|
||||
protected void renderHeader(GuiGraphics pGuiGraphics, int pX, int pY) {
|
||||
}
|
||||
|
||||
protected void renderBackground(GuiGraphics pGuiGraphics) {
|
||||
}
|
||||
|
||||
protected void renderDecorations(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) {
|
||||
}
|
||||
|
||||
public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
this.renderBackground(pGuiGraphics);
|
||||
int i = this.getScrollbarPosition();
|
||||
int j = i + 6;
|
||||
this.hovered = this.isMouseOver((double)pMouseX, (double)pMouseY) ? this.getEntryAtPosition((double)pMouseX, (double)pMouseY) : null;
|
||||
if (this.renderBackground) {
|
||||
pGuiGraphics.setColor(0.125F, 0.125F, 0.125F, 1.0F);
|
||||
int k = 32;
|
||||
pGuiGraphics.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);
|
||||
pGuiGraphics.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
int l1 = this.getRowLeft();
|
||||
int l = this.y0 + 4 - (int)this.getScrollAmount();
|
||||
this.enableScissor(pGuiGraphics);
|
||||
if (this.renderHeader) {
|
||||
this.renderHeader(pGuiGraphics, l1, l);
|
||||
}
|
||||
|
||||
this.renderList(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
|
||||
pGuiGraphics.disableScissor();
|
||||
if (this.renderTopAndBottom) {
|
||||
int i1 = 32;
|
||||
pGuiGraphics.setColor(0.25F, 0.25F, 0.25F, 1.0F);
|
||||
pGuiGraphics.blit(Screen.BACKGROUND_LOCATION, this.x0, 0, 0.0F, 0.0F, this.width, this.y0, 32, 32);
|
||||
pGuiGraphics.blit(Screen.BACKGROUND_LOCATION, this.x0, this.y1, 0.0F, (float)this.y1, this.width, this.height - this.y1, 32, 32);
|
||||
pGuiGraphics.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
int j1 = 4;
|
||||
pGuiGraphics.fillGradient(RenderType.guiOverlay(), this.x0, this.y0, this.x1, this.y0 + 4, -16777216, 0, 0);
|
||||
pGuiGraphics.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;
|
||||
}
|
||||
|
||||
pGuiGraphics.fill(i, this.y0, j, this.y1, -16777216);
|
||||
pGuiGraphics.fill(i, k1, j, k1 + j2, -8355712);
|
||||
pGuiGraphics.fill(i, k1, j - 1, k1 + j2 - 1, -4144960);
|
||||
}
|
||||
|
||||
this.renderDecorations(pGuiGraphics, pMouseX, pMouseY);
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
protected void enableScissor(GuiGraphics pGuiGraphics) {
|
||||
pGuiGraphics.enableScissor(this.x0, this.y0, this.x1, this.y1);
|
||||
}
|
||||
|
||||
protected void centerScrollOn(E pEntry) {
|
||||
this.setScrollAmount((double)(this.children().indexOf(pEntry) * this.itemHeight + this.itemHeight / 2 - (this.y1 - this.y0) / 2));
|
||||
}
|
||||
|
||||
protected void ensureVisible(E pEntry) {
|
||||
int i = this.getRowTop(this.children().indexOf(pEntry));
|
||||
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 pScroll) {
|
||||
this.setScrollAmount(this.getScrollAmount() + (double)pScroll);
|
||||
}
|
||||
|
||||
public double getScrollAmount() {
|
||||
return this.scrollAmount;
|
||||
}
|
||||
|
||||
public void setScrollAmount(double pScroll) {
|
||||
this.scrollAmount = Mth.clamp(pScroll, 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 pMouseX, double pMouseY, int pButton) {
|
||||
this.scrolling = pButton == 0 && pMouseX >= (double)this.getScrollbarPosition() && pMouseX < (double)(this.getScrollbarPosition() + 6);
|
||||
}
|
||||
|
||||
protected int getScrollbarPosition() {
|
||||
return this.width / 2 + 124;
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
|
||||
this.updateScrollingState(pMouseX, pMouseY, pButton);
|
||||
if (!this.isMouseOver(pMouseX, pMouseY)) {
|
||||
return false;
|
||||
} else {
|
||||
E e = this.getEntryAtPosition(pMouseX, pMouseY);
|
||||
if (e != null) {
|
||||
if (e.mouseClicked(pMouseX, pMouseY, pButton)) {
|
||||
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 (pButton == 0) {
|
||||
this.clickedHeader((int)(pMouseX - (double)(this.x0 + this.width / 2 - this.getRowWidth() / 2)), (int)(pMouseY - (double)this.y0) + (int)this.getScrollAmount() - 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.scrolling;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseReleased(double pMouseX, double pMouseY, int pButton) {
|
||||
if (this.getFocused() != null) {
|
||||
this.getFocused().mouseReleased(pMouseX, pMouseY, pButton);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean mouseDragged(double pMouseX, double pMouseY, int pButton, double pDragX, double pDragY) {
|
||||
if (super.mouseDragged(pMouseX, pMouseY, pButton, pDragX, pDragY)) {
|
||||
return true;
|
||||
} else if (pButton == 0 && this.scrolling) {
|
||||
if (pMouseY < (double)this.y0) {
|
||||
this.setScrollAmount(0.0D);
|
||||
} else if (pMouseY > (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() + pDragY * d1);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double pMouseX, double pMouseY, double pDelta) {
|
||||
this.setScrollAmount(this.getScrollAmount() - pDelta * (double)this.itemHeight / 2.0D);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setFocused(@Nullable GuiEventListener pListener) {
|
||||
super.setFocused(pListener);
|
||||
int i = this.children.indexOf(pListener);
|
||||
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 pDirection) {
|
||||
return this.nextEntry(pDirection, (p_93510_) -> {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected E nextEntry(ScreenDirection pDirection, Predicate<E> pPredicate) {
|
||||
return this.nextEntry(pDirection, pPredicate, this.getSelected());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected E nextEntry(ScreenDirection pDirection, Predicate<E> pPredicate, @Nullable E p_265379_) {
|
||||
byte b0;
|
||||
switch (pDirection) {
|
||||
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 (pPredicate.test(e)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (E)null;
|
||||
}
|
||||
|
||||
public boolean isMouseOver(double pMouseX, double pMouseY) {
|
||||
return pMouseY >= (double)this.y0 && pMouseY <= (double)this.y1 && pMouseX >= (double)this.x0 && pMouseX <= (double)this.x1;
|
||||
}
|
||||
|
||||
protected void renderList(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
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(pGuiGraphics, pMouseX, pMouseY, pPartialTick, i1, i, j1, j, k);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void renderItem(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick, int pIndex, int pLeft, int pTop, int pWidth, int pHeight) {
|
||||
E e = this.getEntry(pIndex);
|
||||
e.renderBack(pGuiGraphics, pIndex, pTop, pLeft, pWidth, pHeight, pMouseX, pMouseY, Objects.equals(this.hovered, e), pPartialTick);
|
||||
if (this.renderSelection && this.isSelectedItem(pIndex)) {
|
||||
int i = this.isFocused() ? -1 : -8355712;
|
||||
this.renderSelection(pGuiGraphics, pTop, pWidth, pHeight, i, -16777216);
|
||||
}
|
||||
|
||||
e.render(pGuiGraphics, pIndex, pTop, pLeft, pWidth, pHeight, pMouseX, pMouseY, Objects.equals(this.hovered, e), pPartialTick);
|
||||
}
|
||||
|
||||
protected void renderSelection(GuiGraphics pGuiGraphics, int pTop, int pWidth, int pHeight, int pOuterColor, int pInnerColor) {
|
||||
int i = this.x0 + (this.width - pWidth) / 2;
|
||||
int j = this.x0 + (this.width + pWidth) / 2;
|
||||
pGuiGraphics.fill(i, pTop - 2, j, pTop + pHeight + 2, pOuterColor);
|
||||
pGuiGraphics.fill(i + 1, pTop - 1, j - 1, pTop + pHeight + 1, pInnerColor);
|
||||
}
|
||||
|
||||
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 pIndex) {
|
||||
return this.y0 + 4 - (int)this.getScrollAmount() + pIndex * this.itemHeight + this.headerHeight;
|
||||
}
|
||||
|
||||
protected int getRowBottom(int pIndex) {
|
||||
return this.getRowTop(pIndex) + 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 pIndex) {
|
||||
E e = this.children.get(pIndex);
|
||||
return (E)(this.removeEntry(this.children.get(pIndex)) ? e : null);
|
||||
}
|
||||
|
||||
protected boolean removeEntry(E pEntry) {
|
||||
boolean flag = this.children.remove(pEntry);
|
||||
if (flag && pEntry == this.getSelected()) {
|
||||
this.setSelected((E)null);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected E getHovered() {
|
||||
return this.hovered;
|
||||
}
|
||||
|
||||
void bindEntryToSelf(AbstractSelectionList.Entry<E> pEntry) {
|
||||
pEntry.list = this;
|
||||
}
|
||||
|
||||
protected void narrateListElementPosition(NarrationElementOutput pNarrationElementOutput, E pEntry) {
|
||||
List<E> list = this.children();
|
||||
if (list.size() > 1) {
|
||||
int i = list.indexOf(pEntry);
|
||||
if (i != -1) {
|
||||
pNarrationElementOutput.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 pFocused) {
|
||||
}
|
||||
|
||||
public boolean isFocused() {
|
||||
return this.list.getFocused() == this;
|
||||
}
|
||||
|
||||
public abstract void render(GuiGraphics pGuiGraphics, int pIndex, int pTop, int pLeft, int pWidth, int pHeight, int pMouseX, int pMouseY, boolean p_93531_, float pPartialTick);
|
||||
|
||||
public void renderBack(GuiGraphics pGuiGraphics, int pIndex, int pTop, int pLeft, int pWidth, int pHeight, int pMouseX, int pMouseY, boolean pIsMouseOver, float pPartialTick) {
|
||||
}
|
||||
|
||||
public boolean isMouseOver(double pMouseX, double pMouseY) {
|
||||
return Objects.equals(this.list.getEntryAtPosition(pMouseX, pMouseY), this);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class TrackedList extends AbstractList<E> {
|
||||
private final List<E> delegate = Lists.newArrayList();
|
||||
|
||||
public E get(int pIndex) {
|
||||
return this.delegate.get(pIndex);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.delegate.size();
|
||||
}
|
||||
|
||||
public E set(int pIndex, E pEntry) {
|
||||
E e = this.delegate.set(pIndex, pEntry);
|
||||
AbstractSelectionList.this.bindEntryToSelf(pEntry);
|
||||
return e;
|
||||
}
|
||||
|
||||
public void add(int pIndex, E pEntry) {
|
||||
this.delegate.add(pIndex, pEntry);
|
||||
AbstractSelectionList.this.bindEntryToSelf(pEntry);
|
||||
}
|
||||
|
||||
public E remove(int pIndex) {
|
||||
return this.delegate.remove(pIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
+144
@@ -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 pX, int pY, int pWidth, int pHeight, Component pMessage, double pValue) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage);
|
||||
this.value = pValue;
|
||||
}
|
||||
|
||||
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 pNarrationElementOutput) {
|
||||
pNarrationElementOutput.add(NarratedElementType.TITLE, this.createNarrationMessage());
|
||||
if (this.active) {
|
||||
if (this.isFocused()) {
|
||||
pNarrationElementOutput.add(NarratedElementType.USAGE, Component.translatable("narration.slider.usage.focused"));
|
||||
} else {
|
||||
pNarrationElementOutput.add(NarratedElementType.USAGE, Component.translatable("narration.slider.usage.hovered"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
pGuiGraphics.setColor(1.0F, 1.0F, 1.0F, this.alpha);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableDepthTest();
|
||||
pGuiGraphics.blitNineSliced(SLIDER_LOCATION, this.getX(), this.getY(), this.getWidth(), this.getHeight(), 20, 4, 200, 20, 0, this.getTextureY());
|
||||
pGuiGraphics.blitNineSliced(SLIDER_LOCATION, this.getX() + (int)(this.value * (double)(this.width - 8)), this.getY(), 8, 20, 20, 4, 200, 20, 0, this.getHandleTextureY());
|
||||
pGuiGraphics.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
int i = this.active ? 16777215 : 10526880;
|
||||
this.renderScrollingString(pGuiGraphics, minecraft.font, 2, i | Mth.ceil(this.alpha * 255.0F) << 24);
|
||||
}
|
||||
|
||||
public void onClick(double pMouseX, double pMouseY) {
|
||||
this.setValueFromMouse(pMouseX);
|
||||
}
|
||||
|
||||
public void setFocused(boolean pFocused) {
|
||||
super.setFocused(pFocused);
|
||||
if (!pFocused) {
|
||||
this.canChangeValue = false;
|
||||
} else {
|
||||
InputType inputtype = Minecraft.getInstance().getLastInputType();
|
||||
if (inputtype == InputType.MOUSE || inputtype == InputType.KEYBOARD_TAB) {
|
||||
this.canChangeValue = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
if (CommonInputs.selected(pKeyCode)) {
|
||||
this.canChangeValue = !this.canChangeValue;
|
||||
return true;
|
||||
} else {
|
||||
if (this.canChangeValue) {
|
||||
boolean flag = pKeyCode == 263;
|
||||
if (flag || pKeyCode == 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 pMouseX) {
|
||||
this.setValue((pMouseX - (double)(this.getX() + 4)) / (double)(this.width - 8));
|
||||
}
|
||||
|
||||
private void setValue(double pValue) {
|
||||
double d0 = this.value;
|
||||
this.value = Mth.clamp(pValue, 0.0D, 1.0D);
|
||||
if (d0 != this.value) {
|
||||
this.applyValue();
|
||||
}
|
||||
|
||||
this.updateMessage();
|
||||
}
|
||||
|
||||
protected void onDrag(double pMouseX, double pMouseY, double pDragX, double pDragY) {
|
||||
this.setValueFromMouse(pMouseX);
|
||||
super.onDrag(pMouseX, pMouseY, pDragX, pDragY);
|
||||
}
|
||||
|
||||
public void playDownSound(SoundManager pHandler) {
|
||||
}
|
||||
|
||||
public void onRelease(double pMouseX, double pMouseY) {
|
||||
super.playDownSound(Minecraft.getInstance().getSoundManager());
|
||||
}
|
||||
|
||||
protected abstract void updateMessage();
|
||||
|
||||
protected abstract void applyValue();
|
||||
}
|
||||
+34
@@ -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 pX, int pY, int pWidth, int pHeight, Component pMessage, Font pFont) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage);
|
||||
this.font = pFont;
|
||||
}
|
||||
|
||||
protected void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
}
|
||||
|
||||
public AbstractStringWidget setColor(int pColor) {
|
||||
this.color = pColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected final Font getFont() {
|
||||
return this.font;
|
||||
}
|
||||
|
||||
protected final int getColor() {
|
||||
return this.color;
|
||||
}
|
||||
}
|
||||
+347
@@ -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 pX, int pY, int pWidth, int pHeight, Component pMessage) {
|
||||
this.x = pX;
|
||||
this.y = pY;
|
||||
this.width = pWidth;
|
||||
this.height = pHeight;
|
||||
this.message = pMessage;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
if (this.visible) {
|
||||
this.isHovered = pMouseX >= this.getX() && pMouseY >= this.getY() && pMouseX < this.getX() + this.width && pMouseY < this.getY() + this.height;
|
||||
this.renderWidget(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
|
||||
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 pTooltip) {
|
||||
this.tooltip = pTooltip;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Tooltip getTooltip() {
|
||||
return this.tooltip;
|
||||
}
|
||||
|
||||
public void setTooltipDelay(int pTooltipMsDelay) {
|
||||
this.tooltipMsDelay = pTooltipMsDelay;
|
||||
}
|
||||
|
||||
protected MutableComponent createNarrationMessage() {
|
||||
return wrapDefaultNarrationMessage(this.getMessage());
|
||||
}
|
||||
|
||||
public static MutableComponent wrapDefaultNarrationMessage(Component pMessage) {
|
||||
return Component.translatable("gui.narrate.button", pMessage);
|
||||
}
|
||||
|
||||
protected abstract void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick);
|
||||
|
||||
protected static void renderScrollingString(GuiGraphics pGuiGraphics, Font pFont, Component pText, int pMinX, int pMinY, int pMaxX, int pMaxY, int pColor) {
|
||||
int i = pFont.width(pText);
|
||||
int j = (pMinY + pMaxY - 9) / 2 + 1;
|
||||
int k = pMaxX - pMinX;
|
||||
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);
|
||||
pGuiGraphics.enableScissor(pMinX, pMinY, pMaxX, pMaxY);
|
||||
pGuiGraphics.drawString(pFont, pText, pMinX - (int)d3, j, pColor);
|
||||
pGuiGraphics.disableScissor();
|
||||
} else {
|
||||
pGuiGraphics.drawCenteredString(pFont, pText, (pMinX + pMaxX) / 2, j, pColor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void renderScrollingString(GuiGraphics pGuiGraphics, Font pFont, int pWidth, int pColor) {
|
||||
int i = this.getX() + pWidth;
|
||||
int j = this.getX() + this.getWidth() - pWidth;
|
||||
renderScrollingString(pGuiGraphics, pFont, this.getMessage(), i, this.getY(), j, this.getY() + this.getHeight(), pColor);
|
||||
}
|
||||
|
||||
public void renderTexture(GuiGraphics pGuiGraphics, ResourceLocation pTexture, int pX, int pY, int pUOffset, int pVOffset, int p_283472_, int pWidth, int pHeight, int pTextureWidth, int pTextureHeight) {
|
||||
int i = pVOffset;
|
||||
if (!this.isActive()) {
|
||||
i = pVOffset + p_283472_ * 2;
|
||||
} else if (this.isHoveredOrFocused()) {
|
||||
i = pVOffset + p_283472_;
|
||||
}
|
||||
|
||||
RenderSystem.enableDepthTest();
|
||||
pGuiGraphics.blit(pTexture, pX, pY, (float)pUOffset, (float)i, pWidth, pHeight, pTextureWidth, pTextureHeight);
|
||||
}
|
||||
|
||||
public void onClick(double pMouseX, double pMouseY) {
|
||||
}
|
||||
|
||||
public void onRelease(double pMouseX, double pMouseY) {
|
||||
}
|
||||
|
||||
protected void onDrag(double pMouseX, double pMouseY, double pDragX, double pDragY) {
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
|
||||
if (this.active && this.visible) {
|
||||
if (this.isValidClickButton(pButton)) {
|
||||
boolean flag = this.clicked(pMouseX, pMouseY);
|
||||
if (flag) {
|
||||
this.playDownSound(Minecraft.getInstance().getSoundManager());
|
||||
this.onClick(pMouseX, pMouseY);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseReleased(double pMouseX, double pMouseY, int pButton) {
|
||||
if (this.isValidClickButton(pButton)) {
|
||||
this.onRelease(pMouseX, pMouseY);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isValidClickButton(int pButton) {
|
||||
return pButton == 0;
|
||||
}
|
||||
|
||||
public boolean mouseDragged(double pMouseX, double pMouseY, int pButton, double pDragX, double pDragY) {
|
||||
if (this.isValidClickButton(pButton)) {
|
||||
this.onDrag(pMouseX, pMouseY, pDragX, pDragY);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean clicked(double pMouseX, double pMouseY) {
|
||||
return this.active && this.visible && pMouseX >= (double)this.getX() && pMouseY >= (double)this.getY() && pMouseX < (double)(this.getX() + this.width) && pMouseY < (double)(this.getY() + this.height);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath nextFocusPath(FocusNavigationEvent pEvent) {
|
||||
if (this.active && this.visible) {
|
||||
return !this.isFocused() ? ComponentPath.leaf(this) : null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMouseOver(double pMouseX, double pMouseY) {
|
||||
return this.active && this.visible && pMouseX >= (double)this.getX() && pMouseY >= (double)this.getY() && pMouseX < (double)(this.getX() + this.width) && pMouseY < (double)(this.getY() + this.height);
|
||||
}
|
||||
|
||||
public void playDownSound(SoundManager pHandler) {
|
||||
pHandler.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public void setWidth(int pWidth) {
|
||||
this.width = pWidth;
|
||||
}
|
||||
|
||||
public void setHeight(int value) {
|
||||
this.height = value;
|
||||
}
|
||||
|
||||
public void setAlpha(float pAlpha) {
|
||||
this.alpha = pAlpha;
|
||||
}
|
||||
|
||||
public void setMessage(Component pMessage) {
|
||||
this.message = pMessage;
|
||||
}
|
||||
|
||||
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 pFocused) {
|
||||
this.focused = pFocused;
|
||||
}
|
||||
|
||||
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 pNarrationElementOutput) {
|
||||
this.updateWidgetNarration(pNarrationElementOutput);
|
||||
if (this.tooltip != null) {
|
||||
this.tooltip.updateNarration(pNarrationElementOutput);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected abstract void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput);
|
||||
|
||||
protected void defaultButtonNarrationText(NarrationElementOutput pNarrationElementOutput) {
|
||||
pNarrationElementOutput.add(NarratedElementType.TITLE, this.createNarrationMessage());
|
||||
if (this.active) {
|
||||
if (this.isFocused()) {
|
||||
pNarrationElementOutput.add(NarratedElementType.USAGE, Component.translatable("narration.button.usage.focused"));
|
||||
} else {
|
||||
pNarrationElementOutput.add(NarratedElementType.USAGE, Component.translatable("narration.button.usage.hovered"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public void setX(int pX) {
|
||||
this.x = pX;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public void setY(int pY) {
|
||||
this.y = pY;
|
||||
}
|
||||
|
||||
public void visitWidgets(Consumer<AbstractWidget> pConsumer) {
|
||||
pConsumer.accept(this);
|
||||
}
|
||||
|
||||
public ScreenRectangle getRectangle() {
|
||||
return LayoutElement.super.getRectangle();
|
||||
}
|
||||
|
||||
public int getTabOrderGroup() {
|
||||
return this.tabOrderGroup;
|
||||
}
|
||||
|
||||
public void setTabOrderGroup(int pTabOrderGroup) {
|
||||
this.tabOrderGroup = pTabOrderGroup;
|
||||
}
|
||||
}
|
||||
+47
@@ -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 pFont, Component pMessage, int pMaxWidth) {
|
||||
super(pMessage, pFont);
|
||||
this.setMaxWidth(pMaxWidth);
|
||||
this.setCentered(true);
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
protected void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
pNarrationElementOutput.add(NarratedElementType.TITLE, this.getMessage());
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
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;
|
||||
pGuiGraphics.fill(i - 1, j - 1, i, l + 1, i1);
|
||||
pGuiGraphics.fill(k, j - 1, k + 1, l + 1, i1);
|
||||
pGuiGraphics.fill(i, j, k, j - 1, i1);
|
||||
pGuiGraphics.fill(i, l, k, l + 1, i1);
|
||||
pGuiGraphics.fill(i, j, k, l, 1426063360);
|
||||
super.renderWidget(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
|
||||
}
|
||||
|
||||
public void playDownSound(SoundManager pHandler) {
|
||||
}
|
||||
}
|
||||
+145
@@ -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 pMinecraft) {
|
||||
this.minecraft = pMinecraft;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics pGuiGraphics) {
|
||||
if (!this.events.isEmpty()) {
|
||||
int i = pGuiGraphics.guiWidth();
|
||||
int j = 12;
|
||||
|
||||
for(LerpingBossEvent lerpingbossevent : this.events.values()) {
|
||||
int k = i / 2 - 91;
|
||||
var event = net.minecraftforge.client.ForgeHooksClient.onCustomizeBossEventProgress(pGuiGraphics, this.minecraft.getWindow(), lerpingbossevent, k, j, 10 + this.minecraft.font.lineHeight);
|
||||
if (!event.isCanceled()) {
|
||||
this.drawBar(pGuiGraphics, k, j, lerpingbossevent);
|
||||
Component component = lerpingbossevent.getName();
|
||||
int l = this.minecraft.font.width(component);
|
||||
int i1 = i / 2 - l / 2;
|
||||
int j1 = j - 9;
|
||||
pGuiGraphics.drawString(this.minecraft.font, component, i1, j1, 16777215);
|
||||
}
|
||||
j += event.getIncrement();
|
||||
if (j >= pGuiGraphics.guiHeight() / 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void drawBar(GuiGraphics pGuiGraphics, int pX, int pY, BossEvent pBossEvent) {
|
||||
this.drawBar(pGuiGraphics, pX, pY, pBossEvent, 182, 0);
|
||||
int i = (int)(pBossEvent.getProgress() * 183.0F);
|
||||
if (i > 0) {
|
||||
this.drawBar(pGuiGraphics, pX, pY, pBossEvent, i, 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawBar(GuiGraphics pGuiGraphics, int pX, int pY, BossEvent pBossEvent, int p_283619_, int p_281636_) {
|
||||
pGuiGraphics.blit(GUI_BARS_LOCATION, pX, pY, 0, pBossEvent.getColor().ordinal() * 5 * 2 + p_281636_, p_283619_, 5);
|
||||
if (pBossEvent.getOverlay() != BossEvent.BossBarOverlay.PROGRESS) {
|
||||
RenderSystem.enableBlend();
|
||||
pGuiGraphics.blit(GUI_BARS_LOCATION, pX, pY, 0, 80 + (pBossEvent.getOverlay().ordinal() - 1) * 5 * 2 + p_281636_, p_283619_, 5);
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void update(ClientboundBossEventPacket pPacket) {
|
||||
pPacket.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;
|
||||
}
|
||||
}
|
||||
+117
@@ -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 pMessage, Button.OnPress pOnPress) {
|
||||
return new Button.Builder(pMessage, pOnPress);
|
||||
}
|
||||
|
||||
protected Button(int pX, int pY, int pWidth, int pHeight, Component pMessage, Button.OnPress pOnPress, Button.CreateNarration pCreateNarration) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage);
|
||||
this.onPress = pOnPress;
|
||||
this.createNarration = pCreateNarration;
|
||||
}
|
||||
|
||||
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 pNarrationElementOutput) {
|
||||
this.defaultButtonNarrationText(pNarrationElementOutput);
|
||||
}
|
||||
|
||||
@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 pMessage, Button.OnPress pOnPress) {
|
||||
this.message = pMessage;
|
||||
this.onPress = pOnPress;
|
||||
}
|
||||
|
||||
public Button.Builder pos(int pX, int pY) {
|
||||
this.x = pX;
|
||||
this.y = pY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button.Builder width(int pWidth) {
|
||||
this.width = pWidth;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button.Builder size(int pWidth, int pHeight) {
|
||||
this.width = pWidth;
|
||||
this.height = pHeight;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button.Builder bounds(int pX, int pY, int pWidth, int pHeight) {
|
||||
return this.pos(pX, pY).size(pWidth, pHeight);
|
||||
}
|
||||
|
||||
public Button.Builder tooltip(@Nullable Tooltip pTooltip) {
|
||||
this.tooltip = pTooltip;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button.Builder createNarration(Button.CreateNarration pCreateNarration) {
|
||||
this.createNarration = pCreateNarration;
|
||||
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> pMessageSupplier);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface OnPress {
|
||||
void onPress(Button pButton);
|
||||
}
|
||||
}
|
||||
+495
@@ -0,0 +1,495 @@
|
||||
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;
|
||||
/** A list of messages previously sent through the chat GUI */
|
||||
private final List<String> recentChat = Lists.newArrayList();
|
||||
/** Chat lines to be displayed in the chat box */
|
||||
private final List<GuiMessage> allMessages = Lists.newArrayList();
|
||||
/** List of the ChatLines currently drawn */
|
||||
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 pMinecraft) {
|
||||
this.minecraft = pMinecraft;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (!this.messageDeletionQueue.isEmpty()) {
|
||||
this.processMessageDeletionQueue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void render(GuiGraphics pGuiGraphics, int pTickCount, int pMouseX, int pMouseY) {
|
||||
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 = pGuiGraphics.guiHeight();
|
||||
pGuiGraphics.pose().pushPose();
|
||||
pGuiGraphics.pose().scale(f, f, 1.0F);
|
||||
pGuiGraphics.pose().translate(4.0F, 0.0F, 0.0F);
|
||||
int i1 = Mth.floor((float)(l - 40) / f);
|
||||
int j1 = this.getMessageEndIndexAt(this.screenToChatX((double)pMouseX), this.screenToChatY((double)pMouseY));
|
||||
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 = pTickCount - 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;
|
||||
pGuiGraphics.pose().pushPose();
|
||||
pGuiGraphics.pose().translate(0.0F, 0.0F, 50.0F);
|
||||
pGuiGraphics.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;
|
||||
pGuiGraphics.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(pGuiGraphics, l4, i5, guimessagetag.icon());
|
||||
}
|
||||
}
|
||||
|
||||
pGuiGraphics.pose().translate(0.0F, 0.0F, 50.0F);
|
||||
pGuiGraphics.drawString(this.minecraft.font, guimessage$line.content(), 0, j4, 16777215 + (j3 << 24));
|
||||
pGuiGraphics.pose().popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long j5 = this.minecraft.getChatListener().queueSize();
|
||||
if (j5 > 0L) {
|
||||
int k5 = (int)(128.0D * d0);
|
||||
int i6 = (int)(255.0D * d1);
|
||||
pGuiGraphics.pose().pushPose();
|
||||
pGuiGraphics.pose().translate(0.0F, (float)i1, 50.0F);
|
||||
pGuiGraphics.fill(-2, 0, k + 4, 9, i6 << 24);
|
||||
pGuiGraphics.pose().translate(0.0F, 0.0F, 50.0F);
|
||||
pGuiGraphics.drawString(this.minecraft.font, Component.translatable("chat.queue", j5), 0, 1, 16777215 + (k5 << 24));
|
||||
pGuiGraphics.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;
|
||||
pGuiGraphics.fill(k7, -i3, k7 + 2, -i3 - l6, j7 + (i7 << 24));
|
||||
pGuiGraphics.fill(k7 + 2, -i3, k7 + 1, -i3 - l6, 13421772 + (i7 << 24));
|
||||
}
|
||||
}
|
||||
|
||||
pGuiGraphics.pose().popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawTagIcon(GuiGraphics pGuiGraphics, int pLeft, int pBottom, GuiMessageTag.Icon pTagIcon) {
|
||||
int i = pBottom - pTagIcon.height - 1;
|
||||
pTagIcon.draw(pGuiGraphics, pLeft, i);
|
||||
}
|
||||
|
||||
private int getTagIconLeft(GuiMessage.Line pLine) {
|
||||
return this.minecraft.font.width(pLine.content()) + 4;
|
||||
}
|
||||
|
||||
private boolean isChatHidden() {
|
||||
return this.minecraft.options.chatVisibility().get() == ChatVisiblity.HIDDEN;
|
||||
}
|
||||
|
||||
private static double getTimeFactor(int pCounter) {
|
||||
double d0 = (double)pCounter / 200.0D;
|
||||
d0 = 1.0D - d0;
|
||||
d0 *= 10.0D;
|
||||
d0 = Mth.clamp(d0, 0.0D, 1.0D);
|
||||
return d0 * d0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the chat.
|
||||
* @param pClearSentMsgHistory Whether to clear the user's sent message history
|
||||
*/
|
||||
public void clearMessages(boolean pClearSentMsgHistory) {
|
||||
this.minecraft.getChatListener().clearQueue();
|
||||
this.messageDeletionQueue.clear();
|
||||
this.trimmedMessages.clear();
|
||||
this.allMessages.clear();
|
||||
if (pClearSentMsgHistory) {
|
||||
this.recentChat.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addMessage(Component pChatComponent) {
|
||||
this.addMessage(pChatComponent, (MessageSignature)null, this.minecraft.isSingleplayer() ? GuiMessageTag.systemSinglePlayer() : GuiMessageTag.system());
|
||||
}
|
||||
|
||||
public void addMessage(Component pChatComponent, @Nullable MessageSignature pHeaderSignature, @Nullable GuiMessageTag pTag) {
|
||||
this.logChatMessage(pChatComponent, pTag);
|
||||
this.addMessage(pChatComponent, pHeaderSignature, this.minecraft.gui.getGuiTicks(), pTag, false);
|
||||
}
|
||||
|
||||
private void logChatMessage(Component pChatComponent, @Nullable GuiMessageTag pTag) {
|
||||
String s = pChatComponent.getString().replaceAll("\r", "\\\\r").replaceAll("\n", "\\\\n");
|
||||
String s1 = Optionull.map(pTag, GuiMessageTag::logTag);
|
||||
if (s1 != null) {
|
||||
LOGGER.info("[{}] [CHAT] {}", s1, s);
|
||||
} else {
|
||||
LOGGER.info("[CHAT] {}", (Object)s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addMessage(Component pChatComponent, @Nullable MessageSignature pHeaderSignature, int pAddedTime, @Nullable GuiMessageTag pTag, boolean pOnlyTrim) {
|
||||
int i = Mth.floor((double)this.getWidth() / this.getScale());
|
||||
if (pTag != null && pTag.icon() != null) {
|
||||
i -= pTag.icon().width + 4 + 2;
|
||||
}
|
||||
|
||||
List<FormattedCharSequence> list = ComponentRenderUtils.wrapComponents(pChatComponent, 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(pAddedTime, formattedcharsequence, pTag, flag1));
|
||||
}
|
||||
|
||||
while(this.trimmedMessages.size() > 100) {
|
||||
this.trimmedMessages.remove(this.trimmedMessages.size() - 1);
|
||||
}
|
||||
|
||||
if (!pOnlyTrim) {
|
||||
this.allMessages.add(0, new GuiMessage(pAddedTime, pChatComponent, pHeaderSignature, pTag));
|
||||
|
||||
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 pMessageSignature) {
|
||||
ChatComponent.DelayedMessageDeletion chatcomponent$delayedmessagedeletion = this.deleteMessageOrDelay(pMessageSignature);
|
||||
if (chatcomponent$delayedmessagedeletion != null) {
|
||||
this.messageDeletionQueue.add(chatcomponent$delayedmessagedeletion);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ChatComponent.DelayedMessageDeletion deleteMessageOrDelay(MessageSignature pMessageSignature) {
|
||||
int i = this.minecraft.gui.getGuiTicks();
|
||||
ListIterator<GuiMessage> listiterator = this.allMessages.listIterator();
|
||||
|
||||
while(listiterator.hasNext()) {
|
||||
GuiMessage guimessage = listiterator.next();
|
||||
if (pMessageSignature.equals(guimessage.signature())) {
|
||||
int j = guimessage.addedTime() + 60;
|
||||
if (i >= j) {
|
||||
listiterator.set(this.createDeletedMarker(guimessage));
|
||||
this.refreshTrimmedMessage();
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ChatComponent.DelayedMessageDeletion(pMessageSignature, j);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private GuiMessage createDeletedMarker(GuiMessage pMessage) {
|
||||
return new GuiMessage(pMessage.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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of messages previously sent through the chat GUI
|
||||
*/
|
||||
public List<String> getRecentChat() {
|
||||
return this.recentChat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this string to the list of sent messages, for recall using the up/down arrow keys
|
||||
*/
|
||||
public void addRecentChat(String pMessage) {
|
||||
if (this.recentChat.isEmpty() || !this.recentChat.get(this.recentChat.size() - 1).equals(pMessage)) {
|
||||
this.recentChat.add(pMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the chat scroll (executed when the GUI is closed, among others)
|
||||
*/
|
||||
public void resetChatScroll() {
|
||||
this.chatScrollbarPos = 0;
|
||||
this.newMessageSinceScroll = false;
|
||||
}
|
||||
|
||||
public void scrollChat(int pPosInc) {
|
||||
this.chatScrollbarPos += pPosInc;
|
||||
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 pMouseX, double pMouseY) {
|
||||
if (this.isChatFocused() && !this.minecraft.options.hideGui && !this.isChatHidden()) {
|
||||
ChatListener chatlistener = this.minecraft.getChatListener();
|
||||
if (chatlistener.queueSize() == 0L) {
|
||||
return false;
|
||||
} else {
|
||||
double d0 = pMouseX - 2.0D;
|
||||
double d1 = (double)this.minecraft.getWindow().getGuiScaledHeight() - pMouseY - 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 pMouseX, double pMouseY) {
|
||||
double d0 = this.screenToChatX(pMouseX);
|
||||
double d1 = this.screenToChatY(pMouseY);
|
||||
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 pMouseX, double pMouseY) {
|
||||
double d0 = this.screenToChatX(pMouseX);
|
||||
double d1 = this.screenToChatY(pMouseY);
|
||||
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 pLine, GuiMessageTag pTag) {
|
||||
if (p_240619_ < 0.0D) {
|
||||
return true;
|
||||
} else {
|
||||
GuiMessageTag.Icon guimessagetag$icon = pTag.icon();
|
||||
if (guimessagetag$icon == null) {
|
||||
return false;
|
||||
} else {
|
||||
int i = this.getTagIconLeft(pLine);
|
||||
int j = i + guimessagetag$icon.width;
|
||||
return p_240619_ >= (double)i && p_240619_ <= (double)j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double screenToChatX(double pX) {
|
||||
return pX / this.getScale() - 4.0D;
|
||||
}
|
||||
|
||||
private double screenToChatY(double pY) {
|
||||
double d0 = (double)this.minecraft.getWindow().getGuiScaledHeight() - pY - 40.0D;
|
||||
return d0 / (this.getScale() * (double)this.getLineHeight());
|
||||
}
|
||||
|
||||
private int getMessageEndIndexAt(double pMouseX, double pMouseY) {
|
||||
int i = this.getMessageLineIndexAt(pMouseX, pMouseY);
|
||||
if (i == -1) {
|
||||
return -1;
|
||||
} else {
|
||||
while(i >= 0) {
|
||||
if (this.trimmedMessages.get(i).endOfEntry()) {
|
||||
return i;
|
||||
}
|
||||
|
||||
--i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
private int getMessageLineIndexAt(double pMouseX, double pMouseY) {
|
||||
if (this.isChatFocused() && !this.minecraft.options.hideGui && !this.isChatHidden()) {
|
||||
if (!(pMouseX < -4.0D) && !(pMouseX > (double)Mth.floor((double)this.getWidth() / this.getScale()))) {
|
||||
int i = Math.min(this.getLinesPerPage(), this.trimmedMessages.size());
|
||||
if (pMouseY >= 0.0D && pMouseY < (double)i) {
|
||||
int j = Mth.floor(pMouseY + (double)this.chatScrollbarPos);
|
||||
if (j >= 0 && j < this.trimmedMessages.size()) {
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the chat GUI is open
|
||||
*/
|
||||
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 pWidth) {
|
||||
int i = 320;
|
||||
int j = 40;
|
||||
return Mth.floor(pWidth * 280.0D + 40.0D);
|
||||
}
|
||||
|
||||
public static int getHeight(double pHeight) {
|
||||
int i = 180;
|
||||
int j = 20;
|
||||
return Mth.floor(pHeight * 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) {
|
||||
}
|
||||
}
|
||||
+65
@@ -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 pX, int pY, int pWidth, int pHeight, Component pMessage, boolean pSelected) {
|
||||
this(pX, pY, pWidth, pHeight, pMessage, pSelected, true);
|
||||
}
|
||||
|
||||
public Checkbox(int pX, int pY, int pWidth, int pHeight, Component pMessage, boolean pSelected, boolean pShowLabel) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage);
|
||||
this.selected = pSelected;
|
||||
this.showLabel = pShowLabel;
|
||||
}
|
||||
|
||||
public void onPress() {
|
||||
this.selected = !this.selected;
|
||||
}
|
||||
|
||||
public boolean selected() {
|
||||
return this.selected;
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
pNarrationElementOutput.add(NarratedElementType.TITLE, this.createNarrationMessage());
|
||||
if (this.active) {
|
||||
if (this.isFocused()) {
|
||||
pNarrationElementOutput.add(NarratedElementType.USAGE, Component.translatable("narration.checkbox.usage.focused"));
|
||||
} else {
|
||||
pNarrationElementOutput.add(NarratedElementType.USAGE, Component.translatable("narration.checkbox.usage.hovered"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
RenderSystem.enableDepthTest();
|
||||
Font font = minecraft.font;
|
||||
pGuiGraphics.setColor(1.0F, 1.0F, 1.0F, this.alpha);
|
||||
RenderSystem.enableBlend();
|
||||
pGuiGraphics.blit(TEXTURE, this.getX(), this.getY(), this.isFocused() ? 20.0F : 0.0F, this.selected ? 20.0F : 0.0F, 20, this.height, 64, 64);
|
||||
pGuiGraphics.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
if (this.showLabel) {
|
||||
pGuiGraphics.drawString(font, this.getMessage(), this.getX() + 24, this.getY() + (this.height - 8) / 2, 14737632 | Mth.ceil(this.alpha * 255.0F) << 24);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+535
@@ -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 pMinecraft, Screen pScreen, EditBox pInput, Font pFont, boolean pCommandsOnly, boolean pOnlyShowIfCursorPastError, int pLineStartOffset, int pSuggestionLineLimit, boolean pAnchorToBottom, int pFillColor) {
|
||||
this.minecraft = pMinecraft;
|
||||
this.screen = pScreen;
|
||||
this.input = pInput;
|
||||
this.font = pFont;
|
||||
this.commandsOnly = pCommandsOnly;
|
||||
this.onlyShowIfCursorPastError = pOnlyShowIfCursorPastError;
|
||||
this.lineStartOffset = pLineStartOffset;
|
||||
this.suggestionLineLimit = pSuggestionLineLimit;
|
||||
this.anchorToBottom = pAnchorToBottom;
|
||||
this.fillColor = pFillColor;
|
||||
pInput.setFormatter(this::formatChat);
|
||||
}
|
||||
|
||||
public void setAllowSuggestions(boolean pAutoSuggest) {
|
||||
this.allowSuggestions = pAutoSuggest;
|
||||
if (!pAutoSuggest) {
|
||||
this.suggestions = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
if (this.suggestions != null && this.suggestions.keyPressed(pKeyCode, pScanCode, pModifiers)) {
|
||||
return true;
|
||||
} else if (this.screen.getFocused() == this.input && pKeyCode == 258) {
|
||||
this.showSuggestions(true);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double pDelta) {
|
||||
return this.suggestions != null && this.suggestions.mouseScrolled(Mth.clamp(pDelta, -1.0D, 1.0D));
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double pMouseX, double pMouseY, int pMouseButton) {
|
||||
return this.suggestions != null && this.suggestions.mouseClicked((int)pMouseX, (int)pMouseY, pMouseButton);
|
||||
}
|
||||
|
||||
public void showSuggestions(boolean pNarrateFirstSuggestion) {
|
||||
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), pNarrateFirstSuggestion);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
this.suggestions = null;
|
||||
}
|
||||
|
||||
private List<Suggestion> sortSuggestions(Suggestions pSuggestions) {
|
||||
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 : pSuggestions.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 pText) {
|
||||
if (Strings.isNullOrEmpty(pText)) {
|
||||
return 0;
|
||||
} else {
|
||||
int i = 0;
|
||||
|
||||
for(Matcher matcher = WHITESPACE_PATTERN.matcher(pText); matcher.find(); i = matcher.end()) {
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
private static FormattedCharSequence getExceptionMessage(CommandSyntaxException pException) {
|
||||
Component component = ComponentUtils.fromMessage(pException.getRawMessage());
|
||||
String s = pException.getContext();
|
||||
return s == null ? component.getVisualOrderText() : Component.translatable("command.context.parse_error", component, pException.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 pChatFormatting) {
|
||||
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(pChatFormatting);
|
||||
|
||||
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 pInputText, String pSuggestionText) {
|
||||
return pSuggestionText.startsWith(pInputText) ? pSuggestionText.substring(pInputText.length()) : null;
|
||||
}
|
||||
|
||||
private static FormattedCharSequence formatText(ParseResults<SharedSuggestionProvider> pProvider, String pCommand, int pMaxLength) {
|
||||
List<FormattedCharSequence> list = Lists.newArrayList();
|
||||
int i = 0;
|
||||
int j = -1;
|
||||
CommandContextBuilder<SharedSuggestionProvider> commandcontextbuilder = pProvider.getContext().getLastChild();
|
||||
|
||||
for(ParsedArgument<SharedSuggestionProvider, ?> parsedargument : commandcontextbuilder.getArguments().values()) {
|
||||
++j;
|
||||
if (j >= ARGUMENT_STYLES.size()) {
|
||||
j = 0;
|
||||
}
|
||||
|
||||
int k = Math.max(parsedargument.getRange().getStart() - pMaxLength, 0);
|
||||
if (k >= pCommand.length()) {
|
||||
break;
|
||||
}
|
||||
|
||||
int l = Math.min(parsedargument.getRange().getEnd() - pMaxLength, pCommand.length());
|
||||
if (l > 0) {
|
||||
list.add(FormattedCharSequence.forward(pCommand.substring(i, k), LITERAL_STYLE));
|
||||
list.add(FormattedCharSequence.forward(pCommand.substring(k, l), ARGUMENT_STYLES.get(j)));
|
||||
i = l;
|
||||
}
|
||||
}
|
||||
|
||||
if (pProvider.getReader().canRead()) {
|
||||
int i1 = Math.max(pProvider.getReader().getCursor() - pMaxLength, 0);
|
||||
if (i1 < pCommand.length()) {
|
||||
int j1 = Math.min(i1 + pProvider.getReader().getRemainingLength(), pCommand.length());
|
||||
list.add(FormattedCharSequence.forward(pCommand.substring(i, i1), LITERAL_STYLE));
|
||||
list.add(FormattedCharSequence.forward(pCommand.substring(i1, j1), UNPARSED_STYLE));
|
||||
i = j1;
|
||||
}
|
||||
}
|
||||
|
||||
list.add(FormattedCharSequence.forward(pCommand.substring(i), LITERAL_STYLE));
|
||||
return FormattedCharSequence.composite(list);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) {
|
||||
if (!this.renderSuggestions(pGuiGraphics, pMouseX, pMouseY)) {
|
||||
this.renderUsage(pGuiGraphics);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean renderSuggestions(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) {
|
||||
if (this.suggestions != null) {
|
||||
this.suggestions.render(pGuiGraphics, pMouseX, pMouseY);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void renderUsage(GuiGraphics pGuiGraphics) {
|
||||
int i = 0;
|
||||
|
||||
for(FormattedCharSequence formattedcharsequence : this.commandUsage) {
|
||||
int j = this.anchorToBottom ? this.screen.height - 14 - 13 - 12 * i : 72 + 12 * i;
|
||||
pGuiGraphics.fill(this.commandUsagePosition - 1, j, this.commandUsagePosition + this.commandUsageWidth + 1, j + 12, this.fillColor);
|
||||
pGuiGraphics.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 pXPos, int pYPos, int pWidth, List<Suggestion> pSuggestionList, boolean pNarrateFirstSuggestion) {
|
||||
int i = pXPos - 1;
|
||||
int j = CommandSuggestions.this.anchorToBottom ? pYPos - 3 - Math.min(pSuggestionList.size(), CommandSuggestions.this.suggestionLineLimit) * 12 : pYPos;
|
||||
this.rect = new Rect2i(i, j, pWidth + 1, Math.min(pSuggestionList.size(), CommandSuggestions.this.suggestionLineLimit) * 12);
|
||||
this.originalContents = CommandSuggestions.this.input.getValue();
|
||||
this.lastNarratedEntry = pNarrateFirstSuggestion ? -1 : 0;
|
||||
this.suggestionList = pSuggestionList;
|
||||
this.select(0);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) {
|
||||
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)pMouseX || this.lastMouse.y != (float)pMouseY;
|
||||
if (flag3) {
|
||||
this.lastMouse = new Vec2((float)pMouseX, (float)pMouseY);
|
||||
}
|
||||
|
||||
if (flag2) {
|
||||
pGuiGraphics.fill(this.rect.getX(), this.rect.getY() - 1, this.rect.getX() + this.rect.getWidth(), this.rect.getY(), CommandSuggestions.this.fillColor);
|
||||
pGuiGraphics.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) {
|
||||
pGuiGraphics.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) {
|
||||
pGuiGraphics.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);
|
||||
pGuiGraphics.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 (pMouseX > this.rect.getX() && pMouseX < this.rect.getX() + this.rect.getWidth() && pMouseY > this.rect.getY() + 12 * l && pMouseY < this.rect.getY() + 12 * l + 12) {
|
||||
if (flag3) {
|
||||
this.select(l + this.offset);
|
||||
}
|
||||
|
||||
flag4 = true;
|
||||
}
|
||||
|
||||
pGuiGraphics.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) {
|
||||
pGuiGraphics.renderTooltip(CommandSuggestions.this.font, ComponentUtils.fromMessage(message), pMouseX, pMouseY);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean mouseClicked(int pMouseX, int pMouseY, int pMouseButton) {
|
||||
if (!this.rect.contains(pMouseX, pMouseY)) {
|
||||
return false;
|
||||
} else {
|
||||
int i = (pMouseY - this.rect.getY()) / 12 + this.offset;
|
||||
if (i >= 0 && i < this.suggestionList.size()) {
|
||||
this.select(i);
|
||||
this.useSuggestion();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double pDelta) {
|
||||
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 - pDelta), 0, Math.max(this.suggestionList.size() - CommandSuggestions.this.suggestionLineLimit, 0));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
if (pKeyCode == 265) {
|
||||
this.cycle(-1);
|
||||
this.tabCycles = false;
|
||||
return true;
|
||||
} else if (pKeyCode == 264) {
|
||||
this.cycle(1);
|
||||
this.tabCycles = false;
|
||||
return true;
|
||||
} else if (pKeyCode == 258) {
|
||||
if (this.tabCycles) {
|
||||
this.cycle(Screen.hasShiftDown() ? -1 : 1);
|
||||
}
|
||||
|
||||
this.useSuggestion();
|
||||
return true;
|
||||
} else if (pKeyCode == 256) {
|
||||
CommandSuggestions.this.hide();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void cycle(int pChange) {
|
||||
this.select(this.current + pChange);
|
||||
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 pIndex) {
|
||||
this.current = pIndex;
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -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 pOnPress) {
|
||||
return TextAndImageButton.builder(Component.translatable("options.language"), Button.WIDGETS_LOCATION, pOnPress).texStart(3, 109).offset(65, 3).yDiffTex(20).usedTextureSize(14, 14).textureSize(256, 256).build();
|
||||
}
|
||||
|
||||
public static TextAndImageButton accessibilityTextAndImage(Button.OnPress pOnPress) {
|
||||
return TextAndImageButton.builder(Component.translatable("options.accessibility.title"), Button.ACCESSIBILITY_TEXTURE, pOnPress).texStart(3, 2).offset(65, 2).yDiffTex(20).usedTextureSize(14, 16).textureSize(32, 64).build();
|
||||
}
|
||||
}
|
||||
+38
@@ -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 pText) {
|
||||
return Minecraft.getInstance().options.chatColors().get() ? pText : ChatFormatting.stripFormatting(pText);
|
||||
}
|
||||
|
||||
public static List<FormattedCharSequence> wrapComponents(FormattedText pComponent, int pMaxWidth, Font pFont) {
|
||||
ComponentCollector componentcollector = new ComponentCollector();
|
||||
pComponent.visit((p_93997_, p_93998_) -> {
|
||||
componentcollector.append(FormattedText.of(stripColor(p_93998_), p_93997_));
|
||||
return Optional.empty();
|
||||
}, Style.EMPTY);
|
||||
List<FormattedCharSequence> list = Lists.newArrayList();
|
||||
pFont.getSplitter().splitLines(componentcollector.getResultOrEmpty(), pMaxWidth, 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);
|
||||
}
|
||||
}
|
||||
+219
@@ -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 pMinecraft, int pWidth, int pHeight, int pY0, int pY1, int pItemHeight) {
|
||||
super(pMinecraft, pWidth, pHeight, pY0, pY1, pItemHeight);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath nextFocusPath(FocusNavigationEvent pEvent) {
|
||||
if (this.getItemCount() == 0) {
|
||||
return null;
|
||||
} else if (!(pEvent instanceof FocusNavigationEvent.ArrowNavigation)) {
|
||||
return super.nextFocusPath(pEvent);
|
||||
} else {
|
||||
FocusNavigationEvent.ArrowNavigation focusnavigationevent$arrownavigation = (FocusNavigationEvent.ArrowNavigation)pEvent;
|
||||
E e = this.getFocused();
|
||||
if (focusnavigationevent$arrownavigation.direction().getAxis() == ScreenAxis.HORIZONTAL && e != null) {
|
||||
return ComponentPath.path(this, e.nextFocusPath(pEvent));
|
||||
} 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 pListener) {
|
||||
super.setFocused(pListener);
|
||||
if (pListener == null) {
|
||||
this.setSelected((E)null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public NarratableEntry.NarrationPriority narrationPriority() {
|
||||
return this.isFocused() ? NarratableEntry.NarrationPriority.FOCUSED : super.narrationPriority();
|
||||
}
|
||||
|
||||
protected boolean isSelectedItem(int pIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void updateNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
E e = this.getHovered();
|
||||
if (e != null) {
|
||||
e.updateNarration(pNarrationElementOutput.nest());
|
||||
this.narrateListElementPosition(pNarrationElementOutput, e);
|
||||
} else {
|
||||
E e1 = this.getFocused();
|
||||
if (e1 != null) {
|
||||
e1.updateNarration(pNarrationElementOutput.nest());
|
||||
this.narrateListElementPosition(pNarrationElementOutput, e1);
|
||||
}
|
||||
}
|
||||
|
||||
pNarrationElementOutput.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 pDragging) {
|
||||
this.dragging = pDragging;
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
|
||||
return ContainerEventHandler.super.mouseClicked(pMouseX, pMouseY, pButton);
|
||||
}
|
||||
|
||||
public void setFocused(@Nullable GuiEventListener pListener) {
|
||||
if (this.focused != null) {
|
||||
this.focused.setFocused(false);
|
||||
}
|
||||
|
||||
if (pListener != null) {
|
||||
pListener.setFocused(true);
|
||||
}
|
||||
|
||||
this.focused = pListener;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GuiEventListener getFocused() {
|
||||
return this.focused;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath focusPathAtIndex(FocusNavigationEvent pEvent, int pIndex) {
|
||||
if (this.children().isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
ComponentPath componentpath = this.children().get(Math.min(pIndex, this.children().size() - 1)).nextFocusPath(pEvent);
|
||||
return ComponentPath.path(this, componentpath);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath nextFocusPath(FocusNavigationEvent pEvent) {
|
||||
if (pEvent instanceof FocusNavigationEvent.ArrowNavigation) {
|
||||
FocusNavigationEvent.ArrowNavigation focusnavigationevent$arrownavigation = (FocusNavigationEvent.ArrowNavigation)pEvent;
|
||||
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(pEvent);
|
||||
if (componentpath != null) {
|
||||
return ComponentPath.path(this, componentpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ContainerEventHandler.super.nextFocusPath(pEvent);
|
||||
}
|
||||
|
||||
public abstract List<? extends NarratableEntry> narratables();
|
||||
|
||||
void updateNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
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) {
|
||||
pNarrationElementOutput.add(NarratedElementType.POSITION, Component.translatable("narrator.position.object_list", screen$narratablesearchresult.index + 1, list.size()));
|
||||
if (screen$narratablesearchresult.priority == NarratableEntry.NarrationPriority.FOCUSED) {
|
||||
pNarrationElementOutput.add(NarratedElementType.USAGE, Component.translatable("narration.component_list.usage"));
|
||||
}
|
||||
}
|
||||
|
||||
screen$narratablesearchresult.entry.updateNarration(pNarrationElementOutput.nest());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+275
@@ -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 pX, int pY, int pWidth, int pHeight, Component pMessage, Component pName, int pIndex, T pValue, CycleButton.ValueListSupplier<T> pValues, Function<T, Component> pValueStringifier, Function<CycleButton<T>, MutableComponent> pNarrationProvider, CycleButton.OnValueChange<T> pOnValueChange, OptionInstance.TooltipSupplier<T> pTooltipSupplier, boolean pDisplayOnlyValue) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage);
|
||||
this.name = pName;
|
||||
this.index = pIndex;
|
||||
this.value = pValue;
|
||||
this.values = pValues;
|
||||
this.valueStringifier = pValueStringifier;
|
||||
this.narrationProvider = pNarrationProvider;
|
||||
this.onValueChange = pOnValueChange;
|
||||
this.displayOnlyValue = pDisplayOnlyValue;
|
||||
this.tooltipSupplier = pTooltipSupplier;
|
||||
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 pDelta) {
|
||||
List<T> list = this.values.getSelectedList();
|
||||
this.index = Mth.positiveModulo(this.index + pDelta, list.size());
|
||||
T t = list.get(this.index);
|
||||
this.updateValue(t);
|
||||
this.onValueChange.onValueChange(this, t);
|
||||
}
|
||||
|
||||
private T getCycledValue(int pDelta) {
|
||||
List<T> list = this.values.getSelectedList();
|
||||
return list.get(Mth.positiveModulo(this.index + pDelta, list.size()));
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double pMouseX, double pMouseY, double pDelta) {
|
||||
if (pDelta > 0.0D) {
|
||||
this.cycleValue(-1);
|
||||
} else if (pDelta < 0.0D) {
|
||||
this.cycleValue(1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setValue(T pValue) {
|
||||
List<T> list = this.values.getSelectedList();
|
||||
int i = list.indexOf(pValue);
|
||||
if (i != -1) {
|
||||
this.index = i;
|
||||
}
|
||||
|
||||
this.updateValue(pValue);
|
||||
}
|
||||
|
||||
private void updateValue(T pValue) {
|
||||
Component component = this.createLabelForValue(pValue);
|
||||
this.setMessage(component);
|
||||
this.value = pValue;
|
||||
this.updateTooltip();
|
||||
}
|
||||
|
||||
private Component createLabelForValue(T pValue) {
|
||||
return (Component)(this.displayOnlyValue ? this.valueStringifier.apply(pValue) : this.createFullName(pValue));
|
||||
}
|
||||
|
||||
private MutableComponent createFullName(T pValue) {
|
||||
return CommonComponents.optionNameValue(this.name, this.valueStringifier.apply(pValue));
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
protected MutableComponent createNarrationMessage() {
|
||||
return this.narrationProvider.apply(this);
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
pNarrationElementOutput.add(NarratedElementType.TITLE, this.createNarrationMessage());
|
||||
if (this.active) {
|
||||
T t = this.getCycledValue(1);
|
||||
Component component = this.createLabelForValue(t);
|
||||
if (this.isFocused()) {
|
||||
pNarrationElementOutput.add(NarratedElementType.USAGE, Component.translatable("narration.cycle_button.usage.focused", component));
|
||||
} else {
|
||||
pNarrationElementOutput.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> pValueStringifier) {
|
||||
return new CycleButton.Builder<>(pValueStringifier);
|
||||
}
|
||||
|
||||
public static CycleButton.Builder<Boolean> booleanBuilder(Component pComponentOn, Component pComponentOff) {
|
||||
return (new CycleButton.Builder<Boolean>((p_168902_) -> {
|
||||
return p_168902_ ? pComponentOn : pComponentOff;
|
||||
})).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 pInitialValue) {
|
||||
return onOffBuilder().withInitialValue(pInitialValue);
|
||||
}
|
||||
|
||||
@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> pValueStringifier) {
|
||||
this.valueStringifier = pValueStringifier;
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withValues(Collection<T> pValues) {
|
||||
return this.withValues(CycleButton.ValueListSupplier.create(pValues));
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public final CycleButton.Builder<T> withValues(T... pValues) {
|
||||
return this.withValues(ImmutableList.copyOf(pValues));
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withValues(List<T> pDefaultList, List<T> pSelectedList) {
|
||||
return this.withValues(CycleButton.ValueListSupplier.create(CycleButton.DEFAULT_ALT_LIST_SELECTOR, pDefaultList, pSelectedList));
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withValues(BooleanSupplier pAltListSelector, List<T> pDefaultList, List<T> pSelectedList) {
|
||||
return this.withValues(CycleButton.ValueListSupplier.create(pAltListSelector, pDefaultList, pSelectedList));
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withValues(CycleButton.ValueListSupplier<T> pValues) {
|
||||
this.values = pValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withTooltip(OptionInstance.TooltipSupplier<T> pTooltipSupplier) {
|
||||
this.tooltipSupplier = pTooltipSupplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withInitialValue(T pInitialValue) {
|
||||
this.initialValue = pInitialValue;
|
||||
int i = this.values.getDefaultList().indexOf(pInitialValue);
|
||||
if (i != -1) {
|
||||
this.initialIndex = i;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> withCustomNarration(Function<CycleButton<T>, MutableComponent> pNarrationProvider) {
|
||||
this.narrationProvider = pNarrationProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CycleButton.Builder<T> displayOnlyValue() {
|
||||
this.displayOnlyValue = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CycleButton<T> create(int pX, int pY, int pWidth, int pHeight, Component pName) {
|
||||
return this.create(pX, pY, pWidth, pHeight, pName, (p_168946_, p_168947_) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public CycleButton<T> create(int pX, int pY, int pWidth, int pHeight, Component pName, CycleButton.OnValueChange<T> pOnValueChange) {
|
||||
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(pName, component));
|
||||
return new CycleButton<>(pX, pY, pWidth, pHeight, component1, pName, this.initialIndex, t, this.values, this.valueStringifier, this.narrationProvider, pOnValueChange, this.tooltipSupplier, this.displayOnlyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface OnValueChange<T> {
|
||||
void onValueChange(CycleButton<T> pCycleButton, T pValue);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface ValueListSupplier<T> {
|
||||
List<T> getSelectedList();
|
||||
|
||||
List<T> getDefaultList();
|
||||
|
||||
static <T> CycleButton.ValueListSupplier<T> create(Collection<T> pValues) {
|
||||
final List<T> list = ImmutableList.copyOf(pValues);
|
||||
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 pAltListSelector, List<T> pDefaultList, List<T> pSelectedList) {
|
||||
final List<T> list = ImmutableList.copyOf(pDefaultList);
|
||||
final List<T> list1 = ImmutableList.copyOf(pSelectedList);
|
||||
return new CycleButton.ValueListSupplier<T>() {
|
||||
public List<T> getSelectedList() {
|
||||
return pAltListSelector.getAsBoolean() ? list1 : list;
|
||||
}
|
||||
|
||||
public List<T> getDefaultList() {
|
||||
return list;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
+548
@@ -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 pMinecraft) {
|
||||
this.minecraft = pMinecraft;
|
||||
this.allocationRateCalculator = new DebugScreenOverlay.AllocationRateCalculator();
|
||||
this.font = pMinecraft.font;
|
||||
}
|
||||
|
||||
public void clearChunkCache() {
|
||||
this.serverChunk = null;
|
||||
this.clientChunk = null;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics pGuiGraphics) {
|
||||
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);
|
||||
pGuiGraphics.drawManaged(() -> {
|
||||
this.drawGameInformation(pGuiGraphics);
|
||||
this.drawSystemInformation(pGuiGraphics);
|
||||
if (this.minecraft.options.renderFpsChart) {
|
||||
int i = pGuiGraphics.guiWidth();
|
||||
this.drawChart(pGuiGraphics, this.minecraft.getFrameTimer(), 0, i / 2, true);
|
||||
IntegratedServer integratedserver = this.minecraft.getSingleplayerServer();
|
||||
if (integratedserver != null) {
|
||||
this.drawChart(pGuiGraphics, integratedserver.getFrameTimer(), i - Math.min(i / 2, 240), i / 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
this.minecraft.getProfiler().pop();
|
||||
}
|
||||
|
||||
protected void drawGameInformation(GuiGraphics pGuiGraphics) {
|
||||
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(pGuiGraphics, list, true);
|
||||
}
|
||||
|
||||
protected void drawSystemInformation(GuiGraphics pGuiGraphics) {
|
||||
List<String> list = this.getSystemInformation();
|
||||
this.renderLines(pGuiGraphics, list, false);
|
||||
}
|
||||
|
||||
private void renderLines(GuiGraphics pGuiGraphics, List<String> pLines, boolean pLeftSide) {
|
||||
int i = 9;
|
||||
|
||||
for(int j = 0; j < pLines.size(); ++j) {
|
||||
String s = pLines.get(j);
|
||||
if (!Strings.isNullOrEmpty(s)) {
|
||||
int k = this.font.width(s);
|
||||
int l = pLeftSide ? 2 : pGuiGraphics.guiWidth() - 2 - k;
|
||||
int i1 = 2 + i * j;
|
||||
pGuiGraphics.fill(l - 1, i1 - 1, l + k + 1, i1 + i - 1, -1873784752);
|
||||
}
|
||||
}
|
||||
|
||||
for(int j1 = 0; j1 < pLines.size(); ++j1) {
|
||||
String s1 = pLines.get(j1);
|
||||
if (!Strings.isNullOrEmpty(s1)) {
|
||||
int k1 = this.font.width(s1);
|
||||
int l1 = pLeftSide ? 2 : pGuiGraphics.guiWidth() - 2 - k1;
|
||||
int i2 = 2 + i * j1;
|
||||
pGuiGraphics.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> pBiomeHolder) {
|
||||
return pBiomeHolder.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<?>> pEntry) {
|
||||
Property<?> property = pEntry.getKey();
|
||||
Comparable<?> comparable = pEntry.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 pGuiGraphics, FrameTimer pDrawTimer, int p_283392_, int p_282726_, boolean pDrawForFps) {
|
||||
int i = pDrawTimer.getLogStart();
|
||||
int j = pDrawTimer.getLogEnd();
|
||||
long[] along = pDrawTimer.getLog();
|
||||
int l = p_283392_;
|
||||
int i1 = Math.max(0, along.length - p_282726_);
|
||||
int j1 = along.length - i1;
|
||||
int $$8 = pDrawTimer.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[pDrawTimer.wrapIndex($$8 + j2)] / 1000000L);
|
||||
l1 = Math.min(l1, k2);
|
||||
i2 = Math.max(i2, k2);
|
||||
k1 += (long)k2;
|
||||
}
|
||||
|
||||
int j3 = pGuiGraphics.guiHeight();
|
||||
pGuiGraphics.fill(RenderType.guiOverlay(), p_283392_, j3 - 60, p_283392_ + j1, j3, -1873784752);
|
||||
|
||||
while($$8 != j) {
|
||||
int k3 = pDrawTimer.scaleSampleTo(along[$$8], pDrawForFps ? 30 : 60, pDrawForFps ? 60 : 20);
|
||||
int l2 = pDrawForFps ? 100 : 60;
|
||||
int i3 = this.getSampleColor(Mth.clamp(k3, 0, l2), 0, l2 / 2, l2);
|
||||
pGuiGraphics.fill(RenderType.guiOverlay(), l, j3 - k3, l + 1, j3, i3);
|
||||
++l;
|
||||
$$8 = pDrawTimer.wrapIndex($$8 + 1);
|
||||
}
|
||||
|
||||
if (pDrawForFps) {
|
||||
pGuiGraphics.fill(RenderType.guiOverlay(), p_283392_ + 1, j3 - 30 + 1, p_283392_ + 14, j3 - 30 + 10, -1873784752);
|
||||
pGuiGraphics.drawString(this.font, "60 FPS", p_283392_ + 2, j3 - 30 + 2, 14737632, false);
|
||||
pGuiGraphics.hLine(RenderType.guiOverlay(), p_283392_, p_283392_ + j1 - 1, j3 - 30, -1);
|
||||
pGuiGraphics.fill(RenderType.guiOverlay(), p_283392_ + 1, j3 - 60 + 1, p_283392_ + 14, j3 - 60 + 10, -1873784752);
|
||||
pGuiGraphics.drawString(this.font, "30 FPS", p_283392_ + 2, j3 - 60 + 2, 14737632, false);
|
||||
pGuiGraphics.hLine(RenderType.guiOverlay(), p_283392_, p_283392_ + j1 - 1, j3 - 60, -1);
|
||||
} else {
|
||||
pGuiGraphics.fill(RenderType.guiOverlay(), p_283392_ + 1, j3 - 60 + 1, p_283392_ + 14, j3 - 60 + 10, -1873784752);
|
||||
pGuiGraphics.drawString(this.font, "20 TPS", p_283392_ + 2, j3 - 60 + 2, 14737632, false);
|
||||
pGuiGraphics.hLine(RenderType.guiOverlay(), p_283392_, p_283392_ + j1 - 1, j3 - 60, -1);
|
||||
}
|
||||
|
||||
pGuiGraphics.hLine(RenderType.guiOverlay(), p_283392_, p_283392_ + j1 - 1, j3 - 1, -1);
|
||||
pGuiGraphics.vLine(RenderType.guiOverlay(), p_283392_, j3 - 60, j3, -1);
|
||||
pGuiGraphics.vLine(RenderType.guiOverlay(), p_283392_ + j1 - 1, j3 - 60, j3, -1);
|
||||
int l3 = this.minecraft.options.framerateLimit().get();
|
||||
if (pDrawForFps && l3 > 0 && l3 <= 250) {
|
||||
pGuiGraphics.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";
|
||||
pGuiGraphics.drawString(this.font, s1, p_283392_ + 2, j3 - 60 - 9, 14737632);
|
||||
pGuiGraphics.drawCenteredString(this.font, s2, p_283392_ + j1 / 2, j3 - 60 - 9, 14737632);
|
||||
pGuiGraphics.drawString(this.font, s, p_283392_ + j1 - this.font.width(s), j3 - 60 - 9, 14737632);
|
||||
}
|
||||
|
||||
private int getSampleColor(int pHeight, int pHeightMin, int pHeightMid, int pHeightMax) {
|
||||
return pHeight < pHeightMid ? this.colorLerp(-16711936, -256, (float)pHeight / (float)pHeightMid) : this.colorLerp(-256, -65536, (float)(pHeight - pHeightMid) / (float)(pHeightMax - pHeightMid));
|
||||
}
|
||||
|
||||
private int colorLerp(int pCol1, int pCol2, float pFactor) {
|
||||
int i = pCol1 >> 24 & 255;
|
||||
int j = pCol1 >> 16 & 255;
|
||||
int k = pCol1 >> 8 & 255;
|
||||
int l = pCol1 & 255;
|
||||
int i1 = pCol2 >> 24 & 255;
|
||||
int j1 = pCol2 >> 16 & 255;
|
||||
int k1 = pCol2 >> 8 & 255;
|
||||
int l1 = pCol2 & 255;
|
||||
int i2 = Mth.clamp((int)Mth.lerp(pFactor, (float)i, (float)i1), 0, 255);
|
||||
int j2 = Mth.clamp((int)Mth.lerp(pFactor, (float)j, (float)j1), 0, 255);
|
||||
int k2 = Mth.clamp((int)Mth.lerp(pFactor, (float)k, (float)k1), 0, 255);
|
||||
int l2 = Mth.clamp((int)Mth.lerp(pFactor, (float)l, (float)l1), 0, 255);
|
||||
return i2 << 24 | j2 << 16 | k2 << 8 | l2;
|
||||
}
|
||||
|
||||
private static long bytesToMegabytes(long pBytes) {
|
||||
return pBytes / 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 pHeapUsage) {
|
||||
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 = pHeapUsage - this.lastHeapUsage;
|
||||
this.lastRate = Math.round((double)k * d0);
|
||||
}
|
||||
|
||||
this.lastTime = i;
|
||||
this.lastHeapUsage = pHeapUsage;
|
||||
this.lastGcCounts = j;
|
||||
return this.lastRate;
|
||||
}
|
||||
}
|
||||
|
||||
private static long gcCounts() {
|
||||
long i = 0L;
|
||||
|
||||
for(GarbageCollectorMXBean garbagecollectormxbean : GC_MBEANS) {
|
||||
i += garbagecollectormxbean.getCollectionCount();
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
+656
@@ -0,0 +1,656 @@
|
||||
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;
|
||||
/** Has the current text being edited on the textbox. */
|
||||
private String value = "";
|
||||
private int maxLength = 32;
|
||||
private int frame;
|
||||
private boolean bordered = true;
|
||||
/** if true the textbox can lose focus by clicking elsewhere on the screen */
|
||||
private boolean canLoseFocus = true;
|
||||
/** If this value is true along with isFocused, keyTyped will process the keys. */
|
||||
private boolean isEditable = true;
|
||||
private boolean shiftPressed;
|
||||
/** The current character index that should be used as start of the rendered text. */
|
||||
private int displayPos;
|
||||
private int cursorPos;
|
||||
/** other selection position, maybe the same as the cursor */
|
||||
private int highlightPos;
|
||||
private int textColor = 14737632;
|
||||
private int textColorUneditable = 7368816;
|
||||
@Nullable
|
||||
private String suggestion;
|
||||
@Nullable
|
||||
private Consumer<String> responder;
|
||||
/** Called to check if the text is valid */
|
||||
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 pFont, int pX, int pY, int pWidth, int pHeight, Component pMessage) {
|
||||
this(pFont, pX, pY, pWidth, pHeight, (EditBox)null, pMessage);
|
||||
}
|
||||
|
||||
public EditBox(Font pFont, int pX, int pY, int pWidth, int pHeight, @Nullable EditBox pEditBox, Component pMessage) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage);
|
||||
this.font = pFont;
|
||||
if (pEditBox != null) {
|
||||
this.setValue(pEditBox.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setResponder(Consumer<String> pResponder) {
|
||||
this.responder = pResponder;
|
||||
}
|
||||
|
||||
public void setFormatter(BiFunction<String, Integer, FormattedCharSequence> pTextFormatter) {
|
||||
this.formatter = pTextFormatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the cursor counter
|
||||
*/
|
||||
public void tick() {
|
||||
++this.frame;
|
||||
}
|
||||
|
||||
protected MutableComponent createNarrationMessage() {
|
||||
Component component = this.getMessage();
|
||||
return Component.translatable("gui.narrate.editBox", component, this.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text of the textbox, and moves the cursor to the end.
|
||||
*/
|
||||
public void setValue(String pText) {
|
||||
if (this.filter.test(pText)) {
|
||||
if (pText.length() > this.maxLength) {
|
||||
this.value = pText.substring(0, this.maxLength);
|
||||
} else {
|
||||
this.value = pText;
|
||||
}
|
||||
|
||||
this.moveCursorToEnd();
|
||||
this.setHighlightPos(this.cursorPos);
|
||||
this.onValueChange(pText);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the textbox
|
||||
*/
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text between the cursor and selectionEnd.
|
||||
*/
|
||||
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> pValidator) {
|
||||
this.filter = pValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given text after the cursor, or replaces the currently selected text if there is a selection.
|
||||
*/
|
||||
public void insertText(String pTextToWrite) {
|
||||
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(pTextToWrite);
|
||||
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 pNewText) {
|
||||
if (this.responder != null) {
|
||||
this.responder.accept(pNewText);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void deleteText(int pCount) {
|
||||
if (Screen.hasControlDown()) {
|
||||
this.deleteWords(pCount);
|
||||
} else {
|
||||
this.deleteChars(pCount);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given number of words from the current cursor's position, unless there is currently a selection, in
|
||||
* which case the selection is deleted instead.
|
||||
*/
|
||||
public void deleteWords(int pNum) {
|
||||
if (!this.value.isEmpty()) {
|
||||
if (this.highlightPos != this.cursorPos) {
|
||||
this.insertText("");
|
||||
} else {
|
||||
this.deleteChars(this.getWordPosition(pNum) - this.cursorPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given number of characters from the current cursor's position, unless there is currently a selection,
|
||||
* in which case the selection is deleted instead.
|
||||
*/
|
||||
public void deleteChars(int pNum) {
|
||||
if (!this.value.isEmpty()) {
|
||||
if (this.highlightPos != this.cursorPos) {
|
||||
this.insertText("");
|
||||
} else {
|
||||
int i = this.getCursorPos(pNum);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the starting index of the word at the specified number of words away from the cursor position.
|
||||
*/
|
||||
public int getWordPosition(int pNumWords) {
|
||||
return this.getWordPosition(pNumWords, this.getCursorPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the starting index of the word at a distance of the specified number of words away from the given position.
|
||||
*/
|
||||
private int getWordPosition(int pN, int pPos) {
|
||||
return this.getWordPosition(pN, pPos, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like getNthWordFromPos (which wraps this), but adds option for skipping consecutive spaces
|
||||
*/
|
||||
private int getWordPosition(int pN, int pPos, boolean pSkipWs) {
|
||||
int i = pPos;
|
||||
boolean flag = pN < 0;
|
||||
int j = Math.abs(pN);
|
||||
|
||||
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(pSkipWs && i < l && this.value.charAt(i) == ' ') {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while(pSkipWs && i > 0 && this.value.charAt(i - 1) == ' ') {
|
||||
--i;
|
||||
}
|
||||
|
||||
while(i > 0 && this.value.charAt(i - 1) != ' ') {
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the text cursor by a specified number of characters and clears the selection
|
||||
*/
|
||||
public void moveCursor(int pDelta) {
|
||||
this.moveCursorTo(this.getCursorPos(pDelta));
|
||||
}
|
||||
|
||||
private int getCursorPos(int pDelta) {
|
||||
return Util.offsetByCodepoints(this.value, this.cursorPos, pDelta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current position of the cursor.
|
||||
*/
|
||||
public void moveCursorTo(int pPos) {
|
||||
this.setCursorPosition(pPos);
|
||||
if (!this.shiftPressed) {
|
||||
this.setHighlightPos(this.cursorPos);
|
||||
}
|
||||
|
||||
this.onValueChange(this.value);
|
||||
}
|
||||
|
||||
public void setCursorPosition(int pPos) {
|
||||
this.cursorPos = Mth.clamp(pPos, 0, this.value.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the cursor to the very start of this text box.
|
||||
*/
|
||||
public void moveCursorToStart() {
|
||||
this.moveCursorTo(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the cursor to the very end of this text box.
|
||||
*/
|
||||
public void moveCursorToEnd() {
|
||||
this.moveCursorTo(this.value.length());
|
||||
}
|
||||
|
||||
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
if (!this.canConsumeInput()) {
|
||||
return false;
|
||||
} else {
|
||||
this.shiftPressed = Screen.hasShiftDown();
|
||||
if (Screen.isSelectAll(pKeyCode)) {
|
||||
this.moveCursorToEnd();
|
||||
this.setHighlightPos(0);
|
||||
return true;
|
||||
} else if (Screen.isCopy(pKeyCode)) {
|
||||
Minecraft.getInstance().keyboardHandler.setClipboard(this.getHighlighted());
|
||||
return true;
|
||||
} else if (Screen.isPaste(pKeyCode)) {
|
||||
if (this.isEditable) {
|
||||
this.insertText(Minecraft.getInstance().keyboardHandler.getClipboard());
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (Screen.isCut(pKeyCode)) {
|
||||
Minecraft.getInstance().keyboardHandler.setClipboard(this.getHighlighted());
|
||||
if (this.isEditable) {
|
||||
this.insertText("");
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
switch (pKeyCode) {
|
||||
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 pCodePoint, int pModifiers) {
|
||||
if (!this.canConsumeInput()) {
|
||||
return false;
|
||||
} else if (SharedConstants.isAllowedChatCharacter(pCodePoint)) {
|
||||
if (this.isEditable) {
|
||||
this.insertText(Character.toString(pCodePoint));
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void onClick(double pMouseX, double pMouseY) {
|
||||
int i = Mth.floor(pMouseX) - 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 pHandler) {
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
if (this.isVisible()) {
|
||||
if (this.isBordered()) {
|
||||
int i = this.isFocused() ? -1 : -6250336;
|
||||
pGuiGraphics.fill(this.getX() - 1, this.getY() - 1, this.getX() + this.width + 1, this.getY() + this.height + 1, i);
|
||||
pGuiGraphics.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 = pGuiGraphics.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()) {
|
||||
pGuiGraphics.drawString(this.font, this.formatter.apply(s.substring(j), this.cursorPos), j1, i1, i2);
|
||||
}
|
||||
|
||||
if (this.hint != null && s.isEmpty() && !this.isFocused()) {
|
||||
pGuiGraphics.drawString(this.font, this.hint, j1, i1, i2);
|
||||
}
|
||||
|
||||
if (!flag2 && this.suggestion != null) {
|
||||
pGuiGraphics.drawString(this.font, this.suggestion, k1 - 1, i1, -8355712);
|
||||
}
|
||||
|
||||
if (flag1) {
|
||||
if (flag2) {
|
||||
pGuiGraphics.fill(RenderType.guiOverlay(), k1, i1 - 1, k1 + 1, i1 + 1 + 9, -3092272);
|
||||
} else {
|
||||
pGuiGraphics.drawString(this.font, "_", k1, i1, i2);
|
||||
}
|
||||
}
|
||||
|
||||
if (k != j) {
|
||||
int l1 = l + this.font.width(s.substring(0, k));
|
||||
this.renderHighlight(pGuiGraphics, k1, i1 - 1, l1 - 1, i1 + 1 + 9);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void renderHighlight(GuiGraphics pGuiGraphics, int pMinX, int pMinY, int pMaxX, int pMaxY) {
|
||||
if (pMinX < pMaxX) {
|
||||
int i = pMinX;
|
||||
pMinX = pMaxX;
|
||||
pMaxX = i;
|
||||
}
|
||||
|
||||
if (pMinY < pMaxY) {
|
||||
int j = pMinY;
|
||||
pMinY = pMaxY;
|
||||
pMaxY = j;
|
||||
}
|
||||
|
||||
if (pMaxX > this.getX() + this.width) {
|
||||
pMaxX = this.getX() + this.width;
|
||||
}
|
||||
|
||||
if (pMinX > this.getX() + this.width) {
|
||||
pMinX = this.getX() + this.width;
|
||||
}
|
||||
|
||||
pGuiGraphics.fill(RenderType.guiTextHighlight(), pMinX, pMinY, pMaxX, pMaxY, -16776961);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum length for the text in this text box. If the current text is longer than this length, the current
|
||||
* text will be trimmed.
|
||||
*/
|
||||
public void setMaxLength(int pLength) {
|
||||
this.maxLength = pLength;
|
||||
if (this.value.length() > pLength) {
|
||||
this.value = this.value.substring(0, pLength);
|
||||
this.onValueChange(this.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of character that can be contained in this textbox.
|
||||
*/
|
||||
private int getMaxLength() {
|
||||
return this.maxLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current position of the cursor.
|
||||
*/
|
||||
public int getCursorPosition() {
|
||||
return this.cursorPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the background and outline of this text box should be drawn (true if so).
|
||||
*/
|
||||
private boolean isBordered() {
|
||||
return this.bordered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the background and outline of this text box should be drawn.
|
||||
*/
|
||||
public void setBordered(boolean pEnableBackgroundDrawing) {
|
||||
this.bordered = pEnableBackgroundDrawing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color to use when drawing this text box's text. A different color is used if this text box is disabled.
|
||||
*/
|
||||
public void setTextColor(int pColor) {
|
||||
this.textColor = pColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color to use for text in this text box when this text box is disabled.
|
||||
*/
|
||||
public void setTextColorUneditable(int pColor) {
|
||||
this.textColorUneditable = pColor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ComponentPath nextFocusPath(FocusNavigationEvent pEvent) {
|
||||
return this.visible && this.isEditable ? super.nextFocusPath(pEvent) : null;
|
||||
}
|
||||
|
||||
public boolean isMouseOver(double pMouseX, double pMouseY) {
|
||||
return this.visible && pMouseX >= (double)this.getX() && pMouseX < (double)(this.getX() + this.width) && pMouseY >= (double)this.getY() && pMouseY < (double)(this.getY() + this.height);
|
||||
}
|
||||
|
||||
public void setFocused(boolean pFocused) {
|
||||
if (this.canLoseFocus || pFocused) {
|
||||
super.setFocused(pFocused);
|
||||
if (pFocused) {
|
||||
this.frame = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEditable() {
|
||||
return this.isEditable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this text box is enabled. Disabled text boxes cannot be typed in.
|
||||
*/
|
||||
public void setEditable(boolean pEnabled) {
|
||||
this.isEditable = pEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of the textbox depending on if background drawing is enabled.
|
||||
*/
|
||||
public int getInnerWidth() {
|
||||
return this.isBordered() ? this.width - 8 : this.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the selection anchor (the selection anchor and the cursor position mark the edges of the
|
||||
* selection). If the anchor is set beyond the bounds of the current text, it will be put back inside.
|
||||
*/
|
||||
public void setHighlightPos(int pPosition) {
|
||||
int i = this.value.length();
|
||||
this.highlightPos = Mth.clamp(pPosition, 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this text box loses focus when something other than it is clicked.
|
||||
*/
|
||||
public void setCanLoseFocus(boolean pCanLoseFocus) {
|
||||
this.canLoseFocus = pCanLoseFocus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this textbox is visible.
|
||||
*/
|
||||
public boolean isVisible() {
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this textbox is visible.
|
||||
*/
|
||||
public void setVisible(boolean pIsVisible) {
|
||||
this.visible = pIsVisible;
|
||||
}
|
||||
|
||||
public void setSuggestion(@Nullable String pSuggestion) {
|
||||
this.suggestion = pSuggestion;
|
||||
}
|
||||
|
||||
public int getScreenX(int pCharNum) {
|
||||
return pCharNum > this.value.length() ? this.getX() : this.getX() + this.font.width(this.value.substring(0, pCharNum));
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
pNarrationElementOutput.add(NarratedElementType.TITLE, this.createNarrationMessage());
|
||||
}
|
||||
|
||||
public void setHint(Component pHint) {
|
||||
this.hint = pHint;
|
||||
}
|
||||
}
|
||||
+74
@@ -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 pX, int pY, int pWidth, int pHeight, Component pMessage, Font pFont) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage);
|
||||
this.font = pFont;
|
||||
this.multilineWidget = (new MultiLineTextWidget(0, 0, pMessage, pFont)).setMaxWidth(this.getWidth() - this.totalInnerPadding());
|
||||
}
|
||||
|
||||
public FittingMultiLineTextWidget setColor(int pColor) {
|
||||
this.multilineWidget.setColor(pColor);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setWidth(int pWidth) {
|
||||
super.setWidth(pWidth);
|
||||
this.multilineWidget.setMaxWidth(this.getWidth() - this.totalInnerPadding());
|
||||
}
|
||||
|
||||
protected int getInnerHeight() {
|
||||
return this.multilineWidget.getHeight();
|
||||
}
|
||||
|
||||
protected double scrollRate() {
|
||||
return 9.0D;
|
||||
}
|
||||
|
||||
protected void renderBackground(GuiGraphics pGuiGraphics) {
|
||||
if (this.scrollbarVisible()) {
|
||||
super.renderBackground(pGuiGraphics);
|
||||
} else if (this.isFocused()) {
|
||||
this.renderBorder(pGuiGraphics, this.getX() - this.innerPadding(), this.getY() - this.innerPadding(), this.getWidth() + this.totalInnerPadding(), this.getHeight() + this.totalInnerPadding());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
if (this.visible) {
|
||||
if (!this.scrollbarVisible()) {
|
||||
this.renderBackground(pGuiGraphics);
|
||||
pGuiGraphics.pose().pushPose();
|
||||
pGuiGraphics.pose().translate((float)this.getX(), (float)this.getY(), 0.0F);
|
||||
this.multilineWidget.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
|
||||
pGuiGraphics.pose().popPose();
|
||||
} else {
|
||||
super.renderWidget(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderContents(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
pGuiGraphics.pose().pushPose();
|
||||
pGuiGraphics.pose().translate((float)(this.getX() + this.innerPadding()), (float)(this.getY() + this.innerPadding()), 0.0F);
|
||||
this.multilineWidget.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
|
||||
pGuiGraphics.pose().popPose();
|
||||
}
|
||||
|
||||
protected void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
pNarrationElementOutput.add(NarratedElementType.TITLE, this.getMessage());
|
||||
}
|
||||
}
|
||||
+44
@@ -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 pX, int pY, int pWidth, int pHeight, int pXTexStart, int pYTexStart, ResourceLocation pResourceLocation, Button.OnPress pOnPress) {
|
||||
this(pX, pY, pWidth, pHeight, pXTexStart, pYTexStart, pHeight, pResourceLocation, 256, 256, pOnPress);
|
||||
}
|
||||
|
||||
public ImageButton(int pX, int pY, int pWidth, int pHeight, int pXTexStart, int pYTexStart, int pYDiffTex, ResourceLocation pResourceLocation, Button.OnPress pOnPress) {
|
||||
this(pX, pY, pWidth, pHeight, pXTexStart, pYTexStart, pYDiffTex, pResourceLocation, 256, 256, pOnPress);
|
||||
}
|
||||
|
||||
public ImageButton(int pX, int pY, int pWidth, int pHeight, int pXTexStart, int pYTexStart, int pYDiffTex, ResourceLocation pResourceLocation, int pTextureWidth, int pTextureHeight, Button.OnPress pOnPress) {
|
||||
this(pX, pY, pWidth, pHeight, pXTexStart, pYTexStart, pYDiffTex, pResourceLocation, pTextureWidth, pTextureHeight, pOnPress, CommonComponents.EMPTY);
|
||||
}
|
||||
|
||||
public ImageButton(int pX, int pY, int pWidth, int pHeight, int pXTexStart, int pYTexStart, int pYDiffTex, ResourceLocation pResourceLocation, int pTextureWidth, int pTextureHeight, Button.OnPress pOnPress, Component pMessage) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage, pOnPress, DEFAULT_NARRATION);
|
||||
this.textureWidth = pTextureWidth;
|
||||
this.textureHeight = pTextureHeight;
|
||||
this.xTexStart = pXTexStart;
|
||||
this.yTexStart = pYTexStart;
|
||||
this.yDiffTex = pYDiffTex;
|
||||
this.resourceLocation = pResourceLocation;
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
this.renderTexture(pGuiGraphics, this.resourceLocation, this.getX(), this.getY(), this.xTexStart, this.yTexStart, this.yDiffTex, this.width, this.height, this.textureWidth, this.textureHeight);
|
||||
}
|
||||
}
|
||||
+31
@@ -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 pWidth, int pHeight, ResourceLocation pImageLocation) {
|
||||
this(0, 0, pWidth, pHeight, pImageLocation);
|
||||
}
|
||||
|
||||
public ImageWidget(int pX, int pY, int pWidth, int pHeight, ResourceLocation pImageLocation) {
|
||||
super(pX, pY, pWidth, pHeight, Component.empty());
|
||||
this.imageLocation = pImageLocation;
|
||||
}
|
||||
|
||||
protected void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
int i = this.getWidth();
|
||||
int j = this.getHeight();
|
||||
pGuiGraphics.blit(this.imageLocation, this.getX(), this.getY(), 0.0F, 0.0F, i, j, i, j);
|
||||
}
|
||||
}
|
||||
+38
@@ -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 pId, Component pName, float pProgress, BossEvent.BossBarColor pColor, BossEvent.BossBarOverlay pOverlay, boolean pDarkenScreen, boolean pBossMusic, boolean pWorldFog) {
|
||||
super(pId, pName, pColor, pOverlay);
|
||||
this.targetPercent = pProgress;
|
||||
this.progress = pProgress;
|
||||
this.setTime = Util.getMillis();
|
||||
this.setDarkenScreen(pDarkenScreen);
|
||||
this.setPlayBossMusic(pBossMusic);
|
||||
this.setCreateWorldFog(pWorldFog);
|
||||
}
|
||||
|
||||
public void setProgress(float pProgress) {
|
||||
this.progress = this.getProgress();
|
||||
this.targetPercent = pProgress;
|
||||
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);
|
||||
}
|
||||
}
|
||||
+68
@@ -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 pX, int pY, Button.OnPress pOnPress) {
|
||||
super(pX, pY, 20, 20, Component.translatable("narrator.button.difficulty_lock"), pOnPress, 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 pLocked) {
|
||||
this.locked = pLocked;
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
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;
|
||||
}
|
||||
|
||||
pGuiGraphics.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 pX, int pY) {
|
||||
this.x = pX;
|
||||
this.y = pY;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
@@ -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 pKeepLogoThroughFade) {
|
||||
this.keepLogoThroughFade = pKeepLogoThroughFade;
|
||||
}
|
||||
|
||||
public void renderLogo(GuiGraphics pGuiGraphics, int pScreenWidth, float pTransparency) {
|
||||
this.renderLogo(pGuiGraphics, pScreenWidth, pTransparency, 30);
|
||||
}
|
||||
|
||||
public void renderLogo(GuiGraphics pGuiGraphics, int pScreenWidth, float pTransparency, int pHeight) {
|
||||
pGuiGraphics.setColor(1.0F, 1.0F, 1.0F, this.keepLogoThroughFade ? 1.0F : pTransparency);
|
||||
int i = pScreenWidth / 2 - 128;
|
||||
pGuiGraphics.blit(this.showEasterEgg ? EASTER_EGG_LOGO : MINECRAFT_LOGO, i, pHeight, 0.0F, 0.0F, 256, 44, 256, 64);
|
||||
int j = pScreenWidth / 2 - 64;
|
||||
int k = pHeight + 44 - 7;
|
||||
pGuiGraphics.blit(MINECRAFT_EDITION, j, k, 0.0F, 0.0F, 128, 14, 128, 16);
|
||||
pGuiGraphics.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
+215
@@ -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 pFont, int pX, int pY, int pWidth, int pHeight, Component pPlaceholder, Component pMessage) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage);
|
||||
this.font = pFont;
|
||||
this.placeholder = pPlaceholder;
|
||||
this.textField = new MultilineTextField(pFont, pWidth - this.totalInnerPadding());
|
||||
this.textField.setCursorListener(this::scrollToCursor);
|
||||
}
|
||||
|
||||
public void setCharacterLimit(int pCharacterLimit) {
|
||||
this.textField.setCharacterLimit(pCharacterLimit);
|
||||
}
|
||||
|
||||
public void setValueListener(Consumer<String> pValueListener) {
|
||||
this.textField.setValueListener(pValueListener);
|
||||
}
|
||||
|
||||
public void setValue(String pFullText) {
|
||||
this.textField.setValue(pFullText);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.textField.value();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
++this.frame;
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
pNarrationElementOutput.add(NarratedElementType.TITLE, Component.translatable("gui.narrate.editBox", this.getMessage(), this.getValue()));
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
|
||||
if (super.mouseClicked(pMouseX, pMouseY, pButton)) {
|
||||
return true;
|
||||
} else if (this.withinContentAreaPoint(pMouseX, pMouseY) && pButton == 0) {
|
||||
this.textField.setSelecting(Screen.hasShiftDown());
|
||||
this.seekCursorScreen(pMouseX, pMouseY);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseDragged(double pMouseX, double pMouseY, int pButton, double pDragX, double pDragY) {
|
||||
if (super.mouseDragged(pMouseX, pMouseY, pButton, pDragX, pDragY)) {
|
||||
return true;
|
||||
} else if (this.withinContentAreaPoint(pMouseX, pMouseY) && pButton == 0) {
|
||||
this.textField.setSelecting(true);
|
||||
this.seekCursorScreen(pMouseX, pMouseY);
|
||||
this.textField.setSelecting(Screen.hasShiftDown());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
return this.textField.keyPressed(pKeyCode);
|
||||
}
|
||||
|
||||
public boolean charTyped(char pCodePoint, int pModifiers) {
|
||||
if (this.visible && this.isFocused() && SharedConstants.isAllowedChatCharacter(pCodePoint)) {
|
||||
this.textField.insertText(Character.toString(pCodePoint));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderContents(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
String s = this.textField.value();
|
||||
if (s.isEmpty() && !this.isFocused()) {
|
||||
pGuiGraphics.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 = pGuiGraphics.drawString(this.font, s.substring(multilinetextfield$stringview.beginIndex(), i), this.getX() + this.innerPadding(), l, -2039584) - 1;
|
||||
pGuiGraphics.fill(j, l - 1, j + 1, l + 1 + 9, -3092272);
|
||||
pGuiGraphics.drawString(this.font, s.substring(i, multilinetextfield$stringview.endIndex()), j, l, -2039584);
|
||||
}
|
||||
} else {
|
||||
if (flag2) {
|
||||
j = pGuiGraphics.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)) {
|
||||
pGuiGraphics.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(pGuiGraphics, k1 + i1, l, k1 + j1, l + 9);
|
||||
}
|
||||
|
||||
l += 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderDecorations(GuiGraphics pGuiGraphics) {
|
||||
super.renderDecorations(pGuiGraphics);
|
||||
if (this.textField.hasCharacterLimit()) {
|
||||
int i = this.textField.characterLimit();
|
||||
Component component = Component.translatable("gui.multiLineEditBox.character_limit", this.textField.value().length(), i);
|
||||
pGuiGraphics.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 pGuiGraphics, int pMinX, int pMinY, int pMaxX, int pMaxY) {
|
||||
pGuiGraphics.fill(RenderType.guiTextHighlight(), pMinX, pMinY, pMaxX, pMaxY, -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 pMouseX, double pMouseY) {
|
||||
double d0 = pMouseX - (double)this.getX() - (double)this.innerPadding();
|
||||
double d1 = pMouseY - (double)this.getY() - (double)this.innerPadding() + this.scrollAmount();
|
||||
this.textField.seekCursorToPoint(d0, d1);
|
||||
}
|
||||
}
|
||||
+156
@@ -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 pFont, FormattedText pFormattedText, int pMaxWidth) {
|
||||
return createFixed(pFont, pFont.split(pFormattedText, pMaxWidth).stream().map((p_94374_) -> {
|
||||
return new MultiLineLabel.TextWithWidth(p_94374_, pFont.width(p_94374_));
|
||||
}).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
|
||||
static MultiLineLabel create(Font pFont, FormattedText pFormattedText, int pMaxWidth, int pMaxLines) {
|
||||
return createFixed(pFont, pFont.split(pFormattedText, pMaxWidth).stream().limit((long)pMaxLines).map((p_94371_) -> {
|
||||
return new MultiLineLabel.TextWithWidth(p_94371_, pFont.width(p_94371_));
|
||||
}).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
|
||||
static MultiLineLabel create(Font pFont, Component... pComponents) {
|
||||
return createFixed(pFont, Arrays.stream(pComponents).map(Component::getVisualOrderText).map((p_94360_) -> {
|
||||
return new MultiLineLabel.TextWithWidth(p_94360_, pFont.width(p_94360_));
|
||||
}).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
|
||||
static MultiLineLabel create(Font pFont, List<Component> p_169038_) {
|
||||
return createFixed(pFont, p_169038_.stream().map(Component::getVisualOrderText).map((p_169035_) -> {
|
||||
return new MultiLineLabel.TextWithWidth(p_169035_, pFont.width(p_169035_));
|
||||
}).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
|
||||
static MultiLineLabel createFixed(final Font pFont, final List<MultiLineLabel.TextWithWidth> pTextList) {
|
||||
return pTextList.isEmpty() ? EMPTY : new MultiLineLabel() {
|
||||
private final int width = pTextList.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 : pTextList) {
|
||||
p_281603_.drawString(pFont, 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 : pTextList) {
|
||||
p_282318_.drawString(pFont, 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 : pTextList) {
|
||||
p_281782_.drawString(pFont, 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 = pTextList.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_ + pTextList.size() * p_210834_ + p_210835_, p_210836_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getLineCount() {
|
||||
return pTextList.size();
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int renderCentered(GuiGraphics pGuiGraphics, int pWidth, int pTextWithWidthList);
|
||||
|
||||
int renderCentered(GuiGraphics pGuiGraphics, int pWidth, int pX, int pY, int pColor);
|
||||
|
||||
int renderLeftAligned(GuiGraphics pGuiGraphics, int pX, int pY, int pLineHeight, int pColor);
|
||||
|
||||
int renderLeftAlignedNoShadow(GuiGraphics pGuiGraphics, int pX, int pY, int pLineHeight, int pColor);
|
||||
|
||||
void renderBackgroundCentered(GuiGraphics pGuiGraphics, int p_210818_, int p_210819_, int p_210820_, int p_210821_, int pColor);
|
||||
|
||||
int getLineCount();
|
||||
|
||||
int getWidth();
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class TextWithWidth {
|
||||
final FormattedCharSequence text;
|
||||
final int width;
|
||||
|
||||
TextWithWidth(FormattedCharSequence pText, int pWidth) {
|
||||
this.text = pText;
|
||||
this.width = pWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
+80
@@ -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 pMessage, Font pFont) {
|
||||
this(0, 0, pMessage, pFont);
|
||||
}
|
||||
|
||||
public MultiLineTextWidget(int pX, int pY, Component pMessage, Font pFont) {
|
||||
super(pX, pY, 0, 0, pMessage, pFont);
|
||||
this.cache = Util.singleKeyCache((p_270516_) -> {
|
||||
return p_270516_.maxRows.isPresent() ? MultiLineLabel.create(pFont, p_270516_.message, p_270516_.maxWidth, p_270516_.maxRows.getAsInt()) : MultiLineLabel.create(pFont, p_270516_.message, p_270516_.maxWidth);
|
||||
});
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
public MultiLineTextWidget setColor(int pColor) {
|
||||
super.setColor(pColor);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MultiLineTextWidget setMaxWidth(int pMaxWidth) {
|
||||
this.maxWidth = OptionalInt.of(pMaxWidth);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MultiLineTextWidget setMaxRows(int pMaxRows) {
|
||||
this.maxRows = OptionalInt.of(pMaxRows);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MultiLineTextWidget setCentered(boolean pCentered) {
|
||||
this.centered = pCentered;
|
||||
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 pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
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(pGuiGraphics, i + this.getWidth() / 2, j, k, l);
|
||||
} else {
|
||||
multilinelabel.renderLeftAligned(pGuiGraphics, 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) {
|
||||
}
|
||||
}
|
||||
+367
@@ -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 pFont, int pWidth) {
|
||||
this.font = pFont;
|
||||
this.width = pWidth;
|
||||
this.setValue("");
|
||||
}
|
||||
|
||||
public int characterLimit() {
|
||||
return this.characterLimit;
|
||||
}
|
||||
|
||||
public void setCharacterLimit(int pCharacterLimit) {
|
||||
if (pCharacterLimit < 0) {
|
||||
throw new IllegalArgumentException("Character limit cannot be negative");
|
||||
} else {
|
||||
this.characterLimit = pCharacterLimit;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasCharacterLimit() {
|
||||
return this.characterLimit != Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public void setValueListener(Consumer<String> pValueListener) {
|
||||
this.valueListener = pValueListener;
|
||||
}
|
||||
|
||||
public void setCursorListener(Runnable pCursorListener) {
|
||||
this.cursorListener = pCursorListener;
|
||||
}
|
||||
|
||||
public void setValue(String pFullText) {
|
||||
this.value = this.truncateFullText(pFullText);
|
||||
this.cursor = this.value.length();
|
||||
this.selectCursor = this.cursor;
|
||||
this.onValueChange();
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void insertText(String pText) {
|
||||
if (!pText.isEmpty() || this.hasSelection()) {
|
||||
String s = this.truncateInsertionText(SharedConstants.filterText(pText, 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 pLength) {
|
||||
if (!this.hasSelection()) {
|
||||
this.selectCursor = Mth.clamp(this.cursor + pLength, 0, this.value.length());
|
||||
}
|
||||
|
||||
this.insertText("");
|
||||
}
|
||||
|
||||
public int cursor() {
|
||||
return this.cursor;
|
||||
}
|
||||
|
||||
public void setSelecting(boolean pSelecting) {
|
||||
this.selecting = pSelecting;
|
||||
}
|
||||
|
||||
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 pCursor) {
|
||||
int i;
|
||||
for(i = pCursor; 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 pFullText) {
|
||||
return this.hasCharacterLimit() ? StringUtil.truncateStringIfNecessary(pFullText, this.characterLimit, false) : pFullText;
|
||||
}
|
||||
|
||||
private String truncateInsertionText(String pText) {
|
||||
if (this.hasCharacterLimit()) {
|
||||
int i = this.characterLimit - this.value.length();
|
||||
return StringUtil.truncateStringIfNecessary(pText, i, false);
|
||||
} else {
|
||||
return pText;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected static record StringView(int beginIndex, int endIndex) {
|
||||
static final MultilineTextField.StringView EMPTY = new MultilineTextField.StringView(0, 0);
|
||||
}
|
||||
}
|
||||
+69
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
+106
@@ -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 pMinecraft, int pWidth, int pHeight, int pY0, int pY1, int pItemHeight) {
|
||||
super(pMinecraft, pWidth, pHeight, pY0, pY1, pItemHeight);
|
||||
this.centerListVertically = false;
|
||||
}
|
||||
|
||||
public int addBig(OptionInstance<?> pOption) {
|
||||
return this.addEntry(OptionsList.Entry.big(this.minecraft.options, this.width, pOption));
|
||||
}
|
||||
|
||||
public void addSmall(OptionInstance<?> pLeftOption, @Nullable OptionInstance<?> pRightOption) {
|
||||
this.addEntry(OptionsList.Entry.small(this.minecraft.options, this.width, pLeftOption, pRightOption));
|
||||
}
|
||||
|
||||
public void addSmall(OptionInstance<?>[] pOptions) {
|
||||
for(int i = 0; i < pOptions.length; i += 2) {
|
||||
this.addSmall(pOptions[i], i < pOptions.length - 1 ? pOptions[i + 1] : null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getRowWidth() {
|
||||
return 400;
|
||||
}
|
||||
|
||||
protected int getScrollbarPosition() {
|
||||
return super.getScrollbarPosition() + 32;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AbstractWidget findOption(OptionInstance<?> pOption) {
|
||||
for(OptionsList.Entry optionslist$entry : this.children()) {
|
||||
AbstractWidget abstractwidget = optionslist$entry.options.get(pOption);
|
||||
if (abstractwidget != null) {
|
||||
return abstractwidget;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Optional<AbstractWidget> getMouseOver(double pMouseX, double pMouseY) {
|
||||
for(OptionsList.Entry optionslist$entry : this.children()) {
|
||||
for(AbstractWidget abstractwidget : optionslist$entry.children) {
|
||||
if (abstractwidget.isMouseOver(pMouseX, pMouseY)) {
|
||||
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> pOptions) {
|
||||
this.options = pOptions;
|
||||
this.children = ImmutableList.copyOf(pOptions.values());
|
||||
}
|
||||
|
||||
public static OptionsList.Entry big(Options pOptions, int pGuiWidth, OptionInstance<?> pOption) {
|
||||
return new OptionsList.Entry(ImmutableMap.of(pOption, pOption.createButton(pOptions, pGuiWidth / 2 - 155, 0, 310)));
|
||||
}
|
||||
|
||||
public static OptionsList.Entry small(Options pOptions, int pGuiWidth, OptionInstance<?> pLeftOption, @Nullable OptionInstance<?> pRightOption) {
|
||||
AbstractWidget abstractwidget = pLeftOption.createButton(pOptions, pGuiWidth / 2 - 155, 0, 150);
|
||||
return pRightOption == null ? new OptionsList.Entry(ImmutableMap.of(pLeftOption, abstractwidget)) : new OptionsList.Entry(ImmutableMap.of(pLeftOption, abstractwidget, pRightOption, pRightOption.createButton(pOptions, pGuiWidth / 2 - 155 + 160, 0, 150)));
|
||||
}
|
||||
|
||||
public void render(GuiGraphics pGuiGraphics, int pIndex, int pTop, int pLeft, int pWidth, int pHeight, int pMouseX, int pMouseY, boolean p_94504_, float pPartialTick) {
|
||||
this.children.forEach((p_280776_) -> {
|
||||
p_280776_.setY(pTop);
|
||||
p_280776_.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
|
||||
});
|
||||
}
|
||||
|
||||
public List<? extends GuiEventListener> children() {
|
||||
return this.children;
|
||||
}
|
||||
|
||||
public List<? extends NarratableEntry> narratables() {
|
||||
return this.children;
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -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 pX, int pY, int pWidth, int pHeight, Component pMessage, Button.OnPress pOnPress, Font pFont) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage, pOnPress, DEFAULT_NARRATION);
|
||||
this.font = pFont;
|
||||
this.message = pMessage;
|
||||
this.underlinedMessage = ComponentUtils.mergeStyles(pMessage.copy(), Style.EMPTY.withUnderlined(true));
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
Component component = this.isHoveredOrFocused() ? this.underlinedMessage : this.message;
|
||||
pGuiGraphics.drawString(this.font, component, this.getX(), this.getY(), 16777215 | Mth.ceil(this.alpha * 255.0F) << 24);
|
||||
}
|
||||
}
|
||||
+43
@@ -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 pGuiGraphics, ResourceLocation pAtlasLocation, int pX, int pY, int pSize) {
|
||||
draw(pGuiGraphics, pAtlasLocation, pX, pY, pSize, true, false);
|
||||
}
|
||||
|
||||
public static void draw(GuiGraphics pGuiGraphics, ResourceLocation pAtlasLocation, int pX, int pY, int pSize, boolean pDrawHat, boolean pUpsideDown) {
|
||||
int i = 8 + (pUpsideDown ? 8 : 0);
|
||||
int j = 8 * (pUpsideDown ? -1 : 1);
|
||||
pGuiGraphics.blit(pAtlasLocation, pX, pY, pSize, pSize, 8.0F, (float)i, 8, j, 64, 64);
|
||||
if (pDrawHat) {
|
||||
drawHat(pGuiGraphics, pAtlasLocation, pX, pY, pSize, pUpsideDown);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void drawHat(GuiGraphics pGuiGraphics, ResourceLocation pAtlasLocation, int pX, int pY, int pSize, boolean pUpsideDown) {
|
||||
int i = 8 + (pUpsideDown ? 8 : 0);
|
||||
int j = 8 * (pUpsideDown ? -1 : 1);
|
||||
RenderSystem.enableBlend();
|
||||
pGuiGraphics.blit(pAtlasLocation, pX, pY, pSize, pSize, 40.0F, (float)i, 8, j, 64, 64);
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
}
|
||||
+354
@@ -0,0 +1,354 @@
|
||||
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;
|
||||
/** Weither or not the playerlist is currently being rendered */
|
||||
private boolean visible;
|
||||
private final Map<UUID, PlayerTabOverlay.HealthState> healthStates = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
public PlayerTabOverlay(Minecraft pMinecraft, Gui pGui) {
|
||||
this.minecraft = pMinecraft;
|
||||
this.gui = pGui;
|
||||
}
|
||||
|
||||
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 pPlayerInfo, MutableComponent pName) {
|
||||
return pPlayerInfo.getGameMode() == GameType.SPECTATOR ? pName.withStyle(ChatFormatting.ITALIC) : pName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by GuiIngame to update the information stored in the playerlist, does not actually render the list,
|
||||
* however.
|
||||
*/
|
||||
public void setVisible(boolean pVisible) {
|
||||
if (this.visible != pVisible) {
|
||||
this.healthStates.clear();
|
||||
this.visible = pVisible;
|
||||
if (pVisible) {
|
||||
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 pGuiGraphics, int pWidth, Scoreboard pScoreboard, @Nullable Objective pObjective) {
|
||||
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 (pObjective != null && pObjective.getRenderType() != ObjectiveCriteria.RenderType.HEARTS) {
|
||||
k = this.minecraft.font.width(" " + pScoreboard.getOrCreatePlayerScore(playerinfo.getProfile().getName(), pObjective).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 (pObjective != null) {
|
||||
if (pObjective.getRenderType() == ObjectiveCriteria.RenderType.HEARTS) {
|
||||
l = 90;
|
||||
} else {
|
||||
l = j;
|
||||
}
|
||||
} else {
|
||||
l = 0;
|
||||
}
|
||||
|
||||
int i1 = Math.min(k3 * ((flag ? 9 : 0) + i + l + 13), pWidth - 50) / k3;
|
||||
int j1 = pWidth / 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, pWidth - 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, pWidth - 50);
|
||||
|
||||
for(FormattedCharSequence formattedcharsequence1 : list2) {
|
||||
l1 = Math.max(l1, this.minecraft.font.width(formattedcharsequence1));
|
||||
}
|
||||
}
|
||||
|
||||
if (list1 != null) {
|
||||
pGuiGraphics.fill(pWidth / 2 - l1 / 2 - 1, k1 - 1, pWidth / 2 + l1 / 2 + 1, k1 + list1.size() * 9, Integer.MIN_VALUE);
|
||||
|
||||
for(FormattedCharSequence formattedcharsequence2 : list1) {
|
||||
int i2 = this.minecraft.font.width(formattedcharsequence2);
|
||||
pGuiGraphics.drawString(this.minecraft.font, formattedcharsequence2, pWidth / 2 - i2 / 2, k1, -1);
|
||||
k1 += 9;
|
||||
}
|
||||
|
||||
++k1;
|
||||
}
|
||||
|
||||
pGuiGraphics.fill(pWidth / 2 - l1 / 2 - 1, k1 - 1, pWidth / 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;
|
||||
pGuiGraphics.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(pGuiGraphics, playerinfo1.getSkinLocation(), k2, l2, 8, flag2, flag1);
|
||||
k2 += 9;
|
||||
}
|
||||
|
||||
pGuiGraphics.drawString(this.minecraft.font, this.getNameForDisplay(playerinfo1), k2, l2, playerinfo1.getGameMode() == GameType.SPECTATOR ? -1862270977 : -1);
|
||||
if (pObjective != null && playerinfo1.getGameMode() != GameType.SPECTATOR) {
|
||||
int l4 = k2 + i + 1;
|
||||
int i5 = l4 + l;
|
||||
if (i5 - l4 > 5) {
|
||||
this.renderTablistScore(pObjective, l2, gameprofile.getName(), l4, i5, gameprofile.getId(), pGuiGraphics);
|
||||
}
|
||||
}
|
||||
|
||||
this.renderPingIcon(pGuiGraphics, i1, k2 - (flag ? 9 : 0), l2, playerinfo1);
|
||||
}
|
||||
}
|
||||
|
||||
if (list2 != null) {
|
||||
k1 += j3 * 9 + 1;
|
||||
pGuiGraphics.fill(pWidth / 2 - l1 / 2 - 1, k1 - 1, pWidth / 2 + l1 / 2 + 1, k1 + list2.size() * 9, Integer.MIN_VALUE);
|
||||
|
||||
for(FormattedCharSequence formattedcharsequence3 : list2) {
|
||||
int k4 = this.minecraft.font.width(formattedcharsequence3);
|
||||
pGuiGraphics.drawString(this.minecraft.font, formattedcharsequence3, pWidth / 2 - k4 / 2, k1, -1);
|
||||
k1 += 9;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void renderPingIcon(GuiGraphics pGuiGraphics, int p_281809_, int p_282801_, int pY, PlayerInfo pPlayerInfo) {
|
||||
int i = 0;
|
||||
int j;
|
||||
if (pPlayerInfo.getLatency() < 0) {
|
||||
j = 5;
|
||||
} else if (pPlayerInfo.getLatency() < 150) {
|
||||
j = 0;
|
||||
} else if (pPlayerInfo.getLatency() < 300) {
|
||||
j = 1;
|
||||
} else if (pPlayerInfo.getLatency() < 600) {
|
||||
j = 2;
|
||||
} else if (pPlayerInfo.getLatency() < 1000) {
|
||||
j = 3;
|
||||
} else {
|
||||
j = 4;
|
||||
}
|
||||
|
||||
pGuiGraphics.pose().pushPose();
|
||||
pGuiGraphics.pose().translate(0.0F, 0.0F, 100.0F);
|
||||
pGuiGraphics.blit(GUI_ICONS_LOCATION, p_282801_ + p_281809_ - 11, pY, 0, 176 + j * 8, 10, 8);
|
||||
pGuiGraphics.pose().popPose();
|
||||
}
|
||||
|
||||
private void renderTablistScore(Objective pObjective, int pY, String pUsername, int p_283533_, int p_281254_, UUID pPlayerUuid, GuiGraphics pGuiGraphics) {
|
||||
int i = pObjective.getScoreboard().getOrCreatePlayerScore(pUsername, pObjective).getScore();
|
||||
if (pObjective.getRenderType() == ObjectiveCriteria.RenderType.HEARTS) {
|
||||
this.renderTablistHearts(pY, p_283533_, p_281254_, pPlayerUuid, pGuiGraphics, i);
|
||||
} else {
|
||||
String s = "" + ChatFormatting.YELLOW + i;
|
||||
pGuiGraphics.drawString(this.minecraft.font, s, p_281254_ - this.minecraft.font.width(s), pY, 16777215);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTablistHearts(int pY, int p_283173_, int p_282149_, UUID pPlayerUuid, GuiGraphics pGuiGraphics, int pHealth) {
|
||||
PlayerTabOverlay.HealthState playertaboverlay$healthstate = this.healthStates.computeIfAbsent(pPlayerUuid, (p_249546_) -> {
|
||||
return new PlayerTabOverlay.HealthState(pHealth);
|
||||
});
|
||||
playertaboverlay$healthstate.update(pHealth, (long)this.gui.getGuiTicks());
|
||||
int i = Mth.positiveCeilDiv(Math.max(pHealth, playertaboverlay$healthstate.displayedValue()), 2);
|
||||
int j = Math.max(pHealth, 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)pHealth / 20.0F, 0.0F, 1.0F);
|
||||
int i1 = (int)((1.0F - f) * 255.0F) << 16 | (int)(f * 255.0F) << 8;
|
||||
String s = "" + (float)pHealth / 2.0F;
|
||||
if (p_282149_ - this.minecraft.font.width(s + "hp") >= p_283173_) {
|
||||
s = s + "hp";
|
||||
}
|
||||
|
||||
pGuiGraphics.drawString(this.minecraft.font, s, (p_282149_ + p_283173_ - this.minecraft.font.width(s)) / 2, pY, i1);
|
||||
} else {
|
||||
for(int l = i; l < j; ++l) {
|
||||
pGuiGraphics.blit(GUI_ICONS_LOCATION, p_283173_ + l * k, pY, flag ? 25 : 16, 0, 9, 9);
|
||||
}
|
||||
|
||||
for(int j1 = 0; j1 < i; ++j1) {
|
||||
pGuiGraphics.blit(GUI_ICONS_LOCATION, p_283173_ + j1 * k, pY, flag ? 25 : 16, 0, 9, 9);
|
||||
if (flag) {
|
||||
if (j1 * 2 + 1 < playertaboverlay$healthstate.displayedValue()) {
|
||||
pGuiGraphics.blit(GUI_ICONS_LOCATION, p_283173_ + j1 * k, pY, 70, 0, 9, 9);
|
||||
}
|
||||
|
||||
if (j1 * 2 + 1 == playertaboverlay$healthstate.displayedValue()) {
|
||||
pGuiGraphics.blit(GUI_ICONS_LOCATION, p_283173_ + j1 * k, pY, 79, 0, 9, 9);
|
||||
}
|
||||
}
|
||||
|
||||
if (j1 * 2 + 1 < pHealth) {
|
||||
pGuiGraphics.blit(GUI_ICONS_LOCATION, p_283173_ + j1 * k, pY, j1 >= 10 ? 160 : 52, 0, 9, 9);
|
||||
}
|
||||
|
||||
if (j1 * 2 + 1 == pHealth) {
|
||||
pGuiGraphics.blit(GUI_ICONS_LOCATION, p_283173_ + j1 * k, pY, j1 >= 10 ? 169 : 61, 0, 9, 9);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setFooter(@Nullable Component pFooter) {
|
||||
this.footer = pFooter;
|
||||
}
|
||||
|
||||
public void setHeader(@Nullable Component pHeader) {
|
||||
this.header = pHeader;
|
||||
}
|
||||
|
||||
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 pDisplayedValue) {
|
||||
this.displayedValue = pDisplayedValue;
|
||||
this.lastValue = pDisplayedValue;
|
||||
}
|
||||
|
||||
public void update(int pValue, long pGuiTicks) {
|
||||
if (pValue != this.lastValue) {
|
||||
long i = pValue < this.lastValue ? 20L : 10L;
|
||||
this.blinkUntilTick = pGuiTicks + i;
|
||||
this.lastValue = pValue;
|
||||
this.lastUpdateTick = pGuiTicks;
|
||||
}
|
||||
|
||||
if (pGuiTicks - this.lastUpdateTick > 20L) {
|
||||
this.displayedValue = pValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int displayedValue() {
|
||||
return this.displayedValue;
|
||||
}
|
||||
|
||||
public boolean isBlinking(long pGuiTicks) {
|
||||
return this.blinkUntilTick > pGuiTicks && (this.blinkUntilTick - pGuiTicks) % 6L >= 3L;
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -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 pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick);
|
||||
}
|
||||
+34
@@ -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 pSplash) {
|
||||
this.splash = pSplash;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics pGuiGraphics, int pScreenWidth, Font pFont, int pColor) {
|
||||
pGuiGraphics.pose().pushPose();
|
||||
pGuiGraphics.pose().translate((float)pScreenWidth / 2.0F + 123.0F, 69.0F, 0.0F);
|
||||
pGuiGraphics.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)(pFont.width(this.splash) + 32);
|
||||
pGuiGraphics.pose().scale(f, f, f);
|
||||
pGuiGraphics.drawCenteredString(pFont, this.splash, 0, -8, 16776960 | pColor);
|
||||
pGuiGraphics.pose().popPose();
|
||||
}
|
||||
}
|
||||
+60
@@ -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 pX, int pY, int pWidth, int pHeight, boolean pInitialState) {
|
||||
super(pX, pY, pWidth, pHeight, CommonComponents.EMPTY);
|
||||
this.isStateTriggered = pInitialState;
|
||||
}
|
||||
|
||||
public void initTextureValues(int pXTexStart, int pYTexStart, int pXDiffTex, int pYDiffTex, ResourceLocation pResourceLocation) {
|
||||
this.xTexStart = pXTexStart;
|
||||
this.yTexStart = pYTexStart;
|
||||
this.xDiffTex = pXDiffTex;
|
||||
this.yDiffTex = pYDiffTex;
|
||||
this.resourceLocation = pResourceLocation;
|
||||
}
|
||||
|
||||
public void setStateTriggered(boolean pTriggered) {
|
||||
this.isStateTriggered = pTriggered;
|
||||
}
|
||||
|
||||
public boolean isStateTriggered() {
|
||||
return this.isStateTriggered;
|
||||
}
|
||||
|
||||
public void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
this.defaultButtonNarrationText(pNarrationElementOutput);
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
RenderSystem.disableDepthTest();
|
||||
int i = this.xTexStart;
|
||||
int j = this.yTexStart;
|
||||
if (this.isStateTriggered) {
|
||||
i += this.xDiffTex;
|
||||
}
|
||||
|
||||
if (this.isHoveredOrFocused()) {
|
||||
j += this.yDiffTex;
|
||||
}
|
||||
|
||||
pGuiGraphics.blit(this.resourceLocation, this.getX(), this.getY(), i, j, this.width, this.height);
|
||||
RenderSystem.enableDepthTest();
|
||||
}
|
||||
}
|
||||
+55
@@ -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 pMessage, Font pFont) {
|
||||
this(0, 0, pFont.width(pMessage.getVisualOrderText()), 9, pMessage, pFont);
|
||||
}
|
||||
|
||||
public StringWidget(int pWidth, int pHeight, Component pMessage, Font pFont) {
|
||||
this(0, 0, pWidth, pHeight, pMessage, pFont);
|
||||
}
|
||||
|
||||
public StringWidget(int pX, int pY, int pWidth, int pHeight, Component pMessage, Font pFont) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage, pFont);
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
public StringWidget setColor(int pColor) {
|
||||
super.setColor(pColor);
|
||||
return this;
|
||||
}
|
||||
|
||||
private StringWidget horizontalAlignment(float pHorizontalAlignment) {
|
||||
this.alignX = pHorizontalAlignment;
|
||||
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 pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
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;
|
||||
pGuiGraphics.drawString(font, component, i, j, this.getColor());
|
||||
}
|
||||
}
|
||||
+139
@@ -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 pMinecraft) {
|
||||
this.minecraft = pMinecraft;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics pGuiGraphics) {
|
||||
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;
|
||||
pGuiGraphics.pose().pushPose();
|
||||
pGuiGraphics.pose().translate((float)pGuiGraphics.guiWidth() - (float)l * 1.0F - 2.0F, (float)(pGuiGraphics.guiHeight() - 35) - (float)(i * (i1 + 1)) * 1.0F, 0.0F);
|
||||
pGuiGraphics.pose().scale(1.0F, 1.0F, 1.0F);
|
||||
pGuiGraphics.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) {
|
||||
pGuiGraphics.drawString(this.minecraft.font, ">", l - this.minecraft.font.width(">"), -j1, j2);
|
||||
} else if (d1 < 0.0D) {
|
||||
pGuiGraphics.drawString(this.minecraft.font, "<", -l, -j1, j2);
|
||||
}
|
||||
}
|
||||
|
||||
pGuiGraphics.drawString(this.minecraft.font, component, -k1 / 2, -j1, j2);
|
||||
pGuiGraphics.pose().popPose();
|
||||
++i;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void onPlaySound(SoundInstance pSound, WeighedSoundEvents pAccessor) {
|
||||
if (pAccessor.getSubtitle() != null) {
|
||||
Component component = pAccessor.getSubtitle();
|
||||
if (!this.subtitles.isEmpty()) {
|
||||
for(SubtitleOverlay.Subtitle subtitleoverlay$subtitle : this.subtitles) {
|
||||
if (subtitleoverlay$subtitle.getText().equals(component)) {
|
||||
subtitleoverlay$subtitle.refresh(new Vec3(pSound.getX(), pSound.getY(), pSound.getZ()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.subtitles.add(new SubtitleOverlay.Subtitle(component, new Vec3(pSound.getX(), pSound.getY(), pSound.getZ())));
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Subtitle {
|
||||
private final Component text;
|
||||
private long time;
|
||||
private Vec3 location;
|
||||
|
||||
public Subtitle(Component pText, Vec3 pLocation) {
|
||||
this.text = pText;
|
||||
this.location = pLocation;
|
||||
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 pLocation) {
|
||||
this.location = pLocation;
|
||||
this.time = Util.getMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
+90
@@ -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 pTabManager, Tab pTab, int pWidth, int pHeight) {
|
||||
super(0, 0, pWidth, pHeight, pTab.getTabTitle());
|
||||
this.tabManager = pTabManager;
|
||||
this.tab = pTab;
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
pGuiGraphics.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(pGuiGraphics, font, i);
|
||||
if (this.isSelected()) {
|
||||
this.renderFocusUnderline(pGuiGraphics, font, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void renderString(GuiGraphics pGuiGraphics, Font pFont, int pColor) {
|
||||
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(pGuiGraphics, pFont, this.getMessage(), i, j, k, l, pColor);
|
||||
}
|
||||
|
||||
private void renderFocusUnderline(GuiGraphics pGuiGraphics, Font pFont, int pColor) {
|
||||
int i = Math.min(pFont.width(this.getMessage()), this.getWidth() - 4);
|
||||
int j = this.getX() + (this.getWidth() - i) / 2;
|
||||
int k = this.getY() + this.getHeight() - 2;
|
||||
pGuiGraphics.fill(j, k, j + i, k + 1, pColor);
|
||||
}
|
||||
|
||||
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 pNarrationElementOutput) {
|
||||
pNarrationElementOutput.add(NarratedElementType.TITLE, Component.translatable("gui.narrate.tab", this.tab.getTabTitle()));
|
||||
}
|
||||
|
||||
public void playDownSound(SoundManager pHandler) {
|
||||
}
|
||||
|
||||
public Tab tab() {
|
||||
return this.tab;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return this.tabManager.getCurrentTab() == this.tab;
|
||||
}
|
||||
}
|
||||
+11
@@ -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;
|
||||
}
|
||||
}
|
||||
+114
@@ -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 pMessage, int pXTexStart, int pYTexStart, int pXOffset, int pYOffset, int pYDiffTex, int pUsedTextureWidth, int pUsedTextureHeight, int pTextureWidth, int pTextureHeight, ResourceLocation pResourceLocation, Button.OnPress pOnPress) {
|
||||
super(0, 0, 150, 20, pMessage, pOnPress, DEFAULT_NARRATION);
|
||||
this.textureWidth = pTextureWidth;
|
||||
this.textureHeight = pTextureHeight;
|
||||
this.xTexStart = pXTexStart;
|
||||
this.yTexStart = pYTexStart;
|
||||
this.yDiffTex = pYDiffTex;
|
||||
this.resourceLocation = pResourceLocation;
|
||||
this.xOffset = pXOffset;
|
||||
this.yOffset = pYOffset;
|
||||
this.usedTextureWidth = pUsedTextureWidth;
|
||||
this.usedTextureHeight = pUsedTextureHeight;
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
super.renderWidget(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
|
||||
this.renderTexture(pGuiGraphics, this.resourceLocation, this.getXOffset(), this.getYOffset(), this.xTexStart, this.yTexStart, this.yDiffTex, this.usedTextureWidth, this.usedTextureHeight, this.textureWidth, this.textureHeight);
|
||||
}
|
||||
|
||||
public void renderString(GuiGraphics pGuiGraphics, Font pFont, int pColor) {
|
||||
int i = this.getX() + 2;
|
||||
int j = this.getX() + this.getWidth() - this.usedTextureWidth - 6;
|
||||
renderScrollingString(pGuiGraphics, pFont, this.getMessage(), i, this.getY(), j, this.getY() + this.getHeight(), pColor);
|
||||
}
|
||||
|
||||
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 pMessage, ResourceLocation pResourceLocation, Button.OnPress pOnPress) {
|
||||
return new TextAndImageButton.Builder(pMessage, pResourceLocation, pOnPress);
|
||||
}
|
||||
|
||||
@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 pMessage, ResourceLocation pResourceLocation, Button.OnPress pOnPress) {
|
||||
this.message = pMessage;
|
||||
this.resourceLocation = pResourceLocation;
|
||||
this.onPress = pOnPress;
|
||||
}
|
||||
|
||||
public TextAndImageButton.Builder texStart(int pX, int pY) {
|
||||
this.xTexStart = pX;
|
||||
this.yTexStart = pY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextAndImageButton.Builder offset(int pX, int pY) {
|
||||
this.xOffset = pX;
|
||||
this.yOffset = pY;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextAndImageButton.Builder yDiffTex(int pYDiffTex) {
|
||||
this.yDiffTex = pYDiffTex;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextAndImageButton.Builder usedTextureSize(int pWidth, int pHeight) {
|
||||
this.usedTextureWidth = pWidth;
|
||||
this.usedTextureHeight = pHeight;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextAndImageButton.Builder textureSize(int pWidth, int pHeight) {
|
||||
this.textureWidth = pWidth;
|
||||
this.textureHeight = pHeight;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
@@ -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 pMessage, @Nullable Component pNarration) {
|
||||
this.message = pMessage;
|
||||
this.narration = pNarration;
|
||||
}
|
||||
|
||||
public static Tooltip create(Component pMessage, @Nullable Component pNarration) {
|
||||
return new Tooltip(pMessage, pNarration);
|
||||
}
|
||||
|
||||
public static Tooltip create(Component pMessage) {
|
||||
return new Tooltip(pMessage, pMessage);
|
||||
}
|
||||
|
||||
public void updateNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||
if (this.narration != null) {
|
||||
pNarrationElementOutput.add(NarratedElementType.HINT, this.narration);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<FormattedCharSequence> toCharSequence(Minecraft pMinecraft) {
|
||||
if (this.cachedTooltip == null) {
|
||||
this.cachedTooltip = splitTooltip(pMinecraft, this.message);
|
||||
}
|
||||
|
||||
return this.cachedTooltip;
|
||||
}
|
||||
|
||||
public static List<FormattedCharSequence> splitTooltip(Minecraft pMinecraft, Component pMessage) {
|
||||
return pMinecraft.font.split(pMessage, 170);
|
||||
}
|
||||
}
|
||||
+11
@@ -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;
|
||||
}
|
||||
+37
@@ -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 pDragging) {
|
||||
this.isDragging = pDragging;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GuiEventListener getFocused() {
|
||||
return this.focused;
|
||||
}
|
||||
|
||||
public void setFocused(@Nullable GuiEventListener pListener) {
|
||||
if (this.focused != null) {
|
||||
this.focused.setFocused(false);
|
||||
}
|
||||
|
||||
if (pListener != null) {
|
||||
pListener.setFocused(true);
|
||||
}
|
||||
|
||||
this.focused = pListener;
|
||||
}
|
||||
}
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
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();
|
||||
|
||||
/**
|
||||
* Returns the first event listener that intersects with the mouse coordinates.
|
||||
*/
|
||||
default Optional<GuiEventListener> getChildAt(double pMouseX, double pMouseY) {
|
||||
for(GuiEventListener guieventlistener : this.children()) {
|
||||
if (guieventlistener.isMouseOver(pMouseX, pMouseY)) {
|
||||
return Optional.of(guieventlistener);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
default boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
|
||||
for(GuiEventListener guieventlistener : this.children()) {
|
||||
if (guieventlistener.mouseClicked(pMouseX, pMouseY, pButton)) {
|
||||
this.setFocused(guieventlistener);
|
||||
if (pButton == 0) {
|
||||
this.setDragging(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean mouseReleased(double pMouseX, double pMouseY, int pButton) {
|
||||
this.setDragging(false);
|
||||
return this.getChildAt(pMouseX, pMouseY).filter((p_94708_) -> {
|
||||
return p_94708_.mouseReleased(pMouseX, pMouseY, pButton);
|
||||
}).isPresent();
|
||||
}
|
||||
|
||||
default boolean mouseDragged(double pMouseX, double pMouseY, int pButton, double pDragX, double pDragY) {
|
||||
return this.getFocused() != null && this.isDragging() && pButton == 0 ? this.getFocused().mouseDragged(pMouseX, pMouseY, pButton, pDragX, pDragY) : false;
|
||||
}
|
||||
|
||||
boolean isDragging();
|
||||
|
||||
void setDragging(boolean pIsDragging);
|
||||
|
||||
default boolean mouseScrolled(double pMouseX, double pMouseY, double pDelta) {
|
||||
return this.getChildAt(pMouseX, pMouseY).filter((p_94693_) -> {
|
||||
return p_94693_.mouseScrolled(pMouseX, pMouseY, pDelta);
|
||||
}).isPresent();
|
||||
}
|
||||
|
||||
default boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
return this.getFocused() != null && this.getFocused().keyPressed(pKeyCode, pScanCode, pModifiers);
|
||||
}
|
||||
|
||||
default boolean keyReleased(int pKeyCode, int pScanCode, int pModifiers) {
|
||||
return this.getFocused() != null && this.getFocused().keyReleased(pKeyCode, pScanCode, pModifiers);
|
||||
}
|
||||
|
||||
default boolean charTyped(char pCodePoint, int pModifiers) {
|
||||
return this.getFocused() != null && this.getFocused().charTyped(pCodePoint, pModifiers);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
GuiEventListener getFocused();
|
||||
|
||||
void setFocused(@Nullable GuiEventListener pFocused);
|
||||
|
||||
default void setFocused(boolean pFocused) {
|
||||
}
|
||||
|
||||
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 pEventListener) {
|
||||
this.setFocused(pEventListener);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default ComponentPath nextFocusPath(FocusNavigationEvent pEvent) {
|
||||
GuiEventListener guieventlistener = this.getFocused();
|
||||
if (guieventlistener != null) {
|
||||
ComponentPath componentpath = guieventlistener.nextFocusPath(pEvent);
|
||||
if (componentpath != null) {
|
||||
return ComponentPath.path(this, componentpath);
|
||||
}
|
||||
}
|
||||
|
||||
if (pEvent instanceof FocusNavigationEvent.TabNavigation focusnavigationevent$tabnavigation) {
|
||||
return this.handleTabNavigation(focusnavigationevent$tabnavigation);
|
||||
} else if (pEvent instanceof FocusNavigationEvent.ArrowNavigation focusnavigationevent$arrownavigation) {
|
||||
return this.handleArrowNavigation(focusnavigationevent$arrownavigation);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ComponentPath handleTabNavigation(FocusNavigationEvent.TabNavigation pTabNavigation) {
|
||||
boolean flag = pTabNavigation.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(pTabNavigation);
|
||||
if (componentpath != null) {
|
||||
return ComponentPath.path(this, componentpath);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ComponentPath handleArrowNavigation(FocusNavigationEvent.ArrowNavigation pArrowNavigation) {
|
||||
GuiEventListener guieventlistener = this.getFocused();
|
||||
if (guieventlistener == null) {
|
||||
ScreenDirection screendirection = pArrowNavigation.direction();
|
||||
ScreenRectangle screenrectangle1 = this.getRectangle().getBorder(screendirection.getOpposite());
|
||||
return ComponentPath.path(this, this.nextFocusPathInDirection(screenrectangle1, screendirection, (GuiEventListener)null, pArrowNavigation));
|
||||
} else {
|
||||
ScreenRectangle screenrectangle = guieventlistener.getRectangle();
|
||||
return ComponentPath.path(this, this.nextFocusPathInDirection(screenrectangle, pArrowNavigation.direction(), guieventlistener, pArrowNavigation));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ComponentPath nextFocusPathInDirection(ScreenRectangle pRectangle, ScreenDirection pDirection, @Nullable GuiEventListener pListener, FocusNavigationEvent pEvent) {
|
||||
ScreenAxis screenaxis = pDirection.getAxis();
|
||||
ScreenAxis screenaxis1 = screenaxis.orthogonal();
|
||||
ScreenDirection screendirection = screenaxis1.getPositive();
|
||||
int i = pRectangle.getBoundInDirection(pDirection.getOpposite());
|
||||
List<GuiEventListener> list = new ArrayList<>();
|
||||
|
||||
for(GuiEventListener guieventlistener : this.children()) {
|
||||
if (guieventlistener != pListener) {
|
||||
ScreenRectangle screenrectangle = guieventlistener.getRectangle();
|
||||
if (screenrectangle.overlapsInAxis(pRectangle, screenaxis1)) {
|
||||
int j = screenrectangle.getBoundInDirection(pDirection.getOpposite());
|
||||
if (pDirection.isAfter(j, i)) {
|
||||
list.add(guieventlistener);
|
||||
} else if (j == i && pDirection.isAfter(screenrectangle.getBoundInDirection(pDirection), pRectangle.getBoundInDirection(pDirection))) {
|
||||
list.add(guieventlistener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Comparator<GuiEventListener> comparator = Comparator.comparing((p_264674_) -> {
|
||||
return p_264674_.getRectangle().getBoundInDirection(pDirection.getOpposite());
|
||||
}, pDirection.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(pEvent);
|
||||
if (componentpath != null) {
|
||||
return componentpath;
|
||||
}
|
||||
}
|
||||
|
||||
return this.nextFocusPathVaguelyInDirection(pRectangle, pDirection, pListener, pEvent);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ComponentPath nextFocusPathVaguelyInDirection(ScreenRectangle pRectangle, ScreenDirection pDirection, @Nullable GuiEventListener pListener, FocusNavigationEvent pEvent) {
|
||||
ScreenAxis screenaxis = pDirection.getAxis();
|
||||
ScreenAxis screenaxis1 = screenaxis.orthogonal();
|
||||
List<Pair<GuiEventListener, Long>> list = new ArrayList<>();
|
||||
ScreenPosition screenposition = ScreenPosition.of(screenaxis, pRectangle.getBoundInDirection(pDirection), pRectangle.getCenterInAxis(screenaxis1));
|
||||
|
||||
for(GuiEventListener guieventlistener : this.children()) {
|
||||
if (guieventlistener != pListener) {
|
||||
ScreenRectangle screenrectangle = guieventlistener.getRectangle();
|
||||
ScreenPosition screenposition1 = ScreenPosition.of(screenaxis, screenrectangle.getBoundInDirection(pDirection.getOpposite()), screenrectangle.getCenterInAxis(screenaxis1));
|
||||
if (pDirection.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(pEvent);
|
||||
if (componentpath != null) {
|
||||
return componentpath;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loaded 100 of 14134 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user