Proper Directions

- Added layer of abstraction for Directional Blocks
- Added Cocoa Logs
- Added improved item tooltip framework
This commit is contained in:
simibubi 2019-08-18 17:02:29 +02:00
parent 4cfd7a1bb9
commit ce7356798c
26 changed files with 508 additions and 127 deletions

View file

@ -21,6 +21,7 @@ import com.simibubi.create.modules.contraptions.relays.CogWheelBlock;
import com.simibubi.create.modules.contraptions.relays.EncasedBeltBlock; import com.simibubi.create.modules.contraptions.relays.EncasedBeltBlock;
import com.simibubi.create.modules.contraptions.relays.GearboxBlock; import com.simibubi.create.modules.contraptions.relays.GearboxBlock;
import com.simibubi.create.modules.contraptions.relays.GearshifterBlock; import com.simibubi.create.modules.contraptions.relays.GearshifterBlock;
import com.simibubi.create.modules.gardens.CocoaLogBlock;
import com.simibubi.create.modules.schematics.block.CreativeCrateBlock; import com.simibubi.create.modules.schematics.block.CreativeCrateBlock;
import com.simibubi.create.modules.schematics.block.SchematicTableBlock; import com.simibubi.create.modules.schematics.block.SchematicTableBlock;
import com.simibubi.create.modules.schematics.block.SchematicannonBlock; import com.simibubi.create.modules.schematics.block.SchematicannonBlock;
@ -81,6 +82,9 @@ public enum AllBlocks {
SYMMETRY_CROSSPLANE(new CrossPlaneSymmetryBlock()), SYMMETRY_CROSSPLANE(new CrossPlaneSymmetryBlock()),
SYMMETRY_TRIPLEPLANE(new TriplePlaneSymmetryBlock()), SYMMETRY_TRIPLEPLANE(new TriplePlaneSymmetryBlock()),
// Gardens
COCOA_LOG(new CocoaLogBlock()),
// Palettes // Palettes
ANDESITE_BRICKS(new Block(Properties.from(Blocks.ANDESITE))), ANDESITE_BRICKS(new Block(Properties.from(Blocks.ANDESITE))),
DIORITE_BRICKS(new Block(Properties.from(Blocks.DIORITE))), DIORITE_BRICKS(new Block(Properties.from(Blocks.DIORITE))),

View file

@ -1,10 +1,10 @@
package com.simibubi.create; package com.simibubi.create;
import com.simibubi.create.modules.contraptions.relays.BeltItem; import com.simibubi.create.modules.contraptions.relays.BeltItem;
import com.simibubi.create.modules.curiosities.item.TreeFertilizerItem;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItem; import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItem;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItemRenderer; import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItemRenderer;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunModel; import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunModel;
import com.simibubi.create.modules.gardens.TreeFertilizerItem;
import com.simibubi.create.modules.schematics.item.BlueprintAndQuillItem; import com.simibubi.create.modules.schematics.item.BlueprintAndQuillItem;
import com.simibubi.create.modules.schematics.item.BlueprintItem; import com.simibubi.create.modules.schematics.item.BlueprintItem;
import com.simibubi.create.modules.symmetry.SymmetryWandItem; import com.simibubi.create.modules.symmetry.SymmetryWandItem;

View file

@ -0,0 +1,38 @@
package com.simibubi.create.foundation.block;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
public class ProperDirectionalBlock extends DirectionalBlock {
protected ProperDirectionalBlock(Properties p_i48415_1_) {
super(p_i48415_1_);
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(FACING);
super.fillStateContainer(builder);
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
return getDefaultState().with(FACING, context.getNearestLookingDirection());
}
@Override
public BlockState rotate(BlockState state, Rotation rot) {
return state.with(FACING, rot.rotate(state.get(FACING)));
}
@Override
public BlockState mirror(BlockState state, Mirror mirrorIn) {
return state.rotate(mirrorIn.toRotation(state.get(FACING)));
}
}

View file

@ -0,0 +1,39 @@
package com.simibubi.create.foundation.item;
import java.util.List;
import com.simibubi.create.foundation.utility.ItemDescription;
import com.simibubi.create.foundation.utility.ItemDescription.Palette;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public abstract class ItemWithToolTip extends Item {
protected TooltipCache tooltip;
public ItemWithToolTip(Properties properties) {
super(properties);
tooltip = new TooltipCache();
}
@Override
@OnlyIn(value = Dist.CLIENT)
public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
ItemDescription itemDescription = this.tooltip.getOrCreate(this::getDescription);
itemDescription.addInformation(tooltip);
super.addInformation(stack, worldIn, tooltip, flagIn);
}
protected abstract ItemDescription getDescription();
protected String h(String s, Palette palette) {
return ItemDescription.hightlight(s, palette);
}
}

