Add Annihilation Plane enchantment support, deprecate Identity (#510)

This commit is contained in:
zeng-git
2024-11-29 13:06:55 +08:00
committed by GitHub
parent 925cf092be
commit 7f2318f89c
15 changed files with 365 additions and 78 deletions
@@ -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
@@ -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);
+52 -1
View File
@@ -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);
+15 -4
View File
@@ -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);
}
}
+8 -2
View File
@@ -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
@@ -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"
}
]
}