fix(redstoner): rendre les panneaux de trophées lisibles
Verification 26.2 / check (pull_request) Canceled after 0s
Verification 26.2 / check (pull_request) Canceled after 0s
This commit is contained in:
@@ -6,6 +6,13 @@ Ce journal suit les **versions du modpack**. Lorsqu'un seul module change, sa ve
|
||||
- Depuis `26.2.0-alpha.6`, le pack et les modules ont des versions indépendantes. I Like To Move It et Only Fun deviennent les cinquième et sixième modules actifs dans l'alpha 46.
|
||||
- Les versions ci-dessous ont été reconstituées à partir des JAR archivés, des packs locaux et du code source actuel. Les dates n'étant pas enregistrées de manière fiable, elles ne sont pas inventées.
|
||||
|
||||
## Non publié
|
||||
|
||||
Module modifié : **Red-Stoner `0.0.0-alpha.18`**.
|
||||
|
||||
- transforme le panneau de trophées en plaque verticale de chêne, corrige le texte auparavant masqué et utilise les quatre lignes pour le titre paginé ainsi que les trois places du podium ;
|
||||
- permet de passer à la page suivante d’un clic droit et de revenir à la précédente avec `Maj` + clic droit, sans changer les IDs, les sauvegardes Red-Stoner v4 ni le protocole réseau 7.
|
||||
|
||||
## `26.2.0-alpha.230`
|
||||
|
||||
Modules modifiés : **Sanctuary `0.0.0-alpha.136`** et **Red-Stoner `0.0.0-alpha.17`**.
|
||||
|
||||
@@ -24,6 +24,8 @@ Les descriptions FR/EN/RU sont déclarées dans chaque `fabric.mod.json` et dans
|
||||
|
||||
Version courante du pack distribué : **`26.2.0-alpha.230`**. Cette release distribue Sanctuary **`0.0.0-alpha.136`** et Red-Stoner **`0.0.0-alpha.17`** ; les huit autres modules conservent leur version issue de l'alpha.229.
|
||||
|
||||
Le prochain Red-Stoner **`0.0.0-alpha.18`** présente le panneau de trophées comme une plaque verticale de chêne et rend enfin ses quatre lignes lisibles : titre et numéro de page, puis les trois places du podium. Un clic droit avance d’une page et `Maj` + clic droit revient à la précédente ; les données v4 et le protocole réseau 7 restent inchangés.
|
||||
|
||||
L’alpha.230 attribue les quêtes communautaires terminées à leur preneur et répartit les lits de sortie rares sur chacun des cinq niveaux de la Backroom. Elle ajoute aussi les classements publics et le panneau mural `redstoner:trophy_panel`, corrige la projection des couleurs et motifs de la cape blanche avec les sprites de bouclier, et permet d’équiper une poule adulte avec l’armure de loup vanilla en écailles de tatou. Les sauvegardes restent compatibles ; Sanctuary passe aux données v15 et Red-Stoner aux données v4 sans changer leurs protocoles réseau 24 et 7.
|
||||
|
||||
L’alpha.229 ajoute au terminal les tris alphabétique, par quantité croissante et par quantité décroissante. Le tri ne change que sur demande explicite et les rafraîchissements périodiques conservent l’ordre ainsi que les objets sous le curseur. Les sauvegardes, les données Red-Stoner v3 et le protocole réseau 7 restent compatibles.
|
||||
|
||||
+33
-16
@@ -3692,7 +3692,7 @@ tasks.register("verifyMirrorLavenderDrawerRelease") {
|
||||
def drawerRecipe = file("redstoner/src/main/resources/data/redstoner/recipe/drawer.json")
|
||||
if (rootProject.pack_version != "26.2.0-alpha.230"
|
||||
|| rootProject.anotherworld_version != "0.0.0-alpha.57"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.17"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.18"
|
||||
|| release.pack_version != rootProject.pack_version || index.versionId != rootProject.pack_version
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.191"
|
||||
|| migration.source?.modules != [anotherworld: "0.0.0-alpha.48", redstoner: "0.0.0-alpha.9"]
|
||||
@@ -4225,13 +4225,20 @@ project(":redstoner") {
|
||||
"src/main/java/fr/koka99cab/sanctuary26/redstoner/registry/RedStonerRegistries.java").text
|
||||
def panel = file(
|
||||
"src/main/java/fr/koka99cab/sanctuary26/redstoner/block/entity/TrophyPanelBlockEntity.java").text
|
||||
def block = file(
|
||||
"src/main/java/fr/koka99cab/sanctuary26/redstoner/block/TrophyPanelBlock.java").text
|
||||
def renderer = file(
|
||||
"src/main/java/fr/koka99cab/sanctuary26/redstoner/client/renderer/TrophyPanelBlockEntityRenderer.java").text
|
||||
def model = new JsonSlurper().parse(file(
|
||||
"src/main/resources/assets/redstoner/models/block/trophy_panel.json"))
|
||||
def rankingApi = rootProject.file(
|
||||
"sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/api/ranking/SanctuaryRankingApi.java").text
|
||||
def rankingData = rootProject.file(
|
||||
"sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/api/ranking/SanctuaryRankingData.java").text
|
||||
def requiredKeys = [
|
||||
"block.redstoner.trophy_panel", "message.redstoner.trophy_panel.not_owner",
|
||||
"message.redstoner.trophy_panel.configured"]
|
||||
"message.redstoner.trophy_panel.configured", "block.redstoner.trophy_panel.page_title",
|
||||
"block.redstoner.trophy_panel.podium"]
|
||||
def redstonerLocales = ["fr_fr", "en_us", "ru_ru"].collect {
|
||||
new JsonSlurper().parse(file("src/main/resources/assets/redstoner/lang/${it}.json"))
|
||||
}
|
||||
@@ -4239,7 +4246,7 @@ project(":redstoner") {
|
||||
new JsonSlurper().parse(rootProject.file(
|
||||
"sanctuary/src/main/resources/assets/sanctuary/lang/${it}.json"))
|
||||
}
|
||||
if (rootProject.redstoner_version != "0.0.0-alpha.17"
|
||||
if (rootProject.redstoner_version != "0.0.0-alpha.18"
|
||||
|| rootProject.sanctuary_version != "0.0.0-alpha.136"
|
||||
|| redstonerManifest.custom?.sanctuary26?.data_version != 4
|
||||
|| redstonerManifest.custom?.sanctuary26?.network_protocol != 7
|
||||
@@ -4256,6 +4263,15 @@ project(":redstoner") {
|
||||
|| !panel.contains("REFRESH_INTERVAL_TICKS = 20")
|
||||
|| !panel.contains("CLIENT_SNAPSHOT_TAG")
|
||||
|| !panel.contains("PAGE_CODEC.listOf(0, TrophyPanelRules.MAX_PAGES)")
|
||||
|| !panel.contains("public boolean previousPage()")
|
||||
|| !block.contains("player.isSecondaryUseActive()")
|
||||
|| !renderer.contains("TrophyPanelRenderState.LINE_COUNT")
|
||||
|| !renderer.contains("state.lightCoords, TEXT_COLOR, 0, 0")
|
||||
|| model.textures?.wood != "minecraft:block/oak_planks"
|
||||
|| model.textures?.containsKey("screen")
|
||||
|| model.elements?.size() != 1
|
||||
|| model.elements[0].from != [0, 0, 14]
|
||||
|| model.elements[0].to != [16, 16, 16]
|
||||
|| !rankingApi.contains("public static RankingSnapshot snapshot")
|
||||
|| !rankingApi.contains("!player.isCreative() && !player.isSpectator()")
|
||||
|| !rankingData.contains("vanillaStatsImported")
|
||||
@@ -4400,7 +4416,7 @@ project(":redstoner") {
|
||||
"src/main/resources/data/redstoner/recipe/controller.json"))
|
||||
def terminalRecipe = new JsonSlurper().parse(file(
|
||||
"src/main/resources/data/redstoner/recipe/storage_terminal.json"))
|
||||
if (project.version.toString() != "0.0.0-alpha.17"
|
||||
if (project.version.toString() != "0.0.0-alpha.18"
|
||||
|| manifest.custom?.sanctuary26?.data_version != 4
|
||||
|| manifest.custom?.sanctuary26?.network_protocol != 7
|
||||
|| terminalMigration.source?.pack_version != "26.2.0-alpha.217"
|
||||
@@ -6751,7 +6767,7 @@ tasks.register("verifyAlpha218Release") {
|
||||
"file = \"mods/${id}-${version}.jar\""
|
||||
}
|
||||
if (rootProject.pack_version != "26.2.0-alpha.230"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.17"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.18"
|
||||
|| currentModules.findAll { id, version ->
|
||||
id != "redstoner" && id != "sanctuary" && id != "onlyfun" && id != "iliketomoveit"
|
||||
}.any {
|
||||
@@ -6940,7 +6956,7 @@ tasks.register("verifyAlpha220Release") {
|
||||
def networking = file(
|
||||
"redstoner/src/main/java/fr/koka99cab/sanctuary26/redstoner/network/RedStonerNetworking.java").text
|
||||
if (rootProject.pack_version != "26.2.0-alpha.230"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.17"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.18"
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.219"
|
||||
|| migration.source?.modules != [redstoner: "0.0.0-alpha.11"]
|
||||
|| migration.target?.pack_version != "26.2.0-alpha.220"
|
||||
@@ -7169,7 +7185,7 @@ tasks.register("verifyAlpha222Release") {
|
||||
it.path == "mods/jei-26.2-fabric-30.29.0.199.jar"
|
||||
}
|
||||
if (rootProject.pack_version != "26.2.0-alpha.230"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.17"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.18"
|
||||
|| rootProject.sanctuary_version != "0.0.0-alpha.136"
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.221"
|
||||
|| migration.source?.modules != [
|
||||
@@ -7629,7 +7645,7 @@ tasks.register("verifyAlpha225Release") {
|
||||
def workspaceModules = moduleIds.collectEntries { id ->
|
||||
[(id): project(":${id}").version.toString()]
|
||||
}
|
||||
def releasedModules = workspaceModules
|
||||
def releasedModules = workspaceModules + [redstoner: "0.0.0-alpha.17"]
|
||||
def requiredJars = releasedModules.collect { id, version ->
|
||||
"file = \"mods/${id}-${version}.jar\""
|
||||
}
|
||||
@@ -7789,7 +7805,7 @@ tasks.register("verifyAlpha226Release") {
|
||||
def workspaceModules = moduleIds.collectEntries { id ->
|
||||
[(id): project(":${id}").version.toString()]
|
||||
}
|
||||
def releasedModules = workspaceModules
|
||||
def releasedModules = workspaceModules + [redstoner: "0.0.0-alpha.17"]
|
||||
def requiredJars = releasedModules.collect { id, version ->
|
||||
"file = \"mods/${id}-${version}.jar\""
|
||||
}
|
||||
@@ -7880,7 +7896,7 @@ tasks.register("verifyAlpha227Release") {
|
||||
def workspaceModules = moduleIds.collectEntries { id ->
|
||||
[(id): project(":${id}").version.toString()]
|
||||
}
|
||||
def releasedModules = workspaceModules
|
||||
def releasedModules = workspaceModules + [redstoner: "0.0.0-alpha.17"]
|
||||
def requiredJars = releasedModules.collect { id, version ->
|
||||
"file = \"mods/${id}-${version}.jar\""
|
||||
}
|
||||
@@ -7978,12 +7994,12 @@ tasks.register("verifyAlpha228Release") {
|
||||
def workspaceModules = moduleIds.collectEntries { id ->
|
||||
[(id): project(":${id}").version.toString()]
|
||||
}
|
||||
def releasedModules = workspaceModules
|
||||
def releasedModules = workspaceModules + [redstoner: "0.0.0-alpha.17"]
|
||||
def requiredJars = releasedModules.collect { id, version ->
|
||||
"file = \"mods/${id}-${version}.jar\""
|
||||
}
|
||||
if (rootProject.pack_version != "26.2.0-alpha.230"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.17"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.18"
|
||||
|| rootProject.sanctuary_version != "0.0.0-alpha.136"
|
||||
|| migration.status != "released"
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.227"
|
||||
@@ -8083,7 +8099,7 @@ tasks.register("verifyAlpha229Release") {
|
||||
def workspaceModules = moduleIds.collectEntries { id ->
|
||||
[(id): project(":${id}").version.toString()]
|
||||
}
|
||||
def releasedModules = workspaceModules
|
||||
def releasedModules = workspaceModules + [redstoner: "0.0.0-alpha.17"]
|
||||
def requiredJars = releasedModules.collect { id, version ->
|
||||
"file = \"mods/${id}-${version}.jar\""
|
||||
}
|
||||
@@ -8093,7 +8109,7 @@ tasks.register("verifyAlpha229Release") {
|
||||
"screen.redstoner.storage_terminal.sort.count_ascending",
|
||||
"screen.redstoner.storage_terminal.sort.count_descending"]
|
||||
if (rootProject.pack_version != "26.2.0-alpha.230"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.17"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.18"
|
||||
|| rootProject.sanctuary_version != "0.0.0-alpha.136"
|
||||
|| migration.status != "released"
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.228"
|
||||
@@ -8171,14 +8187,15 @@ tasks.register("verifyAlpha230Release") {
|
||||
def workspaceModules = moduleIds.collectEntries { id ->
|
||||
[(id): project(":${id}").version.toString()]
|
||||
}
|
||||
def requiredJars = workspaceModules.collect { id, version ->
|
||||
def releasedModules = workspaceModules + [redstoner: "0.0.0-alpha.17"]
|
||||
def requiredJars = releasedModules.collect { id, version ->
|
||||
"file = \"mods/${id}-${version}.jar\""
|
||||
}
|
||||
def indexHash = java.security.MessageDigest.getInstance("SHA-256")
|
||||
.digest(packwizIndexFile.bytes).encodeHex().toString()
|
||||
if (rootProject.pack_version != "26.2.0-alpha.230"
|
||||
|| rootProject.sanctuary_version != "0.0.0-alpha.136"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.17"
|
||||
|| rootProject.redstoner_version != "0.0.0-alpha.18"
|
||||
|| migration.schema_version != 1
|
||||
|| migration.status != "released"
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.229"
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ mod_version=0.0.0-alpha.0
|
||||
module_lifecycle=standby
|
||||
ambiance_version=0.0.0-alpha.22
|
||||
ambiance_lifecycle=active
|
||||
redstoner_version=0.0.0-alpha.17
|
||||
redstoner_version=0.0.0-alpha.18
|
||||
redstoner_lifecycle=active
|
||||
anotherworld_version=0.0.0-alpha.57
|
||||
anotherworld_lifecycle=active
|
||||
|
||||
+14
-35
@@ -3,7 +3,6 @@ package fr.koka99cab.sanctuary26.redstoner.block;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import fr.koka99cab.sanctuary26.redstoner.block.entity.TrophyPanelBlockEntity;
|
||||
import fr.koka99cab.sanctuary26.redstoner.registry.RedStonerRegistries;
|
||||
import fr.koka99cab.sanctuary26.sanctuary.api.ranking.RankingUnit;
|
||||
import java.util.Map;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
@@ -45,10 +44,10 @@ public final class TrophyPanelBlock extends BaseEntityBlock {
|
||||
public static final MapCodec<TrophyPanelBlock> CODEC = simpleCodec(TrophyPanelBlock::new);
|
||||
public static final EnumProperty<Direction> FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
private static final Map<Direction, VoxelShape> SHAPES = Map.of(
|
||||
Direction.NORTH, Block.box(0.0D, 0.0D, 13.0D, 16.0D, 16.0D, 16.0D),
|
||||
Direction.SOUTH, Block.box(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 3.0D),
|
||||
Direction.WEST, Block.box(13.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D),
|
||||
Direction.EAST, Block.box(0.0D, 0.0D, 0.0D, 3.0D, 16.0D, 16.0D)
|
||||
Direction.NORTH, Block.box(0.0D, 0.0D, 14.0D, 16.0D, 16.0D, 16.0D),
|
||||
Direction.SOUTH, Block.box(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 2.0D),
|
||||
Direction.WEST, Block.box(14.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D),
|
||||
Direction.EAST, Block.box(0.0D, 0.0D, 0.0D, 2.0D, 16.0D, 16.0D)
|
||||
);
|
||||
|
||||
public TrophyPanelBlock(BlockBehaviour.Properties properties) {
|
||||
@@ -120,18 +119,20 @@ public final class TrophyPanelBlock extends BaseEntityBlock {
|
||||
if (level.isClientSide()) return InteractionResult.SUCCESS;
|
||||
if (!(player instanceof ServerPlayer serverPlayer)
|
||||
|| !(level.getBlockEntity(pos) instanceof TrophyPanelBlockEntity panel)) return InteractionResult.CONSUME;
|
||||
if (player.isSecondaryUseActive()) return cycle(panel, serverPlayer);
|
||||
if (player.isSecondaryUseActive()) return cycle(panel, serverPlayer, true);
|
||||
|
||||
boolean operator = serverPlayer.createCommandSourceStack().permissions()
|
||||
.hasPermission(Permissions.COMMANDS_GAMEMASTER);
|
||||
if (!panel.canConfigure(serverPlayer, operator)) {
|
||||
serverPlayer.sendSystemMessage(Component.translatable("message.redstoner.trophy_panel.not_owner"));
|
||||
return InteractionResult.CONSUME;
|
||||
return cycle(panel, serverPlayer, false);
|
||||
}
|
||||
TrophyPanelBlockEntity.ConfigureResult result = panel.configure(serverPlayer, stack);
|
||||
if (result == TrophyPanelBlockEntity.ConfigureResult.NO_METRIC) {
|
||||
return cycle(panel, serverPlayer, false);
|
||||
}
|
||||
String key = switch (result) {
|
||||
case SUCCESS -> "configured";
|
||||
case NO_METRIC -> "no_metric";
|
||||
case NO_METRIC -> throw new IllegalStateException("Handled above");
|
||||
case NEWER_DATA -> "newer_data";
|
||||
};
|
||||
serverPlayer.sendSystemMessage(Component.translatable("message.redstoner.trophy_panel." + key));
|
||||
@@ -144,9 +145,7 @@ public final class TrophyPanelBlock extends BaseEntityBlock {
|
||||
if (level.isClientSide()) return InteractionResult.SUCCESS;
|
||||
if (!(player instanceof ServerPlayer serverPlayer)
|
||||
|| !(level.getBlockEntity(pos) instanceof TrophyPanelBlockEntity panel)) return InteractionResult.CONSUME;
|
||||
if (player.isSecondaryUseActive()) return cycle(panel, serverPlayer);
|
||||
showDetails(panel, serverPlayer);
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
return cycle(panel, serverPlayer, player.isSecondaryUseActive());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,8 +163,9 @@ public final class TrophyPanelBlock extends BaseEntityBlock {
|
||||
return state.rotate(mirror.getRotation(state.getValue(FACING)));
|
||||
}
|
||||
|
||||
private static InteractionResult cycle(TrophyPanelBlockEntity panel, ServerPlayer player) {
|
||||
if (!panel.cyclePage()) {
|
||||
private static InteractionResult cycle(TrophyPanelBlockEntity panel, ServerPlayer player, boolean backwards) {
|
||||
boolean changed = backwards ? panel.previousPage() : panel.nextPage();
|
||||
if (!changed) {
|
||||
player.sendSystemMessage(Component.translatable("message.redstoner.trophy_panel.newer_data"));
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
@@ -173,25 +173,4 @@ public final class TrophyPanelBlock extends BaseEntityBlock {
|
||||
panel.pageNumber(), panel.pageCount()));
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
}
|
||||
|
||||
private static void showDetails(TrophyPanelBlockEntity panel, ServerPlayer player) {
|
||||
TrophyPanelBlockEntity.ClientSnapshot snapshot = panel.visibleSnapshot();
|
||||
RankingUnit unit = snapshot.unit();
|
||||
ItemStack icon = panel.currentPage().icon();
|
||||
Component metric = icon.isEmpty() ? Component.translatable(snapshot.translationKey())
|
||||
: Component.translatable(snapshot.translationKey(), icon.getHoverName());
|
||||
player.sendSystemMessage(Component.translatable("message.redstoner.trophy_panel.header", metric,
|
||||
panel.pageNumber(), panel.pageCount()));
|
||||
for (TrophyPanelBlockEntity.ClientEntry entry : snapshot.podium()) {
|
||||
player.sendSystemMessage(Component.translatable("message.redstoner.trophy_panel.podium",
|
||||
entry.rank(), entry.name(), unit.format(entry.value())));
|
||||
}
|
||||
if (snapshot.ownerRank() > 0) {
|
||||
player.sendSystemMessage(Component.translatable("message.redstoner.trophy_panel.owner_rank",
|
||||
panel.ownerName(), snapshot.ownerRank(), unit.format(snapshot.ownerValue())));
|
||||
} else {
|
||||
player.sendSystemMessage(Component.translatable("message.redstoner.trophy_panel.owner_unranked",
|
||||
panel.ownerName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-2
@@ -110,9 +110,17 @@ public final class TrophyPanelBlockEntity extends BlockEntity implements ItemOwn
|
||||
return ConfigureResult.SUCCESS;
|
||||
}
|
||||
|
||||
public boolean cyclePage() {
|
||||
public boolean nextPage() {
|
||||
return movePage(1);
|
||||
}
|
||||
|
||||
public boolean previousPage() {
|
||||
return movePage(-1);
|
||||
}
|
||||
|
||||
private boolean movePage(int offset) {
|
||||
if (!writable() || pages.isEmpty()) return false;
|
||||
currentPage = TrophyPanelRules.nextPage(currentPage, pages.size());
|
||||
currentPage = TrophyPanelRules.pageByOffset(currentPage, pages.size(), offset);
|
||||
syncPersistent();
|
||||
if (level instanceof ServerLevel serverLevel) refresh(serverLevel);
|
||||
return true;
|
||||
|
||||
+28
-43
@@ -11,22 +11,21 @@ import net.minecraft.client.renderer.SubmitNodeCollector;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.client.renderer.feature.ModelFeatureRenderer;
|
||||
import net.minecraft.client.renderer.item.ItemModelResolver;
|
||||
import net.minecraft.client.renderer.state.level.CameraRenderState;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public final class TrophyPanelBlockEntityRenderer
|
||||
implements BlockEntityRenderer<TrophyPanelBlockEntity, TrophyPanelRenderState> {
|
||||
private final ItemModelResolver itemModelResolver;
|
||||
private static final int MAX_TEXT_WIDTH = 90;
|
||||
private static final float TEXT_SCALE = 0.010416667F;
|
||||
private static final float[] LINE_HEIGHTS = {0.70F, 0.59F, 0.48F, 0.37F};
|
||||
private static final int TEXT_COLOR = 0xFF3D281A;
|
||||
private final Font font;
|
||||
|
||||
public TrophyPanelBlockEntityRenderer(BlockEntityRendererProvider.Context context) {
|
||||
itemModelResolver = context.itemModelResolver();
|
||||
font = context.font();
|
||||
}
|
||||
|
||||
@@ -40,65 +39,51 @@ public final class TrophyPanelBlockEntityRenderer
|
||||
float tickProgress, Vec3 cameraPos, ModelFeatureRenderer.CrumblingOverlay crumblingOverlay) {
|
||||
BlockEntityRenderer.super.extractRenderState(panel, state, tickProgress, cameraPos, crumblingOverlay);
|
||||
state.facing = panel.getBlockState().getValue(TrophyPanelBlock.FACING);
|
||||
state.icon.clear();
|
||||
ItemStack icon = panel.currentPage().icon();
|
||||
state.hasIcon = !icon.isEmpty();
|
||||
if (state.hasIcon) {
|
||||
itemModelResolver.updateForTopItem(state.icon, icon, ItemDisplayContext.FIXED,
|
||||
panel.level(), panel, (int) panel.getBlockPos().asLong());
|
||||
}
|
||||
|
||||
TrophyPanelBlockEntity.ClientSnapshot snapshot = panel.visibleSnapshot();
|
||||
RankingUnit unit = snapshot.unit();
|
||||
state.metric = state.hasIcon ? Component.translatable(snapshot.translationKey(), icon.getHoverName())
|
||||
Component metric = !icon.isEmpty() ? Component.translatable(snapshot.translationKey(), icon.getHoverName())
|
||||
: Component.translatable(snapshot.translationKey());
|
||||
state.lines[0] = Component.translatable("block.redstoner.trophy_panel.page_title",
|
||||
panel.pageNumber(), panel.pageCount(), metric);
|
||||
if (snapshot.podium().isEmpty()) {
|
||||
state.champion = Component.translatable("block.redstoner.trophy_panel.no_score");
|
||||
state.lines[1] = Component.translatable("block.redstoner.trophy_panel.no_score");
|
||||
state.lines[2] = Component.empty();
|
||||
state.lines[3] = Component.empty();
|
||||
} else {
|
||||
TrophyPanelBlockEntity.ClientEntry champion = snapshot.podium().getFirst();
|
||||
state.champion = Component.translatable("block.redstoner.trophy_panel.champion",
|
||||
champion.name(), unit.format(champion.value()));
|
||||
for (int index = 0; index < 3; index++) {
|
||||
if (index >= snapshot.podium().size()) {
|
||||
state.lines[index + 1] = Component.empty();
|
||||
continue;
|
||||
}
|
||||
TrophyPanelBlockEntity.ClientEntry entry = snapshot.podium().get(index);
|
||||
state.lines[index + 1] = Component.translatable("block.redstoner.trophy_panel.podium",
|
||||
entry.rank(), entry.name(), unit.format(entry.value()));
|
||||
}
|
||||
}
|
||||
state.owner = snapshot.ownerRank() > 0
|
||||
? Component.translatable("block.redstoner.trophy_panel.owner_rank", panel.ownerName(),
|
||||
snapshot.ownerRank(), unit.format(snapshot.ownerValue()))
|
||||
: Component.translatable("block.redstoner.trophy_panel.owner_unranked", panel.ownerName());
|
||||
state.page = Component.literal(panel.pageNumber() + "/" + panel.pageCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submit(TrophyPanelRenderState state, PoseStack poseStack,
|
||||
SubmitNodeCollector submitNodeCollector, CameraRenderState cameraRenderState) {
|
||||
float yRotation = -state.facing.toYRot();
|
||||
if (state.hasIcon) submitIcon(state, poseStack, submitNodeCollector, yRotation);
|
||||
submitText(state.metric, 0.72F, 0.0065F, state, poseStack, submitNodeCollector, yRotation, 0xFFE8B4);
|
||||
submitText(state.champion, 0.52F, 0.0060F, state, poseStack, submitNodeCollector, yRotation, 0xFFFFFF);
|
||||
submitText(state.owner, 0.36F, 0.0055F, state, poseStack, submitNodeCollector, yRotation, 0xB8D9FF);
|
||||
submitText(state.page, 0.20F, 0.0050F, state, poseStack, submitNodeCollector, yRotation, 0xA0A0A0);
|
||||
for (int index = 0; index < TrophyPanelRenderState.LINE_COUNT; index++) {
|
||||
submitText(state.lines[index], LINE_HEIGHTS[index], state, poseStack, submitNodeCollector, yRotation);
|
||||
}
|
||||
}
|
||||
|
||||
private void submitIcon(TrophyPanelRenderState state, PoseStack poseStack,
|
||||
SubmitNodeCollector submitNodeCollector, float yRotation) {
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(0.5F, 0.89F, 0.5F);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(yRotation));
|
||||
poseStack.translate(0.0F, 0.0F, -0.33F);
|
||||
poseStack.scale(0.18F, 0.18F, 0.18F);
|
||||
state.icon.submit(poseStack, submitNodeCollector, state.lightCoords, OverlayTexture.NO_OVERLAY, 0);
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
private void submitText(Component component, float y, float scale, TrophyPanelRenderState state,
|
||||
PoseStack poseStack, SubmitNodeCollector submitNodeCollector, float yRotation, int color) {
|
||||
FormattedCharSequence text = component.getVisualOrderText();
|
||||
private void submitText(Component component, float y, TrophyPanelRenderState state,
|
||||
PoseStack poseStack, SubmitNodeCollector submitNodeCollector, float yRotation) {
|
||||
FormattedCharSequence text = font.split(component, MAX_TEXT_WIDTH).stream().findFirst()
|
||||
.orElse(FormattedCharSequence.EMPTY);
|
||||
float x = -font.width(text) / 2.0F;
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(0.5F, y, 0.5F);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(yRotation));
|
||||
poseStack.translate(0.0F, 0.0F, -0.331F);
|
||||
poseStack.scale(scale, -scale, scale);
|
||||
poseStack.scale(TEXT_SCALE, -TEXT_SCALE, TEXT_SCALE);
|
||||
submitNodeCollector.submitText(poseStack, x, 0.0F, text, false, Font.DisplayMode.POLYGON_OFFSET,
|
||||
color, state.lightCoords, 0, 0x30181818);
|
||||
state.lightCoords, TEXT_COLOR, 0, 0);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
+4
-7
@@ -1,16 +1,13 @@
|
||||
package fr.koka99cab.sanctuary26.redstoner.client.renderer.state;
|
||||
|
||||
import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
|
||||
import net.minecraft.client.renderer.item.ItemStackRenderState;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public final class TrophyPanelRenderState extends BlockEntityRenderState {
|
||||
public final ItemStackRenderState icon = new ItemStackRenderState();
|
||||
public static final int LINE_COUNT = 4;
|
||||
public final Component[] lines = {
|
||||
Component.empty(), Component.empty(), Component.empty(), Component.empty()
|
||||
};
|
||||
public Direction facing = Direction.NORTH;
|
||||
public boolean hasIcon;
|
||||
public Component metric = Component.empty();
|
||||
public Component champion = Component.empty();
|
||||
public Component owner = Component.empty();
|
||||
public Component page = Component.empty();
|
||||
}
|
||||
|
||||
+9
-1
@@ -17,7 +17,15 @@ public final class TrophyPanelRules {
|
||||
}
|
||||
|
||||
public static int nextPage(int currentPage, int pageCount) {
|
||||
return pageCount <= 0 ? 0 : Math.floorMod(currentPage + 1, pageCount);
|
||||
return pageByOffset(currentPage, pageCount, 1);
|
||||
}
|
||||
|
||||
public static int previousPage(int currentPage, int pageCount) {
|
||||
return pageByOffset(currentPage, pageCount, -1);
|
||||
}
|
||||
|
||||
public static int pageByOffset(int currentPage, int pageCount, int offset) {
|
||||
return pageCount <= 0 ? 0 : Math.floorMod(currentPage + offset, pageCount);
|
||||
}
|
||||
|
||||
public static List<Identifier> mergeMetricIds(List<Identifier> current, List<Identifier> offered) {
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
"screen.redstoner.storage_terminal.error.too_large": "Network too large (maximum 128 storage blocks).",
|
||||
"screen.redstoner.storage_terminal.error.locked": "The network contains a locked storage block.",
|
||||
"block.redstoner.trophy_panel": "Trophy Panel",
|
||||
"block.redstoner.trophy_panel.page_title": "[%s/%s] %s",
|
||||
"block.redstoner.trophy_panel.podium": "#%s %s · %s",
|
||||
"block.redstoner.trophy_panel.no_score": "No score yet",
|
||||
"block.redstoner.trophy_panel.champion": "#1 %s · %s",
|
||||
"block.redstoner.trophy_panel.owner_rank": "%s · #%s · %s",
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
"screen.redstoner.storage_terminal.error.too_large": "Réseau trop grand (128 stockages maximum).",
|
||||
"screen.redstoner.storage_terminal.error.locked": "Le réseau contient un stockage verrouillé.",
|
||||
"block.redstoner.trophy_panel": "Panneau de trophées",
|
||||
"block.redstoner.trophy_panel.page_title": "[%s/%s] %s",
|
||||
"block.redstoner.trophy_panel.podium": "#%s %s · %s",
|
||||
"block.redstoner.trophy_panel.no_score": "Aucun score",
|
||||
"block.redstoner.trophy_panel.champion": "#1 %s · %s",
|
||||
"block.redstoner.trophy_panel.owner_rank": "%s · #%s · %s",
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
"screen.redstoner.storage_terminal.error.too_large": "Сеть слишком велика (не более 128 хранилищ).",
|
||||
"screen.redstoner.storage_terminal.error.locked": "В сети есть запертое хранилище.",
|
||||
"block.redstoner.trophy_panel": "Панель трофеев",
|
||||
"block.redstoner.trophy_panel.page_title": "[%s/%s] %s",
|
||||
"block.redstoner.trophy_panel.podium": "#%s %s · %s",
|
||||
"block.redstoner.trophy_panel.no_score": "Результатов пока нет",
|
||||
"block.redstoner.trophy_panel.champion": "#1 %s · %s",
|
||||
"block.redstoner.trophy_panel.owner_rank": "%s · #%s · %s",
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
{
|
||||
"parent": "minecraft:block/block",
|
||||
"textures": {
|
||||
"particle": "minecraft:block/dark_oak_planks",
|
||||
"wood": "minecraft:block/dark_oak_planks",
|
||||
"frame": "minecraft:block/gold_block",
|
||||
"screen": "minecraft:block/black_concrete"
|
||||
"particle": "minecraft:block/oak_planks",
|
||||
"wood": "minecraft:block/oak_planks"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [0, 0, 13],
|
||||
"from": [0, 0, 14],
|
||||
"to": [16, 16, 16],
|
||||
"faces": {
|
||||
"north": { "texture": "#wood" },
|
||||
@@ -18,31 +16,6 @@
|
||||
"up": { "texture": "#wood" },
|
||||
"down": { "texture": "#wood" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1.5, 1.5, 12.5],
|
||||
"to": [14.5, 14.5, 13],
|
||||
"faces": { "north": { "texture": "#screen" } }
|
||||
},
|
||||
{
|
||||
"from": [0.5, 0.5, 12.25],
|
||||
"to": [15.5, 1.5, 13],
|
||||
"faces": { "north": { "texture": "#frame" } }
|
||||
},
|
||||
{
|
||||
"from": [0.5, 14.5, 12.25],
|
||||
"to": [15.5, 15.5, 13],
|
||||
"faces": { "north": { "texture": "#frame" } }
|
||||
},
|
||||
{
|
||||
"from": [0.5, 1.5, 12.25],
|
||||
"to": [1.5, 14.5, 13],
|
||||
"faces": { "north": { "texture": "#frame" } }
|
||||
},
|
||||
{
|
||||
"from": [14.5, 1.5, 12.25],
|
||||
"to": [15.5, 14.5, 13],
|
||||
"faces": { "north": { "texture": "#frame" } }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+4
@@ -15,6 +15,10 @@ public final class TrophyPanelRulesSmoke {
|
||||
require(TrophyPanelRules.canConfigure(owner, visitor, true), "An operator cannot repair a panel");
|
||||
require(TrophyPanelRules.nextPage(0, 3) == 1 && TrophyPanelRules.nextPage(2, 3) == 0,
|
||||
"Public page cycling does not wrap");
|
||||
require(TrophyPanelRules.previousPage(0, 3) == 2 && TrophyPanelRules.previousPage(2, 3) == 1,
|
||||
"Reverse public page cycling does not wrap");
|
||||
require(TrophyPanelRules.pageByOffset(4, 0, 1) == 0,
|
||||
"An empty panel produced an invalid page index");
|
||||
|
||||
Identifier first = Identifier.parse("sanctuary:first");
|
||||
Identifier second = Identifier.parse("sanctuary:second");
|
||||
|
||||
Reference in New Issue
Block a user