Add Annihilation Plane enchantment support, deprecate Identity (#510)
This commit is contained in:
@@ -209,7 +209,11 @@ public enum GuiText {
|
||||
|
||||
// Used in Crafting Toasts
|
||||
CraftingToastDone,
|
||||
CraftingToastCancelled;
|
||||
CraftingToastCancelled,
|
||||
|
||||
CanBeEnchanted,
|
||||
IncreasedEnergyUseFromEnchants,
|
||||
Deprecated;
|
||||
|
||||
private final String root;
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ public enum WailaText {
|
||||
Showing,
|
||||
|
||||
Contains,
|
||||
Channels;
|
||||
Channels,
|
||||
EnchantedWith,
|
||||
IdentityDeprecated;
|
||||
|
||||
private final String root;
|
||||
|
||||
|
||||
@@ -69,8 +69,9 @@ public final class PartWailaDataProvider implements IWailaDataProvider {
|
||||
final IPartWailaDataProvider powerState = new PowerStateWailaDataProvider();
|
||||
final IPartWailaDataProvider p2pState = new P2PStateWailaDataProvider();
|
||||
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
|
||||
|
||||
+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)
|
||||
protected void addCheckedInformation(final ItemStack stack, final World world, final List<String> lines, final ITooltipFlag advancedTooltips) {
|
||||
super.addInformation(stack, world, lines, advancedTooltips);
|
||||
|
||||
@@ -30,8 +30,12 @@ import appeng.core.localization.GuiText;
|
||||
import appeng.items.AEBaseItem;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Enchantments;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
@@ -133,10 +137,20 @@ public final class ItemPart extends AEBaseItem implements IPartItem, IItemGroup
|
||||
|
||||
@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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
public PartType getTypeByStack(final ItemStack is) {
|
||||
Preconditions.checkNotNull(is);
|
||||
|
||||
@@ -359,8 +359,19 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
|
||||
* @param from source of settings
|
||||
* @return compound of source
|
||||
*/
|
||||
@Deprecated
|
||||
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();
|
||||
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() {
|
||||
@@ -419,8 +430,8 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
|
||||
final String name = is.getTranslationKey();
|
||||
|
||||
if (player.isSneaking()) {
|
||||
final NBTTagCompound data = this.downloadSettings(SettingsFrom.MEMORY_CARD);
|
||||
if (data != null) {
|
||||
final NBTTagCompound data = this.downloadSettings(SettingsFrom.MEMORY_CARD, new NBTTagCompound());
|
||||
if (!data.isEmpty()) {
|
||||
memoryCard.setMemoryCardContents(memCardIS, name, data);
|
||||
memoryCard.notifyUser(player, MemoryCardMessages.SETTINGS_SAVED);
|
||||
}
|
||||
|
||||
@@ -48,25 +48,39 @@ import appeng.items.parts.PartModels;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
import appeng.parts.PartBasicState;
|
||||
import appeng.util.EnchantmentUtil;
|
||||
import appeng.util.IWorldCallable;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.SettingsFrom;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.minecraft.block.material.Material;
|
||||
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.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
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.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
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.Map;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
|
||||
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 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) {
|
||||
super(is);
|
||||
}
|
||||
@@ -92,6 +112,7 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
||||
return this.breakBlock(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void getBoxes(final IPartCollisionHelper bch) {
|
||||
int minX = 1;
|
||||
@@ -422,14 +443,38 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
||||
}
|
||||
|
||||
protected List<ItemStack> obtainBlockDrops(final WorldServer w, final BlockPos pos) {
|
||||
final ItemStack[] out = Platform.getBlockDrops(w, pos);
|
||||
return Lists.newArrayList(out);
|
||||
final FakePlayer fakePlayer = FakePlayerFactory.getMinecraft(w);
|
||||
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.
|
||||
*/
|
||||
protected float calculateEnergyUsage(final WorldServer w, final BlockPos pos, final List<ItemStack> items) {
|
||||
boolean useEnergy = true;
|
||||
final IBlockState state = w.getBlockState(pos);
|
||||
final float hardness = state.getBlockHardness(w, pos);
|
||||
|
||||
@@ -438,7 +483,25 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
||||
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.
|
||||
*
|
||||
* @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) {
|
||||
boolean canStore = itemStacks.isEmpty();
|
||||
boolean canStore = true;
|
||||
|
||||
try {
|
||||
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 overflow = storage.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class))
|
||||
.injectItems(itemToTest, Actionable.SIMULATE, this.mySrc);
|
||||
if (overflow == null || itemToTest.getStackSize() > overflow.getStackSize()) {
|
||||
canStore = true;
|
||||
if (overflow != null) {
|
||||
canStore = false;
|
||||
}
|
||||
}
|
||||
} catch (final GridAccessException e) {
|
||||
@@ -472,15 +535,20 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
||||
}
|
||||
|
||||
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);
|
||||
for (final Object ei : w.getEntitiesWithinAABB(EntityItem.class, box)) {
|
||||
if (ei instanceof EntityItem) {
|
||||
final EntityItem entityItem = (EntityItem) ei;
|
||||
this.storeEntityItem(entityItem);
|
||||
try {
|
||||
final IStorageGrid storage = this.getProxy().getStorage();
|
||||
for (ItemStack itemStack : items) {
|
||||
final IAEItemStack aeItemStack = AEItemStack.fromItemStack(itemStack);
|
||||
storage.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class))
|
||||
.injectItems(aeItemStack, Actionable.MODULATE, this.mySrc);
|
||||
}
|
||||
} catch (GridAccessException e) {
|
||||
|
||||
}
|
||||
|
||||
w.destroyBlock(pos, false);
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
@@ -498,4 +566,50 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
|
||||
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;
|
||||
|
||||
|
||||
import appeng.api.parts.IPart;
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.parts.IPartHost;
|
||||
import appeng.api.parts.IPartModel;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.items.parts.PartModels;
|
||||
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.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||
@@ -53,15 +56,6 @@ public class PartIdentityAnnihilationPlane extends PartAnnihilationPlane {
|
||||
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
|
||||
protected float calculateEnergyUsage(final WorldServer w, final BlockPos pos, final List<ItemStack> 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
|
||||
public IPartModel getStaticModels() {
|
||||
return MODELS.getModel(this.getConnections(), this.isPowered(), this.isActive());
|
||||
|
||||
@@ -299,8 +299,8 @@ public class PartInterface extends PartBasicState implements IGridTickable, ISto
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound downloadSettings(SettingsFrom from) {
|
||||
NBTTagCompound output = super.downloadSettings(from);
|
||||
public NBTTagCompound downloadSettings(SettingsFrom from, NBTTagCompound compound) {
|
||||
NBTTagCompound output = super.downloadSettings(from, compound);
|
||||
if (from == SettingsFrom.MEMORY_CARD) {
|
||||
final IItemHandler inv = this.getInventoryByName("patterns");
|
||||
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) {
|
||||
return getBlockDrops(w, pos,0);
|
||||
}
|
||||
|
||||
public static ItemStack[] getBlockDrops(final World w, final BlockPos pos, int fortune) {
|
||||
List<ItemStack> out = new ArrayList<>();
|
||||
final IBlockState state = w.getBlockState(pos);
|
||||
|
||||
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 out.toArray(new ItemStack[out.size()]);
|
||||
|
||||
@@ -258,6 +258,9 @@ gui.appliedenergistics2.CraftingToastDone=Crafting Done!
|
||||
gui.appliedenergistics2.CraftingToastCancelled=Crafting Cancelled!
|
||||
gui.appliedenergistics2.Sticky=Sticky
|
||||
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.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_many_inputs=Linked (Output Side) - §2%d§r Inputs
|
||||
waila.appliedenergistics2.P2POutput=Linked (Output Side)
|
||||
waila.appliedenergistics2.EnchantedWith=Enchanted with:
|
||||
waila.appliedenergistics2.IdentityDeprecated=Deprecated. Convert with SHIFT + RIGHT-CLICK
|
||||
|
||||
// TheOneProbe
|
||||
theoneprobe.appliedenergistics2.crafting=Crafting: §2%1$s§r
|
||||
|
||||
@@ -258,6 +258,9 @@ gui.appliedenergistics2.CraftingToastDone=合成已完成!
|
||||
gui.appliedenergistics2.CraftingToastCancelled=合成已取消!
|
||||
gui.appliedenergistics2.Sticky=粘滞
|
||||
gui.appliedenergistics2.FluidTerminal=流体终端
|
||||
gui.appliedenergistics2.CanBeEnchanted=可被附魔
|
||||
gui.appliedenergistics2.IncreasedEnergyUseFromEnchants=附魔会增加能耗
|
||||
gui.appliedenergistics2.Deprecated=已弃用
|
||||
|
||||
// GUI Tooltips
|
||||
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_many_inputs=已连接(输出端)- §2%d§r输入
|
||||
waila.appliedenergistics2.P2POutput=已连接(输出端)
|
||||
waila.appliedenergistics2.EnchantedWith=已附魔:
|
||||
waila.appliedenergistics2.IdentityDeprecated=已弃用。 使用SHIFT + 右键来转换
|
||||
|
||||
// TheOneProbe
|
||||
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