initial commit for shared version repo of Batteries mod - currently supports 1.21.11 and 1.21.1 of NeoForge.

This commit is contained in:
trunksbomb
2026-03-22 14:18:55 -04:00
commit 8d86c883ae
247 changed files with 18315 additions and 0 deletions

8
common/README.md Normal file
View File

@@ -0,0 +1,8 @@
# Common Sources
Place shared Java and resource files here as you begin supporting more than one NeoForge target.
- Java: `common/src/main/java`
- Resources: `common/src/main/resources`
The version-specific modules include these directories directly in their main source sets.

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,124 @@
package com.trunksbomb.batteries;
import java.util.List;
import net.neoforged.neoforge.common.ModConfigSpec;
public final class BatteriesConfig {
private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder();
public static final ModConfigSpec.IntValue MACHINE_CHARGE_RANGE = BUILDER
.comment("Maximum block range for battery charging of nearby machines.")
.defineInRange("machineChargeRange", 5, 1, 32);
public static final ModConfigSpec.BooleanValue ENABLE_POWERED_WEAPONS = BUILDER
.comment("Whether battery-powered weapons such as swords, bows, and shields can be crafted and shown in the Batteries tab.")
.define("enablePoweredWeapons", true);
public static final ModConfigSpec.BooleanValue ENABLE_POWERED_TOOLS = BUILDER
.comment("Whether battery-powered tools such as pickaxes, axes, shovels, and hoes can be crafted and shown in the Batteries tab.")
.define("enablePoweredTools", true);
public static final ModConfigSpec.BooleanValue ENABLE_POWERED_ARMOR = BUILDER
.comment("Whether battery-powered armor can be crafted and shown in the Batteries tab.")
.define("enablePoweredArmor", true);
public static final ModConfigSpec.BooleanValue CHARGER_GENERATES_CREATIVE_POWER = BUILDER
.comment("If true, chargers generate their own power and fill inserted batteries without an external energy source.")
.define("chargerGeneratesCreativePower", false);
public static final ModConfigSpec.IntValue GENERATOR_ENERGY_PER_TICK = BUILDER
.comment("Energy produced per tick by the coal generator while it is actively burning fuel.")
.defineInRange("generatorEnergyPerTick", 1, 1, Integer.MAX_VALUE);
public static final ModConfigSpec.IntValue PICKAXE_ENERGY_PER_BLOCK = BUILDER
.comment("Energy used by the battery-powered pickaxe for each block broken.")
.defineInRange("pickaxeEnergyPerBlock", 100, 0, Integer.MAX_VALUE);
public static final ModConfigSpec.IntValue AXE_ENERGY_PER_BLOCK = BUILDER
.comment("Energy used by battery-powered axes for each block broken.")
.defineInRange("axeEnergyPerBlock", 100, 0, Integer.MAX_VALUE);
public static final ModConfigSpec.IntValue SHOVEL_ENERGY_PER_BLOCK = BUILDER
.comment("Energy used by battery-powered shovels for each block broken.")
.defineInRange("shovelEnergyPerBlock", 100, 0, Integer.MAX_VALUE);
public static final ModConfigSpec.IntValue HOE_ENERGY_PER_BLOCK = BUILDER
.comment("Energy used by battery-powered hoes for each block broken.")
.defineInRange("hoeEnergyPerBlock", 100, 0, Integer.MAX_VALUE);
public static final ModConfigSpec.IntValue SWORD_ENERGY_PER_HIT = BUILDER
.comment("Energy used by battery-powered swords for each successful hit.")
.defineInRange("swordEnergyPerHit", 100, 0, Integer.MAX_VALUE);
public static final ModConfigSpec.IntValue ARMOR_ENERGY_PER_DAMAGE = BUILDER
.comment("Energy used by powered armor for each point of incoming damage absorbed as durability wear.")
.defineInRange("armorEnergyPerDamage", 500, 0, Integer.MAX_VALUE);
public static final ModConfigSpec.IntValue SHIELD_ENERGY_PER_BLOCK = BUILDER
.comment("Energy used by the powered shield for each blocked hit or projectile.")
.defineInRange("shieldEnergyPerBlock", 1_000, 0, Integer.MAX_VALUE);
public static final ModConfigSpec.IntValue BOW_FULLY_CHARGED_SHOT_COST = BUILDER
.comment("Energy used by the powered bow for a fully charged shot.")
.defineInRange("bowFullyChargedShotCost", 1_000, 0, Integer.MAX_VALUE);
public static final ModConfigSpec.DoubleValue ENCHANTMENT_ENERGY_MULTIPLIER = BUILDER
.comment("Additional power multiplier applied per enchantment at full strength. A level-scaled fraction of this value is added for each enchantment. Default 0.5 means each max-level enchant adds half the base cost.")
.defineInRange("enchantmentEnergyMultiplier", 0.5D, 0.0D, 100.0D);
public static final ModConfigSpec.ConfigValue<List<? extends String>> ENCHANTMENT_ENERGY_MULTIPLIER_OVERRIDES = BUILDER
.comment("Optional per-enchantment overrides in the form namespace:id=multiplier, for example minecraft:efficiency=0.5")
.defineListAllowEmpty("enchantmentEnergyMultiplierOverrides", List.of(), value -> value instanceof String);
public static final ModConfigSpec SPEC = BUILDER.build();
private BatteriesConfig() {
}
public static int machineChargeRange() {
return MACHINE_CHARGE_RANGE.get();
}
public static boolean chargerGeneratesCreativePower() {
return CHARGER_GENERATES_CREATIVE_POWER.get();
}
public static int generatorEnergyPerTick() {
return GENERATOR_ENERGY_PER_TICK.get();
}
public static boolean poweredArmorEnabled() {
return ENABLE_POWERED_ARMOR.get();
}
public static boolean poweredToolsEnabled() {
return ENABLE_POWERED_TOOLS.get();
}
public static boolean poweredWeaponsEnabled() {
return ENABLE_POWERED_WEAPONS.get();
}
public static int armorEnergyPerDamage() { return ARMOR_ENERGY_PER_DAMAGE.get(); }
public static int axeEnergyPerBlock() { return AXE_ENERGY_PER_BLOCK.get(); }
public static float bowFullyChargedShotCost() { return BOW_FULLY_CHARGED_SHOT_COST.get(); }
public static int hoeEnergyPerBlock() { return HOE_ENERGY_PER_BLOCK.get(); }
public static int pickaxeEnergyPerBlock() { return PICKAXE_ENERGY_PER_BLOCK.get(); }
public static double poweredItemEnchantmentMultiplier(String enchantmentId) {
for (String entry : ENCHANTMENT_ENERGY_MULTIPLIER_OVERRIDES.get()) {
int separator = entry.indexOf('=');
if (separator <= 0) {
continue;
}
String configuredId = entry.substring(0, separator).trim();
if (!configuredId.equals(enchantmentId)) {
continue;
}
try {
return Double.parseDouble(entry.substring(separator + 1).trim());
} catch (NumberFormatException ignored) {
return ENCHANTMENT_ENERGY_MULTIPLIER.get();
}
}
return ENCHANTMENT_ENERGY_MULTIPLIER.get();
}
public static int shovelEnergyPerBlock() { return SHOVEL_ENERGY_PER_BLOCK.get(); }
public static int shieldEnergyPerBlock() { return SHIELD_ENERGY_PER_BLOCK.get(); }
public static int swordEnergyPerHit() { return SWORD_ENERGY_PER_HIT.get(); }
}

View File

@@ -0,0 +1,49 @@
package com.trunksbomb.batteries;
import com.trunksbomb.batteries.item.PoweredItem;
import com.trunksbomb.batteries.item.PoweredItemEnergy;
import net.minecraft.core.Holder;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.ItemEnchantments;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.AnvilUpdateEvent;
@EventBusSubscriber(modid = Batteries.MODID)
public final class PoweredItemEvents {
private PoweredItemEvents() {
}
@SubscribeEvent
public static void onAnvilUpdate(AnvilUpdateEvent event) {
ItemStack left = event.getLeft();
if (!(left.getItem() instanceof PoweredItem)) {
return;
}
if (addsMending(left, event.getRight()) || addsMending(left, event.getOutput())) {
event.setCanceled(true);
}
}
private static boolean addsMending(ItemStack original, ItemStack updated) {
if (updated.isEmpty()) {
return false;
}
int originalLevel = getMendingLevel(original);
int updatedLevel = getMendingLevel(updated);
return updatedLevel > originalLevel;
}
private static int getMendingLevel(ItemStack stack) {
ItemEnchantments enchantments = stack.getTagEnchantments();
for (Holder<Enchantment> enchantment : enchantments.keySet()) {
if (PoweredItemEnergy.isMendingEnchantment(enchantment)) {
return enchantments.getLevel(enchantment);
}
}
return 0;
}
}

