Merge branch '20kdc-xray' into feature/master

This commit is contained in:
S-B99 2020-02-17 10:49:22 -05:00
commit fd2d4232de
7 changed files with 289 additions and 0 deletions

View File

@ -0,0 +1,65 @@
package me.zeroeightsix.kami.command.commands;
import me.zeroeightsix.kami.command.Command;
import me.zeroeightsix.kami.command.syntax.ChunkBuilder;
import me.zeroeightsix.kami.module.ModuleManager;
import me.zeroeightsix.kami.module.modules.render.XRay;
import net.minecraft.block.Block;
/**
* Created by 20kdc on 17/02/2020.
*/
public class XRayCommand extends Command {
public XRayCommand() {
super("xray", new ChunkBuilder().append("subcommand").build());
setDescription("Has a set of sub-commands to control the XRay module.");
}
@Override
public void call(String[] args) {
XRay xr = (XRay) ModuleManager.getModuleByName("XRay");
if (xr == null) {
Command.sendChatMessage("&cThe XRay module is not available for some reason.");
return;
}
if (!xr.isEnabled()) {
Command.sendChatMessage("&cWarning: The XRay module is not enabled.");
Command.sendChatMessage("&cThese commands will still have effects, but will not visibly do anything.");
}
for (String s : args) {
if (s == null)
continue;
if (s.equalsIgnoreCase("help")) {
Command.sendChatMessage("The XRay module has a list of blocks.");
Command.sendChatMessage("Normally, the XRay module hides these blocks.");
Command.sendChatMessage("When the Invert setting is on, the XRay only shows these blocks.");
Command.sendChatMessage("This command is a convenient way to quickly edit the list.");
Command.sendChatMessage("XRay Subcommands:");
Command.sendChatMessage(".xray help : Shows this text.");
Command.sendChatMessage(".xray clear : Removes all blocks from the XRay block list.");
Command.sendChatMessage(".xray show : Shows the list.");
Command.sendChatMessage(".xray +<block> : Adds a block to the list.");
Command.sendChatMessage(".xray -<block> : Removes a block from the list.");
} else if (s.equalsIgnoreCase("clear")) {
xr.extClear();
Command.sendChatMessage("Cleared the XRay block list.");
} else if (s.equalsIgnoreCase("show")) {
Command.sendChatMessage(xr.extGet());
} else if (s.startsWith("+") || s.startsWith("-")) {
String name = s.substring(1);
Block b = Block.getBlockFromName(name);
if (b == null) {
Command.sendChatMessage("&cInvalid block name " + name + ".");
} else {
if (s.startsWith("+")) {
xr.extAdd(name);
} else {
xr.extRemove(name);
}
}
} else {
Command.sendChatMessage("&cInvalid subcommand " + s + ".");
}
}
}
}

View File

@ -0,0 +1,29 @@
package me.zeroeightsix.kami.mixin.client;
import me.zeroeightsix.kami.module.ModuleManager;
import me.zeroeightsix.kami.module.modules.render.XRay;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.ChunkCache;
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.CallbackInfoReturnable;
/**
* Created by 20kdc on 15/02/2020.
*/
@Mixin(ChunkCache.class)
public class MixinChunkCache {
@Inject(method = "getBlockState", at = @At("RETURN"), cancellable = true)
public void getState(BlockPos pos, CallbackInfoReturnable<IBlockState> info) {
if (ModuleManager.isModuleEnabled("XRay"))
info.setReturnValue(XRay.transform(info.getReturnValue()));
}
}

View File

