diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 024ff8e05..a77846121 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -116,7 +116,7 @@ e2c81adfe240117fa0ce2e3dfcfd04f4e1034153 assets/actuallyadditions/blockstates/wh 3670535838b4c26d01afe7ee4807c53a6cbaba12 assets/actuallyadditions/blockstates/white_wall_block.json 78e89628e3c6e891f2994b2a1794672f69826516 assets/actuallyadditions/blockstates/wood_casing_block.json 207adf3d139369e983100a6002f6f77d36d40916 assets/actuallyadditions/blockstates/xp_solidifier_block.json -55b66cc71e99edafb64079276e79d9a4806ce168 assets/actuallyadditions/lang/en_us.json +232fcdd6be180accae0f5e5abd68700e70c514c7 assets/actuallyadditions/lang/en_us.json 8ce3f2af3288773fb581a3668c2cb90b64c9ee2f assets/actuallyadditions/models/block/advanced_item_laser_relay_block.json de74eda6290d47ef2b26961693e537d7b8795a06 assets/actuallyadditions/models/block/atomic_reconstructor_block.json 16a76926a07fc8fa10e4a3949d15ad2ca6920bb8 assets/actuallyadditions/models/block/battery_box_block.json diff --git a/src/generated/resources/assets/actuallyadditions/lang/en_us.json b/src/generated/resources/assets/actuallyadditions/lang/en_us.json index 803193a10..49dccadf3 100644 --- a/src/generated/resources/assets/actuallyadditions/lang/en_us.json +++ b/src/generated/resources/assets/actuallyadditions/lang/en_us.json @@ -1,4 +1,5 @@ { + "actuallyadditions.storage.crystal-flux": "%s/%s Crystal Flux", "actuallyadditions.tooltip.booklet.manual.one": "Or \"Booklet\", if you will", "actuallyadditions.tooltip.booklet.manual.three": "Use while holding to open.", "actuallyadditions.tooltip.booklet.manual.two": "This book guides you through all of the feature Actually Additions has to over.", diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/capability/CrystalFluxProvider.java b/src/main/java/de/ellpeck/actuallyadditions/common/capability/CrystalFluxProvider.java new file mode 100644 index 000000000..8e50edefe --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/common/capability/CrystalFluxProvider.java @@ -0,0 +1,29 @@ +package de.ellpeck.actuallyadditions.common.capability; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.energy.IEnergyStorage; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class CrystalFluxProvider implements ICapabilityProvider { + private ItemStack stack; + private int energy; + private LazyOptional capability = LazyOptional.of(() -> new CrystalFluxStorage(stack, energy)); + + public CrystalFluxProvider(ItemStack stack, int energy) { + this.stack = stack; + this.energy = energy; + } + + @Nonnull + @Override + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { + return cap == CapabilityEnergy.ENERGY ? capability.cast() : LazyOptional.empty(); + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/capability/CrystalFluxStorage.java b/src/main/java/de/ellpeck/actuallyadditions/common/capability/CrystalFluxStorage.java new file mode 100644 index 000000000..7bb27849b --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/common/capability/CrystalFluxStorage.java @@ -0,0 +1,48 @@ +package de.ellpeck.actuallyadditions.common.capability; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.energy.EnergyStorage; + +import java.util.Objects; + +/** + * Main Capability for Item Energry storage otherwise referenced as Crystal Flux + */ +public class CrystalFluxStorage extends EnergyStorage { + public static final String NBT_TAG = "crystal-flux"; + private final ItemStack stack; + + public CrystalFluxStorage(ItemStack stack, int capacity) { + super(capacity, Integer.MAX_VALUE, Integer.MAX_VALUE); + + this.stack = stack; + + // hasTag doesn't let the IDE know that the getTag is now safe to use. Instead we're wrapping + // it up in a requireNonNull to stop IDE bitching + this.energy = stack.hasTag() && Objects.requireNonNull(stack.getTag()).contains(NBT_TAG) + ? stack.getTag().getInt(NBT_TAG) + : 0; + } + + @Override + public int extractEnergy(int maxExtract, boolean simulate) { + int extracted = super.extractEnergy(maxExtract, simulate); + + if (extracted > 0 && !simulate) { + stack.getOrCreateTag().putInt(NBT_TAG, getEnergyStored()); + } + + return extracted; + } + + @Override + public int receiveEnergy(int maxReceive, boolean simulate) { + int received = super.receiveEnergy(maxReceive, simulate); + + if (received > 0 && !simulate) { + stack.getOrCreateTag().putInt(NBT_TAG, getEnergyStored()); + } + + return received; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/items/CrystalFluxItem.java b/src/main/java/de/ellpeck/actuallyadditions/common/items/CrystalFluxItem.java new file mode 100644 index 000000000..64bd013f1 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/common/items/CrystalFluxItem.java @@ -0,0 +1,114 @@ +package de.ellpeck.actuallyadditions.common.items; + +import de.ellpeck.actuallyadditions.common.capability.CrystalFluxProvider; +import de.ellpeck.actuallyadditions.common.capability.CrystalFluxStorage; +import de.ellpeck.actuallyadditions.common.utilities.Help; +import de.ellpeck.actuallyadditions.common.utilities.VisualHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.energy.IEnergyStorage; + +import javax.annotation.Nullable; +import java.text.NumberFormat; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Supplier; + +public abstract class CrystalFluxItem extends ActuallyItem { + // Handles modifying an int to a string of either alt ? 100,000 : 100K + private static final BiFunction PRETTY = (value, alt) -> + alt ? NumberFormat.getIntegerInstance().format(value) : Help.compressedValue(value); + + private final Supplier maxFlux; + + /** + * We use a supplier here to allow for config values to be passed around so we are able to + * call the config values get method so we're always getting the most up-to-date value. + * + * @param maxFlux max energy this item can store + */ + public CrystalFluxItem(Properties properties, Supplier maxFlux) { + super(properties); + + this.maxFlux = maxFlux; + } + + @Nullable + @Override + public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundNBT nbt) { + return new CrystalFluxProvider(stack, maxFlux.get()); + } + + @OnlyIn(Dist.CLIENT) + @Override + public void addInformation(ItemStack stack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) { + super.addInformation(stack, worldIn, tooltip, flagIn); + + stack.getCapability(CapabilityEnergy.ENERGY).ifPresent(energy -> + tooltip.add(this.getEnergyPretty(energy, Screen.hasShiftDown()).mergeStyle(TextFormatting.GRAY))); + } + + @Override + public void fillItemGroup(ItemGroup group, NonNullList items) { + super.fillItemGroup(group, items); + if (!isInGroup(group)) { + return; + } + + ItemStack chargedItem = new ItemStack(this); + chargedItem.getOrCreateTag().putInt(CrystalFluxStorage.NBT_TAG, this.maxFlux.get()); + items.add(chargedItem); + } + + /** + * Returns a tidy string either as 100,000 or 100K for example. + * + * @param energy energy capability + * @return either a pretty value or a pretty compressed value + */ + private TranslationTextComponent getEnergyPretty(IEnergyStorage energy, boolean showCompressed) { + return Help.trans( + "storage.crystal-flux", + PRETTY.apply(energy.getEnergyStored(), showCompressed), + PRETTY.apply(energy.getMaxEnergyStored(), showCompressed) + ); + } + + @Override + public boolean showDurabilityBar(ItemStack stack) { + return true; + } + + @Override + public int getRGBDurabilityForDisplay(ItemStack stack) { + ClientWorld clientWorld = Minecraft.getInstance().world; + if (clientWorld != null) { + float[] color = VisualHelper.getWheelColor(clientWorld.getGameTime() % 256); + return MathHelper.rgb(color[0] / 255F, color[1] / 255F, color[2] / 255F); + } + + return super.getRGBDurabilityForDisplay(stack); + } + + @Override + public double getDurabilityForDisplay(ItemStack stack) { + return stack.getCapability(CapabilityEnergy.ENERGY) + .map(energy -> 1D - (energy.getEnergyStored() / (double) energy.getMaxEnergyStored())) + .orElse(0D); + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/items/package-info.java b/src/main/java/de/ellpeck/actuallyadditions/common/items/package-info.java new file mode 100644 index 000000000..42a391d86 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/common/items/package-info.java @@ -0,0 +1,6 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package de.ellpeck.actuallyadditions.common.items; + +import mcp.MethodsReturnNonnullByDefault; +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/items/useables/TeleportStaffItem.java b/src/main/java/de/ellpeck/actuallyadditions/common/items/useables/TeleportStaffItem.java index 112c135eb..e06f0d8d9 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/common/items/useables/TeleportStaffItem.java +++ b/src/main/java/de/ellpeck/actuallyadditions/common/items/useables/TeleportStaffItem.java @@ -1,7 +1,6 @@ package de.ellpeck.actuallyadditions.common.items.useables; -import de.ellpeck.actuallyadditions.common.items.ActuallyItem; -import de.ellpeck.actuallyadditions.common.items.IUseItem; +import de.ellpeck.actuallyadditions.common.items.CrystalFluxItem; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.item.ItemStack; @@ -11,10 +10,13 @@ import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.vector.Vector3f; import net.minecraft.world.World; +import net.minecraftforge.energy.CapabilityEnergy; + +public class TeleportStaffItem extends CrystalFluxItem { + private static final int BASE_COST_PER_USE = 200; -public class TeleportStaffItem extends ActuallyItem implements IUseItem { public TeleportStaffItem() { - super(baseProps()); + super(baseProps(), () -> 250000); } @Override @@ -24,56 +26,35 @@ public class TeleportStaffItem extends ActuallyItem implements IUseItem { return super.onItemRightClick(world, player, hand); } - RayTraceResult traceResult = player.pick(100, 1.0f, false); - if (traceResult.getType() != RayTraceResult.Type.BLOCK || !this.canUse(stack)) { + if (traceResult.getType() != RayTraceResult.Type.BLOCK) { return super.onItemRightClick(world, player, hand); } - BlockPos pos = ((BlockRayTraceResult) traceResult).getPos(); - BlockPos toPos = pos.offset(((BlockRayTraceResult) traceResult).getFace(), 1); + BlockRayTraceResult blockTrace = ((BlockRayTraceResult) traceResult); + BlockPos toPos = blockTrace.getPos().offset(blockTrace.getFace(), 1); Vector3f centerOfHit = new Vector3f(toPos.getX(), toPos.getY(), toPos.getZ()); - centerOfHit.add(.5f, (((BlockRayTraceResult) traceResult).getFace().getAxis() == Direction.Axis.Y ? .5f : 0), .5f); + centerOfHit.add(.5f, (blockTrace.getFace().getAxis() == Direction.Axis.Y ? .5f : 0), .5f); - // power cost for thing - // int use = baseUse + (int) (baseUse * pos.hitVec.distanceTo(new Vec3d(player.posX, player.posY + (player.getEyeHeight() - player.getDefaultEyeHeight()), player.posZ))); + int energyCost = BASE_COST_PER_USE + (int) (BASE_COST_PER_USE * player.getDistanceSq(toPos.getX(), toPos.getY(), toPos.getZ())); + boolean canUse = stack.getCapability(CapabilityEnergy.ENERGY).map(e -> e.getEnergyStored() >= energyCost).orElse(false); + + if (!canUse) { + return super.onItemRightClick(world, player, hand); + } if (!player.isCreative()) { player.getCooldownTracker().setCooldown(this, 50); + stack.getCapability(CapabilityEnergy.ENERGY).ifPresent(energy -> + energy.extractEnergy(energyCost, false)); } player.dismount(); - player.playSound(SoundEvents.ENTITY_ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1.0f, 1.0f); + world.playSound(null, toPos.getX(), toPos.getY(), toPos.getZ(), SoundEvents.ENTITY_ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1.0f, 1.0f); ((ServerPlayerEntity) player).connection.setPlayerLocation(centerOfHit.getX(), centerOfHit.getY(), centerOfHit.getZ(), player.rotationYaw, player.rotationPitch); -// -// if (pos != null && (pos.typeOfHit == RayTraceResult.Type.BLOCK || player.rotationPitch >= -5)) { -// int side = pos.sideHit.ordinal(); -// if (side != -1) { -// double x = pos.hitVec.x - (side == 4 ? 0.5 : 0) + (side == 5 ? 0.5 : 0); -// double y = pos.hitVec.y - (side == 0 ? 2.0 : 0) + (side == 1 ? 0.5 : 0); -// double z = pos.hitVec.z - (side == 2 ? 0.5 : 0) + (side == 3 ? 0.5 : 0); -// int baseUse = 200; -// int use = baseUse + (int) (baseUse * pos.hitVec.distanceTo(new Vec3d(player.posX, player.posY + (player.getEyeHeight() - player.getDefaultEyeHeight()), player.posZ))); -// if (this.getEnergyStored(stack) >= use) { -// ((EntityPlayerMP) player).connection.setPlayerLocation(x, y, z, player.rotationYaw, player.rotationPitch); -// player.dismountRidingEntity(); -// world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.PLAYERS, 1.0F, 1.0F); -// if (!player.capabilities.isCreativeMode) { -// this.extractEnergyInternal(stack, use, false); -// player.getCooldownTracker().setCooldown(this, 50); -// } -// return ActionResult.newResult(EnumActionResult.SUCCESS, stack); -// } -// } -// } player.swingArm(hand); return ActionResult.resultSuccess(stack); } - - @Override - public boolean canUse(ItemStack stack) { - return true; // todo: add energy logic - } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/utilities/Help.java b/src/main/java/de/ellpeck/actuallyadditions/common/utilities/Help.java index 6b62e2227..fa4ab4eee 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/common/utilities/Help.java +++ b/src/main/java/de/ellpeck/actuallyadditions/common/utilities/Help.java @@ -16,4 +16,20 @@ public class Help { public static TranslationTextComponent trans(String key, Object... args) { return new TranslationTextComponent(String.format("%s.%s", ActuallyAdditions.MOD_ID, key), args); } + + /** + * Pretty values, turns numbers like 100000000 into 100M + * + * @param value value you need prettified + * @return a pretty string + */ + public static String compressedValue(int value) { + if (value < 1000) + return String.valueOf(value); + + int exp = (int) (Math.log(value) / Math.log(1000)); + return String.format("%,d%c", + (int) (value / Math.pow(1000, exp)), + "KMGTPE_____".charAt(exp - 1)); + } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/utilities/VisualHelper.java b/src/main/java/de/ellpeck/actuallyadditions/common/utilities/VisualHelper.java new file mode 100644 index 000000000..c63eb90df --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/common/utilities/VisualHelper.java @@ -0,0 +1,12 @@ +package de.ellpeck.actuallyadditions.common.utilities; + +public class VisualHelper { + /** + * Stolen from Ell's original code, because lazy. What does it do? Something with wheels? (It's an hsb selector) + */ + public static float[] getWheelColor(float pos) { + if (pos < 85.0f) { return new float[] { pos * 3.0F, 255.0f - pos * 3.0f, 0.0f }; } + if (pos < 170.0f) { return new float[] { 255.0f - (pos -= 85.0f) * 3.0f, 0.0f, pos * 3.0f }; } + return new float[] { 0.0f, (pos -= 170.0f) * 3.0f, 255.0f - pos * 3.0f }; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/data/GeneratorLanguage.java b/src/main/java/de/ellpeck/actuallyadditions/data/GeneratorLanguage.java index 559a45e28..8bbde9ba5 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/data/GeneratorLanguage.java +++ b/src/main/java/de/ellpeck/actuallyadditions/data/GeneratorLanguage.java @@ -316,6 +316,9 @@ public class GeneratorLanguage extends LanguageProvider { addPrefixed("tooltip.booklet.manual.two", "This book guides you through all of the feature Actually Additions has to over."); addPrefixed("tooltip.booklet.manual.three", "Use while holding to open."); + // Storage + addPrefixed("storage.crystal-flux", "%s/%s Crystal Flux"); + add("itemGroup.actuallyadditions", "Actually Additions"); // Mics