View File

@@ -0,0 +1,48 @@
package com.trunksbomb.batteries.block;
import net.minecraft.core.Direction;
public final class BatteryBlockData {
public static final Direction[] MENU_DIRECTIONS = new Direction[] {
Direction.UP, Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST
};
private BatteryBlockData() {
}
public static Direction directionForIndex(int index) {
return MENU_DIRECTIONS[index];
}
public static int chargeStage(int energy, int capacity) {
if (capacity <= 0 || energy <= 0) {
return 0;
}
float ratio = energy / (float) capacity;
if (ratio >= 0.99F) {
return 4;
}
if (ratio >= 0.74F) {
return 3;
}
if (ratio >= 0.49F) {
return 2;
}
if (ratio >= 0.24F) {
return 1;
}
return 0;
}
public enum SideMode {
INPUT,
OUTPUT,
BOTH,
NONE;
public SideMode next() {
return values()[(this.ordinal() + 1) % values().length];
}
}
}

View File

@@ -0,0 +1,49 @@
package com.trunksbomb.batteries.block;
import com.trunksbomb.batteries.item.BatteryItemData.Tier;
import net.minecraft.util.StringRepresentable;
import org.jspecify.annotations.NonNull;
public final class ChargerBlockData {
private ChargerBlockData() {
}
public static boolean canAcceptBattery(boolean enderCharger, Tier tier) {
if (enderCharger) {
return tier == Tier.ENDER;
}
return tier != Tier.ENDER;
}
public enum BatteryState implements StringRepresentable {
NONE("none"),
BASIC("basic"),
ADVANCED("advanced"),
ELITE("elite"),
ULTIMATE("ultimate"),
CREATIVE("creative"),
ENDER("ender");
private final String name;
BatteryState(String name) {
this.name = name;
}
public static BatteryState fromTier(Tier tier) {
return switch (tier) {
case BASIC -> BASIC;
case ADVANCED -> ADVANCED;
case ELITE -> ELITE;
case ULTIMATE -> ULTIMATE;
case CREATIVE -> CREATIVE;
case ENDER -> ENDER;
};
}
@Override
public @NonNull String getSerializedName() {
return this.name;
}
}
}

View File

@@ -0,0 +1,250 @@
package com.trunksbomb.batteries.command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.trunksbomb.batteries.item.BatteryItemData;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.entity.ChestBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import org.jspecify.annotations.Nullable;
public final class BatteryDebugCommands {
private BatteryDebugCommands() {
}
public static <H> void register(CommandDispatcher<CommandSourceStack> dispatcher, EnergyAdapter<H> adapter) {
dispatcher.register(Commands.literal("batteries")
.then(Commands.literal("kit")
.executes(context -> placeKitChest(context.getSource())))
.then(buildAction("charge", Operation.CHARGE, adapter))
.then(buildAction("drain", Operation.DRAIN, adapter)));
}
private static <H> ArgumentBuilder<CommandSourceStack, ?> buildAction(String name, Operation operation, EnergyAdapter<H> adapter) {
LiteralArgumentBuilder<CommandSourceStack> action = Commands.literal(name);
for (Scope scope : Scope.values()) {
action.then(Commands.literal(scope.argumentName)
.executes(context -> execute(context.getSource(), operation, scope, null, adapter))
.then(Commands.argument("amount", IntegerArgumentType.integer(0))
.executes(context -> execute(
context.getSource(),
operation,
scope,
IntegerArgumentType.getInteger(context, "amount"),
adapter))));
}
return action;
}
private static <H> int execute(CommandSourceStack source, Operation operation, Scope scope, @Nullable Integer amount, EnergyAdapter<H> adapter) throws com.mojang.brigadier.exceptions.CommandSyntaxException {
ServerPlayer player = source.getPlayerOrException();
Summary summary = apply(player, operation, scope, amount, adapter);
source.sendSuccess(() -> summary.message(operation, scope, amount), true);
return summary.totalChangedEnergy;
}
private static <H> Summary apply(ServerPlayer player, Operation operation, Scope scope, @Nullable Integer amount, EnergyAdapter<H> adapter) {
Summary summary = new Summary();
for (ItemStack stack : scope.stacks(player)) {
if (stack.isEmpty()) {
continue;
}
H handler = adapter.resolve(stack);
if (handler == null) {
continue;
}
int capacity = Math.max(0, adapter.capacity(handler));
if (capacity <= 0) {
continue;
}
summary.chargeableItems++;
int stored = Math.max(0, Math.min(adapter.stored(handler), capacity));
int changed = switch (operation) {
case CHARGE -> {
int requested = amount == null ? capacity - stored : Math.min(Math.max(0, amount), capacity - stored);
yield requested <= 0 ? 0 : Math.max(0, adapter.charge(handler, requested));
}
case DRAIN -> {
int requested = amount == null ? stored : Math.min(Math.max(0, amount), stored);
yield requested <= 0 ? 0 : Math.max(0, adapter.drain(handler, requested));
}
};
if (changed > 0) {
summary.changedItems++;
summary.totalChangedEnergy += changed;
}
}
return summary;
}
private static int placeKitChest(CommandSourceStack source) throws com.mojang.brigadier.exceptions.CommandSyntaxException {
ServerPlayer player = source.getPlayerOrException();
Direction direction = player.getDirection();
BlockPos chestPos = player.blockPosition().relative(direction);
BlockState chestState = Blocks.CHEST.defaultBlockState()
.setValue(ChestBlock.FACING, direction.getOpposite());
player.level().setBlockAndUpdate(chestPos, chestState);
if (!(player.level().getBlockEntity(chestPos) instanceof ChestBlockEntity chest)) {
source.sendFailure(Component.literal("Couldn't create the kit chest."));
return 0;
}
chest.clearContent();
List<ItemStack> kit = List.of(
new ItemStack(Items.REDSTONE, 64),
new ItemStack(Items.REDSTONE_BLOCK, 64),
new ItemStack(Items.GOLD_INGOT, 64),
new ItemStack(Items.GOLD_BLOCK, 32),
new ItemStack(Items.IRON_INGOT, 64),
new ItemStack(Items.IRON_BLOCK, 16),
new ItemStack(Items.WHITE_CONCRETE, 64),
new ItemStack(Items.OAK_LOG, 64),
new ItemStack(Items.FURNACE, 16),
new ItemStack(Items.DIAMOND, 64),
new ItemStack(Items.DIAMOND_BLOCK, 16),
new ItemStack(Items.END_STONE, 32),
new ItemStack(Items.ENDER_PEARL, 32),
new ItemStack(Items.DIAMOND_PICKAXE),
new ItemStack(Items.DIAMOND_AXE),
new ItemStack(Items.DIAMOND_SHOVEL),
new ItemStack(Items.DIAMOND_HOE),
new ItemStack(Items.DIAMOND_SWORD),
new ItemStack(Items.DIAMOND_HELMET),
new ItemStack(Items.DIAMOND_CHESTPLATE),
new ItemStack(Items.DIAMOND_LEGGINGS),
new ItemStack(Items.DIAMOND_BOOTS),
new ItemStack(Items.SHIELD),
new ItemStack(Items.BOW)
);
for (int i = 0; i < kit.size() && i < chest.getContainerSize(); i++) {
chest.setItem(i, kit.get(i).copy());
}
chest.setChanged();
source.sendSuccess(() -> Component.literal("Placed a Batteries kit chest at "
+ chestPos.getX() + ", " + chestPos.getY() + ", " + chestPos.getZ() + "."), true);
return 1;
}
private enum Operation {
CHARGE("Charged"),
DRAIN("Drained");
private final String pastTense;
Operation(String pastTense) {
this.pastTense = pastTense;
}
}
private enum Scope {
HELD("held") {
@Override
List<ItemStack> stacks(ServerPlayer player) {
List<ItemStack> stacks = new ArrayList<>(2);
stacks.add(player.getMainHandItem());
stacks.add(player.getOffhandItem());
return stacks;
}
},
HOTBAR("hotbar") {
@Override
List<ItemStack> stacks(ServerPlayer player) {
List<ItemStack> stacks = new ArrayList<>(9);
for (int i = 0; i < 9; i++) {
stacks.add(player.getInventory().getItem(i));
}
return stacks;
}
},
INVENTORY("inventory") {
@Override
List<ItemStack> stacks(ServerPlayer player) {
List<ItemStack> stacks = new ArrayList<>(27);
for (int i = 9; i < 36; i++) {
stacks.add(player.getInventory().getItem(i));
}
return stacks;
}
},
ALL("all") {
@Override
List<ItemStack> stacks(ServerPlayer player) {
List<ItemStack> stacks = new ArrayList<>(player.getInventory().getContainerSize());
for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
stacks.add(player.getInventory().getItem(i));
}
return stacks;
}
};
private final String argumentName;
Scope(String argumentName) {
this.argumentName = argumentName;
}
abstract List<ItemStack> stacks(ServerPlayer player);
}
private static final class Summary {
private int chargeableItems;
private int changedItems;
private int totalChangedEnergy;
private Component message(Operation operation, Scope scope, @Nullable Integer amount) {
if (this.chargeableItems == 0) {
return Component.literal("No chargeable items found in " + scope.argumentName + ".");
}
String amountText = amount == null
? (operation == Operation.CHARGE ? "to full" : "to empty")
: "by " + BatteryItemData.formatCompactAmount(amount) + " E";
return Component.literal(operation.pastTense
+ " "
+ this.changedItems
+ " of "
+ this.chargeableItems
+ " chargeable item(s) in "
+ scope.argumentName
+ " "
+ amountText
+ " ("
+ BatteryItemData.formatCompactAmount(this.totalChangedEnergy)
+ " E total).");
}
}
public interface EnergyAdapter<H> {
@Nullable H resolve(ItemStack stack);
int stored(H handler);
int capacity(H handler);
int charge(H handler, int amount);
int drain(H handler, int amount);
}
}

