/*
* This file is part of NeptuneVanilla, licensed under the MIT License (MIT).
*
* Copyright (c) 2015-2017, Jamie Mansfield <https://github.com/jamierocks>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.neptunepowered.vanilla.mixin.minecraft.block;
import co.aikar.timings.NeptuneTimings;
import co.aikar.timings.Timing;
import net.canarymod.api.entity.Entity;
import net.canarymod.api.world.World;
import net.canarymod.api.world.blocks.BlockBase;
import net.canarymod.api.world.blocks.BlockMaterial;
import net.canarymod.api.world.blocks.MapColor;
import net.canarymod.api.world.position.Position;
import net.canarymod.hook.world.BlockDropXpHook;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.util.BlockPos;
import org.neptunepowered.vanilla.interfaces.minecraft.block.IMixinBlock;
import org.neptunepowered.vanilla.util.converter.PositionConverter;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Random;
@Mixin(Block.class)
@Implements(@Interface(iface = BlockBase.class, prefix = "block$"))
public abstract class MixinBlock implements BlockBase, IMixinBlock {
@Shadow @Final protected Material blockMaterial;
@Shadow protected boolean needsRandomTick;
@Shadow protected double minX;
@Shadow protected double minY;
@Shadow protected double minZ;
@Shadow protected double maxX;
@Shadow protected double maxY;
@Shadow protected double maxZ;
private Timing timing;
@Shadow public abstract boolean isFullBlock();
@Shadow public abstract int getLightOpacity();
@Shadow public abstract int getLightValue();
@Shadow public abstract boolean getUseNeighborBrightness();
@Shadow public abstract boolean isNormalCube();
@Shadow public abstract boolean isFullCube();
@Shadow public abstract boolean hasTileEntity();
@Shadow public abstract boolean isOpaqueCube();
@Shadow public abstract boolean isCollidable();
@Shadow public abstract int getMobilityFlag();
@Shadow public abstract boolean isBlockNormalCube();
@Shadow public abstract boolean isVisuallyOpaque();
@Shadow public abstract int getRenderType();
@Shadow public abstract String getLocalizedName();
@Shadow public abstract boolean canProvidePower();
@Shadow public abstract boolean getEnableStats();
@Shadow public abstract boolean requiresUpdates();
@Shadow public abstract boolean hasComparatorInputOverride();
@Shadow public abstract int quantityDropped(Random random);
@Shadow public abstract int tickRate(net.minecraft.world.World worldIn);
@Shadow public abstract int getComparatorInputOverride(net.minecraft.world.World worldIn, BlockPos pos);
@Shadow public abstract float getExplosionResistance(net.minecraft.entity.Entity exploder);
@Shadow public abstract boolean isReplaceable(net.minecraft.world.World worldIn, BlockPos pos);
@Shadow public abstract float getBlockHardness(net.minecraft.world.World worldIn, BlockPos pos);
@Shadow public abstract double getBlockBoundsMinX();
@Shadow public abstract double getBlockBoundsMaxX();
@Shadow public abstract double getBlockBoundsMinY();
@Shadow public abstract double getBlockBoundsMaxY();
@Shadow public abstract double getBlockBoundsMinZ();
@Shadow public abstract double getBlockBoundsMaxZ();
/**
* @author jamierocks - 26th February 2017
* @reason Fire BlockDropXpHook
*/
@Overwrite
protected void dropXpOnBlockBreak(net.minecraft.world.World worldIn, BlockPos pos, int amount) {
if (!worldIn.isRemote) {
// Neptune: start
final Block block = worldIn.getBlockState(pos).getBlock(); // TODO: test
final BlockDropXpHook hook = (BlockDropXpHook) new BlockDropXpHook((net.canarymod.api.world.blocks.Block) block, amount).call();
if (hook.isCanceled()) return;
amount = hook.getXp();
// Neptune: end
while (amount > 0) {
int i = EntityXPOrb.getXPSplit(amount);
amount -= i;
worldIn.spawnEntityInWorld(new EntityXPOrb(worldIn, pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, i));
}
}
}
@Intrinsic
public boolean block$isFullBlock() {
return this.isFullBlock();
}
@Intrinsic
public int block$getLightOpacity() {
return this.getLightOpacity();
}
@Intrinsic
public int block$getLightValue() {
return this.getLightValue();
}
@Intrinsic
public boolean block$getUseNeighborBrightness() {
return this.getUseNeighborBrightness();
}
@Override
public BlockMaterial getMaterial() {
return (BlockMaterial) this.blockMaterial;
}
@Override
public MapColor getMapColor(net.canarymod.api.world.blocks.Block block) {
return null;
}
@Override
public boolean isSolidFullCube() {
return this.isBlockNormalCube();
}
@Intrinsic
public boolean block$isNormalCube() {
return this.isNormalCube();
}
@Intrinsic
public boolean block$isVisuallyOpaque() {
return this.isVisuallyOpaque();
}
@Intrinsic
public boolean block$isFullCube() {
return this.isFullCube();
}
@Override
public boolean isPassable(net.canarymod.api.world.blocks.Block block, Position pos) {
return false;
}
@Intrinsic
public int block$getRenderType() {
return this.getRenderType();
}
@Override
public boolean isReplaceable(World worldIn, Position pos) {
return this.isReplaceable((net.minecraft.world.World) worldIn, PositionConverter.of(pos));
}
@Override
public float getBlockHardness(World worldIn, Position pos) {
return this.getBlockHardness((net.minecraft.world.World) worldIn, PositionConverter.of(pos));
}
@Override
public boolean ticksRandomly() {
return this.needsRandomTick;
}
@Intrinsic
public boolean block$hasTileEntity() {
return this.hasTileEntity();
}
@Intrinsic
public boolean block$isOpaqueCube() {
return this.isOpaqueCube();
}
@Intrinsic
public boolean block$isCollidable() {
return this.isCollidable();
}
@Override
public int tickRate(World worldIn) {
return this.tickRate((net.minecraft.world.World) worldIn);
}
@Intrinsic
public int block$quantityDropped(Random random) {
return this.quantityDropped(random);
}
@Override
public int damageDropped(net.canarymod.api.world.blocks.Block block) {
return 0;
}
@Override
public float getExplosionResistance(Entity exploder) {
return this.getExplosionResistance((net.minecraft.entity.Entity) exploder);
}
@Intrinsic
public double block$getBlockBoundsMinX() {
return this.getBlockBoundsMinX();
}
@Intrinsic
public double block$getBlockBoundsMaxX() {
return this.getBlockBoundsMaxX();
}
@Intrinsic
public double block$getBlockBoundsMinY() {
return this.getBlockBoundsMinY();
}
@Intrinsic
public double block$getBlockBoundsMaxY() {
return this.getBlockBoundsMaxY();
}
@Intrinsic
public double block$getBlockBoundsMinZ() {
return this.getBlockBoundsMinZ();
}
@Intrinsic
public double block$getBlockBoundsMaxZ() {
return this.getBlockBoundsMaxZ();
}
@Intrinsic
public boolean block$canProvidePower() {
return this.canProvidePower();
}
@Intrinsic
public String block$getLocalizedName() {
return this.getLocalizedName();
}
@Intrinsic
public boolean block$getEnableStats() {
return this.getEnableStats();
}
@Intrinsic
public int block$getMobilityFlag() {
return this.getMobilityFlag();
}
@Intrinsic
public boolean block$requiresUpdates() {
return this.requiresUpdates();
}
@Intrinsic
public boolean block$hasComparatorInputOverride() {
return this.hasComparatorInputOverride();
}
@Override
public int getComparatorInputOverride(World worldIn, Position pos) {
return this.getComparatorInputOverride((net.minecraft.world.World) worldIn, PositionConverter.of(pos));
}
@Override
public Timing getTimingsHandler() {
if (this.timing == null) {
this.timing = NeptuneTimings.getBlockTiming((net.minecraft.block.Block)(Object) this);
}
return this.timing;
}
}