下面列出了怎么用net.minecraft.util.Tuple的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public boolean mouseClicked(int mouseX, int mouseY, int button) {
super.mouseClicked(mouseX, mouseY, button);
Tuple<ITabInfo, int[]> tabOnMouse = getTabOnMouse(mouseX, mouseY);
if (tabOnMouse != null) {
ITabInfo tabInfo = tabOnMouse.getFirst();
int tabIndex = tabInfos.indexOf(tabInfo);
if (selectedTabIndex != tabIndex) {
setSelectedTab(tabIndex);
playButtonClickSound();
writeClientAction(2, buf -> buf.writeVarInt(tabIndex));
return true;
}
}
return false;
}
private static OptionalInt getColor(BlockPos pos, IBlockState heldBlock) {
final Optional<Tuple<Schematic, BlockPos>> optSchematic = SchematicaHelper.getOpenSchematic();
if (optSchematic.isPresent()) {
final Schematic schematic = optSchematic.get().getFirst();
final BlockPos schematicOffset = optSchematic.get().getSecond();
final BlockPos schematicPos = pos.subtract(schematicOffset);
if (schematic.inSchematic(schematicPos)) {
final IBlockState schematicBlock = schematic.desiredState(schematicPos);
return OptionalInt
.of(schematicBlock.equals(heldBlock) ? Colors.GREEN.toBuffer() : Colors.RED.toBuffer());
} else {
return OptionalInt.empty();
}
} else {
return OptionalInt.empty();
}
}
@Override
public WrappedBlockState deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
ResourceLocation block;
List<Tuple<String, String>> properties = Lists.newArrayList();
if (json.isJsonObject())
{
JsonObject jsonObject = json.getAsJsonObject();
block = context.deserialize(jsonObject.get("block"), ResourceLocation.class);
if (jsonObject.has("properties"))
{
properties = deserializeProperties(jsonObject.get("properties"));
}
} else
{
block = context.deserialize(json, ResourceLocation.class);
}
return new WrappedBlockStateImpl(block, properties);
}
/**
* Set the angular velocity for an entire gear train based on the gear ratios.
*
* @param start The node that will get get angular velocity of newOmega.
* @param newOmega The new angular velocity of the node start.
* @param deltaTime The timestep used in our gear train simulation.
* @param visitedNodes Nodes that won't have their angular velocity changed.
*/
private void applyNewOmega(IRotationNode start, double newOmega, double deltaTime,
Set<IRotationNode> visitedNodes) {
visitedNodes.add(start); // kind of a bad spot to put this
start.setAngularRotation(
start.getAngularRotation() + (start.getAngularVelocity() * deltaTime) + (
(newOmega - start.getAngularVelocity()) * deltaTime / 2D));
start.setAngularVelocity(newOmega);
for (Tuple<IRotationNode, EnumFacing> connectedNode : start.connectedTorqueTilesList()) {
IRotationNode endNode = connectedNode.getFirst();
EnumFacing exploreDirection = connectedNode.getSecond();
if (visitedNodes.contains(connectedNode.getFirst())) {
continue;
}
double ratioStart = start.getAngularVelocityRatioFor(exploreDirection).get();
double ratioEnd = endNode.getAngularVelocityRatioFor(exploreDirection.getOpposite())
.get();
double multiplier = -ratioStart / ratioEnd;
applyNewOmega(endNode, newOmega * multiplier, deltaTime, visitedNodes);
}
}
/**
* Calculate the rotational total energy stored in a gear train (not including any nodes in
* visitedNodes).
*
* @param start
* @param visitedNodes Nodes we ignore in our calculations.
* @return
*/
private double calculateTotalEnergy(IRotationNode start, Set<IRotationNode> visitedNodes) {
visitedNodes.add(start); // kind of a bad spot to put this
// actual code start
double totalEnergy = start.getEnergy();
for (Tuple<IRotationNode, EnumFacing> connectedNode : start.connectedTorqueTilesList()) {
IRotationNode endNode = connectedNode.getFirst();
EnumFacing exploreDirection = connectedNode.getSecond();
if (visitedNodes.contains(connectedNode.getFirst())) {
continue;
}
// double ratioStart = start.getAngularVelocityRatioFor(exploreDirection).get();
// double ratioEnd = endNode.getAngularVelocityRatioFor(exploreDirection.getOpposite()).get();
// double multiplier = -ratioStart / ratioEnd;
totalEnergy += calculateTotalEnergy(endNode, visitedNodes);
}
return totalEnergy;
}
/**
* Calculate the rotational inertia of the start node with the gear train (not including any
* nodes in visitedNodes) attached. Reference: https://www.engineersedge.com/motors/gear_drive_system.htm
*
* @param start The node which we calculate the inertia relative to.
* @param visitedNodes Nodes we ignore in our calculations.
* @return
*/
private double calculateApparentInertia(IRotationNode start, Set<IRotationNode> visitedNodes) {
visitedNodes.add(start); // kind of a bad spot to put this
// actual code start
double apparentInertia = start.getRotationalInertia();
for (Tuple<IRotationNode, EnumFacing> connectedNode : start.connectedTorqueTilesList()) {
IRotationNode endNode = connectedNode.getFirst();
EnumFacing exploreDirection = connectedNode.getSecond();
if (visitedNodes.contains(connectedNode.getFirst())) {
continue;
}
double ratioStart = start.getAngularVelocityRatioFor(exploreDirection).get();
double ratioEnd = endNode.getAngularVelocityRatioFor(exploreDirection.getOpposite())
.get();
double multiplier = -ratioStart / ratioEnd;
apparentInertia += (multiplier * multiplier * calculateApparentInertia(endNode,
visitedNodes));
}
return apparentInertia;
}
/**
* Calculate the 'apparent' angular velocity of a gear train (not including any nodes in
* visitedNodes) relative to start. This probably isn't physically correct, but its good enough
* for our purposes.
*
* @param start The node we calculate the apparent angular velocity relative to.
* @param visitedNodes Nodes we ignore in our calculations.
* @return
*/
private double calculateApparentOmega(IRotationNode start, Set<IRotationNode> visitedNodes) {
visitedNodes.add(start); // kind of a bad spot to put this
// actual code start
double apparentOmega = start.getAngularVelocity();
for (Tuple<IRotationNode, EnumFacing> connectedNode : start.connectedTorqueTilesList()) {
IRotationNode endNode = connectedNode.getFirst();
EnumFacing exploreDirection = connectedNode.getSecond();
if (visitedNodes.contains(connectedNode.getFirst())) {
continue;
}
double ratioStart = start.getAngularVelocityRatioFor(exploreDirection).get();
double ratioEnd = endNode.getAngularVelocityRatioFor(exploreDirection.getOpposite())
.get();
double multiplier = -ratioStart / ratioEnd;
apparentOmega += (multiplier * calculateApparentOmega(endNode, visitedNodes));
}
return apparentOmega;
}
/**
* Calculate the net torque experienced by the gear train (not including any nodes in
* visitedNodes) relative to start.
*
* @param start The node we calculate the apparent torque relative to.
* @param visitedNodes Nodes we ignore in our calculations.
* @return
*/
private double calculateApparentTorque(IRotationNode start, Set<IRotationNode> visitedNodes) {
visitedNodes.add(start); // kind of a bad spot to put this
// actual code start
double apparentTorque = start.calculateInstantaneousTorque(parent);
for (Tuple<IRotationNode, EnumFacing> connectedNode : start.connectedTorqueTilesList()) {
IRotationNode endNode = connectedNode.getFirst();
EnumFacing exploreDirection = connectedNode.getSecond();
if (visitedNodes.contains(connectedNode.getFirst())) {
continue;
}
double ratioStart = start.getAngularVelocityRatioFor(exploreDirection).get();
double ratioEnd = endNode.getAngularVelocityRatioFor(exploreDirection.getOpposite())
.get();
double multiplier = -ratioStart / ratioEnd;
apparentTorque += (multiplier * calculateApparentTorque(endNode, visitedNodes));
}
return apparentTorque;
}
@Override
public boolean registerStrategy(IAgriCrossStrategy strategy) {
// Validate
Preconditions.checkNotNull(strategy, "Cannot register a null strategy to the mutation engine!");
// Register
if (strategy.getRollChance() > 1f || strategy.getRollChance() < 0f) {
throw new IndexOutOfBoundsException(
"Invalid roll chance of " + strategy.getRollChance() + "!\n"
+ "The roll chance must be in the range 0.0 (inclusive) to 1.0 (exclusive)!"
);
} else if (strategy.getRollChance() == 0) {
AgriCore.getLogger("agricraft").debug("Skipping mutation strategy with zero chance!");
return false;
} else if (hasStrategy(strategy)) {
AgriCore.getLogger("agricraft").debug("Skipping duplicate mutation strategy!");
return false;
} else {
this.sigma += strategy.getRollChance();
this.strategies.add(new Tuple<>(sigma, strategy));
return true;
}
}
public static void encode(PacketDurabilitySync msg, PacketBuffer buffer) {
List<Tuple<BlockPos, Integer>> thisList = msg.updateList;
CompoundNBT tag = new CompoundNBT();
ListNBT nbtList = new ListNBT();
for (int i = 0; i < thisList.size(); i++) {
CompoundNBT nbt = new CompoundNBT();
nbt.put("pos", NBTUtil.writeBlockPos(thisList.get(i).getA()));
nbt.putInt("dur", thisList.get(i).getB());
nbtList.add(i, nbt);
}
tag.put("list", nbtList);
buffer.writeCompoundTag(tag);
}
public static PacketDurabilitySync decode(PacketBuffer buffer) {
CompoundNBT tag = buffer.readCompoundTag();
ListNBT nbtList = tag.getList("list", Constants.NBT.TAG_COMPOUND);
List<Tuple<BlockPos, Integer>> thisList = new ArrayList<>();
for (int i = 0; i < nbtList.size(); i++) {
CompoundNBT nbt = nbtList.getCompound(i);
thisList.add(new Tuple<>(NBTUtil.readBlockPos(nbt.getCompound("pos")), nbt.getInt("dur")));
}
return new PacketDurabilitySync(thisList);
}
public static void clientPacketHandler(PacketDurabilitySync msg) {
List<Tuple<BlockPos, Integer>> thisList = msg.updateList;
for (int i = 0; i < thisList.size(); i++) {
BlockPos pos = thisList.get(i).getA();
int durability = thisList.get(i).getB();
TileEntity clientTE = Minecraft.getInstance().world.getTileEntity(pos);
if (!(clientTE instanceof RenderBlockTileEntity)) return;
((RenderBlockTileEntity) clientTE).setClientDurability(durability);
}
}
@Override
public void drawInForeground(int mouseX, int mouseY) {
super.drawInForeground(mouseX, mouseY);
Tuple<ITabInfo, int[]> tabOnMouse = getTabOnMouse(mouseX, mouseY);
if (tabOnMouse != null) {
int[] tabSizes = tabOnMouse.getSecond();
ITabInfo tabInfo = tabOnMouse.getFirst();
boolean isSelected = tabInfos.get(selectedTabIndex) == tabInfo;
tabInfo.renderHoverText(tabSizes[0], tabSizes[1], tabSizes[2], tabSizes[3], sizes.getWidth(), sizes.getHeight(), isSelected, mouseX, mouseY);
}
}
private Tuple<ITabInfo, int[]> getTabOnMouse(int mouseX, int mouseY) {
for (int tabIndex = 0; tabIndex < tabInfos.size(); tabIndex++) {
ITabInfo tabInfo = tabInfos.get(tabIndex);
int[] tabSizes = tabListRenderer.getTabPos(tabIndex, sizes.getWidth(), sizes.getHeight());
tabSizes[0] += getPosition().x;
tabSizes[1] += getPosition().y;
if (isMouseOverTab(mouseX, mouseY, tabSizes)) {
return new Tuple<>(tabInfo, tabSizes);
}
}
return null;
}
public void addBuiltInBlock(Block block, String particleTexture) {
this.builtInBlocks.add(new Tuple<>(block, particleTexture));
ModelLoader.setCustomStateMapper(block, SIMPLE_STATE_MAPPER);
Item itemFromBlock = Item.getItemFromBlock(block);
if (itemFromBlock != Items.AIR) {
ModelLoader.setCustomMeshDefinition(itemFromBlock, SIMPLE_MESH_DEFINITION);
}
}
/** Created by e99999, does fluid container handling for GTC tiles **/
public static void doFluidContainerThings(TileEntityMachine tile, IC2Tank tank, int slotInput, int slotOutput) {
if (!GTHelperStack.isSlotEmpty(tile, slotInput)) {
// emptying items
ItemStack emptyStack = FluidUtil.tryEmptyContainer(tile.getStackInSlot(slotInput), tank, tank.getCapacity()
- tank.getFluidAmount(), null, false).getResult();
boolean didEmpty = FluidUtil.tryEmptyContainer(tile.getStackInSlot(slotInput), tank, tank.getCapacity()
- tank.getFluidAmount(), null, false) != FluidActionResult.FAILURE;
if (!isTankFull(tank) && !GTHelperStack.isSlotFull(tile, slotOutput)
&& GTHelperStack.canOutputStack(tile, emptyStack, slotOutput) && didEmpty) {
FluidUtil.tryEmptyContainer(tile.getStackInSlot(slotInput), tank, tank.getCapacity()
- tank.getFluidAmount(), null, true);
if (GTHelperStack.isSlotEmpty(tile, slotOutput)) {
tile.setStackInSlot(slotOutput, emptyStack);
} else {
tile.getStackInSlot(slotOutput).grow(1);
}
tile.getStackInSlot(slotInput).shrink(1);
}
// filling items
Tuple<ItemStack, FluidStack> filled = FluidHelper.fillContainer(tile.getStackInSlot(slotInput), tank.getFluid(), true, true);
if (filled != null && GTHelperStack.canOutputStack(tile, filled.getFirst(), slotOutput)) {
if (GTHelperStack.isSlotEmpty(tile, slotOutput)) {
tile.setStackInSlot(slotOutput, filled.getFirst());
} else {
tile.getStackInSlot(slotOutput).grow(1);
}
tile.getStackInSlot(slotInput).shrink(1);
tank.drainInternal((FluidStack) filled.getSecond(), true);
}
}
}
private List<Tuple<String, String>> deserializeProperties(JsonElement element)
{
if (element.isJsonObject())
{
return element.getAsJsonObject().entrySet().stream()
.map(e -> new Tuple<>(e.getKey(), e.getValue().getAsString()))
.collect(Collectors.toList());
} else
{
return Arrays.stream(element.getAsString().split(","))
.map(s -> s.split("="))
.map(a -> new Tuple<>(a[0], a[1]))
.collect(Collectors.toList());
}
}
@Override
@SuppressWarnings("unchecked")
public IBlockState createState()
{
Block block = getBlock();
if (block != null)
{
IBlockState state = block.getDefaultState();
for (Tuple<String, String> tuple : properties)
{
String name = tuple.getFirst();
Optional<IProperty> prop = getProperty(state, name);
if (prop.isPresent())
{
IProperty property = prop.get();
state = state.withProperty(property, (Comparable) property.parseValue(tuple.getSecond()).get());
}
}
return state;
} else
{
return null;
}
}
@Test
@SuppressWarnings("unchecked")
public void testProperties()
{
ContentBlockStairs content = new ContentBlockStairs();
content.id = "test_getSubtype";
content.modelState = new WrappedBlockStateImpl(new ResourceLocation("minecraft:log"),
Collections.singletonList(new Tuple<>("variant", "spruce")));
Block block = content.createBlock();
Collection<IProperty<?>> properties = block.getBlockState().getProperties();
assertEquals(3, properties.size());
}
@Test
@SuppressWarnings("unchecked")
public void test_getSubtype()
{
ContentBlockStairs content = new ContentBlockStairs();
content.id = "test_getSubtype";
content.modelState = new WrappedBlockStateImpl(new ResourceLocation("minecraft:log"),
Collections.singletonList(new Tuple<>("variant", "spruce")));
Block block = content.createBlock();
CSBlock<ContentBlockStairs> csblock = (CSBlock<ContentBlockStairs>) block;
for (EnumFacing facing : BlockStairs.FACING.getAllowedValues())
{
for (net.minecraft.block.BlockStairs.EnumHalf half : BlockStairs.HALF.getAllowedValues())
{
for (net.minecraft.block.BlockStairs.EnumShape shape : BlockStairs.SHAPE.getAllowedValues())
{
IBlockState state = block.getDefaultState()
.withProperty(BlockStairs.FACING, facing)
.withProperty(BlockStairs.HALF, half)
.withProperty(BlockStairs.SHAPE, shape);
assertEquals(0, csblock.getSubtype(state));
}
}
}
}
/**
* @param start The node where we start our traversal of the gear train graph to reset
* the train.
* @param visitedNodes Nodes that have already been reset.
*/
private void resetGearTrain(IRotationNode start, Set<IRotationNode> visitedNodes) {
visitedNodes.add(start); // kind of a bad spot to put this
start.setAngularRotation(0);
start.setAngularVelocity(0);
for (Tuple<IRotationNode, EnumFacing> connectedNode : start.connectedTorqueTilesList()) {
IRotationNode endNode = connectedNode.getFirst();
if (visitedNodes.contains(connectedNode.getFirst())) {
continue;
}
resetGearTrain(endNode, visitedNodes);
}
}
@PhysicsThreadOnly
default List<Tuple<IRotationNode, EnumFacing>> connectedTorqueTilesList() {
List<Tuple<IRotationNode, EnumFacing>> connectedTiles = new ArrayList<>();
for (EnumFacing facing : EnumFacing.values()) {
if (isConnectedToSide(facing)) {
Optional<IRotationNode> tileOnSide = getTileOnSide(facing);
if (!tileOnSide.isPresent()) {
throw new IllegalStateException("I thought this was impossible!");
}
connectedTiles.add(new Tuple<>(tileOnSide.get(), facing));
}
}
return connectedTiles;
}
public void setAxleAxis(EnumFacing.Axis axleAxis) {
this.rotationNode.queueTask(() -> {
for (EnumFacing facing : EnumFacing.values()) {
rotationNode.setAngularVelocityRatio(facing, Optional.empty());
}
Tuple<EnumFacing, EnumFacing> enumFacingFromAxis = AXIS_TO_FACING_MAP.get(axleAxis);
rotationNode.setAngularVelocityRatio(enumFacingFromAxis.getFirst(), Optional.of(1D));
rotationNode.setAngularVelocityRatio(enumFacingFromAxis.getSecond(), Optional.of(-1D));
});
}
private boolean absorb(World world, int x, int y, int z) {
LinkedList<Tuple> linkedlist = Lists.newLinkedList();
ArrayList<WorldCoord> arraylist = Lists.newArrayList();
linkedlist.add(new Tuple(new WorldCoord(x, y, z), 0));
int i = 0;
WorldCoord blockpos1;
while (!linkedlist.isEmpty()) {
Tuple tuple = linkedlist.poll();
blockpos1 = (WorldCoord) tuple.getFirst();
int j = (Integer) tuple.getSecond();
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
WorldCoord blockpos2 = blockpos1.add(dir);
if (world.getBlock(blockpos2.x, blockpos2.y, blockpos2.z).getMaterial() == Material.water) {
world.setBlockToAir(blockpos2.x, blockpos2.y, blockpos2.z);
arraylist.add(blockpos2);
i++;
if (j < 6)
linkedlist.add(new Tuple(blockpos2, j + 1));
}
}
if (i > 64)
break;
}
Iterator<WorldCoord> iterator = arraylist.iterator();
while (iterator.hasNext()) {
blockpos1 = iterator.next();
world.notifyBlockOfNeighborChange(blockpos1.x, blockpos1.y, blockpos1.z, Blocks.air);
}
return i > 0;
}
@SubscribeEvent
public void registerItems(RegistryEvent.Register<Item> event) {
if (ENABLE_AGRI_BAUBLE) {
final ItemAgriBauble agriBauble = new ItemAgriBauble();
agriBauble.setUnlocalizedName("agricraft:agri_bauble");
agriBauble.setRegistryName("agricraft:agri_bauble");
event.getRegistry().register(agriBauble);
if (FMLCommonHandler.instance().getSide() == Side.CLIENT) {
for (Tuple<Integer, ModelResourceLocation> entry : agriBauble.getModelDefinitions()) {
ModelLoader.setCustomModelResourceLocation(agriBauble, entry.getFirst(), entry.getSecond());
}
}
}
}
@Override
public List<Tuple<Integer, ModelResourceLocation>> getModelDefinitions() {
return ImmutableList.of(
new Tuple<>(0, new ModelResourceLocation(this.getRegistryName() + "")),
new Tuple<>(1, new ModelResourceLocation(this.getRegistryName() + "_full"))
);
}
public PacketDurabilitySync(List<Tuple<BlockPos, Integer>> updateList) {
this.updateList = updateList;
}
public static void addToList(BlockPos pos, int durability, World world) {
updateList.add(new Tuple<>(pos, durability));
serverWorld = world;
}
public WrappedBlockStateImpl(ResourceLocation block, List<Tuple<String, String>> properties)
{
this.block = block;
this.properties = properties;
}
@Override
public List<Tuple<ItemStack, String>> getModels() {
ItemStack stack = new ItemStack(this);
return Collections.singletonList(new Tuple<>(stack, super.getUnlocalizedName(stack).substring(5)));
}