@ -0,0 +1,177 @@
package me.zeroeightsix.kami.module.modules.render;
import java.util.Set;
import java.util.Collections;
import java.util.HashSet;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.util.EnumFacing;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.state.BlockStateBase;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockRenderLayer;
import me.zeroeightsix.kami.event.events.PacketEvent;
import me.zeroeightsix.kami.event.events.PlayerMoveEvent;
import me.zeroeightsix.kami.module.Module;
import me.zeroeightsix.kami.setting.Setting;
import me.zeroeightsix.kami.setting.Settings;
import me.zeroeightsix.kami.KamiMod;
/**
* Created by 20kdc on 15/02/2020.
*/
@Module.Info(name = "XRay", category = Module.Category.RENDER, description = "Filters away common blocks.")
@EventBusSubscriber(modid = KamiMod.MODID)
public class XRay extends Module {
// A default reasonable configuration for the XRay. Most people will want to use it like this.
private static final String DEFAULT_XRAY_CONFIG = "minecraft:grass,minecraft:dirt,minecraft:netherrack,minecraft:gravel,minecraft:sand,minecraft:stone";
// Split by ',' & each element trimmed (this is a bit weird but it works for now?)
private Setting<String> hiddenBlockNames = register(Settings.stringBuilder("HiddenBlocks").withValue(DEFAULT_XRAY_CONFIG).withConsumer((old, value) -> {
refreshHiddenBlocksSet(value);
if (isEnabled())
mc.renderGlobal.loadRenderers();
}));
private Setting<Boolean> invert = register(Settings.booleanBuilder("Invert").withValue(false).withConsumer((old, value) -> {
invertStatic = value;
if (isEnabled())
mc.renderGlobal.loadRenderers();
}));
private Setting<Boolean> outlines = register(Settings.booleanBuilder("Outlines").withValue(true).withConsumer((old, value) -> {
outlinesStatic = value;
if (isEnabled())
mc.renderGlobal.loadRenderers();
}));
// A static mirror of the state.
private static Set<Block> hiddenBlocks = Collections.synchronizedSet(new HashSet<>());
private static boolean invertStatic, outlinesStatic = true;
// This is the state used for hidden blocks.
private static IBlockState transparentState;
// This is used as part of a mechanism to make the Minecraft renderer play along with the XRay.
// Essentially, the XRay primitive is just a block state transformer.
// Then this implements a custom block that the block state transformer can use for hidden blocks.
public static Block transparentBlock;
public XRay() {
invertStatic = invert.getValue();
outlinesStatic = outlines.getValue();
refreshHiddenBlocksSet(hiddenBlockNames.getValue());
}
// Get hidden block list for command display
public String extGet() {
return extGetInternal(null);
}
// Add entry by arbitrary user-provided string
public void extAdd(String s) {
hiddenBlockNames.setValue(extGetInternal(null) + ", " + s);
}
// Remove entry by arbitrary user-provided string
public void extRemove(String s) {
hiddenBlockNames.setValue(extGetInternal(Block.getBlockFromName(s)));
}
// Clears the list.
public void extClear() {
hiddenBlockNames.setValue("");
}
private String extGetInternal(Block filter) {
StringBuilder sb = new StringBuilder();
boolean notFirst = false;
for (Block b : hiddenBlocks) {
if (b == filter)
continue;
if (notFirst)
sb.append(", ");
notFirst = true;
sb.append(Block.REGISTRY.getNameForObject(b));
}
return sb.toString();
}
private void refreshHiddenBlocksSet(String v) {
hiddenBlocks.clear();
for (String s : v.split(",")) {
String s2 = s.trim();
Block block = Block.getBlockFromName(s2);
if (block != null)
hiddenBlocks.add(block);
}
}
@SubscribeEvent
public static void registerBlocks(RegistryEvent.Register<Block> event) {
transparentBlock = new Block(Material.GLASS) {
// did you know this name's new
@Override
public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT;
}
// Not opaque so other materials (such as, of course, ores) will render
@Override
public boolean isOpaqueCube(IBlockState blah) {
return false;
}
// Essentially, the hidden-block world should be a projected grid-like thing...?
@Override
public boolean shouldSideBeRendered(IBlockState blah, IBlockAccess w, BlockPos pos, EnumFacing side) {
BlockPos adj = pos.offset(side);
IBlockState other = w.getBlockState(adj);
// this directly adj. to this must never be rendered
if (other.getBlock() == this)
return false;
// if it contacts something opaque, don't render as we'll probably accidentally make it harder to see
return !other.isOpaqueCube();
}
};
transparentBlock.setRegistryName("kami_xray_transparent");
transparentState = transparentBlock.getDefaultState();
event.getRegistry().registerAll(transparentBlock);
}
@SubscribeEvent
public static void registerItems(RegistryEvent.Register<Item> event) {
// this runs after transparentBlock is set, right?
event.getRegistry().registerAll(new ItemBlock(transparentBlock).setRegistryName(transparentBlock.getRegistryName()));
}
public static IBlockState transform(IBlockState input) {
Block b = input.getBlock();
boolean hide = hiddenBlocks.contains(b);
if (invertStatic)
hide = !hide;
if (hide) {
IBlockState target = Blocks.AIR.getDefaultState();
if (outlinesStatic && (transparentState != null))
target = transparentState;
return target;
}
return input;
}
@Override
protected void onEnable() {
// This is important because otherwise the changes in ChunkCache behavior won't propagate.
// Also needs to be done if shouldHide effects change.
mc.renderGlobal.loadRenderers();
}
@Override
protected void onDisable() {
// This is important because otherwise the changes in ChunkCache behavior won't propagate.
// Also needs to be done if shouldHide effects change.
mc.renderGlobal.loadRenderers();
}
}

View File

@ -0,0 +1,10 @@
{
"variants": {
"normal": [
{
"model": "kami:kami_xray_transparent"
}
]
}
}

View File

@ -0,0 +1,7 @@
{
"parent": "block/cube_all",
"textures": {
"all": "kami:blocks/kami_xray_transparent"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -27,5 +27,6 @@
"MixinGuiNewChat",
"MixinLayerArmorBase",
"MixinNettyCompressionDecoder"
"MixinChunkCache"
]
}