View file

@ -0,0 +1,17 @@
package com.simibubi.create.foundation.item;
import java.util.function.Supplier;
import com.simibubi.create.foundation.utility.ItemDescription;
public class TooltipCache {
private ItemDescription toolTip;
public ItemDescription getOrCreate(Supplier<ItemDescription> factory) {
if (toolTip == null)
toolTip = factory.get();
return toolTip;
}
}

View file

@ -0,0 +1,190 @@
package com.simibubi.create.foundation.utility;
import static net.minecraft.util.text.TextFormatting.AQUA;
import static net.minecraft.util.text.TextFormatting.BLUE;
import static net.minecraft.util.text.TextFormatting.DARK_GRAY;
import static net.minecraft.util.text.TextFormatting.DARK_GREEN;
import static net.minecraft.util.text.TextFormatting.DARK_PURPLE;
import static net.minecraft.util.text.TextFormatting.DARK_RED;
import static net.minecraft.util.text.TextFormatting.GOLD;
import static net.minecraft.util.text.TextFormatting.GRAY;
import static net.minecraft.util.text.TextFormatting.GREEN;
import static net.minecraft.util.text.TextFormatting.LIGHT_PURPLE;
import static net.minecraft.util.text.TextFormatting.RED;
import static net.minecraft.util.text.TextFormatting.STRIKETHROUGH;
import static net.minecraft.util.text.TextFormatting.WHITE;
import static net.minecraft.util.text.TextFormatting.YELLOW;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
public class ItemDescription {
public static final int maxCharsPerLine = 35;
public static ITextComponent trim = new StringTextComponent(
WHITE + "" + STRIKETHROUGH + " ");
public enum Palette {
Blue(BLUE, AQUA), Green(DARK_GREEN, GREEN), Yellow(GOLD, YELLOW), Red(DARK_RED, RED),
Purple(DARK_PURPLE, LIGHT_PURPLE),
;
private Palette(TextFormatting primary, TextFormatting highlight) {
color = primary;
hColor = highlight;
}
public TextFormatting color;
public TextFormatting hColor;
}
private List<ITextComponent> lines;
private List<ITextComponent> linesOnShift;
private List<ITextComponent> linesOnCtrl;
private Palette palette;
public ItemDescription(Palette palette) {
this.palette = palette;
lines = new ArrayList<>();
linesOnShift = new ArrayList<>();
linesOnCtrl = new ArrayList<>();
trim = new StringTextComponent(WHITE + "" + STRIKETHROUGH + " ");
}
public ItemDescription withSummary(String summary) {
add(linesOnShift, cutString(summary, palette.color));
linesOnShift.add(trim);
return this;
}
public ItemDescription withBehaviour(String condition, String behaviour) {
add(linesOnShift, GRAY + condition);
add(linesOnShift, cutString(behaviour, palette.hColor, 1));
return this;
}
public ItemDescription withControl(String condition, String action) {
add(linesOnCtrl, GRAY + condition);
add(linesOnCtrl, cutString(action, palette.color, 1));
return this;
}
public ItemDescription createTabs() {
boolean hasDescription = !linesOnShift.isEmpty();
boolean hasControls = !linesOnCtrl.isEmpty();
if (hasDescription || hasControls) {
for (List<ITextComponent> list : Arrays.asList(lines, linesOnShift, linesOnCtrl)) {
boolean shift = list == linesOnShift;
boolean ctrl = list == linesOnCtrl;
String tabs = DARK_GRAY + "Hold ";
if (hasDescription)
tabs += "<" + (shift ? palette.hColor : palette.color) + "Shift" + DARK_GRAY + ">";
if (hasDescription && hasControls)
tabs += " or ";
if (hasControls)
tabs += "<" + (ctrl ? palette.hColor : palette.color) + "Control" + DARK_GRAY + ">";
list.add(0, new StringTextComponent(tabs));
if (shift || ctrl)
list.add(1, trim);
}
}
if (!hasDescription)
linesOnShift = lines;
if (!hasControls)
linesOnCtrl = lines;
return this;
}
public static String hightlight(String s, Palette palette) {
return palette.hColor + s + palette.color;
}
public List<String> cutString(String s, TextFormatting defaultColor) {
return cutString(s, defaultColor, 0);
}
public List<String> cutString(String s, TextFormatting defaultColor, int indent) {
String lineStart = defaultColor.toString();
for (int i = 0; i < indent; i++)
lineStart += " ";
String[] words = s.split(" ");
List<String> lines = new ArrayList<>();
StringBuilder currentLine = new StringBuilder(lineStart);
boolean firstWord = true;
for (int i = 0; i < words.length; i++) {
String word = words[i];
boolean lastWord = i == words.length - 1;
if (!lastWord && !firstWord && currentLine.length() + word.length() > maxCharsPerLine) {
lines.add(currentLine.toString());
currentLine = new StringBuilder(lineStart);
firstWord = true;
}
currentLine.append((firstWord ? "" : " ") + word);
firstWord = false;
}
if (!firstWord) {
lines.add(currentLine.toString());
}
return lines;
}
public static void add(List<ITextComponent> infoList, List<String> textLines) {
textLines.forEach(s -> add(infoList, s));
}
public static void add(List<ITextComponent> infoList, String line) {
infoList.add(new StringTextComponent(line));
}
public Palette getPalette() {
return palette;
}
public List<ITextComponent> addInformation(List<ITextComponent> tooltip) {
if (Screen.hasShiftDown()) {
tooltip.addAll(linesOnShift);
return tooltip;
}
if (Screen.hasControlDown()) {
tooltip.addAll(linesOnCtrl);
return tooltip;
}
tooltip.addAll(lines);
return tooltip;
}
public List<ITextComponent> getLines() {
return lines;
}
public List<ITextComponent> getLinesOnCtrl() {
return linesOnCtrl;
}
public List<ITextComponent> getLinesOnShift() {
return linesOnShift;
}
}

