Add Annihilation Plane enchantment support, deprecate Identity (#510)
This commit is contained in:
@@ -209,7 +209,11 @@ public enum GuiText {
|
|||||||
|
|
||||||
// Used in Crafting Toasts
|
// Used in Crafting Toasts
|
||||||
CraftingToastDone,
|
CraftingToastDone,
|
||||||
CraftingToastCancelled;
|
CraftingToastCancelled,
|
||||||
|
|
||||||
|
CanBeEnchanted,
|
||||||
|
IncreasedEnergyUseFromEnchants,
|
||||||
|
Deprecated;
|
||||||
|
|
||||||
private final String root;
|
private final String root;
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ public enum WailaText {
|
|||||||
Showing,
|
Showing,
|
||||||
|
|
||||||
Contains,
|
Contains,
|
||||||
Channels;
|
Channels,
|
||||||
|
EnchantedWith,
|
||||||
|
IdentityDeprecated;
|
||||||
|
|
||||||
private final String root;
|
private final String root;
|
||||||
|
|
||||||
|
|||||||
@@ -69,8 +69,9 @@ public final class PartWailaDataProvider implements IWailaDataProvider {
|
|||||||
final IPartWailaDataProvider powerState = new PowerStateWailaDataProvider();
|
final IPartWailaDataProvider powerState = new PowerStateWailaDataProvider();
|
||||||
final IPartWailaDataProvider p2pState = new P2PStateWailaDataProvider();
|
final IPartWailaDataProvider p2pState = new P2PStateWailaDataProvider();
|
||||||
final IPartWailaDataProvider partStack = new PartStackWailaDataProvider();
|
final IPartWailaDataProvider partStack = new PartStackWailaDataProvider();
|
||||||
|
final IPartWailaDataProvider annihilationPlane = new AnnihilationPlaneDataProvider();
|
||||||
|
|
||||||
this.providers = Lists.newArrayList(channel, storageMonitor, powerState, partStack, p2pState);
|
this.providers = Lists.newArrayList(channel, storageMonitor, powerState, partStack, p2pState, annihilationPlane);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
package appeng.integration.modules.waila.part;
|
||||||
|
|
||||||
|
import appeng.api.parts.IPart;
|
||||||
|
import appeng.core.localization.WailaText;
|
||||||
|
import appeng.parts.automation.PartAnnihilationPlane;
|
||||||
|
import appeng.parts.automation.PartIdentityAnnihilationPlane;
|
||||||
|
import appeng.util.EnchantmentUtil;
|
||||||
|
import mcp.mobius.waila.api.IWailaConfigHandler;
|
||||||
|
import mcp.mobius.waila.api.IWailaDataAccessor;
|
||||||
|
import net.minecraft.enchantment.Enchantment;
|
||||||
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AnnihilationPlaneDataProvider extends BasePartWailaDataProvider {
|
||||||
|
@Override
|
||||||
|
public List<String> getWailaBody(IPart part, List<String> currentToolTip, IWailaDataAccessor accessor, IWailaConfigHandler config) {
|
||||||
|
if (part instanceof PartIdentityAnnihilationPlane) {
|
||||||
|
currentToolTip.add(WailaText.IdentityDeprecated.getLocal());
|
||||||
|
} else if (part instanceof PartAnnihilationPlane plane) {
|
||||||
|
NBTTagCompound nbtData = accessor.getNBTData();
|
||||||
|
Map<Enchantment, Integer> enchantments = EnchantmentUtil.getEnchantments(nbtData);
|
||||||
|
if (!enchantments.isEmpty()) {
|
||||||
|
currentToolTip.add(WailaText.EnchantedWith.getLocal());
|
||||||
|
for (var enchantment : enchantments.keySet()) {
|
||||||
|
currentToolTip.add(enchantment.getTranslatedName(enchantments.get(enchantment)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentToolTip;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTTagCompound getNBTData(EntityPlayerMP player, IPart part, TileEntity te, NBTTagCompound tag, World world, BlockPos pos) {
|
||||||
|
if (part instanceof PartAnnihilationPlane plane) {
|
||||||
|
plane.writeEnchantments(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,11 +57,6 @@ public abstract class AEBaseItem extends Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBookEnchantable(final ItemStack itemstack1, final ItemStack itemstack2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
protected void addCheckedInformation(final ItemStack stack, final World world, final List<String> lines, final ITooltipFlag advancedTooltips) {
|
protected void addCheckedInformation(final ItemStack stack, final World world, final List<String> lines, final ITooltipFlag advancedTooltips) {
|
||||||
super.addInformation(stack, world, lines, advancedTooltips);
|
super.addInformation(stack, world, lines, advancedTooltips);
|
||||||
|
|||||||
@@ -30,8 +30,12 @@ import appeng.core.localization.GuiText;
|
|||||||
import appeng.items.AEBaseItem;
|
import appeng.items.AEBaseItem;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import net.minecraft.client.util.ITooltipFlag;
|
||||||
import net.minecraft.creativetab.CreativeTabs;
|
import net.minecraft.creativetab.CreativeTabs;
|
||||||
|
import net.minecraft.enchantment.Enchantment;
|
||||||
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.init.Enchantments;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.EnumActionResult;
|
import net.minecraft.util.EnumActionResult;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
@@ -133,10 +137,20 @@ public final class ItemPart extends AEBaseItem implements IPartItem, IItemGroup
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EnumActionResult onItemUse(final EntityPlayer player, final World w, final BlockPos pos, final EnumHand hand, final EnumFacing side, final float hitX, final float hitY, final float hitZ) {
|
public EnumActionResult onItemUse(final EntityPlayer player, final World w, final BlockPos pos, final EnumHand hand, final EnumFacing side, final float hitX, final float hitY, final float hitZ) {
|
||||||
if (this.getTypeByStack(player.getHeldItem(hand)) == PartType.INVALID_TYPE) {
|
ItemStack heldItem = player.getHeldItem(hand);
|
||||||
|
PartType typeByStack = getTypeByStack(heldItem);
|
||||||
|
if (typeByStack == PartType.INVALID_TYPE) {
|
||||||
return EnumActionResult.FAIL;
|
return EnumActionResult.FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player.isSneaking() && typeByStack == PartType.IDENTITY_ANNIHILATION_PLANE) {
|
||||||
|
ItemStack newPlane = new ItemStack(this, heldItem.getCount(), PartType.ANNIHILATION_PLANE.getBaseDamage());
|
||||||
|
newPlane.addEnchantment(Enchantments.SILK_TOUCH,1);
|
||||||
|
|
||||||
|
player.setHeldItem(hand, newPlane);
|
||||||
|
return EnumActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
return AEApi.instance().partHelper().placeBus(player.getHeldItem(hand), pos, side, player, hand, w);
|
return AEApi.instance().partHelper().placeBus(player.getHeldItem(hand), pos, side, player, hand, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,6 +192,43 @@ public final class ItemPart extends AEBaseItem implements IPartItem, IItemGroup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addCheckedInformation(ItemStack stack, World world, List<String> lines, ITooltipFlag advancedTooltips) {
|
||||||
|
if (getTypeByStack(stack) == PartType.ANNIHILATION_PLANE) {
|
||||||
|
var enchantments = EnchantmentHelper.getEnchantments(stack);
|
||||||
|
if (enchantments.isEmpty()) {
|
||||||
|
lines.add(GuiText.CanBeEnchanted.getLocal());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lines.add(GuiText.IncreasedEnergyUseFromEnchants.getLocal());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getTypeByStack(stack) == PartType.IDENTITY_ANNIHILATION_PLANE) {
|
||||||
|
lines.add(GuiText.Deprecated.getLocal());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemEnchantability() {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnchantable(ItemStack stack) {
|
||||||
|
return getTypeByStack(stack) == PartType.ANNIHILATION_PLANE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
|
||||||
|
return enchantment == Enchantments.UNBREAKING || enchantment == Enchantments.FORTUNE || enchantment == Enchantments.SILK_TOUCH || enchantment == Enchantments.EFFICIENCY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBookEnchantable(ItemStack stack, ItemStack book) {
|
||||||
|
return getTypeByStack(stack) == PartType.ANNIHILATION_PLANE;
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public PartType getTypeByStack(final ItemStack is) {
|
public PartType getTypeByStack(final ItemStack is) {
|
||||||
Preconditions.checkNotNull(is);
|
Preconditions.checkNotNull(is);
|
||||||
|
|||||||
@@ -359,8 +359,19 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
|
|||||||
* @param from source of settings
|
* @param from source of settings
|
||||||
* @return compound of source
|
* @return compound of source
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
protected NBTTagCompound downloadSettings(final SettingsFrom from) {
|
protected NBTTagCompound downloadSettings(final SettingsFrom from) {
|
||||||
final NBTTagCompound output = new NBTTagCompound();
|
NBTTagCompound compound = downloadSettings(from, new NBTTagCompound());
|
||||||
|
return compound.isEmpty() ? null : compound;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exports settings for attaching it to a memory card or item stack.
|
||||||
|
*
|
||||||
|
* @param from The purpose to export settings for.
|
||||||
|
* @param output The tag to write the settings to.
|
||||||
|
*/
|
||||||
|
protected NBTTagCompound downloadSettings(final SettingsFrom from, final NBTTagCompound output) {
|
||||||
|
|
||||||
final IConfigManager cm = this.getConfigManager();
|
final IConfigManager cm = this.getConfigManager();
|
||||||
if (cm != null) {
|
if (cm != null) {
|
||||||
@@ -392,7 +403,7 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output.isEmpty() ? null : output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean useStandardMemoryCard() {
|
public boolean useStandardMemoryCard() {
|
||||||
@@ -419,8 +430,8 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
|
|||||||
final String name = is.getTranslationKey();
|
final String name = is.getTranslationKey();
|
||||||
|
|
||||||
if (player.isSneaking()) {
|
if (player.isSneaking()) {
|
||||||
final NBTTagCompound data = this.downloadSettings(SettingsFrom.MEMORY_CARD);
|
final NBTTagCompound data = this.downloadSettings(SettingsFrom.MEMORY_CARD, new NBTTagCompound());
|
||||||
if (data != null) {
|
if (!data.isEmpty()) {
|
||||||
memoryCard.setMemoryCardContents(memCardIS, name, data);
|
memoryCard.setMemoryCardContents(memCardIS, name, data);
|
||||||
memoryCard.notifyUser(player, MemoryCardMessages.SETTINGS_SAVED);
|
memoryCard.notifyUser(player, MemoryCardMessages.SETTINGS_SAVED);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,25 +48,39 @@ import appeng.items.parts.PartModels;
|
|||||||
import appeng.me.GridAccessException;
|
import appeng.me.GridAccessException;
|
||||||
import appeng.me.helpers.MachineSource;
|
import appeng.me.helpers.MachineSource;
|
||||||
import appeng.parts.PartBasicState;
|
import appeng.parts.PartBasicState;
|
||||||
|
import appeng.util.EnchantmentUtil;
|
||||||
import appeng.util.IWorldCallable;
|
import appeng.util.IWorldCallable;
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
|
import appeng.util.SettingsFrom;
|
||||||
import appeng.util.item.AEItemStack;
|
import appeng.util.item.AEItemStack;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.enchantment.Enchantment;
|
||||||
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.item.EntityItem;
|
import net.minecraft.entity.item.EntityItem;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.init.Enchantments;
|
||||||
|
import net.minecraft.init.Items;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.WorldServer;
|
import net.minecraft.world.WorldServer;
|
||||||
|
import net.minecraftforge.common.util.FakePlayer;
|
||||||
|
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
|
||||||
public class PartAnnihilationPlane extends PartBasicState implements IGridTickable, IWorldCallable<TickRateModulation> {
|
public class PartAnnihilationPlane extends PartBasicState implements IGridTickable, IWorldCallable<TickRateModulation> {
|
||||||
@@ -82,6 +96,12 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
|||||||
private boolean isAccepting = true;
|
private boolean isAccepting = true;
|
||||||
private boolean breaking = false;
|
private boolean breaking = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enchantments found on the plane when it was placed will be used to enchant the fake tool used for picking up
|
||||||
|
* blocks.
|
||||||
|
*/
|
||||||
|
private Map<Enchantment, Integer> enchantments = new LinkedHashMap<>();
|
||||||
|
|
||||||
public PartAnnihilationPlane(final ItemStack is) {
|
public PartAnnihilationPlane(final ItemStack is) {
|
||||||
super(is);
|
super(is);
|
||||||
}
|
}
|
||||||
@@ -92,6 +112,7 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
|||||||
return this.breakBlock(true);
|
return this.breakBlock(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getBoxes(final IPartCollisionHelper bch) {
|
public void getBoxes(final IPartCollisionHelper bch) {
|
||||||
int minX = 1;
|
int minX = 1;
|
||||||
@@ -422,14 +443,38 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected List<ItemStack> obtainBlockDrops(final WorldServer w, final BlockPos pos) {
|
protected List<ItemStack> obtainBlockDrops(final WorldServer w, final BlockPos pos) {
|
||||||
final ItemStack[] out = Platform.getBlockDrops(w, pos);
|
final FakePlayer fakePlayer = FakePlayerFactory.getMinecraft(w);
|
||||||
return Lists.newArrayList(out);
|
final IBlockState state = w.getBlockState(pos);
|
||||||
|
|
||||||
|
if (state.getBlock().canSilkHarvest(w, pos, state, fakePlayer) && enchantments.containsKey(Enchantments.SILK_TOUCH)) {
|
||||||
|
final List<ItemStack> out = new ArrayList<>(1);
|
||||||
|
final Item item = Item.getItemFromBlock(state.getBlock());
|
||||||
|
|
||||||
|
if (item != Items.AIR) {
|
||||||
|
int meta = 0;
|
||||||
|
if (item.getHasSubtypes()) {
|
||||||
|
meta = state.getBlock().getMetaFromState(state);
|
||||||
|
}
|
||||||
|
final ItemStack itemstack = new ItemStack(item, 1, meta);
|
||||||
|
out.add(itemstack);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
} else {
|
||||||
|
if (enchantments.containsKey(Enchantments.FORTUNE)) {
|
||||||
|
final ItemStack[] out = Platform.getBlockDrops(w, pos, enchantments.get(Enchantments.FORTUNE));
|
||||||
|
return Lists.newArrayList(out);
|
||||||
|
} else {
|
||||||
|
ItemStack[] blockDrops = Platform.getBlockDrops(w, pos);
|
||||||
|
return Lists.newArrayList(blockDrops);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if this plane can handle the block at the specific coordinates.
|
* Checks if this plane can handle the block at the specific coordinates.
|
||||||
*/
|
*/
|
||||||
protected float calculateEnergyUsage(final WorldServer w, final BlockPos pos, final List<ItemStack> items) {
|
protected float calculateEnergyUsage(final WorldServer w, final BlockPos pos, final List<ItemStack> items) {
|
||||||
|
boolean useEnergy = true;
|
||||||
final IBlockState state = w.getBlockState(pos);
|
final IBlockState state = w.getBlockState(pos);
|
||||||
final float hardness = state.getBlockHardness(w, pos);
|
final float hardness = state.getBlockHardness(w, pos);
|
||||||
|
|
||||||
@@ -438,7 +483,25 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
|||||||
requiredEnergy += is.getCount();
|
requiredEnergy += is.getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
return requiredEnergy;
|
if (!enchantments.isEmpty()) {
|
||||||
|
var efficiencyFactor = 1f;
|
||||||
|
var efficiencyLevel = 0;
|
||||||
|
if (enchantments.containsKey(Enchantments.EFFICIENCY)) {
|
||||||
|
// Reduce total energy usage incurred by other enchantments by 15% per Efficiency level.
|
||||||
|
efficiencyLevel = enchantments.get(Enchantments.EFFICIENCY);
|
||||||
|
efficiencyFactor *= Math.pow(0.85, efficiencyLevel);
|
||||||
|
}
|
||||||
|
if (enchantments.containsKey(Enchantments.UNBREAKING)) {
|
||||||
|
// Give plane only a (100 / (level + 1))% chance to use energy.
|
||||||
|
// This is similar to vanilla Unbreaking behaviour for tools.
|
||||||
|
int randomNumber = ThreadLocalRandom.current().nextInt(enchantments.get(Enchantments.UNBREAKING) + 1);
|
||||||
|
useEnergy = randomNumber == 0;
|
||||||
|
}
|
||||||
|
var levelSum = enchantments.values().stream().reduce(0, Integer::sum) - efficiencyLevel;
|
||||||
|
requiredEnergy *= 8 * levelSum * efficiencyFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return useEnergy ? requiredEnergy : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -447,10 +510,10 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
|||||||
* It also sets isAccepting to false, if the item can not be stored.
|
* It also sets isAccepting to false, if the item can not be stored.
|
||||||
*
|
*
|
||||||
* @param itemStacks an array of {@link ItemStack} to test
|
* @param itemStacks an array of {@link ItemStack} to test
|
||||||
* @return true, if the network can store at least a single item of all drops or no drops are reported
|
* @return true, if the network can store all drops or no drops are reported
|
||||||
*/
|
*/
|
||||||
private boolean canStoreItemStacks(final List<ItemStack> itemStacks) {
|
private boolean canStoreItemStacks(final List<ItemStack> itemStacks) {
|
||||||
boolean canStore = itemStacks.isEmpty();
|
boolean canStore = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final IStorageGrid storage = this.getProxy().getStorage();
|
final IStorageGrid storage = this.getProxy().getStorage();
|
||||||
@@ -459,8 +522,8 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
|||||||
final IAEItemStack itemToTest = AEItemStack.fromItemStack(itemStack);
|
final IAEItemStack itemToTest = AEItemStack.fromItemStack(itemStack);
|
||||||
final IAEItemStack overflow = storage.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class))
|
final IAEItemStack overflow = storage.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class))
|
||||||
.injectItems(itemToTest, Actionable.SIMULATE, this.mySrc);
|
.injectItems(itemToTest, Actionable.SIMULATE, this.mySrc);
|
||||||
if (overflow == null || itemToTest.getStackSize() > overflow.getStackSize()) {
|
if (overflow != null) {
|
||||||
canStore = true;
|
canStore = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (final GridAccessException e) {
|
} catch (final GridAccessException e) {
|
||||||
@@ -472,15 +535,20 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void breakBlockAndStoreItems(final WorldServer w, final BlockPos pos) {
|
private void breakBlockAndStoreItems(final WorldServer w, final BlockPos pos) {
|
||||||
w.destroyBlock(pos, true);
|
final List<ItemStack> items = this.obtainBlockDrops(w, pos);
|
||||||
|
|
||||||
final AxisAlignedBB box = new AxisAlignedBB(pos).grow(0.2);
|
try {
|
||||||
for (final Object ei : w.getEntitiesWithinAABB(EntityItem.class, box)) {
|
final IStorageGrid storage = this.getProxy().getStorage();
|
||||||
if (ei instanceof EntityItem) {
|
for (ItemStack itemStack : items) {
|
||||||
final EntityItem entityItem = (EntityItem) ei;
|
final IAEItemStack aeItemStack = AEItemStack.fromItemStack(itemStack);
|
||||||
this.storeEntityItem(entityItem);
|
storage.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class))
|
||||||
|
.injectItems(aeItemStack, Actionable.MODULATE, this.mySrc);
|
||||||
}
|
}
|
||||||
|
} catch (GridAccessException e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.destroyBlock(pos, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refresh() {
|
private void refresh() {
|
||||||
@@ -498,4 +566,50 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
|||||||
return MODELS.getModel(this.getConnections(), this.isPowered(), this.isActive());
|
return MODELS.getModel(this.getConnections(), this.isPowered(), this.isActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NBTTagCompound downloadSettings(SettingsFrom from, NBTTagCompound output) {
|
||||||
|
super.downloadSettings(from, output);
|
||||||
|
// Save enchants only when the actual plane is dismantled
|
||||||
|
if (from == SettingsFrom.DISMANTLE_ITEM) {
|
||||||
|
writeEnchantments(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uploadSettings(SettingsFrom from, NBTTagCompound output, EntityPlayer player) {
|
||||||
|
super.uploadSettings(from, output, player);
|
||||||
|
// Import enchants only when the plan is placed, not from memory cards
|
||||||
|
if (from == SettingsFrom.DISMANTLE_ITEM) {
|
||||||
|
readEnchantments(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readEnchantments(NBTTagCompound data) {
|
||||||
|
enchantments = EnchantmentUtil.getEnchantments(data);
|
||||||
|
EnchantmentHelper.setEnchantments(enchantments, getItemStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeEnchantments(NBTTagCompound data) {
|
||||||
|
EnchantmentUtil.setEnchantments(data, enchantments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFromNBT(NBTTagCompound data) {
|
||||||
|
super.readFromNBT(data);
|
||||||
|
readEnchantments(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToNBT(NBTTagCompound data) {
|
||||||
|
super.writeToNBT(data);
|
||||||
|
writeEnchantments(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addToWorld() {
|
||||||
|
super.addToWorld();
|
||||||
|
enchantments = EnchantmentHelper.getEnchantments(getItemStack());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,17 +19,20 @@
|
|||||||
package appeng.parts.automation;
|
package appeng.parts.automation;
|
||||||
|
|
||||||
|
|
||||||
import appeng.api.parts.IPart;
|
import appeng.api.AEApi;
|
||||||
import appeng.api.parts.IPartHost;
|
import appeng.api.parts.IPartHost;
|
||||||
import appeng.api.parts.IPartModel;
|
import appeng.api.parts.IPartModel;
|
||||||
import appeng.api.util.AEPartLocation;
|
|
||||||
import appeng.items.parts.PartModels;
|
import appeng.items.parts.PartModels;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.init.Enchantments;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.WorldServer;
|
import net.minecraft.world.WorldServer;
|
||||||
import net.minecraftforge.common.util.FakePlayer;
|
import net.minecraftforge.common.util.FakePlayer;
|
||||||
import net.minecraftforge.common.util.FakePlayerFactory;
|
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||||
@@ -53,15 +56,6 @@ public class PartIdentityAnnihilationPlane extends PartAnnihilationPlane {
|
|||||||
super(is);
|
super(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isAnnihilationPlane(final TileEntity blockTileEntity, final AEPartLocation side) {
|
|
||||||
if (blockTileEntity instanceof IPartHost) {
|
|
||||||
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
|
|
||||||
return p != null && p.getClass() == this.getClass();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float calculateEnergyUsage(final WorldServer w, final BlockPos pos, final List<ItemStack> items) {
|
protected float calculateEnergyUsage(final WorldServer w, final BlockPos pos, final List<ItemStack> items) {
|
||||||
final float requiredEnergy = super.calculateEnergyUsage(w, pos, items);
|
final float requiredEnergy = super.calculateEnergyUsage(w, pos, items);
|
||||||
@@ -92,6 +86,20 @@ public class PartIdentityAnnihilationPlane extends PartAnnihilationPlane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPartShiftActivate(EntityPlayer player, EnumHand hand, Vec3d pos) {
|
||||||
|
TileEntity tile = getTile();
|
||||||
|
if (tile instanceof IPartHost host) {
|
||||||
|
host.removePart(getSide(), false);
|
||||||
|
ItemStack itemStack = AEApi.instance().definitions().parts().annihilationPlane().maybeStack(1).orElse(ItemStack.EMPTY);
|
||||||
|
itemStack.addEnchantment(Enchantments.SILK_TOUCH, 1);
|
||||||
|
host.addPart(itemStack, getSide(), player, hand);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPartModel getStaticModels() {
|
public IPartModel getStaticModels() {
|
||||||
return MODELS.getModel(this.getConnections(), this.isPowered(), this.isActive());
|
return MODELS.getModel(this.getConnections(), this.isPowered(), this.isActive());
|
||||||
|
|||||||
@@ -299,8 +299,8 @@ public class PartInterface extends PartBasicState implements IGridTickable, ISto
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBTTagCompound downloadSettings(SettingsFrom from) {
|
public NBTTagCompound downloadSettings(SettingsFrom from, NBTTagCompound compound) {
|
||||||
NBTTagCompound output = super.downloadSettings(from);
|
NBTTagCompound output = super.downloadSettings(from, compound);
|
||||||
if (from == SettingsFrom.MEMORY_CARD) {
|
if (from == SettingsFrom.MEMORY_CARD) {
|
||||||
final IItemHandler inv = this.getInventoryByName("patterns");
|
final IItemHandler inv = this.getInventoryByName("patterns");
|
||||||
if (inv instanceof AppEngInternalInventory) {
|
if (inv instanceof AppEngInternalInventory) {
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package appeng.util;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import net.minecraft.enchantment.Enchantment;
|
||||||
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.nbt.NBTTagList;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public final class EnchantmentUtil {
|
||||||
|
private EnchantmentUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Enchantment, Integer> deserializeEnchantments(NBTTagList tagList) {
|
||||||
|
Map<Enchantment, Integer> map = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
|
for(int i = 0; i < tagList.tagCount(); ++i) {
|
||||||
|
NBTTagCompound compoundtag = tagList.getCompoundTagAt(i);
|
||||||
|
Enchantment enchantmentByID = Enchantment.getEnchantmentByID(getEnchantmentId(compoundtag));
|
||||||
|
if (enchantmentByID != null) {
|
||||||
|
map.put(enchantmentByID, getEnchantmentLevel(compoundtag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getEnchantmentId(NBTTagCompound tagCompound) {
|
||||||
|
return tagCompound.getInteger("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getEnchantmentLevel(NBTTagCompound tagCompound) {
|
||||||
|
return Math.max(0, Math.min(255, tagCompound.getInteger("lvl")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NBTTagCompound storeEnchantment(int id, int level) {
|
||||||
|
NBTTagCompound compoundtag = new NBTTagCompound();
|
||||||
|
compoundtag.setShort("id",(short) id);
|
||||||
|
compoundtag.setShort("lvl", ((short) level));
|
||||||
|
return compoundtag;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Read enchants written using {@link #setEnchantments} or added to an itemstack's tag using normal enchanting.
|
||||||
|
*/
|
||||||
|
public static Map<Enchantment, Integer> getEnchantments(NBTTagCompound data) {
|
||||||
|
if (data.hasKey("Enchantments",9)) {
|
||||||
|
var list = data.getTagList("Enchantments",10);
|
||||||
|
var enchants = deserializeEnchantments(list);
|
||||||
|
if (!enchants.isEmpty()) {
|
||||||
|
return enchants;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a list of enchantments to the given tag the same way as
|
||||||
|
* {@link EnchantmentHelper#setEnchantments(Map, ItemStack)} would.
|
||||||
|
*/
|
||||||
|
public static void setEnchantments(NBTTagCompound tag, Map<Enchantment, Integer> enchantments) {
|
||||||
|
NBTTagList enchantList = new NBTTagList();
|
||||||
|
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||||
|
Enchantment enchantment = entry.getKey();
|
||||||
|
if (enchantment == null)
|
||||||
|
continue;
|
||||||
|
int level = entry.getValue();
|
||||||
|
enchantList.appendTag(storeEnchantment(Enchantment.getEnchantmentID(enchantment), level));
|
||||||
|
}
|
||||||
|
tag.setTag("Enchantments", enchantList);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -430,15 +430,21 @@ public class Platform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static ItemStack[] getBlockDrops(final World w, final BlockPos pos) {
|
public static ItemStack[] getBlockDrops(final World w, final BlockPos pos) {
|
||||||
|
return getBlockDrops(w, pos,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack[] getBlockDrops(final World w, final BlockPos pos, int fortune) {
|
||||||
List<ItemStack> out = new ArrayList<>();
|
List<ItemStack> out = new ArrayList<>();
|
||||||
final IBlockState state = w.getBlockState(pos);
|
final IBlockState state = w.getBlockState(pos);
|
||||||
|
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
out = state.getBlock().getDrops(w, pos, state, 0);
|
out = state.getBlock().getDrops(w, pos, state, fortune);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out == null) {
|
if (out == null || out.isEmpty()) {
|
||||||
return new ItemStack[0];
|
return new ItemStack[0];
|
||||||
}
|
}
|
||||||
return out.toArray(new ItemStack[out.size()]);
|
return out.toArray(new ItemStack[out.size()]);
|
||||||
|
|||||||
@@ -258,6 +258,9 @@ gui.appliedenergistics2.CraftingToastDone=Crafting Done!
|
|||||||
gui.appliedenergistics2.CraftingToastCancelled=Crafting Cancelled!
|
gui.appliedenergistics2.CraftingToastCancelled=Crafting Cancelled!
|
||||||
gui.appliedenergistics2.Sticky=Sticky
|
gui.appliedenergistics2.Sticky=Sticky
|
||||||
gui.appliedenergistics2.FluidTerminal=Fluid Terminal
|
gui.appliedenergistics2.FluidTerminal=Fluid Terminal
|
||||||
|
gui.appliedenergistics2.CanBeEnchanted=Can be enchanted
|
||||||
|
gui.appliedenergistics2.IncreasedEnergyUseFromEnchants=Enchants increase energy use
|
||||||
|
gui.appliedenergistics2.Deprecated=Deprecated
|
||||||
|
|
||||||
// GUI Tooltips
|
// GUI Tooltips
|
||||||
gui.tooltips.appliedenergistics2.Stash=Store Items
|
gui.tooltips.appliedenergistics2.Stash=Store Items
|
||||||
@@ -441,6 +444,8 @@ waila.appliedenergistics2.p2p_input_many_outputs=Linked (Input Side) - §4%d§r
|
|||||||
waila.appliedenergistics2.p2p_output_one_input=Linked (Output Side) - 1 Input
|
waila.appliedenergistics2.p2p_output_one_input=Linked (Output Side) - 1 Input
|
||||||
waila.appliedenergistics2.p2p_output_many_inputs=Linked (Output Side) - §2%d§r Inputs
|
waila.appliedenergistics2.p2p_output_many_inputs=Linked (Output Side) - §2%d§r Inputs
|
||||||
waila.appliedenergistics2.P2POutput=Linked (Output Side)
|
waila.appliedenergistics2.P2POutput=Linked (Output Side)
|
||||||
|
waila.appliedenergistics2.EnchantedWith=Enchanted with:
|
||||||
|
waila.appliedenergistics2.IdentityDeprecated=Deprecated. Convert with SHIFT + RIGHT-CLICK
|
||||||
|
|
||||||
// TheOneProbe
|
// TheOneProbe
|
||||||
theoneprobe.appliedenergistics2.crafting=Crafting: §2%1$s§r
|
theoneprobe.appliedenergistics2.crafting=Crafting: §2%1$s§r
|
||||||
|
|||||||
@@ -258,6 +258,9 @@ gui.appliedenergistics2.CraftingToastDone=合成已完成!
|
|||||||
gui.appliedenergistics2.CraftingToastCancelled=合成已取消!
|
gui.appliedenergistics2.CraftingToastCancelled=合成已取消!
|
||||||
gui.appliedenergistics2.Sticky=粘滞
|
gui.appliedenergistics2.Sticky=粘滞
|
||||||
gui.appliedenergistics2.FluidTerminal=流体终端
|
gui.appliedenergistics2.FluidTerminal=流体终端
|
||||||
|
gui.appliedenergistics2.CanBeEnchanted=可被附魔
|
||||||
|
gui.appliedenergistics2.IncreasedEnergyUseFromEnchants=附魔会增加能耗
|
||||||
|
gui.appliedenergistics2.Deprecated=已弃用
|
||||||
|
|
||||||
// GUI Tooltips
|
// GUI Tooltips
|
||||||
gui.tooltips.appliedenergistics2.Stash=存储物品
|
gui.tooltips.appliedenergistics2.Stash=存储物品
|
||||||
@@ -442,6 +445,8 @@ waila.appliedenergistics2.p2p_input_many_outputs=已连接(输入端)- §4%d
|
|||||||
waila.appliedenergistics2.p2p_output_one_input=已连接(输出端)- 1输入
|
waila.appliedenergistics2.p2p_output_one_input=已连接(输出端)- 1输入
|
||||||
waila.appliedenergistics2.p2p_output_many_inputs=已连接(输出端)- §2%d§r输入
|
waila.appliedenergistics2.p2p_output_many_inputs=已连接(输出端)- §2%d§r输入
|
||||||
waila.appliedenergistics2.P2POutput=已连接(输出端)
|
waila.appliedenergistics2.P2POutput=已连接(输出端)
|
||||||
|
waila.appliedenergistics2.EnchantedWith=已附魔:
|
||||||
|
waila.appliedenergistics2.IdentityDeprecated=已弃用。 使用SHIFT + 右键来转换
|
||||||
|
|
||||||
// TheOneProbe
|
// TheOneProbe
|
||||||
theoneprobe.appliedenergistics2.crafting=合成中:§2%1$s§r
|
theoneprobe.appliedenergistics2.crafting=合成中:§2%1$s§r
|
||||||
|
|||||||
-36
@@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
"conditions": [
|
|
||||||
{
|
|
||||||
"type": "forge:and",
|
|
||||||
"values": [
|
|
||||||
{
|
|
||||||
"type": "appliedenergistics2:part_exists",
|
|
||||||
"part": "part.identity_annihilation_plane"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "appliedenergistics2:part_exists",
|
|
||||||
"part": "part.annihilation_plane"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "appliedenergistics2:material_exists",
|
|
||||||
"material": "material.fluix_pearl"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"result": {
|
|
||||||
"type": "appliedenergistics2:part",
|
|
||||||
"part": "part.identity_annihilation_plane"
|
|
||||||
},
|
|
||||||
"type": "appliedenergistics2:part_shapeless",
|
|
||||||
"ingredients": [
|
|
||||||
{
|
|
||||||
"type": "appliedenergistics2:part",
|
|
||||||
"part": "part.annihilation_plane"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "appliedenergistics2:part",
|
|
||||||
"part": "material.fluix_pearl"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user