Added power requirements to Teleport Staff, Added Crystal Flux Cap, more

This commit is contained in:
Michael Hillcox 2020-11-29 14:03:55 +00:00
parent 8b525252a5
commit 0a036ee1ef
No known key found for this signature in database
GPG key ID: 971C5B254742488F
10 changed files with 249 additions and 39 deletions

View file

@ -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

View file

@ -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.",

View file

@ -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<IEnergyStorage> capability = LazyOptional.of(() -> new CrystalFluxStorage(stack, energy));
public CrystalFluxProvider(ItemStack stack, int energy) {
this.stack = stack;
this.energy = energy;
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
return cap == CapabilityEnergy.ENERGY ? capability.cast() : LazyOptional.empty();
}
}

View file

@ -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;
}
}

View file

@ -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<Integer, Boolean, String> PRETTY = (value, alt) ->
alt ? NumberFormat.getIntegerInstance().format(value) : Help.compressedValue(value);
private final Supplier<Integer> 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<Integer> 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<ITextComponent> 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<ItemStack> 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);
}
}

View file

@ -0,0 +1,6 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package de.ellpeck.actuallyadditions.common.items;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View file

@ -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
}
}

View file

@ -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));
}
}

View file

@ -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 };
}
}

View file

@ -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