View file

@ -1,23 +1,14 @@
package com.simibubi.create.modules.contraptions.base; package com.simibubi.create.modules.contraptions.base;
import com.simibubi.create.foundation.block.IRenderUtilityBlock; import com.simibubi.create.foundation.block.IRenderUtilityBlock;
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.state.StateContainer.Builder;
public class HalfAxisBlock extends DirectionalBlock implements IRenderUtilityBlock { public class HalfAxisBlock extends ProperDirectionalBlock implements IRenderUtilityBlock {
public HalfAxisBlock() { public HalfAxisBlock() {
super(Properties.create(Material.ROCK)); super(Properties.create(Material.ROCK));
} }
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(FACING);
super.fillStateContainer(builder);
}
} }

View file

@ -2,12 +2,12 @@ package com.simibubi.create.modules.contraptions.receivers.constructs;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IWithoutBlockItem; import com.simibubi.create.foundation.block.IWithoutBlockItem;
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState; import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.state.EnumProperty; import net.minecraft.state.EnumProperty;
@ -23,7 +23,7 @@ import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class MechanicalPistonHeadBlock extends DirectionalBlock implements IWithoutBlockItem { public class MechanicalPistonHeadBlock extends ProperDirectionalBlock implements IWithoutBlockItem {
public static final EnumProperty<PistonType> TYPE = BlockStateProperties.PISTON_TYPE; public static final EnumProperty<PistonType> TYPE = BlockStateProperties.PISTON_TYPE;
@ -49,7 +49,7 @@ public class MechanicalPistonHeadBlock extends DirectionalBlock implements IWith
@Override @Override
protected void fillStateContainer(Builder<Block, BlockState> builder) { protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(TYPE, FACING); builder.add(TYPE);
super.fillStateContainer(builder); super.fillStateContainer(builder);
} }

View file

@ -1,21 +1,17 @@
package com.simibubi.create.modules.contraptions.receivers.constructs; package com.simibubi.create.modules.contraptions.receivers.constructs;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState; import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShape;
@ -23,7 +19,7 @@ import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class PistonPoleBlock extends DirectionalBlock { public class PistonPoleBlock extends ProperDirectionalBlock {
public PistonPoleBlock() { public PistonPoleBlock() {
super(Properties.from(Blocks.PISTON_HEAD)); super(Properties.from(Blocks.PISTON_HEAD));
@ -88,25 +84,9 @@ public class PistonPoleBlock extends DirectionalBlock {
return VoxelShapes.empty(); return VoxelShapes.empty();
} }
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(FACING);
super.fillStateContainer(builder);
}
@Override @Override
public BlockState getStateForPlacement(BlockItemUseContext context) { public BlockState getStateForPlacement(BlockItemUseContext context) {
return getDefaultState().with(FACING, context.getFace().getOpposite()); return getDefaultState().with(FACING, context.getFace().getOpposite());
} }
@Override
public BlockState rotate(BlockState state, Rotation rot) {
return state.with(FACING, rot.rotate(state.get(FACING)));
}
@Override
public BlockState mirror(BlockState state, Mirror mirrorIn) {
return state.rotate(mirrorIn.toRotation(state.get(FACING)));
}
} }

View file

@ -3,27 +3,25 @@ package com.simibubi.create.modules.contraptions.redstone;
import java.util.Random; import java.util.Random;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior; import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntity; import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.BooleanProperty; import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.TickPriority; import net.minecraft.world.TickPriority;
import net.minecraft.world.World; import net.minecraft.world.World;
public class ContactBlock extends DirectionalBlock implements IHaveMovementBehavior { public class ContactBlock extends ProperDirectionalBlock implements IHaveMovementBehavior {
public static final BooleanProperty POWERED = BlockStateProperties.POWERED; public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
@ -34,7 +32,7 @@ public class ContactBlock extends DirectionalBlock implements IHaveMovementBehav
@Override @Override
protected void fillStateContainer(Builder<Block, BlockState> builder) { protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(FACING, POWERED); builder.add(POWERED);
super.fillStateContainer(builder); super.fillStateContainer(builder);
} }
@ -85,16 +83,6 @@ public class ContactBlock extends DirectionalBlock implements IHaveMovementBehav
return AllBlocks.CONTACT.typeOf(blockState) && blockState.get(FACING) == direction.getOpposite(); return AllBlocks.CONTACT.typeOf(blockState) && blockState.get(FACING) == direction.getOpposite();
} }
@Override
public BlockState rotate(BlockState state, Rotation rot) {
return state.with(FACING, rot.rotate(state.get(FACING)));
}
@Override
public BlockState mirror(BlockState state, Mirror mirrorIn) {
return state.rotate(mirrorIn.toRotation(state.get(FACING)));
}
@Override @Override
public boolean canProvidePower(BlockState state) { public boolean canProvidePower(BlockState state) {
return state.get(POWERED); return state.get(POWERED);

View file

@ -22,8 +22,8 @@ import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent.ClientTickEvent;
import net.minecraftforge.event.TickEvent.Phase; import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.event.TickEvent.RenderTickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@ -33,7 +33,7 @@ public class BeltItemHandler {
private static Random r = new Random(); private static Random r = new Random();
@SubscribeEvent @SubscribeEvent
public static void onRenderTick(RenderTickEvent event) { public static void onClientTick(ClientTickEvent event) {
if (event.phase == Phase.START) if (event.phase == Phase.START)
return; return;
@ -42,6 +42,8 @@ public class BeltItemHandler {
if (player == null || world == null) if (player == null || world == null)
return; return;
if (Minecraft.getInstance().currentScreen != null)
return;
for (Hand hand : Hand.values()) { for (Hand hand : Hand.values()) {
ItemStack heldItem = player.getHeldItem(hand); ItemStack heldItem = player.getHeldItem(hand);
@ -56,7 +58,7 @@ public class BeltItemHandler {
continue; continue;
BlockPos first = NBTUtil.readBlockPos(tag.getCompound("FirstPulley")); BlockPos first = NBTUtil.readBlockPos(tag.getCompound("FirstPulley"));
if (!world.getBlockState(first).has(BlockStateProperties.AXIS)) if (!world.getBlockState(first).has(BlockStateProperties.AXIS))
continue; continue;
Axis axis = world.getBlockState(first).get(BlockStateProperties.AXIS); Axis axis = world.getBlockState(first).get(BlockStateProperties.AXIS);
@ -91,6 +93,7 @@ public class BeltItemHandler {
double x = Math.abs(diff.x); double x = Math.abs(diff.x);
double y = Math.abs(diff.y); double y = Math.abs(diff.y);
double z = Math.abs(diff.z); double z = Math.abs(diff.z);
float length = (float) Math.max(x, Math.max(y, z));
Vec3d step = diff.normalize(); Vec3d step = diff.normalize();
int sames = ((x == y) ? 1 : 0) + ((y == z) ? 1 : 0) + ((z == x) ? 1 : 0); int sames = ((x == y) ? 1 : 0) + ((y == z) ? 1 : 0) + ((z == x) ? 1 : 0);
@ -115,12 +118,13 @@ public class BeltItemHandler {
} }
} }
step = validDiffs.get(closestIndex); step = validDiffs.get(closestIndex);
} }
for (float f = 0; f < actualDiff.length(); f += .25f) { step = new Vec3d(Math.signum(step.x), Math.signum(step.y), Math.signum(step.z));
for (float f = 0; f < length; f += .0625f) {
Vec3d position = start.add(step.scale(f)); Vec3d position = start.add(step.scale(f));
if (r.nextInt(100) == 0) { if (r.nextInt(10) == 0) {
world.addParticle(new RedstoneParticleData(canConnect ? .3f : .9f, canConnect ? .9f : .3f, .5f, 1), world.addParticle(new RedstoneParticleData(canConnect ? .3f : .9f, canConnect ? .9f : .3f, .5f, 1),
position.x + .5f, position.y + .5f, position.z + .5f, 0, 0, 0); position.x + .5f, position.y + .5f, position.z + .5f, 0, 0, 0);
} }

View file

@ -12,19 +12,21 @@ import com.simibubi.create.AllItems;
import com.simibubi.create.AllPackets; import com.simibubi.create.AllPackets;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.item.ItemWithToolTip;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.KeyboardHelper; import com.simibubi.create.foundation.utility.ItemDescription;
import com.simibubi.create.foundation.utility.ItemDescription.Palette;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.ITooltipFlag; import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.fluid.IFluidState; import net.minecraft.fluid.IFluidState;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext; import net.minecraft.item.ItemUseContext;
@ -59,10 +61,19 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.fml.network.PacketDistributor;
public class BuilderGunItem extends Item { public class BuilderGunItem extends ItemWithToolTip {
public static enum ComponentTier { public static enum ComponentTier {
None, BlazeBrass, ChorusChrome None(TextFormatting.DARK_GRAY + "Andesite Alloy"), BlazeBrass(TextFormatting.GOLD + "Blaze Brass"),
ChorusChrome(TextFormatting.LIGHT_PURPLE + "Chorus Chrome"),
;
protected String displayName;
private ComponentTier(String displayName) {
this.displayName = displayName;
}
} }
public static enum Components { public static enum Components {
@ -78,39 +89,38 @@ public class BuilderGunItem extends Item {
return UseAction.NONE; return UseAction.NONE;
} }
@Override
protected ItemDescription getDescription() {
Palette palette = Palette.Purple;
return new ItemDescription(palette).withSummary("Novel gadget for placing or exchanging blocks at a distance.")
.withControl("L-Click at Block", "Sets blocks placed by the tool to the targeted block.")
.withControl("R-Click at Block",
h("Places", palette) + " or " + h("Replaces", palette) + " the targeted block.")
.withControl("R-Click while Sneaking", "Opens the " + h("Configuration", palette) + " Interface")
.createTabs();
}
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) { public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
if (KeyboardHelper.isKeyDown(KeyboardHelper.LSHIFT)) { if (stack.hasTag() && stack.getTag().contains("BlockUsed")) {
if (stack.getOrCreateTag().contains("BlockUsed")) { String usedblock = NBTUtil.readBlockState(stack.getTag().getCompound("BlockUsed")).getBlock()
BlockState state = NBTUtil.readBlockState(stack.getTag().getCompound("BlockUsed")); .getTranslationKey();
tooltip.add(new StringTextComponent(TextFormatting.BLUE + "Using Block: " + TextFormatting.WHITE ItemDescription.add(tooltip, TextFormatting.DARK_GRAY + "Using: " + TextFormatting.GRAY
+ new TranslationTextComponent(state.getBlock().getTranslationKey()).getFormattedText())); + new TranslationTextComponent(usedblock).getFormattedText());
} else { }
tooltip.add(new StringTextComponent(TextFormatting.BLUE + "Hit a Block to set the material."));
} super.addInformation(stack, worldIn, tooltip, flagIn);
tooltip.add(new StringTextComponent(""));
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Places or Replaces Blocks at a range.")); Palette palette = Palette.Purple;
tooltip.add(new StringTextComponent( if (Screen.hasShiftDown()) {
TextFormatting.GRAY + "> [Left-Click] to set the material used by the gun")); ItemDescription.add(tooltip, palette.color + "Component Tiers:");
tooltip.add(new StringTextComponent(
TextFormatting.GRAY + "> [Right-Click] to place/replace blocks with the material"));
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "> [Shift-Right-Click] to configure"));
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Craft with components to upgrade."));
tooltip.add(new StringTextComponent(""));
for (Components c : Components.values()) { for (Components c : Components.values()) {
ComponentTier tier = getTier(c, stack); ComponentTier tier = getTier(c, stack);
tooltip.add(new StringTextComponent( ItemDescription.add(tooltip, "> " + TextFormatting.GRAY + c.name() + ": " + tier.displayName);
TextFormatting.AQUA + "" + TextFormatting.ITALIC + c.name() + ": " + TextFormatting.GRAY
+ (tier == ComponentTier.None ? (c == Components.Body ? "Andesite Alloy" : "Missing")
: tier.name())));
} }
} else {
tooltip.add(new StringTextComponent(TextFormatting.DARK_GRAY + "< Hold Shift >"));
} }
super.addInformation(stack, worldIn, tooltip, flagIn);
} }
@Override @Override
@ -208,7 +218,8 @@ public class BuilderGunItem extends Item {
// Find exact position of gun barrel for VFX // Find exact position of gun barrel for VFX
float yaw = (float) ((player.rotationYaw) / -180 * Math.PI); float yaw = (float) ((player.rotationYaw) / -180 * Math.PI);
float pitch = (float) ((player.rotationPitch) / -180 * Math.PI); float pitch = (float) ((player.rotationPitch) / -180 * Math.PI);
Vec3d barrelPosNoTransform = new Vec3d(mainHand == (player.getPrimaryHand() == HandSide.RIGHT) ? -.35f : .35f, -0.1f, 1); Vec3d barrelPosNoTransform = new Vec3d(mainHand == (player.getPrimaryHand() == HandSide.RIGHT) ? -.35f : .35f,
-0.1f, 1);
Vec3d barrelPos = start.add(barrelPosNoTransform.rotatePitch(pitch).rotateYaw(yaw)); Vec3d barrelPos = start.add(barrelPosNoTransform.rotatePitch(pitch).rotateYaw(yaw));
// Client side - Shoot visual laser // Client side - Shoot visual laser

View file

@ -0,0 +1,85 @@
package com.simibubi.create.modules.gardens;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.IGrowable;
import net.minecraft.block.RotatedPillarBlock;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
public class CocoaLogBlock extends RotatedPillarBlock implements IGrowable {
public static IntegerProperty AGE = BlockStateProperties.AGE_0_2;
private static final int GROWTH_CHANCE = 20;
public CocoaLogBlock() {
super(Properties.from(Blocks.JUNGLE_LOG).tickRandomly());
}
@Override
public boolean canGrow(IBlockReader arg0, BlockPos arg1, BlockState state, boolean arg3) {
return true;
}
@Override
public void tick(BlockState state, World worldIn, BlockPos pos, Random random) {
if (!worldIn.isAreaLoaded(pos, 1))
return; // Forge: prevent loading unloaded chunks when checking neighbor's light
grow(worldIn, random, pos, state);
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(AGE);
super.fillStateContainer(builder);
}
@Override
public boolean canUseBonemeal(World arg0, Random arg1, BlockPos arg2, BlockState arg3) {
return true;
}
@Override
public void grow(World world, Random random, BlockPos pos, BlockState state) {
if (random.nextInt(100 / GROWTH_CHANCE) != 0)
return;
int age = state.get(AGE);
if (age < 2) {
world.setBlockState(pos, state.with(AGE, age + 1));
return;
}
List<Direction> shuffledDirections = Arrays.asList(Direction.values());
Collections.shuffle(shuffledDirections);
for (Direction facing : shuffledDirections) {
if (facing.getAxis().isVertical())
continue;
if (facing.getAxis() == state.get(AXIS))
continue;
if (!world.getBlockState(pos.offset(facing)).getMaterial().isReplaceable())
continue;
world.setBlockState(pos.offset(facing),
Blocks.COCOA.getDefaultState().with(BlockStateProperties.HORIZONTAL_FACING, facing.getOpposite())
.with(BlockStateProperties.AGE_0_2, 0));
break;
}
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.curiosities.item; package com.simibubi.create.modules.gardens;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -6,19 +6,18 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.function.Predicate; import java.util.function.Predicate;
import com.simibubi.create.foundation.utility.KeyboardHelper; import com.simibubi.create.foundation.item.ItemWithToolTip;
import com.simibubi.create.foundation.utility.ItemDescription;
import com.simibubi.create.foundation.utility.ItemDescription.Palette;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.SaplingBlock; import net.minecraft.block.SaplingBlock;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid; import net.minecraft.fluid.Fluid;
import net.minecraft.item.BoneMealItem; import net.minecraft.item.BoneMealItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext; import net.minecraft.item.ItemUseContext;
import net.minecraft.item.crafting.RecipeManager; import net.minecraft.item.crafting.RecipeManager;
import net.minecraft.scoreboard.Scoreboard; import net.minecraft.scoreboard.Scoreboard;
@ -27,30 +26,22 @@ import net.minecraft.util.ActionResultType;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent; import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.EmptyTickList; import net.minecraft.world.EmptyTickList;
import net.minecraft.world.ITickList; import net.minecraft.world.ITickList;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.storage.MapData; import net.minecraft.world.storage.MapData;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class TreeFertilizerItem extends Item { public class TreeFertilizerItem extends ItemWithToolTip {
public TreeFertilizerItem(Properties properties) { public TreeFertilizerItem(Properties properties) {
super(properties); super(properties);
} }
@Override @Override
@OnlyIn(Dist.CLIENT) protected ItemDescription getDescription() {
public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) { return new ItemDescription(Palette.Green)
if (KeyboardHelper.isKeyDown(KeyboardHelper.LSHIFT)) .withSummary("A powerful combination of minerals suitable for common tree types.")
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Tree won't grow? Try this on it.")); .withBehaviour("When used on Sapling", "Grows Trees regardless of their spacing Conditions").createTabs();
else
tooltip.add(new StringTextComponent(TextFormatting.DARK_GRAY + "< Hold Shift >"));
super.addInformation(stack, worldIn, tooltip, flagIn);
} }
@Override @Override

View file

@ -7,8 +7,10 @@ import java.util.Map;
import com.simibubi.create.AllPackets; import com.simibubi.create.AllPackets;
import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.item.ItemWithToolTip;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.KeyboardHelper; import com.simibubi.create.foundation.utility.ItemDescription;
import com.simibubi.create.foundation.utility.ItemDescription.Palette;
import com.simibubi.create.modules.symmetry.mirror.CrossPlaneMirror; import com.simibubi.create.modules.symmetry.mirror.CrossPlaneMirror;
import com.simibubi.create.modules.symmetry.mirror.EmptyMirror; import com.simibubi.create.modules.symmetry.mirror.EmptyMirror;
import com.simibubi.create.modules.symmetry.mirror.PlaneMirror; import com.simibubi.create.modules.symmetry.mirror.PlaneMirror;
@ -17,10 +19,8 @@ import com.simibubi.create.modules.symmetry.mirror.SymmetryMirror;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext; import net.minecraft.item.ItemUseContext;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
@ -32,7 +32,6 @@ import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -41,7 +40,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.fml.network.PacketDistributor;
public class SymmetryWandItem extends Item { public class SymmetryWandItem extends ItemWithToolTip {
public static final String $SYMMETRY = "symmetry"; public static final String $SYMMETRY = "symmetry";
private static final String $ENABLE = "enable"; private static final String $ENABLE = "enable";
@ -51,22 +50,16 @@ public class SymmetryWandItem extends Item {
} }
@Override @Override
@OnlyIn(Dist.CLIENT) protected ItemDescription getDescription() {
public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) { Palette palette = Palette.Purple;
if (KeyboardHelper.isKeyDown(KeyboardHelper.LSHIFT)) { return new ItemDescription(palette)
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "Perfectly mirrors your Block placement")); .withSummary("Perfectly mirrors your Block placement across the configured planes.")
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "across the configured planes.")); .withBehaviour("When in Hotbar", "Stays Active")
tooltip.add(new StringTextComponent("")); .withControl("R-Click on Ground",
tooltip.add( h("Creates", palette) + " or " + h("Moves", palette) + " the Mirror")
new StringTextComponent(TextFormatting.GRAY + "> [Right-Click] on ground to place/move mirror")); .withControl("R-Click in the Air", h("Removes", palette) + " the active Mirror")
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "> [Right-Click] in air to remove mirror")); .withControl("R-Click while Sneaking", "Opens the " + h("Configuration Screen", palette))
tooltip.add(new StringTextComponent(TextFormatting.GRAY + "> [Shift-Right-Click] to configure")); .createTabs();
tooltip.add(new StringTextComponent(""));
tooltip.add(new StringTextComponent(TextFormatting.DARK_GRAY + "Active while held in the Hotbar"));
} else
tooltip.add(new StringTextComponent(TextFormatting.DARK_GRAY + "< Hold Shift >"));
super.addInformation(stack, worldIn, tooltip, flagIn);
} }
@Override @Override

View file

@ -0,0 +1,15 @@
{
"forge_marker": 1,
"variants": {
"age": {
"0": { "model": "create:block/cocoa_log_0" },
"1": { "model": "create:block/cocoa_log_1" },
"2": { "model": "create:block/cocoa_log_2" }
},
"axis": {
"y": {},
"x": { "x": 90, "y": 90 },
"z": { "x": 90 }
}
}
}

View file

@ -58,6 +58,8 @@
"block.create.schematicannon": "Schematicannon", "block.create.schematicannon": "Schematicannon",
"block.create.schematic_table": "Schematic Table", "block.create.schematic_table": "Schematic Table",
"block.create.creative_crate": "Schematicannon Creatifier", "block.create.creative_crate": "Schematicannon Creatifier",
"block.create.cocoa_log": "Cocoa Jungle Log",
"itemGroup.create": "Create" "itemGroup.create": "Create"
} }

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_column",
"textures": {
"end": "block/jungle_log_top"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "create:block/cocoa_log",
"textures": {
"side": "create:block/cocoa_log_0"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "create:block/cocoa_log",
"textures": {
"side": "create:block/cocoa_log_1"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "create:block/cocoa_log",
"textures": {
"side": "create:block/cocoa_log_2"
}
}

View file

@ -0,0 +1,3 @@
{
"parent": "create:block/cocoa_log_2"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

View file

@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"create:cocoa_log"
]
}