@Override
 public long getLongValue(
     @Nullable final Object criterionUser,
     @Nullable final Object criterionTarget,
     @Nullable final Object criterionContent,
     @Nullable final Object criterionContext) {
   if (criterionContext == null) {
     throw new CriteriaExecutionException("Pas de contexte...");
   }
   final AbstractFight<?> fight = CriteriaUtils.getFight(criterionUser, criterionContext);
   if (fight == null) {
     throw new CriteriaExecutionException("Impossible de r\u00e9cup\u00e9rer le combat");
   }
   final byte type = (byte) (this.m_monsters ? 1 : 0);
   final Collection<? extends BasicCharacterInfo> fighters =
       fight.getFighters(
           ProtagonistFilter.inPlay(),
           ProtagonistFilter.ofType(type),
           ProtagonistFilter.not(
               ProtagonistFilter.hasProperty(WorldPropertyType.NOT_PRESENT_IN_TIMELINE)));
   short level = 0;
   for (final BasicCharacterInfo f : fighters) {
     level += f.getLevel();
   }
   return level;
 }
 @Override
 public int getValidity(
     final Object criterionUser,
     final Object criterionTarget,
     final Object criterionContent,
     final Object criterionContext) {
   final CriterionUser targetCharacter =
       CriteriaUtils.getTargetCriterionUserFromParameters(
           this.m_target, criterionUser, criterionTarget, criterionContext, criterionContent);
   final byte worldPropertyId = (byte) this.getWorldPropertyId();
   final WorldPropertyType property = WorldPropertyType.getPropertyFromId(worldPropertyId);
   if (property == null) {
     throw new CriteriaExecutionException(
         "Le param\u00e8tre du crit\u00e8re HasWorldProperty doit \u00eatre un id de WorldPropertyType valide (id="
             + worldPropertyId
             + " n'existe pas)");
   }
   final boolean hasProperty = targetCharacter.hasProperty(property);
   if (!hasProperty) {
     return -1;
   }
   if (this.m_durationToCheck == null) {
     return 0;
   }
   final long duration = this.getDurationToCheck() * 1000L;
   if (System.currentTimeMillis()
           - AbstractMonsterTimedPropertyManager.getStateStartTime(
               targetCharacter.getId(), property)
       < duration) {
     return -1;
   }
   return 0;
 }
 @Override
 public long getLongValue(
     final Object criterionUser,
     final Object criterionTarget,
     final Object criterionContent,
     final Object criterionContext) {
   if (criterionContext == null) {
     throw new CriteriaExecutionException("Pas de contexte...");
   }
   final AbstractFight<?> fight = CriteriaUtils.getFight(criterionUser, criterionContext);
   if (fight == null) {
     throw new CriteriaExecutionException("Impossible de r\u00e9cup\u00e9rer le combat");
   }
   this.hook(criterionUser, criterionTarget, criterionContext, criterionContent);
   final CriterionUser user =
       CriteriaUtils.getTargetCriterionUserFromParameters(
           false, criterionUser, criterionTarget, criterionContext, criterionContent);
   Point3 center = null;
   CriterionUser targetCharacter = null;
   if (!this.m_target) {
     if (user != null) {
       center = user.getPosition();
     }
   } else if (criterionTarget instanceof Point3) {
     center = (Point3) criterionTarget;
   } else {
     targetCharacter =
         CriteriaUtils.getTargetCriterionUserFromParameters(
             true, criterionUser, criterionTarget, criterionContext, criterionContent);
     if (targetCharacter != null) {
       center = targetCharacter.getPosition();
     }
   }
   if (center == null) {
     return 0L;
   }
   final Collection<? extends EffectUser> fighters = this.getFighters(fight, user);
   final Iterator<? extends EffectUser> it = fighters.iterator();
   while (it.hasNext()) {
     final EffectUser fighter = (EffectUser) it.next();
     if (fighter.isActiveProperty(FightPropertyType.CANNOT_BE_EFFECT_TARGET)) {
       it.remove();
     }
   }
   final long maxRange =
       this.m_maxRange.getLongValue(
           criterionUser, criterionTarget, criterionContent, criterionContext);
   if (maxRange <= 0L) {
     return super.getSign() * fighters.size();
   }
   final long minRange =
       (this.m_minRange == null)
           ? 0L
           : this.m_minRange.getLongValue(
               criterionUser, criterionTarget, criterionContent, criterionContext);
   final boolean inLine =
       this.m_inLine != null
           && this.m_inLine.isValid(
               criterionUser, criterionTarget, criterionContent, criterionContext);
   final boolean testLoS =
       this.m_testLoS != null
           && this.m_testLoS.isValid(
               criterionUser, criterionTarget, criterionContent, criterionContext);
   long value = 0L;
   for (final EffectUser fighter2 : fighters) {
     int distanceBetweenUserAndFighter;
     if (targetCharacter != null) {
       distanceBetweenUserAndFighter =
           DistanceUtils.getIntersectionDistance(fighter2, targetCharacter);
     } else {
       distanceBetweenUserAndFighter = DistanceUtils.getIntersectionDistance(fighter2, center);
     }
     if (distanceBetweenUserAndFighter <= maxRange && distanceBetweenUserAndFighter >= minRange) {
       final Point3 fighterPosition = fighter2.getPosition();
       if (inLine
           && center.getX() != fighterPosition.getX()
           && center.getY() != fighterPosition.getY()) {
         continue;
       }
       if (testLoS) {
         final FightMap fightMap = fight.getFightMap();
         final LineOfSightChecker losChecker = LineOfSightChecker.checkOut();
         losChecker.setTopologyMapInstanceSet(fightMap);
         losChecker.setStartPoint(center.getX(), center.getY(), center.getZ());
         losChecker.setEndPoint(
             fighterPosition.getX(), fighterPosition.getY(), fighterPosition.getZ());
         if (!losChecker.checkLOS()) {
           continue;
         }
       }
       ++value;
     }
   }
   return super.getSign() * value;
 }