View File

@@ -0,0 +1,97 @@
package com.trunksbomb.batteries.item;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import java.lang.reflect.Method;
import java.util.Optional;
public final class BatteryItemData {
private static final String ENERGY_KEY = "energy";
private BatteryItemData() {
}
public static int getStoredEnergy(ItemStack stack, Tier tier) {
if (tier == Tier.CREATIVE) {
return getEnergyCapacity(tier);
}
CompoundTag tag = stack.getOrDefault(DataComponents.CUSTOM_DATA, net.minecraft.world.item.component.CustomData.EMPTY).copyTag();
return Math.max(0, readInt(tag, ENERGY_KEY));
}
public static void setStoredEnergy(ItemStack stack, int energy) {
net.minecraft.world.item.component.CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> tag.putInt(ENERGY_KEY, Math.max(0, energy)));
}
public static int getEnergyCapacity(Tier tier) {
return switch (tier) {
case BASIC -> 100_000;
case ADVANCED -> 750_000;
case ELITE -> 2_000_000;
case ULTIMATE, ENDER -> 10_000_000;
case CREATIVE -> Integer.MAX_VALUE;
};
}
public static int getMaxTransfer(Tier tier) {
return tier == Tier.CREATIVE ? Integer.MAX_VALUE : EnergyTierHelper.transferRateForCapacity(getEnergyCapacity(tier));
}
public static String formatWithCommas(int amount) {
return String.format("%,d", amount);
}
public static String formatCompactAmount(int amount) {
if (amount < 10_000) {
return formatWithCommas(amount);
}
if (amount < 1_000_000) {
return abbreviateRounded(amount, 1_000, "K");
}
if (amount < 1_000_000_000) {
return abbreviateRounded(amount, 1_000_000, "M");
}
return formatWithCommas(amount);
}
private static String abbreviateRounded(int amount, int divisor, String suffix) {
return Math.round(amount / (float) divisor) + suffix;
}
@SuppressWarnings("unchecked")
private static int readInt(CompoundTag tag, String key) {
try {
Method getIntMethod = CompoundTag.class.getMethod("getInt", String.class);
Object value = getIntMethod.invoke(tag, key);
if (value instanceof Integer intValue) {
return intValue;
}
if (value instanceof Optional<?> optionalValue && optionalValue.orElse(null) instanceof Integer intValue) {
return intValue;
}
} catch (ReflectiveOperationException ignored) {
}
try {
Method getIntOrMethod = CompoundTag.class.getMethod("getIntOr", String.class, int.class);
Object value = getIntOrMethod.invoke(tag, key, 0);
if (value instanceof Integer intValue) {
return intValue;
}
} catch (ReflectiveOperationException ignored) {
}
return 0;
}
public enum Tier {
BASIC,
ADVANCED,
ELITE,
ULTIMATE,
ENDER,
CREATIVE
}
}

View File

@@ -0,0 +1,86 @@
package com.trunksbomb.batteries.item;
import com.trunksbomb.batteries.BatteriesConfig;
import java.util.function.Consumer;
import net.minecraft.core.Holder;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.equipment.ArmorMaterial;
import net.minecraft.world.item.equipment.ArmorType;
import net.minecraft.world.item.enchantment.Enchantment;
import org.jspecify.annotations.Nullable;
public class BatteryPoweredArmorItem extends Item implements PoweredItem {
private final ArmorType armorType;
public BatteryPoweredArmorItem(ArmorMaterial material, ArmorType armorType, Properties properties) {
super(properties.humanoidArmor(material, armorType).stacksTo(1));
this.armorType = armorType;
}
@Override
public boolean isBarVisible(ItemStack stack) {
return this.isEnergyBarVisible(stack);
}
@Override
public int getBarWidth(ItemStack stack) {
return this.getEnergyBarWidth(stack);
}
@Override
public int getBarColor(ItemStack stack) {
return this.getEnergyBarColor(stack);
}
@Override
public void appendHoverText(ItemStack stack, TooltipContext context, net.minecraft.world.item.component.TooltipDisplay tooltipDisplay, Consumer<Component> tooltipAdder, TooltipFlag flag) {
this.addEnergyTooltip(stack, tooltipAdder, flag);
}
@Override
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return this.shouldCauseEnergyReequipAnimation(oldStack, newStack, slotChanged);
}
@Override
public ItemStack getEnchantingBaseStack(ItemStack stack) {
return new ItemStack(switch (this.armorType) {
case HELMET -> Items.DIAMOND_HELMET;
case CHESTPLATE -> Items.DIAMOND_CHESTPLATE;
case LEGGINGS -> Items.DIAMOND_LEGGINGS;
case BOOTS -> Items.DIAMOND_BOOTS;
default -> Items.DIAMOND_CHESTPLATE;
});
}
@Override
public boolean supportsEnchantment(ItemStack stack, Holder<Enchantment> enchantment) {
return this.supportsPoweredEnchantment(stack, enchantment);
}
@Override
public boolean isPrimaryItemFor(ItemStack stack, Holder<Enchantment> enchantment) {
return this.isPrimaryPoweredItemFor(stack, enchantment);
}
@Override
public int getEnchantmentLevel(ItemStack stack, Holder<Enchantment> enchantment) {
return this.getPoweredEnchantmentLevel(stack, enchantment);
}
@Override
public float getXpRepairRatio(ItemStack stack) {
return this.getPoweredXpRepairRatio(stack);
}
@Override
public <T extends LivingEntity> int damageItem(ItemStack stack, int amount, @Nullable T entity, Consumer<Item> onBroken) {
int energyCost = this.getAdjustedEnergyCost(stack, amount * BatteriesConfig.armorEnergyPerDamage());
return PoweredItemEnergy.consumeEnergy(stack, energyCost) ? 0 : amount;
}
}

View File

@@ -0,0 +1,11 @@
package com.trunksbomb.batteries.item;
import com.trunksbomb.batteries.BatteriesConfig;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ToolMaterial;
public class BatteryPoweredAxeItem extends BatteryPoweredMiningToolItem {
public BatteryPoweredAxeItem(Properties properties) {
super(Items.DIAMOND_AXE, properties.axe(ToolMaterial.DIAMOND, 5.0F, -3.0F), BatteriesConfig::axeEnergyPerBlock);
}
}

View File

