Initial work of separating BackTank ItemStack specific calls into an interface

This commit is contained in:
Lgmrszd 2023-07-10 14:13:55 +03:00
parent 0bfd98fccd
commit 68ba30e122
No known key found for this signature in database
GPG key ID: D8E0CC2BFF5D4D9B
3 changed files with 99 additions and 31 deletions

View file

@ -3,6 +3,7 @@ package com.simibubi.create.content.equipment.armor;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import com.simibubi.create.AllEnchantments;
import com.simibubi.create.AllSoundEvents;
@ -29,8 +30,8 @@ import net.minecraftforge.fml.DistExecutor;
public class BacktankUtil {
private static final List<Function<LivingEntity, List<ItemStack>>> BACKTANK_SUPPLIERS = new ArrayList<>();
private static final List<Function<LivingEntity, List<BacktankWrapper>>> BACKTANK_SUPPLIERS = new ArrayList<>();
static {
addBacktankSupplier(entity -> {
List<ItemStack> stacks = new ArrayList<>();
@ -42,23 +43,25 @@ public class BacktankUtil {
});
}
public static List<ItemStack> getAllWithAir(LivingEntity entity) {
List<ItemStack> all = new ArrayList<>();
public static List<BacktankWrapper> getAllWithAir(LivingEntity entity) {
List<BacktankWrapper> all = new ArrayList<>();
for (Function<LivingEntity, List<ItemStack>> supplier : BACKTANK_SUPPLIERS) {
List<ItemStack> result = supplier.apply(entity);
for (Function<LivingEntity, List<BacktankWrapper>> supplier : BACKTANK_SUPPLIERS) {
List<BacktankWrapper> result = supplier.apply(entity);
for (ItemStack stack : result)
if (hasAirRemaining(stack))
for (BacktankWrapper stack : result)
if (stack.hasAirRemaining())
all.add(stack);
}
// Sort with ascending order (we want to prioritize the most empty so things actually run out)
all.sort((a, b) -> Float.compare(getAir(a), getAir(b)));
all.sort((a, b) -> Float.compare(a.getAir(), b.getAir()));
return all;
}
// BackTank-specific functions - could be moved to DefaultBacktankWrapper
public static boolean hasAirRemaining(ItemStack backtank) {
return getAir(backtank) > 0;
}
@ -78,7 +81,7 @@ public class BacktankUtil {
if (!(entity instanceof ServerPlayer player))
return;
sendWarning(player, air, newAir, maxAir / 10f);
sendWarning(player, air, newAir, 1);
}
@ -115,16 +118,18 @@ public class BacktankUtil {
return AllConfigs.server().equipment.airInBacktank.get();
}
// BackTank-agnostic functions
public static boolean canAbsorbDamage(LivingEntity entity, int usesPerTank) {
if (usesPerTank == 0)
return true;
if (entity instanceof Player && ((Player) entity).isCreative())
return true;
List<ItemStack> backtanks = getAllWithAir(entity);
List<BacktankWrapper> backtanks = getAllWithAir(entity);
if (backtanks.isEmpty())
return false;
float cost = ((float) maxAirWithoutEnchants()) / usesPerTank;
consumeAir(entity, backtanks.get(0), cost);
backtanks.get(0).consumeAir(entity, cost);
return true;
}
@ -136,7 +141,7 @@ public class BacktankUtil {
Player player = DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> () -> Minecraft.getInstance().player);
if (player == null)
return false;
List<ItemStack> backtanks = getAllWithAir(player);
List<BacktankWrapper> backtanks = getAllWithAir(player);
if (backtanks.isEmpty())
return stack.isDamaged();
return true;
@ -149,20 +154,17 @@ public class BacktankUtil {
if (player == null)
return 13;
List<ItemStack> backtanks = getAllWithAir(player);
List<BacktankWrapper> backtanks = getAllWithAir(player);
if (backtanks.isEmpty())
return Math.round(13.0F - (float) stack.getDamageValue() / stack.getMaxDamage() * 13.0F);
if (backtanks.size() == 1)
return backtanks.get(0)
.getItem()
.getBarWidth(backtanks.get(0));
return backtanks.get(0).getBarWidth();
// If there is more than one backtank, average the bar widths.
int sumBarWidth = backtanks.stream()
.map(backtank -> backtank.getItem()
.getBarWidth(backtank))
.map(BacktankWrapper::getBarWidth)
.reduce(0, Integer::sum);
return Math.round((float) sumBarWidth / backtanks.size());
@ -174,17 +176,15 @@ public class BacktankUtil {
Player player = DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> () -> Minecraft.getInstance().player);
if (player == null)
return 0;
List<ItemStack> backtanks = getAllWithAir(player);
List<BacktankWrapper> backtanks = getAllWithAir(player);
// Fallback colour
if (backtanks.isEmpty())
return Mth.hsvToRgb(Math.max(0.0F, 1.0F - (float) stack.getDamageValue() / stack.getMaxDamage()) / 3.0F,
1.0F, 1.0F);
// Just return the "first" backtank for the bar color since that's the one we are consuming from
return backtanks.get(0)
.getItem()
.getBarColor(backtanks.get(0));
return backtanks.get(0).getBarColor();
}
/**
@ -192,6 +192,74 @@ public class BacktankUtil {
* slots or items.
*/
public static void addBacktankSupplier(Function<LivingEntity, List<ItemStack>> supplier) {
BACKTANK_SUPPLIERS.add(entity ->
supplier.apply(entity).stream().map(DefaultBacktankWrapper::new).collect(Collectors.toList())
);
}
public static void addBacktankWrapperSupplier(Function<LivingEntity, List<BacktankWrapper>> 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;
}
}
}

View file

@ -77,7 +77,7 @@ public class DivingHelmetItem extends BaseArmorItem {
if (entity instanceof Player && ((Player) entity).isCreative())
return;
List<ItemStack> backtanks = BacktankUtil.getAllWithAir(entity);
List<BacktankUtil.BacktankWrapper> backtanks = BacktankUtil.getAllWithAir(entity);
if (backtanks.isEmpty())
return;
@ -85,8 +85,7 @@ public class DivingHelmetItem extends BaseArmorItem {
if (entity instanceof ServerPlayer sp)
AllAdvancements.DIVING_SUIT_LAVA.awardTo(sp);
if (backtanks.stream()
.noneMatch(backtank -> backtank.getItem()
.isFireResistant()))
.noneMatch(backtank -> backtank.isFireResistant()))
return;
}
@ -96,13 +95,14 @@ public class DivingHelmetItem extends BaseArmorItem {
if (world.isClientSide)
entity.getPersistentData()
.putInt("VisualBacktankAir", Math.round(backtanks.stream()
.map(BacktankUtil::getAir)
.map(BacktankUtil.BacktankWrapper::getAir)
.reduce(0f, Float::sum)));
if (!second)
return;
BacktankUtil.consumeAir(entity, backtanks.get(0), 1);
// BacktankUtil.consumeAir(entity, backtanks.get(0), 1);
backtanks.get(0).consumeAir(entity, 1);
if (lavaDiving)
return;

View file

@ -61,9 +61,9 @@ public class RemainingAirOverlay implements IIngameOverlay {
}
public static ItemStack getDisplayedBacktank(LocalPlayer player) {
List<ItemStack> backtanks = BacktankUtil.getAllWithAir(player);
List<BacktankUtil.BacktankWrapper> backtanks = BacktankUtil.getAllWithAir(player);
if (!backtanks.isEmpty()) {
return backtanks.get(0);
return backtanks.get(0).getDisplayedBacktank();
}
return AllItems.COPPER_BACKTANK.asStack();
}