continue/armor_aura #1
@ -8,6 +8,7 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@ -19,10 +20,13 @@ public final class ProtectionAuraHandler {
|
||||
private static final float BASE_RECHARGE_RATE = 0.0005f;
|
||||
private static final float BASE_DRAIN_RATE = 0.0008f;
|
||||
|
||||
private static final float CASCADE_LOSS = 0.30f; // 30% relative
|
||||
private static final int CRITICAL_PCT = 10;
|
||||
|
||||
private ProtectionAuraHandler() {}
|
||||
|
||||
/* ==========================================================
|
||||
ENTRY POINT — CALLED SERVER SIDE
|
||||
ENTRY POINT — SERVER SIDE
|
||||
========================================================== */
|
||||
|
||||
public static void tick(PlayerEntity player) {
|
||||
@ -40,22 +44,14 @@ public final class ProtectionAuraHandler {
|
||||
float rechargeRate = BASE_RECHARGE_RATE * durabilityFactor;
|
||||
float drainRate = BASE_DRAIN_RATE * (1.0f + (1.0f - durabilityFactor));
|
||||
|
||||
float next = value;
|
||||
|
||||
if (!inChipi || protectedAura) {
|
||||
next = Math.min(1.0f, value + rechargeRate);
|
||||
} else {
|
||||
next = Math.max(0.0f, value - drainRate);
|
||||
}
|
||||
float next = (!inChipi || protectedAura)
|
||||
? Math.min(1.0f, value + rechargeRate)
|
||||
: Math.max(0.0f, value - drainRate);
|
||||
|
||||
if (next == value) return;
|
||||
|
||||
// ─────────────────────────────────────────────
|
||||
// PERCENT-BASED DURABILITY LOGIC
|
||||
// ─────────────────────────────────────────────
|
||||
int oldPercent = (int) Math.floor(value * 100f);
|
||||
int newPercent = (int) Math.floor(next * 100f);
|
||||
|
||||
int oldPercent = (int) (value * 100f);
|
||||
int newPercent = (int) (next * 100f);
|
||||
int delta = Math.abs(newPercent - oldPercent);
|
||||
|
||||
if (delta > 0) {
|
||||
@ -82,26 +78,113 @@ public final class ProtectionAuraHandler {
|
||||
========================================================== */
|
||||
|
||||
private static float getDurabilityFactor(PlayerEntity player) {
|
||||
int max = 0;
|
||||
int current = 0;
|
||||
int max = 0, current = 0;
|
||||
|
||||
for (ItemStack stack : player.getArmorItems()) {
|
||||
if (!stack.isEmpty()) {
|
||||
max += stack.getMaxDamage();
|
||||
current += (stack.getMaxDamage() - stack.getDamage());
|
||||
current += stack.getMaxDamage() - stack.getDamage();
|
||||
}
|
||||
}
|
||||
|
||||
if (max <= 0) return 0f;
|
||||
return Math.max(0f, Math.min(1f, (float) current / max));
|
||||
return Math.min(1f, (float) current / max);
|
||||
}
|
||||
|
||||
private static void damageArmor(PlayerEntity player, int amount) {
|
||||
int[] before = getArmorPercents(player);
|
||||
boolean broke = false;
|
||||
|
||||
for (ItemStack stack : player.getArmorItems()) {
|
||||
if (!stack.isEmpty()) {
|
||||
stack.damage(amount, player, p -> {});
|
||||
if (stack.getDamage() >= stack.getMaxDamage()) {
|
||||
broke = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (broke) {
|
||||
applyCascadeDamage(player, before);
|
||||
} else {
|
||||
sendWarningIfNeeded(player, before, getArmorPercents(player));
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyCascadeDamage(PlayerEntity player, int[] before) {
|
||||
for (ItemStack stack : player.getArmorItems()) {
|
||||
if (stack.isEmpty()) continue;
|
||||
|
||||
int max = stack.getMaxDamage();
|
||||
int current = max - stack.getDamage();
|
||||
if (current <= 0) continue;
|
||||
|
||||
int extra = Math.round(current * CASCADE_LOSS);
|
||||
stack.setDamage(Math.min(max, stack.getDamage() + extra));
|
||||
}
|
||||
|
||||
player.getDataTracker().set(CHIPI_ENERGY, 0f);
|
||||
sendCollapseMessage(player, before, getArmorPercents(player));
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
CHAT MESSAGES (PLAYER ONLY)
|
||||
========================================================== */
|
||||
|
||||
private static void sendWarningIfNeeded(PlayerEntity player, int[] before, int[] after) {
|
||||
boolean trigger = false;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (before[i] > CRITICAL_PCT && after[i] <= CRITICAL_PCT) {
|
||||
trigger = true;
|
||||
}
|
||||
}
|
||||
if (!trigger) return;
|
||||
|
||||
player.sendMessage(Text.literal(buildWarningMessage(after)), false);
|
||||
}
|
||||
|
||||
private static void sendCollapseMessage(PlayerEntity player, int[] before, int[] after) {
|
||||
StringBuilder sb = new StringBuilder("§c[AURA COLLAPSE]\n");
|
||||
appendPiece(sb, "Head", before[3], after[3]);
|
||||
appendPiece(sb, "Body", before[2], after[2]);
|
||||
appendPiece(sb, "Legs", before[1], after[1]);
|
||||
appendPiece(sb, "Feet", before[0], after[0]);
|
||||
player.sendMessage(Text.literal(sb.toString()), false);
|
||||
}
|
||||
|
||||
private static String buildWarningMessage(int[] pct) {
|
||||
StringBuilder sb = new StringBuilder("§6[AURA WARNING]\n");
|
||||
appendPiece(sb, "Head", pct[3]);
|
||||
appendPiece(sb, "Body", pct[2]);
|
||||
appendPiece(sb, "Legs", pct[1]);
|
||||
appendPiece(sb, "Feet", pct[0]);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void appendPiece(StringBuilder sb, String name, int pct) {
|
||||
sb.append("§7").append(name).append(": ").append(pct).append("%");
|
||||
if (pct <= CRITICAL_PCT) sb.append(" §c!!!");
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
private static void appendPiece(StringBuilder sb, String name, int before, int after) {
|
||||
sb.append("§7").append(name).append(": ")
|
||||
.append(after).append("% (was ").append(before).append("%)\n");
|
||||
}
|
||||
|
||||
private static int[] getArmorPercents(PlayerEntity player) {
|
||||
int[] out = new int[4];
|
||||
int i = 0;
|
||||
for (ItemStack stack : player.getArmorItems()) {
|
||||
if (stack.isEmpty()) {
|
||||
out[i++] = 0;
|
||||
} else {
|
||||
int max = stack.getMaxDamage();
|
||||
int cur = max - stack.getDamage();
|
||||
out[i++] = Math.max(0, (int) ((cur / (float) max) * 100f));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
@ -126,10 +209,7 @@ public final class ProtectionAuraHandler {
|
||||
|
||||
public static boolean hasAura(PlayerEntity player) {
|
||||
if (!hasFullChipperArmor(player)) return false;
|
||||
|
||||
Float value = player.getDataTracker().get(CHIPI_ENERGY);
|
||||
if (value == null || value <= 0f) return false;
|
||||
|
||||
return getDurabilityFactor(player) > 0f;
|
||||
return value != null && value > 0f && getDurabilityFactor(player) > 0f;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user