@@ -0,0 +1,143 @@
package com.trunksbomb.batteries.item;
import com.trunksbomb.batteries.BatteriesConfig;
import java.util.List;
import java.util.function.Consumer;
import net.minecraft.core.Holder;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.stats.Stats;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BowItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.level.Level;
import org.jspecify.annotations.Nullable;
public class BatteryPoweredBowItem extends BowItem implements PoweredItem {
public BatteryPoweredBowItem(Properties properties) {
super(properties.stacksTo(1));
}
@Override
public boolean isBarVisible(ItemStack stack) {
return this.isEnergyBarVisible(stack);
}
@Override
public int getBarWidth(ItemStack stack) {
return this.getEnergyBarWidth(stack);
}
@Override
public int getBarColor(ItemStack stack) {
return this.getEnergyBarColor(stack);
}
@Override
public void appendHoverText(ItemStack stack, TooltipContext context, net.minecraft.world.item.component.TooltipDisplay tooltipDisplay, Consumer<Component> tooltipAdder, TooltipFlag flag) {
this.addEnergyTooltip(stack, tooltipAdder, flag);
}
@Override
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return this.shouldCauseEnergyReequipAnimation(oldStack, newStack, slotChanged);
}
@Override
public ItemStack getEnchantingBaseStack(ItemStack stack) {
return new ItemStack(Items.BOW);
}
@Override
public boolean supportsEnchantment(ItemStack stack, Holder<Enchantment> enchantment) {
return this.supportsPoweredEnchantment(stack, enchantment);
}
@Override
public boolean isPrimaryItemFor(ItemStack stack, Holder<Enchantment> enchantment) {
return this.isPrimaryPoweredItemFor(stack, enchantment);
}
@Override
public int getEnchantmentLevel(ItemStack stack, Holder<Enchantment> enchantment) {
return this.getPoweredEnchantmentLevel(stack, enchantment);
}
@Override
public float getXpRepairRatio(ItemStack stack) {
return this.getPoweredXpRepairRatio(stack);
}
@Override
public InteractionResult use(Level level, Player player, InteractionHand usedHand) {
ItemStack stack = player.getItemInHand(usedHand);
if (!PoweredItemEnergy.hasEnergy(stack, 1)) {
return InteractionResult.FAIL;
}
return super.use(level, player, usedHand);
}
@Override
public boolean releaseUsing(ItemStack stack, Level level, LivingEntity livingEntity, int timeLeft) {
if (!(livingEntity instanceof Player player)) {
return false;
}
ItemStack projectile = player.getProjectile(stack);
if (projectile.isEmpty()) {
return false;
}
int charge = this.getUseDuration(stack, livingEntity) - timeLeft;
charge = net.neoforged.neoforge.event.EventHooks.onArrowLoose(stack, level, player, charge, !projectile.isEmpty());
if (charge < 0) {
return false;
}
float power = BowItem.getPowerForTime(charge);
if (power < 0.1F) {
return false;
}
int baseEnergyCost = Math.max(1, Math.round(BatteriesConfig.bowFullyChargedShotCost() * power));
int energyCost = this.getAdjustedEnergyCost(stack, baseEnergyCost);
if (!PoweredItemEnergy.hasEnergy(stack, energyCost)) {
return false;
}
List<ItemStack> projectiles = draw(stack, projectile, player);
if (level instanceof ServerLevel serverLevel && !projectiles.isEmpty()) {
if (!PoweredItemEnergy.consumeEnergy(stack, energyCost)) {
return false;
}
this.shoot(serverLevel, player, player.getUsedItemHand(), stack, projectiles, power * 3.0F, 1.0F, power == 1.0F, null);
}
level.playSound(
null,
player.getX(),
player.getY(),
player.getZ(),
SoundEvents.ARROW_SHOOT,
SoundSource.PLAYERS,
1.0F,
1.0F / (level.getRandom().nextFloat() * 0.4F + 1.2F) + power * 0.5F
);
player.awardStat(Stats.ITEM_USED.get(this));
return true;
}
@Override
public <T extends LivingEntity> int damageItem(ItemStack stack, int amount, @Nullable T entity, Consumer<Item> onBroken) {
return 0;
}
}

View File

@@ -0,0 +1,11 @@
package com.trunksbomb.batteries.item;
import com.trunksbomb.batteries.BatteriesConfig;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ToolMaterial;
public class BatteryPoweredHoeItem extends BatteryPoweredMiningToolItem {
public BatteryPoweredHoeItem(Properties properties) {
super(Items.DIAMOND_HOE, properties.hoe(ToolMaterial.DIAMOND, -3.0F, 0.0F), BatteriesConfig::hoeEnergyPerBlock);
}
}

View File

@@ -0,0 +1,108 @@
package com.trunksbomb.batteries.item;
import java.util.function.Consumer;
import java.util.function.IntSupplier;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import org.jspecify.annotations.Nullable;
public abstract class BatteryPoweredMiningToolItem extends Item implements PoweredItem {
private final Item enchantingReferenceItem;
private final IntSupplier baseEnergyCostSupplier;
protected BatteryPoweredMiningToolItem(Item enchantingReferenceItem, Properties properties, IntSupplier baseEnergyCostSupplier) {
super(properties.stacksTo(1));
this.enchantingReferenceItem = enchantingReferenceItem;
this.baseEnergyCostSupplier = baseEnergyCostSupplier;
}
@Override
public boolean isBarVisible(ItemStack stack) {
return this.isEnergyBarVisible(stack);
}
@Override
public int getBarWidth(ItemStack stack) {
return this.getEnergyBarWidth(stack);
}
@Override
public int getBarColor(ItemStack stack) {
return this.getEnergyBarColor(stack);
}
@Override
public void appendHoverText(ItemStack stack, TooltipContext context, net.minecraft.world.item.component.TooltipDisplay tooltipDisplay, Consumer<Component> tooltipAdder, TooltipFlag flag) {
this.addEnergyTooltip(stack, tooltipAdder, flag);
}
@Override
public ItemStack getEnchantingBaseStack(ItemStack stack) {
return new ItemStack(this.enchantingReferenceItem);
}
@Override
public boolean supportsEnchantment(ItemStack stack, Holder<Enchantment> enchantment) {
return this.supportsPoweredEnchantment(stack, enchantment);
}
@Override
public boolean isPrimaryItemFor(ItemStack stack, Holder<Enchantment> enchantment) {
return this.isPrimaryPoweredItemFor(stack, enchantment);
}
@Override
public int getEnchantmentLevel(ItemStack stack, Holder<Enchantment> enchantment) {
return this.getPoweredEnchantmentLevel(stack, enchantment);
}
@Override
public float getXpRepairRatio(ItemStack stack) {
return this.getPoweredXpRepairRatio(stack);
}
@Override
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return this.shouldCauseEnergyReequipAnimation(oldStack, newStack, slotChanged);
}
@Override
public boolean shouldCauseBlockBreakReset(ItemStack oldStack, ItemStack newStack) {
return this.shouldCauseEnergyBlockBreakReset(oldStack, newStack);
}
@Override
public float getDestroySpeed(ItemStack stack, BlockState state) {
return PoweredItemEnergy.hasEnergy(stack, this.energyCost(stack)) ? super.getDestroySpeed(stack, state) : 1.0F;
}
@Override
public boolean isCorrectToolForDrops(ItemStack stack, BlockState state) {
return PoweredItemEnergy.hasEnergy(stack, this.energyCost(stack)) && super.isCorrectToolForDrops(stack, state);
}
@Override
public boolean mineBlock(ItemStack stack, Level level, BlockState state, BlockPos pos, LivingEntity miningEntity) {
if (!level.isClientSide() && !state.isAir()) {
PoweredItemEnergy.consumeEnergy(stack, this.energyCost(stack));
}
return true;
}
@Override
public <T extends LivingEntity> int damageItem(ItemStack stack, int amount, @Nullable T entity, Consumer<Item> onBroken) {
return 0;
}
protected int energyCost(ItemStack stack) {
return this.getAdjustedEnergyCost(stack, this.baseEnergyCostSupplier.getAsInt());
}
}

View File

@@ -0,0 +1,11 @@
package com.trunksbomb.batteries.item;
import com.trunksbomb.batteries.BatteriesConfig;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ToolMaterial;
public class BatteryPoweredPickaxeItem extends BatteryPoweredMiningToolItem {
public BatteryPoweredPickaxeItem(Properties properties) {
super(Items.DIAMOND_PICKAXE, properties.pickaxe(ToolMaterial.DIAMOND, 1.0F, -2.8F), BatteriesConfig::pickaxeEnergyPerBlock);
}
}

View File

