package tc.oc.pgm.tracker; import java.util.Set; import javax.annotation.Nullable; import javax.inject.Inject; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.projectiles.BlockProjectileSource; import org.bukkit.projectiles.ProjectileSource; import tc.oc.pgm.match.MatchPlayerFinder; import tc.oc.pgm.tracker.damage.DamageInfo; import tc.oc.pgm.tracker.damage.NullDamageInfo; import tc.oc.pgm.tracker.damage.PhysicalInfo; import tc.oc.pgm.tracker.resolvers.DamageResolver; import tc.oc.pgm.tracker.trackers.BlockTracker; import tc.oc.pgm.tracker.trackers.EntityTracker; class MasterResolver implements EventResolver, ProjectileResolver { private final MatchPlayerFinder players; private final EntityTracker entityTracker; private final BlockTracker blockTracker; private final Set<DamageResolver> damageResolvers; @Inject MasterResolver(MatchPlayerFinder players, EntityTracker entityTracker, BlockTracker blockTracker, Set<DamageResolver> damageResolvers) { this.players = players; this.entityTracker = entityTracker; this.blockTracker = blockTracker; this.damageResolvers = damageResolvers; } @Override public DamageInfo resolveDamage(EntityDamageEvent.DamageCause damageType, Entity victim, @Nullable Block damager) { if(damager == null) return resolveDamage(damageType, victim); return resolveDamage(damageType, victim, blockTracker.resolveBlock(damager)); } @Override public DamageInfo resolveDamage(EntityDamageEvent.DamageCause damageType, Entity victim, @Nullable Entity damager) { if(damager == null) return resolveDamage(damageType, victim); return resolveDamage(damageType, victim, entityTracker.resolveEntity(damager)); } @Override public DamageInfo resolveDamage(EntityDamageEvent.DamageCause damageType, Entity victim, @Nullable PhysicalInfo damager) { // Filter out observers immediately if(!players.canInteract(victim)) return new NullDamageInfo(); for(DamageResolver resolver : damageResolvers) { DamageInfo resolvedInfo = resolver.resolveDamage(damageType, victim, damager); if(resolvedInfo != null) { return resolvedInfo; } } // This should never happen return new NullDamageInfo(); } @Override public @Nullable PhysicalInfo resolveShooter(ProjectileSource source) { if(source instanceof Entity) { return entityTracker.resolveEntity((Entity) source); } else if(source instanceof BlockProjectileSource) { return blockTracker.resolveBlock(((BlockProjectileSource) source).getBlock()); } return null; } }