diff --git a/src/main/java/WayofTime/bloodmagic/core/data/SoulNetwork.java b/src/main/java/WayofTime/bloodmagic/core/data/SoulNetwork.java index 046c6b61..d0686067 100644 --- a/src/main/java/WayofTime/bloodmagic/core/data/SoulNetwork.java +++ b/src/main/java/WayofTime/bloodmagic/core/data/SoulNetwork.java @@ -1,24 +1,27 @@ package WayofTime.bloodmagic.core.data; -import WayofTime.bloodmagic.util.BMLog; -import WayofTime.bloodmagic.util.DamageSourceBloodMagic; -import WayofTime.bloodmagic.event.AddToNetworkEvent; import WayofTime.bloodmagic.event.SoulNetworkEvent; +import WayofTime.bloodmagic.util.BMLog; +import WayofTime.bloodmagic.util.BooleanResult; +import WayofTime.bloodmagic.util.DamageSourceBloodMagic; import WayofTime.bloodmagic.util.helper.PlayerHelper; -import com.google.common.base.Strings; +import com.google.common.collect.EvictingQueue; +import com.google.common.collect.ImmutableList; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.MobEffects; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.INBTSerializable; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.eventhandler.Event; import javax.annotation.Nullable; +import java.util.List; +import java.util.Queue; import java.util.UUID; public class SoulNetwork implements INBTSerializable { + + private final Queue ticketHistory; private BMWorldSavedData parent; private EntityPlayer cachedPlayer; private UUID playerId; @@ -27,72 +30,93 @@ public class SoulNetwork implements INBTSerializable { private SoulNetwork() { // No-op - For creation via NBT only + ticketHistory = EvictingQueue.create(16); } - public int add(int toAdd, int maximum) { - AddToNetworkEvent event = new AddToNetworkEvent(playerId.toString(), toAdd, maximum); - + public int add(SoulTicket ticket, int maximum) { + SoulNetworkEvent.Fill event = new SoulNetworkEvent.Fill(this, ticket, maximum); if (MinecraftForge.EVENT_BUS.post(event)) return 0; - if (FMLCommonHandler.instance().getMinecraftServerInstance() == null) - return 0; - int currEss = getCurrentEssence(); - if (currEss >= event.maximum) + if (currEss >= event.getMaximum()) return 0; - int newEss = Math.min(event.maximum, currEss + event.addedAmount); - if (event.getResult() != Event.Result.DENY) - setCurrentEssence(newEss); + int newEss = Math.min(event.getMaximum(), currEss + event.getTicket().getAmount()); + setCurrentEssence(newEss); + ticketHistory.add(ticket); return newEss - currEss; } /** - * @deprecated - Please use {@link #add(int, int)} + * @deprecated For future proofing, use {@link #add(SoulTicket, int)} instead. + */ + @Deprecated + public int add(int toAdd, int maximum) { + return add(new SoulTicket(toAdd), maximum); + } + + /** + * @deprecated Use {@link #add(SoulTicket, int)} instead. */ @Deprecated public int addLifeEssence(int toAdd, int maximum) { return add(toAdd, maximum); } - public int syphon(int syphon) { + public int syphon(SoulTicket ticket) { + return syphon(ticket, false); + } + + public int syphon(SoulTicket ticket, boolean skipEvent) { + SoulNetworkEvent.Syphon event = new SoulNetworkEvent.Syphon(this, ticket); + if (!skipEvent && MinecraftForge.EVENT_BUS.post(event)) + return 0; + + int syphon = event.getTicket().getAmount(); if (getCurrentEssence() >= syphon) { setCurrentEssence(getCurrentEssence() - syphon); + ticketHistory.add(ticket); return syphon; } return 0; } - public boolean syphonAndDamage(EntityPlayer user, int toSyphon) { - if (user != null) { - if (user.getEntityWorld().isRemote) - return false; + /** + * @deprecated For future proofing, use {@link #syphon(SoulTicket)} instead. + */ + @Deprecated + public int syphon(int amount) { + return syphon(new SoulTicket(amount)); + } - if (!Strings.isNullOrEmpty(playerId.toString())) { - SoulNetworkEvent.ItemDrainNetworkEvent event = new SoulNetworkEvent.ItemDrainNetworkEvent(user, playerId, null, toSyphon); + public BooleanResult syphonAndDamage(EntityPlayer user, SoulTicket ticket) { + if (user.getEntityWorld().isRemote) + return BooleanResult.newResult(false, 0); - if (MinecraftForge.EVENT_BUS.post(event)) - return false; + SoulNetworkEvent.Syphon.User event = new SoulNetworkEvent.Syphon.User(this, ticket, user); - int drainAmount = syphon(event.syphon); + if (MinecraftForge.EVENT_BUS.post(event)) + return BooleanResult.newResult(false, 0); - if (drainAmount <= 0 || event.shouldDamage) - hurtPlayer(user, event.syphon); + int drainAmount = syphon(event.getTicket(), true); - return event.getResult() != Event.Result.DENY; - } + if (drainAmount <= 0 || event.shouldDamage()) + hurtPlayer(user, event.getTicket().getAmount()); - int amount = syphon(toSyphon); - hurtPlayer(user, toSyphon - amount); + ticketHistory.add(ticket); + return BooleanResult.newResult(true, event.getTicket().getAmount()); + } - return true; - } - - return false; + /** + * @deprecated Use {@link #syphonAndDamage(EntityPlayer, SoulTicket)} instead. + */ + @Deprecated + public boolean syphonAndDamage(EntityPlayer user, int amount) { + return syphonAndDamage(user, new SoulTicket(amount)).isSuccess(); } public void causeNausea() { @@ -180,6 +204,10 @@ public class SoulNetwork implements INBTSerializable { return this; } + public List getTicketHistory() { + return ImmutableList.copyOf(ticketHistory); + } + // INBTSerializable @Override diff --git a/src/main/java/WayofTime/bloodmagic/core/data/SoulTicket.java b/src/main/java/WayofTime/bloodmagic/core/data/SoulTicket.java new file mode 100644 index 00000000..1f9c4c60 --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/core/data/SoulTicket.java @@ -0,0 +1,33 @@ +package WayofTime.bloodmagic.core.data; + +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; + +public class SoulTicket { + + private static final ITextComponent EMPTY = new TextComponentString(""); + + private final ITextComponent description; + private final int amount; + + public SoulTicket(ITextComponent description, int amount) { + this.description = description; + this.amount = amount; + } + + public SoulTicket(int amount) { + this(EMPTY, amount); + } + + public boolean isSyphon() { + return amount < 0; + } + + public ITextComponent getDescription() { + return description; + } + + public int getAmount() { + return amount; + } +} diff --git a/src/main/java/WayofTime/bloodmagic/event/SoulNetworkEvent.java b/src/main/java/WayofTime/bloodmagic/event/SoulNetworkEvent.java index cb962fdd..560b19a5 100644 --- a/src/main/java/WayofTime/bloodmagic/event/SoulNetworkEvent.java +++ b/src/main/java/WayofTime/bloodmagic/event/SoulNetworkEvent.java @@ -1,86 +1,99 @@ package WayofTime.bloodmagic.event; +import WayofTime.bloodmagic.core.data.SoulNetwork; +import WayofTime.bloodmagic.core.data.SoulTicket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.common.eventhandler.Cancelable; import net.minecraftforge.fml.common.eventhandler.Event; -import javax.annotation.Nullable; -import java.util.UUID; - -/** - * Base event class for Soul Network related events. - *

- * {@link #ownerUUID} contains the owner's UUID {@link #syphon} contains the - * amount of LP to be drained - */ public class SoulNetworkEvent extends Event { - public final UUID ownerUUID; - public int syphon; - public SoulNetworkEvent(UUID ownerUUID, int syphon) { - this.ownerUUID = ownerUUID; - this.syphon = syphon; + private final SoulNetwork network; + private SoulTicket ticket; + + public SoulNetworkEvent(SoulNetwork network, SoulTicket ticket) { + this.network = network; + this.ticket = ticket; } - /** - * This event is called when an - * {@link WayofTime.bloodmagic.iface.IBindable} is being drained - * inside of a {@link net.minecraft.tileentity.TileEntity}. - *

- * If canceled, the drain will not be executed. - */ - @Cancelable - public static class ItemDrainInContainerEvent extends SoulNetworkEvent { - public ItemStack stack; + public SoulNetwork getNetwork() { + return network; + } - public ItemDrainInContainerEvent(ItemStack stack, UUID ownerId, int syphon) { - super(ownerId, syphon); - this.stack = stack; + public SoulTicket getTicket() { + return ticket; + } + + public void setTicket(SoulTicket ticket) { + this.ticket = ticket; + } + + @Cancelable + public static class Syphon extends SoulNetworkEvent { + + private boolean shouldDamage; + + public Syphon(SoulNetwork network, SoulTicket ticket) { + super(network, ticket); } - } - /** - * This event is called when a {@link EntityPlayer} drains the Soul Network - *

- * If canceled, the drain will not be executed. - */ - @Cancelable - public static class PlayerDrainNetworkEvent extends SoulNetworkEvent { - public final EntityPlayer player; - // If true, will damage regardless of if the network had enough inside it - public boolean shouldDamage; + public boolean shouldDamage() { + return shouldDamage; + } - public PlayerDrainNetworkEvent(EntityPlayer player, UUID ownerId, int drainAmount) { - super(ownerId, drainAmount); - this.shouldDamage = false; - this.player = player; + public void setShouldDamage(boolean shouldDamage) { + this.shouldDamage = shouldDamage; + } + + public static class Item extends Syphon { + + private final ItemStack stack; + + public Item(SoulNetwork network, SoulTicket ticket, ItemStack stack) { + super(network, ticket); + + this.stack = stack; + } + + public ItemStack getStack() { + return stack; + } + } + + public static class User extends Syphon { + + private final EntityPlayer user; + + public User(SoulNetwork network, SoulTicket ticket, EntityPlayer user) { + super(network, ticket); + + this.user = user; + } + + public EntityPlayer getUser() { + return user; + } } } @Cancelable - public static class ItemDrainNetworkEvent extends PlayerDrainNetworkEvent { - @Nullable - public final ItemStack itemStack; - /** - * Amount of damage that would incur if the network could not drain - * properly - */ - public float damageAmount; + public static class Fill extends SoulNetworkEvent { - /** - * Set result to deny the action i.e. damage/drain anyways. Cancelling - * event prevents action without penalties - * - * @param player Player using the item - * @param ownerId Network that the item is tied to - * @param itemStack Item used - * @param drainAmount Original drain amount - change to alter cost - */ - public ItemDrainNetworkEvent(EntityPlayer player, UUID ownerId, @Nullable ItemStack itemStack, int drainAmount) { - super(player, ownerId, drainAmount); - this.itemStack = itemStack; - this.damageAmount = (float) (drainAmount) / 100.0f; + private int maximum; + + public Fill(SoulNetwork network, SoulTicket ticket, int maximum) { + super(network, ticket); + + this.maximum = maximum; + } + + public int getMaximum() { + return maximum; + } + + public void setMaximum(int maximum) { + this.maximum = maximum; } } } diff --git a/src/main/java/WayofTime/bloodmagic/util/BooleanResult.java b/src/main/java/WayofTime/bloodmagic/util/BooleanResult.java new file mode 100644 index 00000000..c4cb571f --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/util/BooleanResult.java @@ -0,0 +1,24 @@ +package WayofTime.bloodmagic.util; + +public class BooleanResult { + + private final boolean result; + private final T value; + + private BooleanResult(boolean result, T value) { + this.result = result; + this.value = value; + } + + public boolean isSuccess() { + return result; + } + + public T getValue() { + return value; + } + + public static BooleanResult newResult(boolean success, T value) { + return new BooleanResult<>(success, value); + } +} diff --git a/src/main/java/WayofTime/bloodmagic/util/helper/NetworkHelper.java b/src/main/java/WayofTime/bloodmagic/util/helper/NetworkHelper.java index bdc7f096..dbd07fc5 100644 --- a/src/main/java/WayofTime/bloodmagic/util/helper/NetworkHelper.java +++ b/src/main/java/WayofTime/bloodmagic/util/helper/NetworkHelper.java @@ -1,8 +1,9 @@ package WayofTime.bloodmagic.util.helper; import WayofTime.bloodmagic.core.data.Binding; -import WayofTime.bloodmagic.iface.IBindable; +import WayofTime.bloodmagic.core.data.SoulTicket; import WayofTime.bloodmagic.event.SoulNetworkEvent; +import WayofTime.bloodmagic.iface.IBindable; import WayofTime.bloodmagic.orb.BloodOrb; import WayofTime.bloodmagic.orb.IBloodOrb; import WayofTime.bloodmagic.core.registry.OrbRegistry; @@ -97,7 +98,7 @@ public class NetworkHelper { * @param user - User of the item. * @param toSyphon - Amount of LP to syphon * @return - Whether the action should be performed. - * @deprecated Use {@link #getSoulNetwork(EntityPlayer)} and {@link SoulNetwork#syphonAndDamage(EntityPlayer, int)} + * @deprecated Use {@link #getSoulNetwork(EntityPlayer)} and {@link SoulNetwork#syphonAndDamage(EntityPlayer, SoulTicket)} */ @Deprecated public static boolean syphonAndDamage(SoulNetwork soulNetwork, EntityPlayer user, int toSyphon) { @@ -128,9 +129,9 @@ public class NetworkHelper { return false; SoulNetwork network = getSoulNetwork(binding); - SoulNetworkEvent.ItemDrainInContainerEvent event = new SoulNetworkEvent.ItemDrainInContainerEvent(stack, binding.getOwnerId(), toSyphon); + SoulNetworkEvent.Syphon.Item event = new SoulNetworkEvent.Syphon.Item(network, new SoulTicket(toSyphon), stack); - return !MinecraftForge.EVENT_BUS.post(event) && network.syphon(event.syphon) >= toSyphon; + return !MinecraftForge.EVENT_BUS.post(event) && network.syphon(event.getTicket(), true) >= toSyphon; } /**