package tc.oc.pgm.tracker.trackers; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import javax.annotation.Nullable; import javax.inject.Inject; import org.bukkit.entity.Entity; import org.bukkit.entity.FallingBlock; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.ThrownPotion; import org.bukkit.event.Listener; import tc.oc.commons.core.logging.Loggers; import tc.oc.pgm.match.Match; import tc.oc.pgm.match.MatchPlayer; import tc.oc.pgm.match.ParticipantState; import tc.oc.pgm.tracker.EntityResolver; import tc.oc.pgm.tracker.damage.EntityInfo; import tc.oc.pgm.tracker.damage.FallingBlockInfo; import tc.oc.pgm.tracker.damage.MobInfo; import tc.oc.pgm.tracker.damage.OwnerInfo; import tc.oc.pgm.tracker.damage.PhysicalInfo; import tc.oc.pgm.tracker.damage.PlayerInfo; import tc.oc.pgm.tracker.damage.ThrownPotionInfo; import tc.oc.pgm.tracker.damage.TrackerInfo; import static com.google.common.base.Preconditions.checkNotNull; /** * Tracks the ownership of {@link Entity}s and resolves damage caused by them */ public class EntityTracker implements EntityResolver, Listener { private final Logger logger; private final Match match; private final Map<Entity, TrackerInfo> entities = new HashMap<>(); @Inject EntityTracker(Loggers loggers, Match match) { this.logger = loggers.get(getClass()); this.match = match; } public PhysicalInfo createEntity(Entity entity, @Nullable ParticipantState owner) { if(entity instanceof ThrownPotion) { return new ThrownPotionInfo((ThrownPotion) entity, owner); } else if(entity instanceof FallingBlock) { return new FallingBlockInfo((FallingBlock) entity, owner); } else if(entity instanceof LivingEntity) { return new MobInfo((LivingEntity) entity, owner); } else { return new EntityInfo(entity, owner); } } @Override public PhysicalInfo resolveEntity(Entity entity) { MatchPlayer player = match.getParticipant(entity); if(player != null) { return new PlayerInfo(player); } TrackerInfo info = entities.get(entity); if(info instanceof PhysicalInfo) return (PhysicalInfo) info; ParticipantState owner = info instanceof OwnerInfo ? ((OwnerInfo) info).getOwner() : null; return createEntity(entity, owner); } @Override public @Nullable TrackerInfo resolveInfo(Entity entity) { return entities.get(checkNotNull(entity)); } @Override public @Nullable ParticipantState getOwner(Entity entity) { if(entity instanceof Player) { return match.getParticipantState(entity); // Players own themselves } else { OwnerInfo info = resolveInfo(entity, OwnerInfo.class); return info == null ? null : info.getOwner(); } } public void trackEntity(Entity entity, @Nullable TrackerInfo info) { checkNotNull(entity); if(info == null) { entities.remove(entity); logger.fine("Clear entity=" + entity); } else { entities.put(entity, info); logger.fine("Track entity=" + entity + " info=" + info); } } }