/**
  * @param WeaponlikeCode $weaponlikeCode
  * @return array|string[]
  */
 private function getWeaponTypesByWeaponCode(WeaponlikeCode $weaponlikeCode)
 {
     $types = [];
     if ($weaponlikeCode->isMelee()) {
         $types[] = self::MELEE;
     }
     if ($weaponlikeCode->isShootingWeapon()) {
         $types[] = self::SHOOTING;
     }
     if ($weaponlikeCode->isThrowingWeapon()) {
         $types[] = self::THROWING;
     }
     return $types;
 }
 /**
  * Using ranged weapon for defense is possible (it has always cover of 2) but there is 50% chance it will be
  * destroyed.
  * Note about shield: this malus is very same if used shield as a protective item as well as a weapon.
  *
  * @param WeaponlikeCode $weaponOrShield
  * @param Strength $currentStrength
  * @return int
  * @throws \DrdPlus\Tables\Armaments\Exceptions\UnknownArmament
  * @throws \DrdPlus\Tables\Armaments\Exceptions\UnknownMeleeWeaponlike
  * @throws \DrdPlus\Tables\Armaments\Weapons\Exceptions\CanNotUseWeaponBecauseOfMissingStrength
  */
 public function getDefenseNumberMalusByStrengthWithWeaponOrShield(WeaponlikeCode $weaponOrShield, Strength $currentStrength)
 {
     if ($weaponOrShield instanceof RangedWeaponCode && $weaponOrShield->isMelee()) {
         // spear can be used more effectively to cover as a melee weapon
         $weaponOrShield = $weaponOrShield->convertToMeleeWeaponCodeEquivalent();
     }
     /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
     return $this->tables->getWeaponlikeStrengthSanctionsTableByCode($weaponOrShield)->getDefenseNumberSanction($this->getMissingStrengthForArmament($weaponOrShield, $currentStrength, Size::getIt(0)));
 }
 /**
  * Note about SHIELD: "fight with" means attacking - for shield standard usage as
  * a protective armament @see \DrdPlus\Skills\Physical\PhysicalSkills::getMalusToFightNumberWithProtective
  *
  * @param WeaponlikeCode $weaponlikeCode
  * @return int
  * @throws \DrdPlus\Skills\Physical\Exceptions\PhysicalSkillsDoNotKnowHowToUseThatWeapon
  */
 private function getHighestRankForSuitableFightWithWeapon(WeaponlikeCode $weaponlikeCode)
 {
     // TODO what about 0 skill rank???
     $rankValues = [];
     if ($weaponlikeCode->isMelee()) {
         $weaponlikeCode = $weaponlikeCode->convertToMeleeWeaponCodeEquivalent();
         /** @var MeleeWeaponCode $weaponlikeCode */
         if ($weaponlikeCode->isAxe()) {
             $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightWithAxes());
         }
         if ($weaponlikeCode->isKnifeOrDagger()) {
             $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightWithKnifesAndDaggers());
         }
         if ($weaponlikeCode->isMaceOrClub()) {
             $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightWithMacesAndClubs());
         }
         if ($weaponlikeCode->isMorningstarOrMorgenstern()) {
             $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightWithMorningStarsAndMorgensterns());
         }
         if ($weaponlikeCode->isSaberOrBowieKnife()) {
             $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightWithSabersAndBowieKnifes());
         }
         if ($weaponlikeCode->isStaffOrSpear()) {
             $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightWithStaffsAndSpears());
         }
         if ($weaponlikeCode->isSword()) {
             $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightWithSwords());
         }
         if ($weaponlikeCode->isUnarmed()) {
             $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightUnarmed());
         }
         if ($weaponlikeCode->isVoulgeOrTrident()) {
             $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightWithVoulgesAndTridents());
         }
         if ($weaponlikeCode->isShield()) {
             // shield as a weapon
             $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightWithShields());
         }
     }
     if ($weaponlikeCode->isThrowingWeapon()) {
         $rankValues[] = $this->determineCurrentSkillRankValue($this->getFightWithThrowingWeapons());
     }
     $rankValue = false;
     if (count($rankValues) > 0) {
         $rankValue = max($rankValues);
     }
     if (!is_int($rankValue)) {
         throw new Exceptions\PhysicalSkillsDoNotKnowHowToUseThatWeapon("Given weapon '{$weaponlikeCode}' is not usable by any physical skill");
     }
     return $rankValue;
 }
 /**
  * If you want to use shield as a PROTECTIVE item, there is no base of wounds malus from that.
  *
  * @param WeaponlikeCode $weaponlikeCode
  * @param MissingWeaponSkillTable $missingWeaponSkillsTable
  * @param bool $fightsWithTwoWeapons
  * @return int
  * @throws Exceptions\UnknownTypeOfWeapon
  */
 public function getMalusToBaseOfWoundsWithWeaponlike(WeaponlikeCode $weaponlikeCode, MissingWeaponSkillTable $missingWeaponSkillsTable, $fightsWithTwoWeapons)
 {
     if ($weaponlikeCode->isMelee() || $weaponlikeCode->isThrowingWeapon()) {
         /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
         return $this->getPhysicalSkills()->getMalusToBaseOfWoundsWithWeaponlike($weaponlikeCode, $missingWeaponSkillsTable, $fightsWithTwoWeapons);
     }
     if ($weaponlikeCode->isShootingWeapon()) {
         /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
         return $this->getCombinedSkills()->getMalusToBaseOfWoundsWithShootingWeapon($weaponlikeCode->convertToRangedWeaponCodeEquivalent(), $missingWeaponSkillsTable);
     }
     if ($weaponlikeCode->isProjectile()) {
         return 0;
     }
     throw new Exceptions\UnknownTypeOfWeapon($weaponlikeCode);
 }