@@ -0,0 +1,76 @@
package com.trunksbomb.batteries.item;
import com.trunksbomb.batteries.BatteriesConfig;
import java.util.function.Consumer;
import net.minecraft.core.Holder;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ShieldItem;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.enchantment.Enchantment;
import org.jspecify.annotations.Nullable;
public class BatteryPoweredShieldItem extends ShieldItem implements PoweredItem {
public BatteryPoweredShieldItem(Properties properties) {
super(properties.stacksTo(1));
}
@Override
public boolean isBarVisible(ItemStack stack) {
return this.isEnergyBarVisible(stack);
}
@Override
public int getBarWidth(ItemStack stack) {
return this.getEnergyBarWidth(stack);
}
@Override
public int getBarColor(ItemStack stack) {
return this.getEnergyBarColor(stack);
}
@Override
public void appendHoverText(ItemStack stack, TooltipContext context, net.minecraft.world.item.component.TooltipDisplay tooltipDisplay, Consumer<Component> tooltipAdder, TooltipFlag flag) {
this.addEnergyTooltip(stack, tooltipAdder, flag);
}
@Override
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return this.shouldCauseEnergyReequipAnimation(oldStack, newStack, slotChanged);
}
@Override
public ItemStack getEnchantingBaseStack(ItemStack stack) {
return new ItemStack(Items.SHIELD);
}
@Override
public boolean supportsEnchantment(ItemStack stack, Holder<Enchantment> enchantment) {
return this.supportsPoweredEnchantment(stack, enchantment);
}
@Override
public boolean isPrimaryItemFor(ItemStack stack, Holder<Enchantment> enchantment) {
return this.isPrimaryPoweredItemFor(stack, enchantment);
}
@Override
public int getEnchantmentLevel(ItemStack stack, Holder<Enchantment> enchantment) {
return this.getPoweredEnchantmentLevel(stack, enchantment);
}
@Override
public float getXpRepairRatio(ItemStack stack) {
return this.getPoweredXpRepairRatio(stack);
}
@Override
public <T extends LivingEntity> int damageItem(ItemStack stack, int amount, @Nullable T entity, Consumer<Item> onBroken) {
int energyCost = this.getAdjustedEnergyCost(stack, amount * BatteriesConfig.shieldEnergyPerBlock());
return PoweredItemEnergy.consumeEnergy(stack, energyCost) ? 0 : amount;
}
}

View File

@@ -0,0 +1,11 @@
package com.trunksbomb.batteries.item;
import com.trunksbomb.batteries.BatteriesConfig;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ToolMaterial;
public class BatteryPoweredShovelItem extends BatteryPoweredMiningToolItem {
public BatteryPoweredShovelItem(Properties properties) {
super(Items.DIAMOND_SHOVEL, properties.shovel(ToolMaterial.DIAMOND, 1.5F, -3.0F), BatteriesConfig::shovelEnergyPerBlock);
}
}

View File

@@ -0,0 +1,93 @@
package com.trunksbomb.batteries.item;
import com.trunksbomb.batteries.BatteriesConfig;
import java.util.function.Consumer;
import net.minecraft.core.Holder;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ToolMaterial;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.enchantment.Enchantment;
import org.jspecify.annotations.Nullable;
public class BatteryPoweredSwordItem extends Item implements PoweredItem {
public BatteryPoweredSwordItem(Properties properties) {
super(properties.sword(ToolMaterial.DIAMOND, 3.0F, -2.4F).stacksTo(1));
}
@Override
public boolean isBarVisible(ItemStack stack) {
return this.isEnergyBarVisible(stack);
}
@Override
public int getBarWidth(ItemStack stack) {
return this.getEnergyBarWidth(stack);
}
@Override
public int getBarColor(ItemStack stack) {
return this.getEnergyBarColor(stack);
}
@Override
public void appendHoverText(ItemStack stack, TooltipContext context, net.minecraft.world.item.component.TooltipDisplay tooltipDisplay, Consumer<Component> tooltipAdder, TooltipFlag flag) {
this.addEnergyTooltip(stack, tooltipAdder, flag);
}
@Override
public ItemStack getEnchantingBaseStack(ItemStack stack) {
return new ItemStack(Items.DIAMOND_SWORD);
}
@Override
public boolean supportsEnchantment(ItemStack stack, Holder<Enchantment> enchantment) {
return this.supportsPoweredEnchantment(stack, enchantment);
}
@Override
public boolean isPrimaryItemFor(ItemStack stack, Holder<Enchantment> enchantment) {
return this.isPrimaryPoweredItemFor(stack, enchantment);
}
@Override
public int getEnchantmentLevel(ItemStack stack, Holder<Enchantment> enchantment) {
return this.getPoweredEnchantmentLevel(stack, enchantment);
}
@Override
public float getXpRepairRatio(ItemStack stack) {
return this.getPoweredXpRepairRatio(stack);
}
@Override
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return this.shouldCauseEnergyReequipAnimation(oldStack, newStack, slotChanged);
}
@Override
public boolean onLeftClickEntity(ItemStack stack, Player player, Entity entity) {
return !PoweredItemEnergy.hasEnergy(stack, this.energyCost(stack));
}
@Override
public void hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
if (!attacker.level().isClientSide()) {
PoweredItemEnergy.consumeEnergy(stack, this.energyCost(stack));
}
}
@Override
public <T extends LivingEntity> int damageItem(ItemStack stack, int amount, @Nullable T entity, Consumer<Item> onBroken) {
return 0;
}
private int energyCost(ItemStack stack) {
return this.getAdjustedEnergyCost(stack, BatteriesConfig.swordEnergyPerHit());
}
}

View File

@@ -0,0 +1,22 @@
package com.trunksbomb.batteries.item;
public final class EnergyTierHelper {
private EnergyTierHelper() {
}
public static int transferRateForCapacity(int capacity) {
if (capacity >= 10_000_000) {
return 5_000;
}
if (capacity >= 2_000_000) {
return 1_000;
}
if (capacity >= 750_000) {
return 300;
}
if (capacity >= 100_000) {
return 100;
}
return 50;
}
}

View File

@@ -0,0 +1,18 @@
package com.trunksbomb.batteries.item;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.transfer.energy.SimpleEnergyHandler;
final class PoweredEnergyHandler extends SimpleEnergyHandler {
private final ItemStack stack;
PoweredEnergyHandler(ItemStack stack, int capacity, int maxTransfer, int energy) {
super(capacity, maxTransfer, maxTransfer, energy);
this.stack = stack;
}
@Override
protected void onEnergyChanged(int previousAmount) {
PoweredItemEnergy.setStoredEnergy(this.stack, this.energy);
}
}

View File

@@ -0,0 +1,86 @@
package com.trunksbomb.batteries.item;
import java.util.Optional;
import java.util.function.Consumer;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderSet;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.enchantment.Enchantment;
import net.neoforged.neoforge.transfer.energy.EnergyHandler;
public interface PoweredItem {
default EnergyHandler createEnergyHandler(ItemStack stack) {
return PoweredItemEnergy.createEnergyHandler(stack, this.getMaxTransfer(stack));
}
default int getMaxTransfer(ItemStack stack) {
return EnergyTierHelper.transferRateForCapacity(PoweredItemEnergy.getEnergyCapacity(stack));
}
default boolean isEnergyBarVisible(ItemStack stack) {
return PoweredItemEnergy.getEnergyCapacity(stack) > 0;
}
default int getEnergyBarWidth(ItemStack stack) {
return PoweredItemEnergy.getBarWidth(stack);
}
default int getEnergyBarColor(ItemStack stack) {
return 0x55CC55;
}
default void addEnergyTooltip(ItemStack stack, Consumer<Component> tooltipAdder, TooltipFlag flag) {
PoweredItemEnergy.addEnergyTooltip(stack, tooltipAdder);
}
default ItemStack getEnchantingBaseStack(ItemStack stack) {
return stack;
}
default int getAdjustedEnergyCost(ItemStack stack, int baseCost) {
return PoweredItemEnergy.adjustEnergyCostForEnchantments(stack, baseCost);
}
default int getPoweredEnchantmentLevel(ItemStack stack, Holder<Enchantment> enchantment) {
if (PoweredItemEnergy.isDisabledPoweredItemEnchantment(enchantment)) {
return 0;
}
return stack.getTagEnchantments().getLevel(enchantment);
}
default float getPoweredXpRepairRatio(ItemStack stack) {
return 0.0F;
}
default boolean supportsPoweredEnchantment(ItemStack stack, Holder<Enchantment> enchantment) {
if (PoweredItemEnergy.isMendingEnchantment(enchantment)) {
return false;
}
ItemStack baseStack = this.getEnchantingBaseStack(stack);
return baseStack.is(Items.ENCHANTED_BOOK) || enchantment.value().isSupportedItem(baseStack);
}
default boolean isPrimaryPoweredItemFor(ItemStack stack, Holder<Enchantment> enchantment) {
ItemStack baseStack = this.getEnchantingBaseStack(stack);
if (baseStack.getItem() == Items.BOOK) {
return true;
}
Optional<HolderSet<Item>> primaryItems = enchantment.value().definition().primaryItems();
return this.supportsPoweredEnchantment(stack, enchantment) && (primaryItems.isEmpty() || baseStack.is(primaryItems.get()));
}
default boolean shouldCauseEnergyReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return slotChanged || !newStack.is(oldStack.getItem());
}
default boolean shouldCauseEnergyBlockBreakReset(ItemStack oldStack, ItemStack newStack) {
return !newStack.is(oldStack.getItem());
}
}

