Added Tooltips that tell players what type of ground they can place vegetation on.

This commit is contained in:
Frank 2022-03-18 19:18:09 +01:00
parent a9c9a7359b
commit 5a30e60d31
7 changed files with 158 additions and 3 deletions

View file

@ -0,0 +1,27 @@
package ru.bclib.interfaces;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import java.util.List;
import java.util.stream.Collectors;
public interface SurvivesOnBlocks extends SurvivesOnSpecialGround{
List<Block> getSurvivableBlocks();
@Override
default String getSurvivableBlocksString(){
return getSurvivableBlocks()
.stream()
.filter(block -> block!= Blocks.AIR)
.map(block ->new ItemStack(block).getHoverName().getString())
.collect(Collectors.joining(", "));
}
@Override
default boolean isSurvivable(BlockState state){
return getSurvivableBlocks().contains(state.getBlock());
}
}

View file

@ -0,0 +1,65 @@
package ru.bclib.interfaces;
import com.google.common.collect.Lists;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.state.BlockState;
import java.util.List;
public interface SurvivesOnSpecialGround {
String getSurvivableBlocksString();
@Environment(EnvType.CLIENT)
static List<String> splitLines(String input){
final int MAX_LEN = 30;
final int MAX_LEN_SECOND = 40;
List<String> lines = Lists.newArrayList();
int maxLen = MAX_LEN;
while (input.length()>maxLen){
int idx = input.lastIndexOf(",", maxLen);
if (idx>=0) {
lines.add( input.substring(0, idx+1).trim());
input = input.substring(idx+1, input.length()).trim();
} else {
break;
}
maxLen = MAX_LEN_SECOND;
}
lines.add(input.trim());
return lines;
}
@Environment(EnvType.CLIENT)
static void appendHoverText(List<Component> list, String description) {
final int MAX_LINES = 5;
List<String> lines = splitLines(description);
if (lines.size()>0) {
list.add(new TranslatableComponent("tooltip.bclib.place_on", lines.get(0)).withStyle(ChatFormatting.GREEN));
}
for (int i=1; i<Math.min(lines.size(),MAX_LINES); i++){
String line = lines.get(i);
if (i==MAX_LINES-1 && i<lines.size()-1) line +=" ...";
list.add(new TextComponent(" " + line).withStyle(ChatFormatting.GREEN));
}
}
boolean isSurvivable(BlockState state);
default boolean canSurviveOnTop(BlockState state, LevelReader world, BlockPos pos) {
return isSurvivable(world.getBlockState(pos.below()));
}
default boolean canSurviveOnBottom(BlockState state, LevelReader world, BlockPos pos) {
return isSurvivable(world.getBlockState(pos.above()));
}
}

View file

@ -0,0 +1,33 @@
package ru.bclib.interfaces;
import net.minecraft.core.Registry;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import java.util.List;
import java.util.stream.Collectors;
public interface SurvivesOnTags extends SurvivesOnSpecialGround{
List<TagKey<Block>> getSurvivableTags();
@Override
default String getSurvivableBlocksString(){
return getSurvivableTags()
.stream()
.map(tag -> Registry.BLOCK.getTag(tag))
.filter(named->named.isPresent())
.map(named->named.get())
.flatMap(named->named.stream())
.filter(block -> block != Blocks.AIR && block != null)
.map(block ->new ItemStack(block.value()).getHoverName().getString())
.collect(Collectors.joining(", "));
}
@Override
default boolean isSurvivable(BlockState state){
return getSurvivableTags().stream().anyMatch(tag->state.is(tag));
}
}

View file

@ -0,0 +1,25 @@
package ru.bclib.mixin.client;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import ru.bclib.interfaces.SurvivesOnSpecialGround;
import java.util.List;
@Mixin(Block.class)
public class BlockMixin {
@Inject(method="appendHoverText", at=@At("HEAD"))
void bclib_appendSurvivalBlock(ItemStack itemStack, @Nullable BlockGetter blockGetter, List<Component> list, TooltipFlag tooltipFlag, CallbackInfo ci){
if (this instanceof SurvivesOnSpecialGround surv){
SurvivesOnSpecialGround.appendHoverText(list, surv.getSurvivableBlocksString());
}
}
}

View file

@ -52,5 +52,7 @@
"title.bclib.datafixer.error": "Fehler beim Reparieren der Welt",
"message.bclib.datafixer.error": "Es gab Fehler beim Reparieren der Welt. Das bedeutet, dass dieser Level wahrscheinlich in einem inkonsistenten Zustand ist und Sie ihn nicht spielen sollten. Bitte stellen Sie Ihr Backup wieder her und beheben Sie die unten aufgeführten Fehler, bevor Sie es erneut versuchen.",
"title.bclib.datafixer.error.continue": "Continue and Mark as Fixed",
"title.config.bclib.main.ui.suppressExperimentalDialogOnLoad": "Disable Experimental Warning Screen on Load"
"title.config.bclib.main.ui.suppressExperimentalDialogOnLoad": "Disable Experimental Warning Screen on Load",
"tooltip.bclib.place_on": "Lebt auf: %s"
}

View file

@ -54,5 +54,7 @@
"title.bclib.datafixer.error.continue": "Proceed and mark as fixed",
"title.config.bclib.client.rendering.customFogRendering": "Custom Fog Rendering",
"title.config.bclib.client.rendering.netherThickFog": "Nether Thick Fog"
"title.config.bclib.client.rendering.netherThickFog": "Nether Thick Fog",
"tooltip.bclib.place_on": "Survives on: %s"
}

View file

@ -13,7 +13,8 @@
"ModelBakeryMixin",
"WorldPresetMixin",
"MinecraftMixin",
"GameMixin"
"GameMixin",
"BlockMixin"
],
"injectors": {
"defaultRequire": 1