refactor: simplify rendering logic, remove redundant cases, and replace bounds checks with Math.clamp
This commit is contained in:
@@ -44,8 +44,8 @@ public final class Face {
|
||||
|
||||
int px = (int) Math.floor(u * w);
|
||||
int py = (int) Math.floor(v * h);
|
||||
px = Math.max(0, Math.min(w - 1, px));
|
||||
py = Math.max(0, Math.min(h - 1, py));
|
||||
px = Math.clamp(px, 0, w - 1);
|
||||
py = Math.clamp(py, 0, h - 1);
|
||||
return texture[py][px];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,6 @@ public final class BlockEntityModels {
|
||||
private static void headTextures(List<String> paths, String headType) {
|
||||
if (headType == null) { paths.add("entity/skeleton/skeleton"); return; }
|
||||
switch (headType) {
|
||||
case "skeleton" -> paths.add("entity/skeleton/skeleton");
|
||||
case "wither_skeleton" -> paths.add("entity/skeleton/wither_skeleton");
|
||||
case "zombie" -> paths.add("entity/zombie/zombie");
|
||||
case "creeper" -> paths.add("entity/creeper/creeper");
|
||||
|
||||
@@ -61,11 +61,10 @@ public final class DecorationBaker implements EntityBaker<DecorationState> {
|
||||
|
||||
List<EntityCube> cubes = new ArrayList<>(3);
|
||||
// Wood border 12x12 (behind), leather back 10x10 (1px proud), item 8x8 (in front). Front = local +Z.
|
||||
if (wood != null) {
|
||||
Face[] f = new Face[6];
|
||||
f[si] = new Face(wood, 1, 0, 0, 1, 0, -1); // tileable; flip matches the others
|
||||
cubes.add(new EntityCube(px(-6, -6, 0), px(6, 6, 1), f, toWorld));
|
||||
}
|
||||
// `wood` is never null here (orElse(leather) and leather is non-null past the guard above).
|
||||
Face[] woodFace = new Face[6];
|
||||
woodFace[si] = new Face(wood, 1, 0, 0, 1, 0, -1); // tileable; flip matches the others
|
||||
cubes.add(new EntityCube(px(-6, -6, 0), px(6, 6, 1), woodFace, toWorld));
|
||||
Face[] back = new Face[6];
|
||||
back[si] = new Face(leather, 13.0 / 16, 3.0 / 16, 3.0 / 16, 13.0 / 16, 0, -1); // centre 10x10, flipped
|
||||
cubes.add(new EntityCube(px(-5, -5, 1), px(5, 5, 2), back, toWorld));
|
||||
|
||||
@@ -138,26 +138,26 @@ public final class EntityModels {
|
||||
* fallbacks, so an unknown variant still degrades to the base texture.
|
||||
*/
|
||||
private static List<String> variantPaths(String typeKey, String v) {
|
||||
switch (typeKey) {
|
||||
case "cat": return List.of("entity/cat/cat_" + v);
|
||||
case "axolotl": return List.of("entity/axolotl/axolotl_" + v);
|
||||
case "wolf": return List.of("entity/wolf/wolf_" + v, "entity/wolf/wolf");
|
||||
case "horse": return List.of("entity/horse/horse_" + HORSE_COLOR.getOrDefault(v, v));
|
||||
case "llama": return List.of("entity/llama/llama_" + v);
|
||||
case "cow": return List.of("entity/cow/cow_" + v);
|
||||
case "pig": return List.of("entity/pig/pig_" + v);
|
||||
case "chicken": return List.of("entity/chicken/chicken_" + v);
|
||||
case "frog": return List.of("entity/frog/frog_" + v);
|
||||
case "panda": return List.of(v.equals("normal") ? "entity/panda/panda" : "entity/panda/panda_" + v);
|
||||
case "fox": return List.of(v.equals("snow") ? "entity/fox/fox_snow" : "entity/fox/fox");
|
||||
case "parrot": return List.of("entity/parrot/parrot_" + PARROT_COLOR.getOrDefault(v, v));
|
||||
case "rabbit": return List.of("entity/rabbit/rabbit_" + RABBIT_TYPE.getOrDefault(v, v));
|
||||
case "mooshroom": return List.of("entity/cow/mooshroom_" + v);
|
||||
case "shulker": return List.of("entity/shulker/shulker_" + v);
|
||||
return switch (typeKey) {
|
||||
case "cat" -> List.of("entity/cat/cat_" + v);
|
||||
case "axolotl" -> List.of("entity/axolotl/axolotl_" + v);
|
||||
case "wolf" -> List.of("entity/wolf/wolf_" + v, "entity/wolf/wolf");
|
||||
case "horse" -> List.of("entity/horse/horse_" + HORSE_COLOR.getOrDefault(v, v));
|
||||
case "llama" -> List.of("entity/llama/llama_" + v);
|
||||
case "cow" -> List.of("entity/cow/cow_" + v);
|
||||
case "pig" -> List.of("entity/pig/pig_" + v);
|
||||
case "chicken" -> List.of("entity/chicken/chicken_" + v);
|
||||
case "frog" -> List.of("entity/frog/frog_" + v);
|
||||
case "panda" -> List.of(v.equals("normal") ? "entity/panda/panda" : "entity/panda/panda_" + v);
|
||||
case "fox" -> List.of(v.equals("snow") ? "entity/fox/fox_snow" : "entity/fox/fox");
|
||||
case "parrot" -> List.of("entity/parrot/parrot_" + PARROT_COLOR.getOrDefault(v, v));
|
||||
case "rabbit" -> List.of("entity/rabbit/rabbit_" + RABBIT_TYPE.getOrDefault(v, v));
|
||||
case "mooshroom" -> List.of("entity/cow/mooshroom_" + v);
|
||||
case "shulker" -> List.of("entity/shulker/shulker_" + v);
|
||||
// villager/zombie_villager: type/<biome> and profession are transparent OVERLAYS (clothing
|
||||
// only); the opaque base body is entity/<folder>/<folder> — handled by the generic candidates.
|
||||
default: return List.of();
|
||||
}
|
||||
default -> List.of();
|
||||
};
|
||||
}
|
||||
|
||||
private static final Map<String, String> HORSE_COLOR = Map.of("dark_brown", "darkbrown");
|
||||
|
||||
@@ -10,7 +10,7 @@ public final class ModelCube {
|
||||
public final double inflate; // px, expands the box on all sides (overlay layers)
|
||||
public final double[] uv; // 2, box-UV offset (texels)
|
||||
public final boolean mirror;
|
||||
/** Optional modern per-face UV, indexed by {@link Direction#ordinal()}: {u, v, w, h} texels (h/w may be negative for flips). Null = use box-UV. */
|
||||
/** Optional modern per-face UV, indexed by {@code Direction.ordinal()}: {u, v, w, h} texels (h/w may be negative for flips). Null = use box-UV. */
|
||||
public final double[][] faceUv;
|
||||
|
||||
public ModelCube(double[] origin, double[] size, double inflate, double[] uv, boolean mirror) {
|
||||
|
||||
@@ -63,7 +63,7 @@ public final class BlockEntityBaker implements EntityBaker<BlockEntityState> {
|
||||
if (layers.isEmpty()) return null;
|
||||
// Head model depends on the texture aspect (skeleton 64x32 vs zombie/player 64x64), so resolve it
|
||||
// from the chosen texture rather than statically.
|
||||
CemModelLoader.CemModel model = models.get(modelName(s, layers.get(0).tex));
|
||||
CemModelLoader.CemModel model = models.get(modelName(s, layers.getFirst().tex));
|
||||
if (model == null) return null;
|
||||
|
||||
Place p = place(s);
|
||||
@@ -230,7 +230,6 @@ public final class BlockEntityBaker implements EntityBaker<BlockEntityState> {
|
||||
return switch (s.kind()) {
|
||||
case SIGN -> new Place(yaw, SIGN_SCALE, 0, 0, 0);
|
||||
case WALL_SIGN -> new Place(yaw, SIGN_SCALE, 0, -0.3125, 0.4375); // drop to mid-block, push to wall
|
||||
case HANGING_SIGN -> new Place(yaw, 1.0, 0, 0, 0);
|
||||
case WALL_HEAD -> new Place(yaw, 1.0, 0, 0.25, 0.25); // mid-height, against the wall
|
||||
case WALL_BANNER -> new Place(yaw, 1.0, 0, -0.16, 0.4375);
|
||||
default -> new Place(yaw, 1.0, 0, 0, 0);
|
||||
|
||||
-1
@@ -270,7 +270,6 @@ public final class BlockEntitySnapshotBuilder {
|
||||
case "CREEPER_HEAD" -> "creeper";
|
||||
case "DRAGON_HEAD" -> "dragon";
|
||||
case "PIGLIN_HEAD" -> "piglin";
|
||||
case "SKELETON_SKULL" -> "skeleton";
|
||||
case "WITHER_SKELETON_SKULL" -> "wither_skeleton";
|
||||
default -> "skeleton";
|
||||
};
|
||||
|
||||
@@ -71,8 +71,8 @@ public final class BiomeTintProvider {
|
||||
int y = (int) ((1.0 - down) * 255.0);
|
||||
int h = colormap.length;
|
||||
int w = colormap[0].length;
|
||||
x = Math.max(0, Math.min(w - 1, x));
|
||||
y = Math.max(0, Math.min(h - 1, y));
|
||||
x = Math.clamp(x, 0, w - 1);
|
||||
y = Math.clamp(y, 0, h - 1);
|
||||
return 0xFF000000 | (colormap[y][x] & 0xFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public final class CameraItems {
|
||||
|
||||
/** Returns a copy of {@code camera} with its film count set to {@code newCount} and lore refreshed. */
|
||||
public static ItemStack withFilmCount(ItemStack camera, int newCount) {
|
||||
int count = Math.max(0, Math.min(MAX_FILM, newCount));
|
||||
int count = Math.clamp(newCount, 0, MAX_FILM);
|
||||
ItemStack copy = camera.clone();
|
||||
SkullMeta meta = (SkullMeta) copy.getItemMeta();
|
||||
meta.getPersistentDataContainer().set(Main.getInstance().filmCountKey, PersistentDataType.INTEGER, count);
|
||||
|
||||
@@ -129,7 +129,7 @@ public class CraftingListener implements Listener {
|
||||
return SurvivalRecipes.LOAD.equals(key) || SurvivalRecipes.COPY.equals(key);
|
||||
}
|
||||
|
||||
/** A second photo referencing the same {@link MapView} and picture id as {@code photo}. */
|
||||
/** A second photo referencing the same {@link org.bukkit.map.MapView} and picture id as {@code photo}. */
|
||||
private static ItemStack buildPhotoCopy(ItemStack photo) {
|
||||
MapMeta src = (MapMeta) photo.getItemMeta();
|
||||
if (!src.hasMapView() || src.getMapView() == null) return null;
|
||||
|
||||
Reference in New Issue
Block a user