View File

@@ -0,0 +1,171 @@
package com.trunksbomb.batteries.item;
import com.trunksbomb.batteries.BatteriesConfig;
import java.util.function.Consumer;
import net.minecraft.ChatFormatting;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.ItemEnchantments;
import net.neoforged.neoforge.transfer.energy.EnergyHandler;
public final class PoweredItemEnergy {
private static final String ENERGY_KEY = "energy";
private static final String CAPACITY_KEY = "capacity";
public static final int DEFAULT_CAPACITY = 50_000;
private PoweredItemEnergy() {
}
public static EnergyHandler createEnergyHandler(ItemStack stack, int maxTransfer) {
if (!(stack.getItem() instanceof PoweredItem)) {
return null;
}
int capacity = getEnergyCapacity(stack);
return new PoweredEnergyHandler(stack, capacity, Math.max(1, maxTransfer), getStoredEnergy(stack));
}
public static int getStoredEnergy(ItemStack stack) {
CompoundTag tag = stack.getOrDefault(DataComponents.CUSTOM_DATA, net.minecraft.world.item.component.CustomData.EMPTY).copyTag();
return Math.max(0, tag.getIntOr(ENERGY_KEY, 0));
}
public static void setStoredEnergy(ItemStack stack, int energy) {
int capacity = getEnergyCapacity(stack);
int clamped = Math.max(0, Math.min(energy, capacity));
net.minecraft.world.item.component.CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> tag.putInt(ENERGY_KEY, clamped));
}
public static int getEnergyCapacity(ItemStack stack) {
CompoundTag tag = stack.getOrDefault(DataComponents.CUSTOM_DATA, net.minecraft.world.item.component.CustomData.EMPTY).copyTag();
int storedCapacity = Math.max(0, tag.getIntOr(CAPACITY_KEY, 0));
if (storedCapacity > 0) {
return storedCapacity;
}
return stack.getItem() instanceof PoweredItem ? DEFAULT_CAPACITY : 0;
}
public static void setEnergyCapacity(ItemStack stack, int capacity) {
int clampedCapacity = Math.max(0, capacity);
net.minecraft.world.item.component.CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> {
tag.putInt(CAPACITY_KEY, clampedCapacity);
tag.putInt(ENERGY_KEY, Math.max(0, Math.min(tag.getIntOr(ENERGY_KEY, 0), clampedCapacity)));
});
}
public static boolean hasEnergy(ItemStack stack, int amount) {
return amount <= 0 || getStoredEnergy(stack) >= amount;
}
public static boolean consumeEnergy(ItemStack stack, int amount) {
if (amount <= 0) {
return true;
}
int stored = getStoredEnergy(stack);
if (stored < amount) {
return false;
}
setStoredEnergy(stack, stored - amount);
return true;
}
public static int getBarWidth(ItemStack stack) {
int capacity = getEnergyCapacity(stack);
if (capacity <= 0) {
return 0;
}
return Math.round(13.0F * getStoredEnergy(stack) / (float) capacity);
}
public static void addEnergyTooltip(ItemStack stack, Consumer<Component> tooltipAdder) {
tooltipAdder.accept(Component.translatable("batteries.tooltip.energy", formatWithCommas(getStoredEnergy(stack)), abbreviateAmount(getEnergyCapacity(stack)))
.withStyle(ChatFormatting.GREEN));
}
public static int adjustEnergyCostForEnchantments(ItemStack stack, int baseCost) {
if (baseCost <= 0) {
return 0;
}
ItemEnchantments enchantments = stack.getTagEnchantments();
if (enchantments.keySet().isEmpty()) {
return baseCost;
}
double totalMultiplier = 1.0D;
for (Holder<Enchantment> enchantment : enchantments.keySet()) {
int level = enchantments.getLevel(enchantment);
if (level <= 0) {
continue;
}
int maxLevel = Math.max(1, enchantment.value().getMaxLevel());
double scaledLevel = Math.min(level, maxLevel) / (double) maxLevel;
String enchantmentId = enchantment.unwrapKey()
.map(key -> key.identifier().toString())
.orElse("");
totalMultiplier += BatteriesConfig.poweredItemEnchantmentMultiplier(enchantmentId) * scaledLevel;
}
return clampToInt(Math.max(1L, Math.round(baseCost * totalMultiplier)));
}
public static int clampToInt(long value) {
return (int) Math.max(0L, Math.min(Integer.MAX_VALUE, value));
}
public static boolean isMendingEnchantment(Holder<Enchantment> enchantment) {
return hasEnchantmentId(enchantment, "minecraft:mending");
}
public static boolean isDisabledPoweredItemEnchantment(Holder<Enchantment> enchantment) {
return hasEnchantmentId(enchantment, "minecraft:mending")
|| hasEnchantmentId(enchantment, "minecraft:unbreaking");
}
private static boolean hasEnchantmentId(Holder<Enchantment> enchantment, String id) {
return enchantment.unwrapKey()
.map(key -> id.equals(key.identifier().toString()))
.orElse(false);
}
public static String formatWithCommas(int amount) {
return String.format("%,d", amount);
}
public static String abbreviateAmount(int amount) {
if (amount >= 1_000_000_000) {
return abbreviate(amount, 1_000_000_000, "G");
}
if (amount >= 1_000_000) {
return abbreviate(amount, 1_000_000, "M");
}
if (amount >= 1_000) {
return abbreviate(amount, 1_000, "k");
}
return formatWithCommas(amount);
}
private static String abbreviate(int amount, int divisor, String suffix) {
int whole = amount / divisor;
int remainder = amount % divisor;
if (remainder == 0) {
return whole + suffix;
}
int decimal = (remainder * 10) / divisor;
if (decimal == 0) {
return whole + suffix;
}
return whole + "." + decimal + suffix;
}
}

View File

@@ -0,0 +1,48 @@
package com.trunksbomb.batteries.shared;
import net.minecraft.core.Direction;
public final class BatteryBlockData {
public static final Direction[] MENU_DIRECTIONS = new Direction[] {
Direction.UP, Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST
};
private BatteryBlockData() {
}
public static Direction directionForIndex(int index) {
return MENU_DIRECTIONS[index];
}
public static int chargeStage(int energy, int capacity) {
if (capacity <= 0 || energy <= 0) {
return 0;
}
float ratio = energy / (float) capacity;
if (ratio >= 0.99F) {
return 4;
}
if (ratio >= 0.74F) {
return 3;
}
if (ratio >= 0.49F) {
return 2;
}
if (ratio >= 0.24F) {
return 1;
}
return 0;
}
public enum SideMode {
INPUT,
OUTPUT,
BOTH,
NONE;
public SideMode next() {
return values()[(this.ordinal() + 1) % values().length];
}
}
}

View File

