Move and rename Air Source interface and backtank implementation, move static functions related to the backtank item.
This commit is contained in:
parent
68ba30e122
commit
826669eb71
|
@ -5,6 +5,7 @@ import java.util.List;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.content.equipment.armor.backtank_utils.BacktankAirSource;
|
||||
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
|
||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
import com.simibubi.create.foundation.blockEntity.ComparatorUtil;
|
||||
|
@ -80,7 +81,7 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable
|
|||
return;
|
||||
}
|
||||
|
||||
int max = BacktankUtil.maxAir(capacityEnchantLevel);
|
||||
int max = BacktankAirSource.maxAir(capacityEnchantLevel);
|
||||
if (level.isClientSide) {
|
||||
Vec3 centerOf = VecHelper.getCenterOf(worldPosition);
|
||||
Vec3 v = VecHelper.offsetRandomly(centerOf, level.random, .65f);
|
||||
|
@ -105,7 +106,7 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable
|
|||
}
|
||||
|
||||
public int getComparatorOutput() {
|
||||
int max = BacktankUtil.maxAir(capacityEnchantLevel);
|
||||
int max = BacktankAirSource.maxAir(capacityEnchantLevel);
|
||||
return ComparatorUtil.fractionToRedstoneLevel(airLevel / (float) max);
|
||||
}
|
||||
|
||||
|
@ -130,7 +131,7 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable
|
|||
enchantmentTag = compound.getList("Enchantments", Tag.TAG_COMPOUND);
|
||||
if (compound.contains("CustomName", 8))
|
||||
this.customName = Component.Serializer.fromJson(compound.getString("CustomName"));
|
||||
if (prev != 0 && prev != airLevel && airLevel == BacktankUtil.maxAir(capacityEnchantLevel) && clientPacket)
|
||||
if (prev != 0 && prev != airLevel && airLevel == BacktankAirSource.maxAir(capacityEnchantLevel) && clientPacket)
|
||||
playFilledEffect();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ package com.simibubi.create.content.equipment.armor;
|
|||
import java.util.Locale;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.content.equipment.armor.backtank_utils.BacktankAirSource;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.content.equipment.armor.CapacityEnchantment.ICapacityEnchantable;
|
||||
|
@ -27,7 +29,7 @@ import net.minecraft.world.level.block.Block;
|
|||
public class BacktankItem extends BaseArmorItem implements ICapacityEnchantable {
|
||||
public static final EquipmentSlot SLOT = EquipmentSlot.CHEST;
|
||||
public static final int BAR_COLOR = 0xEFEFEF;
|
||||
|
||||
|
||||
private final Supplier<BacktankBlockItem> blockItem;
|
||||
|
||||
public BacktankItem(ArmorMaterial material, Properties properties, ResourceLocation textureLoc, Supplier<BacktankBlockItem> placeable) {
|
||||
|
@ -69,7 +71,7 @@ public class BacktankItem extends BaseArmorItem implements ICapacityEnchantable
|
|||
|
||||
ItemStack stack = new ItemStack(this);
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
nbt.putInt("Air", BacktankUtil.maxAirWithoutEnchants());
|
||||
nbt.putInt("Air", BacktankAirSource.maxAirWithoutEnchants());
|
||||
stack.setTag(nbt);
|
||||
items.add(stack);
|
||||
}
|
||||
|
@ -81,7 +83,7 @@ public class BacktankItem extends BaseArmorItem implements ICapacityEnchantable
|
|||
|
||||
@Override
|
||||
public int getBarWidth(ItemStack stack) {
|
||||
return Math.round(13.0F * Mth.clamp(getRemainingAir(stack) / ((float) BacktankUtil.maxAir(stack)), 0, 1));
|
||||
return Math.round(13.0F * Mth.clamp(getRemainingAir(stack) / ((float) BacktankAirSource.maxAir(stack)), 0, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,32 +5,21 @@ import java.util.List;
|
|||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.simibubi.create.AllEnchantments;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.AllTags;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
import com.simibubi.create.content.equipment.armor.backtank_utils.BacktankAirSource;
|
||||
import com.simibubi.create.content.equipment.armor.backtank_utils.IAirSource;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class BacktankUtil {
|
||||
|
||||
private static final List<Function<LivingEntity, List<BacktankWrapper>>> BACKTANK_SUPPLIERS = new ArrayList<>();
|
||||
private static final List<Function<LivingEntity, List<IAirSource>>> BACKTANK_SUPPLIERS = new ArrayList<>();
|
||||
|
||||
static {
|
||||
addBacktankSupplier(entity -> {
|
||||
|
@ -43,13 +32,19 @@ public class BacktankUtil {
|
|||
});
|
||||
}
|
||||
|
||||
public static List<BacktankWrapper> getAllWithAir(LivingEntity entity) {
|
||||
List<BacktankWrapper> all = new ArrayList<>();
|
||||
/**
|
||||
* Get all Air Sources from the entity that have some air.
|
||||
* Will return empty list if all Air Sources (i.e. Backtanks) are empty.
|
||||
* @param entity player or other entity to check
|
||||
* @return list of Air Sources
|
||||
*/
|
||||
public static List<IAirSource> getAllWithAir(LivingEntity entity) {
|
||||
List<IAirSource> all = new ArrayList<>();
|
||||
|
||||
for (Function<LivingEntity, List<BacktankWrapper>> supplier : BACKTANK_SUPPLIERS) {
|
||||
List<BacktankWrapper> result = supplier.apply(entity);
|
||||
for (Function<LivingEntity, List<IAirSource>> supplier : BACKTANK_SUPPLIERS) {
|
||||
List<IAirSource> result = supplier.apply(entity);
|
||||
|
||||
for (BacktankWrapper stack : result)
|
||||
for (IAirSource stack : result)
|
||||
if (stack.hasAirRemaining())
|
||||
all.add(stack);
|
||||
}
|
||||
|
@ -60,75 +55,22 @@ public class BacktankUtil {
|
|||
return all;
|
||||
}
|
||||
|
||||
// BackTank-specific functions - could be moved to DefaultBacktankWrapper
|
||||
|
||||
public static boolean hasAirRemaining(ItemStack backtank) {
|
||||
return getAir(backtank) > 0;
|
||||
}
|
||||
|
||||
public static float getAir(ItemStack backtank) {
|
||||
CompoundTag tag = backtank.getOrCreateTag();
|
||||
return Math.min(tag.getFloat("Air"), maxAir(backtank));
|
||||
}
|
||||
|
||||
public static void consumeAir(LivingEntity entity, ItemStack backtank, float i) {
|
||||
CompoundTag tag = backtank.getOrCreateTag();
|
||||
int maxAir = maxAir(backtank);
|
||||
float air = getAir(backtank);
|
||||
float newAir = Math.max(air - i, 0);
|
||||
tag.putFloat("Air", Math.min(newAir, maxAir));
|
||||
backtank.setTag(tag);
|
||||
|
||||
if (!(entity instanceof ServerPlayer player))
|
||||
return;
|
||||
|
||||
sendWarning(player, air, newAir, maxAir / 10f);
|
||||
sendWarning(player, air, newAir, 1);
|
||||
}
|
||||
|
||||
private static void sendWarning(ServerPlayer player, float air, float newAir, float threshold) {
|
||||
if (newAir > threshold)
|
||||
return;
|
||||
if (air <= threshold)
|
||||
return;
|
||||
|
||||
boolean depleted = threshold == 1;
|
||||
MutableComponent component = Lang.translateDirect(depleted ? "backtank.depleted" : "backtank.low");
|
||||
|
||||
AllSoundEvents.DENY.play(player.level, null, player.blockPosition(), 1, 1.25f);
|
||||
AllSoundEvents.STEAM.play(player.level, null, player.blockPosition(), .5f, .5f);
|
||||
|
||||
player.connection.send(new ClientboundSetTitlesAnimationPacket(10, 40, 10));
|
||||
player.connection.send(new ClientboundSetSubtitleTextPacket(
|
||||
Components.literal("\u26A0 ").withStyle(depleted ? ChatFormatting.RED : ChatFormatting.GOLD)
|
||||
.append(component.withStyle(ChatFormatting.GRAY))));
|
||||
player.connection.send(new ClientboundSetTitleTextPacket(Components.immutableEmpty()));
|
||||
}
|
||||
|
||||
public static int maxAir(ItemStack backtank) {
|
||||
return maxAir(EnchantmentHelper.getItemEnchantmentLevel(AllEnchantments.CAPACITY.get(), backtank));
|
||||
}
|
||||
|
||||
public static int maxAir(int enchantLevel) {
|
||||
return AllConfigs.server().equipment.airInBacktank.get()
|
||||
+ AllConfigs.server().equipment.enchantedBacktankCapacity.get() * enchantLevel;
|
||||
}
|
||||
|
||||
public static int maxAirWithoutEnchants() {
|
||||
return AllConfigs.server().equipment.airInBacktank.get();
|
||||
}
|
||||
|
||||
// BackTank-agnostic functions
|
||||
/**
|
||||
* Try to use air from any Air Source available.
|
||||
* @param entity player or other entity to check
|
||||
* @param usesPerTank how many uses does the tool have per non-enchanted Copper Backtank (used to calculate cost)
|
||||
* @return if air was consumed
|
||||
*/
|
||||
|
||||
public static boolean canAbsorbDamage(LivingEntity entity, int usesPerTank) {
|
||||
if (usesPerTank == 0)
|
||||
return true;
|
||||
if (entity instanceof Player && ((Player) entity).isCreative())
|
||||
return true;
|
||||
List<BacktankWrapper> backtanks = getAllWithAir(entity);
|
||||
List<IAirSource> backtanks = getAllWithAir(entity);
|
||||
if (backtanks.isEmpty())
|
||||
return false;
|
||||
float cost = ((float) maxAirWithoutEnchants()) / usesPerTank;
|
||||
float cost = ((float) BacktankAirSource.maxAirWithoutEnchants()) / usesPerTank;
|
||||
backtanks.get(0).consumeAir(entity, cost);
|
||||
return true;
|
||||
}
|
||||
|
@ -141,7 +83,7 @@ public class BacktankUtil {
|
|||
Player player = DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> () -> Minecraft.getInstance().player);
|
||||
if (player == null)
|
||||
return false;
|
||||
List<BacktankWrapper> backtanks = getAllWithAir(player);
|
||||
List<IAirSource> backtanks = getAllWithAir(player);
|
||||
if (backtanks.isEmpty())
|
||||
return stack.isDamaged();
|
||||
return true;
|
||||
|
@ -154,7 +96,7 @@ public class BacktankUtil {
|
|||
if (player == null)
|
||||
return 13;
|
||||
|
||||
List<BacktankWrapper> backtanks = getAllWithAir(player);
|
||||
List<IAirSource> backtanks = getAllWithAir(player);
|
||||
|
||||
if (backtanks.isEmpty())
|
||||
return Math.round(13.0F - (float) stack.getDamageValue() / stack.getMaxDamage() * 13.0F);
|
||||
|
@ -164,7 +106,7 @@ public class BacktankUtil {
|
|||
|
||||
// If there is more than one backtank, average the bar widths.
|
||||
int sumBarWidth = backtanks.stream()
|
||||
.map(BacktankWrapper::getBarWidth)
|
||||
.map(IAirSource::getBarWidth)
|
||||
.reduce(0, Integer::sum);
|
||||
|
||||
return Math.round((float) sumBarWidth / backtanks.size());
|
||||
|
@ -176,7 +118,7 @@ public class BacktankUtil {
|
|||
Player player = DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> () -> Minecraft.getInstance().player);
|
||||
if (player == null)
|
||||
return 0;
|
||||
List<BacktankWrapper> backtanks = getAllWithAir(player);
|
||||
List<IAirSource> backtanks = getAllWithAir(player);
|
||||
|
||||
// Fallback colour
|
||||
if (backtanks.isEmpty())
|
||||
|
@ -193,73 +135,15 @@ public class BacktankUtil {
|
|||
*/
|
||||
public static void addBacktankSupplier(Function<LivingEntity, List<ItemStack>> supplier) {
|
||||
BACKTANK_SUPPLIERS.add(entity ->
|
||||
supplier.apply(entity).stream().map(DefaultBacktankWrapper::new).collect(Collectors.toList())
|
||||
supplier.apply(entity).stream().map(BacktankAirSource::new).collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
public static void addBacktankWrapperSupplier(Function<LivingEntity, List<BacktankWrapper>> supplier) {
|
||||
|
||||
/**
|
||||
* Use this method to add entry points to custom, non-backtank air sources.
|
||||
*/
|
||||
public static void addBacktankWrapperSupplier(Function<LivingEntity, List<IAirSource>> supplier) {
|
||||
BACKTANK_SUPPLIERS.add(supplier);
|
||||
}
|
||||
|
||||
public interface BacktankWrapper {
|
||||
float getAir();
|
||||
int maxAir();
|
||||
void consumeAir(LivingEntity entity, float i);
|
||||
boolean hasAirRemaining();
|
||||
|
||||
int getBarWidth();
|
||||
|
||||
int getBarColor();
|
||||
|
||||
boolean isFireResistant();
|
||||
|
||||
ItemStack getDisplayedBacktank();
|
||||
}
|
||||
|
||||
public static class DefaultBacktankWrapper implements BacktankWrapper {
|
||||
private final ItemStack backtankStack;
|
||||
|
||||
public DefaultBacktankWrapper(ItemStack backtankStack) {
|
||||
this.backtankStack = backtankStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAir() {
|
||||
return BacktankUtil.getAir(backtankStack);
|
||||
}
|
||||
|
||||
public int maxAir() {
|
||||
return BacktankUtil.maxAir(backtankStack);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void consumeAir(LivingEntity entity, float i) {
|
||||
BacktankUtil.consumeAir(entity, backtankStack, i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAirRemaining() {
|
||||
return BacktankUtil.hasAirRemaining(backtankStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBarWidth() {
|
||||
return backtankStack.getBarWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBarColor() {
|
||||
return backtankStack.getBarColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFireResistant() {
|
||||
return backtankStack.getItem().isFireResistant();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getDisplayedBacktank() {
|
||||
return backtankStack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.content.equipment.armor;
|
||||
|
||||
import com.simibubi.create.content.equipment.armor.backtank_utils.IAirSource;
|
||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -77,7 +78,7 @@ public class DivingHelmetItem extends BaseArmorItem {
|
|||
if (entity instanceof Player && ((Player) entity).isCreative())
|
||||
return;
|
||||
|
||||
List<BacktankUtil.BacktankWrapper> backtanks = BacktankUtil.getAllWithAir(entity);
|
||||
List<IAirSource> backtanks = BacktankUtil.getAllWithAir(entity);
|
||||
if (backtanks.isEmpty())
|
||||
return;
|
||||
|
||||
|
@ -85,7 +86,7 @@ public class DivingHelmetItem extends BaseArmorItem {
|
|||
if (entity instanceof ServerPlayer sp)
|
||||
AllAdvancements.DIVING_SUIT_LAVA.awardTo(sp);
|
||||
if (backtanks.stream()
|
||||
.noneMatch(backtank -> backtank.isFireResistant()))
|
||||
.noneMatch(IAirSource::isFireResistant))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -95,13 +96,12 @@ public class DivingHelmetItem extends BaseArmorItem {
|
|||
if (world.isClientSide)
|
||||
entity.getPersistentData()
|
||||
.putInt("VisualBacktankAir", Math.round(backtanks.stream()
|
||||
.map(BacktankUtil.BacktankWrapper::getAir)
|
||||
.map(IAirSource::getAir)
|
||||
.reduce(0f, Float::sum)));
|
||||
|
||||
if (!second)
|
||||
return;
|
||||
|
||||
// BacktankUtil.consumeAir(entity, backtanks.get(0), 1);
|
||||
backtanks.get(0).consumeAir(entity, 1);
|
||||
|
||||
if (lavaDiving)
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.simibubi.create.content.equipment.armor;
|
|||
|
||||
import com.simibubi.create.AllItems;
|
||||
|
||||
import com.simibubi.create.content.equipment.armor.backtank_utils.BacktankAirSource;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
|
@ -34,7 +36,7 @@ public final class NetheriteDivingHandler {
|
|||
clearBit(entity, slot);
|
||||
}
|
||||
} else if (slot == EquipmentSlot.CHEST) {
|
||||
if (AllItems.NETHERITE_BACKTANK.isIn(to) && BacktankUtil.hasAirRemaining(to)) {
|
||||
if (AllItems.NETHERITE_BACKTANK.isIn(to) && BacktankAirSource.hasAirRemaining(to)) {
|
||||
setBit(entity, slot);
|
||||
} else {
|
||||
clearBit(entity, slot);
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.content.equipment.armor;
|
|||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.content.equipment.armor.backtank_utils.IAirSource;
|
||||
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
||||
import com.simibubi.create.foundation.utility.Color;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
|
@ -61,7 +62,7 @@ public class RemainingAirOverlay implements IIngameOverlay {
|
|||
}
|
||||
|
||||
public static ItemStack getDisplayedBacktank(LocalPlayer player) {
|
||||
List<BacktankUtil.BacktankWrapper> backtanks = BacktankUtil.getAllWithAir(player);
|
||||
List<IAirSource> backtanks = BacktankUtil.getAllWithAir(player);
|
||||
if (!backtanks.isEmpty()) {
|
||||
return backtanks.get(0).getDisplayedBacktank();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
package com.simibubi.create.content.equipment.armor.backtank_utils;
|
||||
|
||||
import com.simibubi.create.AllEnchantments;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
|
||||
public class BacktankAirSource implements IAirSource {
|
||||
private final ItemStack backtankStack;
|
||||
|
||||
public BacktankAirSource(ItemStack backtankStack) {
|
||||
this.backtankStack = backtankStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAir() {
|
||||
return getAir(backtankStack);
|
||||
}
|
||||
|
||||
// public int maxAir() {
|
||||
// return maxAir(backtankStack);
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
public void consumeAir(LivingEntity entity, float i) {
|
||||
consumeAir(entity, backtankStack, i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAirRemaining() {
|
||||
return hasAirRemaining(backtankStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBarWidth() {
|
||||
return backtankStack.getBarWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBarColor() {
|
||||
return backtankStack.getBarColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFireResistant() {
|
||||
return backtankStack.getItem().isFireResistant();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getDisplayedBacktank() {
|
||||
return backtankStack;
|
||||
}
|
||||
|
||||
|
||||
// Static methods moved from BacktankUtil
|
||||
|
||||
public static boolean hasAirRemaining(ItemStack backtank) {
|
||||
return getAir(backtank) > 0;
|
||||
}
|
||||
|
||||
public static float getAir(ItemStack backtank) {
|
||||
CompoundTag tag = backtank.getOrCreateTag();
|
||||
return Math.min(tag.getFloat("Air"), maxAir(backtank));
|
||||
}
|
||||
|
||||
public static void consumeAir(LivingEntity entity, ItemStack backtank, float i) {
|
||||
CompoundTag tag = backtank.getOrCreateTag();
|
||||
int maxAir = maxAir(backtank);
|
||||
float air = getAir(backtank);
|
||||
float newAir = Math.max(air - i, 0);
|
||||
tag.putFloat("Air", Math.min(newAir, maxAir));
|
||||
backtank.setTag(tag);
|
||||
|
||||
if (!(entity instanceof ServerPlayer player))
|
||||
return;
|
||||
|
||||
sendWarning(player, air, newAir, maxAir / 10f);
|
||||
sendWarning(player, air, newAir, 1);
|
||||
}
|
||||
|
||||
private static void sendWarning(ServerPlayer player, float air, float newAir, float threshold) {
|
||||
if (newAir > threshold)
|
||||
return;
|
||||
if (air <= threshold)
|
||||
return;
|
||||
|
||||
boolean depleted = threshold == 1;
|
||||
MutableComponent component = Lang.translateDirect(depleted ? "backtank.depleted" : "backtank.low");
|
||||
|
||||
AllSoundEvents.DENY.play(player.level, null, player.blockPosition(), 1, 1.25f);
|
||||
AllSoundEvents.STEAM.play(player.level, null, player.blockPosition(), .5f, .5f);
|
||||
|
||||
player.connection.send(new ClientboundSetTitlesAnimationPacket(10, 40, 10));
|
||||
player.connection.send(new ClientboundSetSubtitleTextPacket(
|
||||
Components.literal("\u26A0 ").withStyle(depleted ? ChatFormatting.RED : ChatFormatting.GOLD)
|
||||
.append(component.withStyle(ChatFormatting.GRAY))));
|
||||
player.connection.send(new ClientboundSetTitleTextPacket(Components.immutableEmpty()));
|
||||
}
|
||||
|
||||
public static int maxAir(ItemStack backtank) {
|
||||
return maxAir(EnchantmentHelper.getItemEnchantmentLevel(AllEnchantments.CAPACITY.get(), backtank));
|
||||
}
|
||||
|
||||
public static int maxAir(int enchantLevel) {
|
||||
return AllConfigs.server().equipment.airInBacktank.get()
|
||||
+ AllConfigs.server().equipment.enchantedBacktankCapacity.get() * enchantLevel;
|
||||
}
|
||||
|
||||
public static int maxAirWithoutEnchants() {
|
||||
return AllConfigs.server().equipment.airInBacktank.get();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.simibubi.create.content.equipment.armor.backtank_utils;
|
||||
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Base interface for the Air provider (such as Backtanks).
|
||||
* <p>
|
||||
* If you use Air Providers (such as implementing a tool),
|
||||
* you should use {@link com.simibubi.create.content.equipment.armor.BacktankUtil}
|
||||
* (For example, use {@link com.simibubi.create.content.equipment.armor.BacktankUtil#getAllWithAir(LivingEntity)}
|
||||
* to get player Air Sources )
|
||||
*/
|
||||
public interface IAirSource {
|
||||
float getAir();
|
||||
|
||||
// int maxAir();
|
||||
|
||||
void consumeAir(LivingEntity entity, float i);
|
||||
|
||||
boolean hasAirRemaining();
|
||||
|
||||
int getBarWidth();
|
||||
|
||||
int getBarColor();
|
||||
|
||||
boolean isFireResistant();
|
||||
|
||||
ItemStack getDisplayedBacktank();
|
||||
}
|
Loading…
Reference in a new issue