diff --git a/src/me/libraryaddict/disguise/DisguiseAPI.java b/src/me/libraryaddict/disguise/DisguiseAPI.java index d230d7af..de109dc1 100644 --- a/src/me/libraryaddict/disguise/DisguiseAPI.java +++ b/src/me/libraryaddict/disguise/DisguiseAPI.java @@ -2,6 +2,7 @@ package me.libraryaddict.disguise; import java.lang.reflect.Field; import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.TargettedDisguise; import me.libraryaddict.disguise.events.DisguiseEvent; import me.libraryaddict.disguise.events.UndisguiseEvent; import me.libraryaddict.disguise.utilities.DisguiseUtilities; @@ -36,7 +37,7 @@ public class DisguiseAPI { Field field = ReflectionManager.getNmsClass("Entity").getDeclaredField("entityCount"); field.setAccessible(true); int id = field.getInt(null); - DisguiseUtilities.getDisguises().put(id, disguise); + DisguiseUtilities.addDisguise(id, (TargettedDisguise) disguise); } catch (Exception ex) { ex.printStackTrace(); } @@ -70,7 +71,7 @@ public class DisguiseAPI { } // If there was a old disguise Disguise oldDisguise = getDisguise(entity); // Stick the disguise in the disguises bin - DisguiseUtilities.getDisguises().put(entity.getEntityId(), disguise); + DisguiseUtilities.addDisguise(entity.getEntityId(), (TargettedDisguise) disguise); // Resend the disguised entity's packet DisguiseUtilities.refreshTrackers(entity); // If he is a player, then self disguise himself @@ -86,9 +87,7 @@ public class DisguiseAPI { public static Disguise getDisguise(Entity disguised) { if (disguised == null) return null; - if (DisguiseUtilities.getDisguises().containsKey(disguised.getEntityId())) - return DisguiseUtilities.getDisguises().get(disguised.getEntityId()); - return null; + return DisguiseUtilities.getDisguise(disguised.getEntityId()); } /** diff --git a/src/me/libraryaddict/disguise/disguisetypes/Disguise.java b/src/me/libraryaddict/disguise/disguisetypes/Disguise.java index edbba176..7742514b 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/Disguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/Disguise.java @@ -61,7 +61,7 @@ public abstract class Disguise { setReplaceSounds(doSounds); // Get if they are a adult now.. boolean isAdult = true; - if (this instanceof MobDisguise) { + if (isMobDisguise()) { isAdult = ((MobDisguise) this).isAdult(); } try { @@ -368,17 +368,14 @@ public abstract class Disguise { velocityRunnable.cancel(); } catch (Exception ex) { } - HashMap disguises = DisguiseUtilities.getDisguises(); + HashMap> disguises = DisguiseUtilities.getDisguises(); // If this disguise has a entity set if (getEntity() != null) { // If the entity is valid if (getEntity().isValid()) { // If this disguise is active - if (disguises.containsKey(getEntity().getEntityId()) && disguises.get(getEntity().getEntityId()) == this) { - // Now remove the disguise from the current disguises. - disguises.remove(getEntity().getEntityId()); - // Gotta do reflection, copy code or open up calls. - // Reflection is the cleanest? + // Remove the disguise from the current disguises. + if (DisguiseUtilities.removeDisguise((TargettedDisguise) this)) { if (getEntity() instanceof Player) { DisguiseUtilities.removeSelfDisguise((Player) getEntity()); } @@ -391,7 +388,7 @@ public abstract class Disguise { Iterator itel = disguises.keySet().iterator(); while (itel.hasNext()) { int id = itel.next(); - if (disguises.get(id) == this) { + if (disguises.get(id).remove(this) && disguises.get(id).isEmpty()) { itel.remove(); } } diff --git a/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java index 0ea7942f..e11652d1 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java @@ -11,7 +11,7 @@ import org.bukkit.Art; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; -public class MiscDisguise extends Disguise { +public class MiscDisguise extends TargettedDisguise { private int data = -1; private int id = -1; diff --git a/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java index b4bca238..09f442b9 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java @@ -5,7 +5,7 @@ import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; import org.bukkit.entity.EntityType; -public class MobDisguise extends Disguise { +public class MobDisguise extends TargettedDisguise { private boolean isAdult; diff --git a/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java index 00c7036b..d0621efd 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java @@ -1,6 +1,6 @@ package me.libraryaddict.disguise.disguisetypes; -public class PlayerDisguise extends Disguise { +public class PlayerDisguise extends TargettedDisguise { private String playerName; public PlayerDisguise(String name) { diff --git a/src/me/libraryaddict/disguise/disguisetypes/TargettedDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/TargettedDisguise.java new file mode 100644 index 00000000..950f2b15 --- /dev/null +++ b/src/me/libraryaddict/disguise/disguisetypes/TargettedDisguise.java @@ -0,0 +1,34 @@ +package me.libraryaddict.disguise.disguisetypes; + +import java.util.HashSet; + +import org.bukkit.entity.Player; + +public abstract class TargettedDisguise extends Disguise { + public enum TargetType { + SHOW_TO_THESE, HIDE_FROM_THESE; + } + + private HashSet disguiseViewers = new HashSet(); + private TargetType targetType = TargetType.HIDE_FROM_THESE; + + public boolean canSee(Player player) { + return canSee(player.getName()); + } + + public boolean canSee(String playername) { + return disguiseViewers.contains(playername); + } + + public void setViewDisguise(Player player) { + setViewDisguise(player.getName()); + } + + public void setViewDisguise(String playername) { + disguiseViewers.add(playername); + } + + public TargetType getTargetType() { + return targetType; + } +} diff --git a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 15aa569c..301893ca 100644 --- a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -8,6 +8,8 @@ import java.util.Iterator; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.TargettedDisguise; +import me.libraryaddict.disguise.disguisetypes.TargettedDisguise.TargetType; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -26,14 +28,14 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher; public class DisguiseUtilities { // Store the entity IDs instead of entitys because then I can disguise entitys even before they exist - private static HashMap disguises = new HashMap(); + private static HashMap> targetedDisguises = new HashMap>(); private static LibsDisguises libsDisguises; // A internal storage of fake entity ID's I can use. // Realistically I could probably use a ID like "4" for everyone, seeing as no one shares the ID private static HashMap selfDisguisesIds = new HashMap(); - public static HashMap getDisguises() { - return disguises; + public static HashMap> getDisguises() { + return targetedDisguises; } public static HashMap getSelfDisguisesIds() { @@ -222,14 +224,62 @@ public class DisguiseUtilities { } } + public static void addDisguise(int entityId, TargettedDisguise disguise) { + if (!getDisguises().containsKey(entityId)) { + getDisguises().put(entityId, new HashSet()); + } + getDisguises().get(entityId).add(disguise); + } + + public static boolean removeDisguise(TargettedDisguise disguise) { + int entityId = disguise.getEntity().getEntityId(); + if (getDisguises().containsKey(entityId) && getDisguises().get(entityId).remove(disguise)) { + if (getDisguises().get(entityId).isEmpty()) { + getDisguises().remove(entityId); + } + return true; + } + return false; + } + + public static TargettedDisguise getDisguise(int entityId) { + TargettedDisguise toReturn = null; + if (getDisguises().containsKey(entityId)) { + for (TargettedDisguise disguise : getDisguises().get(entityId)) { + if (disguise.getTargetType() == TargetType.HIDE_FROM_THESE) { + return disguise; + } + if (toReturn == null) { + toReturn = disguise; + } + } + } + return toReturn; + } + + public static TargettedDisguise getDisguise(Player observer, int entityId) { + if (getDisguises().containsKey(entityId)) { + for (TargettedDisguise disguise : getDisguises().get(entityId)) { + if (disguise.getTargetType() == TargetType.HIDE_FROM_THESE && !disguise.canSee(observer)) { + return disguise; + } else if (disguise.getTargetType() == TargetType.SHOW_TO_THESE && disguise.canSee(observer)) { + return disguise; + } + } + } + return null; + } + /** * Setup it so he can see himself when disguised */ public static void setupFakeDisguise(final Disguise disguise) { + Entity e = disguise.getEntity(); // If the disguises entity is null, or the disguised entity isn't a player return - if (disguise.getEntity() == null || !(disguise.getEntity() instanceof Player) || !disguises.containsValue(disguise)) + if (e == null || !(e instanceof Player) || !getDisguises().containsKey(e.getEntityId()) + || !getDisguises().get(e).contains(disguise)) return; - Player player = (Player) disguise.getEntity(); + Player player = (Player) e; // Remove the old disguise, else we have weird disguises around the place DisguiseUtilities.removeSelfDisguise(player); // If the disguised player can't see himself. Return