@@ -0,0 +1,49 @@
package com.trunksbomb.batteries.shared;
import com.trunksbomb.batteries.item.BatteryItemData.Tier;
import net.minecraft.util.StringRepresentable;
import org.jspecify.annotations.NonNull;
public final class ChargerBlockData {
private ChargerBlockData() {
}
public static boolean canAcceptBattery(boolean enderCharger, Tier tier) {
if (enderCharger) {
return tier == Tier.ENDER;
}
return tier != Tier.ENDER;
}
public enum BatteryState implements StringRepresentable {
NONE("none"),
BASIC("basic"),
ADVANCED("advanced"),
ELITE("elite"),
ULTIMATE("ultimate"),
CREATIVE("creative"),
ENDER("ender");
private final String name;
BatteryState(String name) {
this.name = name;
}
public static BatteryState fromTier(Tier tier) {
return switch (tier) {
case BASIC -> BASIC;
case ADVANCED -> ADVANCED;
case ELITE -> ELITE;
case ULTIMATE -> ULTIMATE;
case CREATIVE -> CREATIVE;
case ENDER -> ENDER;
};
}
@Override
public @NonNull String getSerializedName() {
return this.name;
}
}
}

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,24 @@
{
"variants": {
"charge=0,facing=north": { "model": "batteries:block/battery_block_0" },
"charge=0,facing=east": { "model": "batteries:block/battery_block_0", "y": 90 },
"charge=0,facing=south": { "model": "batteries:block/battery_block_0", "y": 180 },
"charge=0,facing=west": { "model": "batteries:block/battery_block_0", "y": 270 },
"charge=1,facing=north": { "model": "batteries:block/battery_block_1" },
"charge=1,facing=east": { "model": "batteries:block/battery_block_1", "y": 90 },
"charge=1,facing=south": { "model": "batteries:block/battery_block_1", "y": 180 },
"charge=1,facing=west": { "model": "batteries:block/battery_block_1", "y": 270 },
"charge=2,facing=north": { "model": "batteries:block/battery_block_2" },
"charge=2,facing=east": { "model": "batteries:block/battery_block_2", "y": 90 },
"charge=2,facing=south": { "model": "batteries:block/battery_block_2", "y": 180 },
"charge=2,facing=west": { "model": "batteries:block/battery_block_2", "y": 270 },
"charge=3,facing=north": { "model": "batteries:block/battery_block_3" },
"charge=3,facing=east": { "model": "batteries:block/battery_block_3", "y": 90 },
"charge=3,facing=south": { "model": "batteries:block/battery_block_3", "y": 180 },
"charge=3,facing=west": { "model": "batteries:block/battery_block_3", "y": 270 },
"charge=4,facing=north": { "model": "batteries:block/battery_block_4" },
"charge=4,facing=east": { "model": "batteries:block/battery_block_4", "y": 90 },
"charge=4,facing=south": { "model": "batteries:block/battery_block_4", "y": 180 },
"charge=4,facing=west": { "model": "batteries:block/battery_block_4", "y": 270 }
}
}

View File

@@ -0,0 +1,109 @@
{
"variants": {
"battery=none,facing=north": {
"model": "batteries:block/charger/charger_none"
},
"battery=basic,facing=north": {
"model": "batteries:block/charger/charger_basic"
},
"battery=advanced,facing=north": {
"model": "batteries:block/charger/charger_advanced"
},
"battery=elite,facing=north": {
"model": "batteries:block/charger/charger_elite"
},
"battery=ultimate,facing=north": {
"model": "batteries:block/charger/charger_ultimate"
},
"battery=creative,facing=north": {
"model": "batteries:block/charger/charger_creative"
},
"battery=ender,facing=north": {
"model": "batteries:block/charger/charger_ender"
},
"battery=none,facing=south": {
"model": "batteries:block/charger/charger_none",
"y": 180
},
"battery=basic,facing=south": {
"model": "batteries:block/charger/charger_basic",
"y": 180
},
"battery=advanced,facing=south": {
"model": "batteries:block/charger/charger_advanced",
"y": 180
},
"battery=elite,facing=south": {
"model": "batteries:block/charger/charger_elite",
"y": 180
},
"battery=ultimate,facing=south": {
"model": "batteries:block/charger/charger_ultimate",
"y": 180
},
"battery=creative,facing=south": {
"model": "batteries:block/charger/charger_creative",
"y": 180
},
"battery=ender,facing=south": {
"model": "batteries:block/charger/charger_ender",
"y": 180
},
"battery=none,facing=west": {
"model": "batteries:block/charger/charger_none",
"y": 270
},
"battery=basic,facing=west": {
"model": "batteries:block/charger/charger_basic",
"y": 270
},
"battery=advanced,facing=west": {
"model": "batteries:block/charger/charger_advanced",
"y": 270
},
"battery=elite,facing=west": {
"model": "batteries:block/charger/charger_elite",
"y": 270
},
"battery=ultimate,facing=west": {
"model": "batteries:block/charger/charger_ultimate",
"y": 270
},
"battery=creative,facing=west": {
"model": "batteries:block/charger/charger_creative",
"y": 270
},
"battery=ender,facing=west": {
"model": "batteries:block/charger/charger_ender",
"y": 270
},
"battery=none,facing=east": {
"model": "batteries:block/charger/charger_none",
"y": 90
},
"battery=basic,facing=east": {
"model": "batteries:block/charger/charger_basic",
"y": 90
},
"battery=advanced,facing=east": {
"model": "batteries:block/charger/charger_advanced",
"y": 90
},
"battery=elite,facing=east": {
"model": "batteries:block/charger/charger_elite",
"y": 90
},
"battery=ultimate,facing=east": {
"model": "batteries:block/charger/charger_ultimate",
"y": 90
},
"battery=creative,facing=east": {
"model": "batteries:block/charger/charger_creative",
"y": 90
},
"battery=ender,facing=east": {
"model": "batteries:block/charger/charger_ender",
"y": 90
}
}
}

View File

@@ -0,0 +1,12 @@
{
"variants": {
"facing=north,lit=false": { "model": "batteries:block/coal_generator" },
"facing=east,lit=false": { "model": "batteries:block/coal_generator", "y": 90 },
"facing=south,lit=false": { "model": "batteries:block/coal_generator", "y": 180 },
"facing=west,lit=false": { "model": "batteries:block/coal_generator", "y": 270 },
"facing=north,lit=true": { "model": "batteries:block/coal_generator_lit" },
"facing=east,lit=true": { "model": "batteries:block/coal_generator_lit", "y": 90 },
"facing=south,lit=true": { "model": "batteries:block/coal_generator_lit", "y": 180 },
"facing=west,lit=true": { "model": "batteries:block/coal_generator_lit", "y": 270 }
}
}

View File

@@ -0,0 +1,109 @@
{
"variants": {
"battery=none,facing=north": {
"model": "batteries:block/charger/ender_charger"
},
"battery=basic,facing=north": {
"model": "batteries:block/charger/ender_charger_full"
},
"battery=advanced,facing=north": {
"model": "batteries:block/charger/ender_charger_full"
},
"battery=elite,facing=north": {
"model": "batteries:block/charger/ender_charger_full"
},
"battery=ultimate,facing=north": {
"model": "batteries:block/charger/ender_charger_full"
},
"battery=creative,facing=north": {
"model": "batteries:block/charger/ender_charger_full"
},
"battery=ender,facing=north": {
"model": "batteries:block/charger/ender_charger_full"
},
"battery=none,facing=south": {
"model": "batteries:block/charger/ender_charger",
"y": 180
},
"battery=basic,facing=south": {
"model": "batteries:block/charger/ender_charger_full",
"y": 180
},
"battery=advanced,facing=south": {
"model": "batteries:block/charger/ender_charger_full",
"y": 180
},
"battery=elite,facing=south": {
"model": "batteries:block/charger/ender_charger_full",
"y": 180
},
"battery=ultimate,facing=south": {
"model": "batteries:block/charger/ender_charger_full",
"y": 180
},
"battery=creative,facing=south": {
"model": "batteries:block/charger/ender_charger_full",
"y": 180
},
"battery=ender,facing=south": {
"model": "batteries:block/charger/ender_charger_full",
"y": 180
},
"battery=none,facing=west": {
"model": "batteries:block/charger/ender_charger",
"y": 270
},
"battery=basic,facing=west": {
"model": "batteries:block/charger/ender_charger_full",
"y": 270
},
"battery=advanced,facing=west": {
"model": "batteries:block/charger/ender_charger_full",
"y": 270
},
"battery=elite,facing=west": {
"model": "batteries:block/charger/ender_charger_full",
"y": 270
},
"battery=ultimate,facing=west": {
"model": "batteries:block/charger/ender_charger_full",
"y": 270
},
"battery=creative,facing=west": {
"model": "batteries:block/charger/ender_charger_full",
"y": 270
},
"battery=ender,facing=west": {
"model": "batteries:block/charger/ender_charger_full",
"y": 270
},
"battery=none,facing=east": {
"model": "batteries:block/charger/ender_charger",
"y": 90
},
"battery=basic,facing=east": {
"model": "batteries:block/charger/ender_charger_full",
"y": 90
},
"battery=advanced,facing=east": {
"model": "batteries:block/charger/ender_charger_full",
"y": 90
},
"battery=elite,facing=east": {
"model": "batteries:block/charger/ender_charger_full",
"y": 90
},
"battery=ultimate,facing=east": {
"model": "batteries:block/charger/ender_charger_full",
"y": 90
},
"battery=creative,facing=east": {
"model": "batteries:block/charger/ender_charger_full",
"y": 90
},
"battery=ender,facing=east": {
"model": "batteries:block/charger/ender_charger_full",
"y": 90
}
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery1"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery2"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery3"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_axe"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:block/battery_block_4"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_boots"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_bow"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_chestplate"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_creative"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_ender"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_helmet"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_hoe"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_leggings"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_pickaxe"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_shield"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_shovel"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:item/battery_sword"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:block/charger/charger_none"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:block/coal_generator"
}
}

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "batteries:block/charger/ender_charger"
}
}

