diff --git a/Xplat/src/main/java/vazkii/botania/common/entity/ManaSparkEntity.java b/Xplat/src/main/java/vazkii/botania/common/entity/ManaSparkEntity.java index 0653ab208d..6bb396b7c4 100644 --- a/Xplat/src/main/java/vazkii/botania/common/entity/ManaSparkEntity.java +++ b/Xplat/src/main/java/vazkii/botania/common/entity/ManaSparkEntity.java @@ -60,7 +60,7 @@ public class ManaSparkEntity extends SparkBaseEntity implements ManaSpark { private final Set outgoingTransfers = Collections.newSetFromMap(new WeakHashMap<>()); - private final ArrayList transfersTowardsSelfToRegister = new ArrayList<>(); + private final ArrayList inboundTransfers = new ArrayList<>(); private boolean shouldFilterTransfers = true; private boolean receiverWasFull = true; @@ -105,7 +105,7 @@ public void tick() { var receiver = getAttachedManaReceiver(); SparkUpgradeType upgrade = getUpgrade(); - Collection transfers = getOutgoingTransfers(); + Collection outgoingTransfers = getOutgoingTransfers(); switch (upgrade) { case DISPERSIVE -> { @@ -171,12 +171,9 @@ public void tick() { } case DOMINANT -> { - if (receiverWasFull && !receiver.isFull()) { + if (!receiver.isFull()) { updateTransfers(); } - if (!transfersTowardsSelfToRegister.isEmpty()) { - transfersTowardsSelfToRegister.remove(transfersTowardsSelfToRegister.size() - 1).registerTransfer(this); - } } // Recessive does not need to be handled because recessive sparks get notified in all relevant cases default -> { @@ -188,9 +185,9 @@ public void tick() { checkReceiverFull(); - if (!transfers.isEmpty()) { - int manaTotal = Math.min(TRANSFER_RATE * transfers.size(), receiver.getCurrentMana()); - int count = transfers.size(); + if (!outgoingTransfers.isEmpty()) { + int manaTotal = Math.min(TRANSFER_RATE * outgoingTransfers.size(), receiver.getCurrentMana()); + int count = outgoingTransfers.size(); int manaSpent = 0; if (manaTotal > 0) { @@ -199,7 +196,7 @@ public void tick() { shouldFilterTransfers = false; } - for (ManaSpark spark : transfers) { + for (ManaSpark spark : outgoingTransfers) { count--; SparkAttachable attached = spark.getAttachedTile(); var attachedReceiver = spark.getAttachedManaReceiver(); @@ -218,6 +215,36 @@ public void tick() { receiver.receiveMana(-manaSpent); } } + if (!inboundTransfers.isEmpty()) { + int manaNeeded = Math.min(TRANSFER_RATE * inboundTransfers.size(), tile.getAvailableSpaceForMana()); + int count = inboundTransfers.size(); + int manaRecieved = 0; + + if (manaNeeded > 0) { + if (shouldFilterTransfers) { + filterTransfers(); + shouldFilterTransfers = false; + } + + inboundTransfers.sort(Comparator.comparingInt(s -> s.getAttachedManaReceiver().getCurrentMana())); + for (ManaSpark spark : inboundTransfers) { + count--; + SparkAttachable attached = spark.getAttachedTile(); + var attachedReceiver = spark.getAttachedManaReceiver(); + if (attached == null || attachedReceiver == null) { + shouldFilterTransfers = true; + continue; + } + + int gained = Math.min(attachedReceiver.getCurrentMana(), (manaNeeded - manaRecieved) / (count + 1)); + attachedReceiver.receiveMana(-gained); + manaRecieved += gained; + + particlesFrom(spark.entity()); + } + receiver.receiveMana(manaRecieved); + } + } firstTick = false; } @@ -234,7 +261,8 @@ public void checkReceiverFull() { @Override public void updateTransfers() { - transfersTowardsSelfToRegister.clear(); + inboundTransfers.clear(); + outgoingTransfers.clear(); switch (getUpgrade()) { case RECESSIVE -> { var otherSparks = SparkHelper.getSparksAround(level(), getX(), getY() + (getBbHeight() / 2), getZ(), getNetwork()); @@ -251,13 +279,13 @@ public void updateTransfers() { } case DOMINANT -> { List validSparks = SparkHelper.getSparksAround(level(), getX(), getY() + (getBbHeight() / 2), getZ(), getNetwork()); + Collections.shuffle(validSparks); for (var spark : validSparks) { SparkUpgradeType otherUpgrade = spark.getUpgrade(); if (spark != this && otherUpgrade == SparkUpgradeType.NONE && spark.getAttachedManaReceiver() instanceof ManaPool) { - transfersTowardsSelfToRegister.add(spark); + inboundTransfers.add(spark); } } - Collections.shuffle(transfersTowardsSelfToRegister); } } filterTransfers(); @@ -268,6 +296,11 @@ private void particlesTowards(Entity e) { getId(), e.getId(), ColorHelper.getColorValue(getNetwork()))); } + private void particlesFrom(Entity e) { + XplatAbstractions.INSTANCE.sendToTracking(this, new BotaniaEffectPacket(EffectType.SPARK_MANA_FLOW, e.getX(), e.getY(), e.getZ(), + e.getId(), getId(), ColorHelper.getColorValue(getNetwork()))); + } + public static void particleBeam(Player player, Entity e1, Entity e2) { if (e1 != null && e2 != null && !e1.level().isClientSide) { XplatAbstractions.INSTANCE.sendToPlayer(player, new BotaniaEffectPacket(EffectType.SPARK_NET_INDICATOR, @@ -370,10 +403,10 @@ public ManaReceiver getAttachedManaReceiver() { } private void filterTransfers() { + SparkUpgradeType upgr = getUpgrade(); Iterator iter = outgoingTransfers.iterator(); while (iter.hasNext()) { ManaSpark spark = iter.next(); - SparkUpgradeType upgr = getUpgrade(); SparkUpgradeType supgr = spark.getUpgrade(); ManaReceiver arecv = spark.getAttachedManaReceiver(); @@ -389,6 +422,24 @@ private void filterTransfers() { iter.remove(); } } + + Iterator iter2 = inboundTransfers.iterator(); + while (iter2.hasNext()) { + ManaSpark spark = iter2.next(); + SparkUpgradeType supgr = spark.getUpgrade(); + ManaReceiver arecv = spark.getAttachedManaReceiver(); + + if (spark == this + || !((Entity) spark).isAlive() + || getNetwork() != spark.getNetwork() + || arecv == null + || arecv.getCurrentMana() == 0 + || getAttachedManaReceiver().isFull() + || !(upgr == SparkUpgradeType.DOMINANT && supgr == SparkUpgradeType.NONE + || !(arecv instanceof ManaPool))) { + iter2.remove(); + } + } } @Override