View File

@@ -0,0 +1,35 @@
{
"itemGroup.batteries": "Batteries",
"item.batteries.battery": "Basic Battery",
"item.batteries.battery1": "Advanced Battery",
"item.batteries.battery2": "Elite Battery",
"item.batteries.battery3": "Ultimate Battery",
"item.batteries.battery_ender": "Ender Battery",
"item.batteries.battery_creative": "Creative Battery",
"item.batteries.battery_pickaxe": "Battery-powered Pickaxe",
"item.batteries.battery_axe": "Battery-powered Axe",
"item.batteries.battery_shovel": "Battery-powered Shovel",
"item.batteries.battery_hoe": "Battery-powered Hoe",
"item.batteries.battery_sword": "Battery-powered Sword",
"item.batteries.battery_helmet": "Battery-powered Helmet",
"item.batteries.battery_chestplate": "Battery-powered Chestplate",
"item.batteries.battery_leggings": "Battery-powered Leggings",
"item.batteries.battery_boots": "Battery-powered Boots",
"item.batteries.battery_shield": "Battery-powered Shield",
"item.batteries.battery_bow": "Battery-powered Bow",
"item.batteries.battery_block": "Battery Block",
"block.batteries.coal_generator": "Coal Generator",
"block.batteries.battery_block": "Battery Block",
"block.batteries.charger": "Battery Charger",
"block.batteries.ender_charger": "Ender Battery Uplink",
"batteries.gui.button.whitelist": "Whitelist",
"batteries.gui.button.blacklist": "Blacklist",
"batteries.gui.button.charge_hotbar": "Charge Items on Hotbar",
"batteries.gui.button.charge_inventory": "Charge Items in Inventory",
"batteries.gui.button.charge_armor": "Charge Worn Items",
"batteries.gui.button.charge_fairly": "Charge items fairly",
"batteries.gui.button.charge_machine": "Charge nearby machines",
"container.batteries.battery_block": "Battery Block",
"container.batteries.coal_generator": "Coal Generator",
"batteries.tooltip.energy": "Energy: %s / %s"
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/battery_block_side",
"up": "batteries:block/battery_block_top",
"down": "batteries:block/battery_block_bottom",
"north": "batteries:block/battery_block_front_0",
"south": "batteries:block/battery_block_front_0",
"east": "batteries:block/battery_block_side",
"west": "batteries:block/battery_block_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/battery_block_side",
"up": "batteries:block/battery_block_top",
"down": "batteries:block/battery_block_bottom",
"north": "batteries:block/battery_block_front_1",
"south": "batteries:block/battery_block_front_1",
"east": "batteries:block/battery_block_side",
"west": "batteries:block/battery_block_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/battery_block_side",
"up": "batteries:block/battery_block_top",
"down": "batteries:block/battery_block_bottom",
"north": "batteries:block/battery_block_front_2",
"south": "batteries:block/battery_block_front_2",
"east": "batteries:block/battery_block_side",
"west": "batteries:block/battery_block_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/battery_block_side",
"up": "batteries:block/battery_block_top",
"down": "batteries:block/battery_block_bottom",
"north": "batteries:block/battery_block_front_3",
"south": "batteries:block/battery_block_front_3",
"east": "batteries:block/battery_block_side",
"west": "batteries:block/battery_block_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/battery_block_side",
"up": "batteries:block/battery_block_top",
"down": "batteries:block/battery_block_bottom",
"north": "batteries:block/battery_block_front_4",
"south": "batteries:block/battery_block_front_4",
"east": "batteries:block/battery_block_side",
"west": "batteries:block/battery_block_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/charger/charger_top",
"down": "batteries:block/charger/charger_top",
"up": "batteries:block/charger/charger_top",
"north": "batteries:block/charger/charger_front",
"south": "batteries:block/charger/charger_front",
"west": "batteries:block/charger/charger_side",
"east": "batteries:block/charger/charger_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/charger/charger_top",
"down": "batteries:block/charger/charger_top",
"up": "batteries:block/charger/charger_top",
"north": "batteries:block/charger/charger_advanced",
"south": "batteries:block/charger/charger_advanced",
"west": "batteries:block/charger/charger_side",
"east": "batteries:block/charger/charger_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/charger/charger_top",
"down": "batteries:block/charger/charger_top",
"up": "batteries:block/charger/charger_top",
"north": "batteries:block/charger/charger_basic",
"south": "batteries:block/charger/charger_basic",
"west": "batteries:block/charger/charger_side",
"east": "batteries:block/charger/charger_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/charger/charger_top",
"down": "batteries:block/charger/charger_top",
"up": "batteries:block/charger/charger_top",
"north": "batteries:block/charger/charger_creative",
"south": "batteries:block/charger/charger_creative",
"west": "batteries:block/charger/charger_side",
"east": "batteries:block/charger/charger_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/charger/charger_top",
"down": "batteries:block/charger/charger_top",
"up": "batteries:block/charger/charger_top",
"north": "batteries:block/charger/charger_elite",
"south": "batteries:block/charger/charger_elite",
"west": "batteries:block/charger/charger_side",
"east": "batteries:block/charger/charger_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/charger/charger_top",
"down": "batteries:block/charger/charger_top",
"up": "batteries:block/charger/charger_top",
"north": "batteries:block/charger/charger_ender",
"south": "batteries:block/charger/charger_ender",
"west": "batteries:block/charger/charger_side",
"east": "batteries:block/charger/charger_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/charger/charger_top",
"down": "batteries:block/charger/charger_top",
"up": "batteries:block/charger/charger_top",
"north": "batteries:block/charger/charger_front",
"south": "batteries:block/charger/charger_front",
"west": "batteries:block/charger/charger_side",
"east": "batteries:block/charger/charger_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/charger/charger_top",
"down": "batteries:block/charger/charger_top",
"up": "batteries:block/charger/charger_top",
"north": "batteries:block/charger/charger_ultimate",
"south": "batteries:block/charger/charger_ultimate",
"west": "batteries:block/charger/charger_side",
"east": "batteries:block/charger/charger_side"
}
}

View File

@@ -0,0 +1,9 @@
{
"parent": "batteries:block/charger/charger_none",
"textures": {
"north": "batteries:block/charger/charger_front",
"south": "batteries:block/charger/charger_front",
"up": "batteries:block/charger/ender_charger_top",
"down": "batteries:block/charger/ender_charger_top"
}
}

View File

@@ -0,0 +1,7 @@
{
"parent": "batteries:block/charger/ender_charger",
"textures": {
"north": "batteries:block/charger/charger_ender",
"south": "batteries:block/charger/charger_ender"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/battery_block_side",
"up": "batteries:block/battery_block_top",
"down": "batteries:block/battery_block_bottom",
"north": "minecraft:block/furnace_front",
"south": "minecraft:block/furnace_front",
"east": "batteries:block/battery_block_side",
"west": "batteries:block/battery_block_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/battery_block_side",
"up": "batteries:block/battery_block_top",
"down": "batteries:block/battery_block_bottom",
"north": "minecraft:block/furnace_front_on",
"south": "minecraft:block/furnace_front_on",
"east": "batteries:block/battery_block_side",
"west": "batteries:block/battery_block_side"
}
}

View File

@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"particle": "batteries:block/charger/ender_charger_top",
"down": "batteries:block/charger/ender_charger_top",
"up": "batteries:block/charger/ender_charger_top",
"north": "batteries:block/charger/charger_front",
"south": "batteries:block/charger/charger_front",
"west": "batteries:block/charger/charger_side",
"east": "batteries:block/charger/charger_side"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery1"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery2"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery3"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "batteries:item/battery_axe"
}
}

View File

@@ -0,0 +1,3 @@
{
"parent": "batteries:block/battery_block_4"
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery_boots"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery_bow"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery_chestplate"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery_creative"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery_ender"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery_helmet"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "batteries:item/battery_hoe"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery_leggings"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "batteries:item/battery_pickaxe"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "batteries:item/battery_shield"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "batteries:item/battery_shovel"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "batteries:item/battery_sword"
}
}

View File

@@ -0,0 +1,3 @@
{
"parent": "batteries:block/charger/charger_none"
}

View File

@@ -0,0 +1,3 @@
{
"parent": "batteries:block/coal_generator"
}

View File

@@ -0,0 +1,3 @@
{
"parent": "batteries:block/charger/ender_charger"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Some files were not shown because too many files have changed in this diff Show More