/**
  * @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;
 }
 /**
  * Gives malus to cover with a weapon or a shield according to given skill rank.
  * Warning: PPH gives you invalid info about cover with shield malus on PPH page 86 right column (-2 if you do not
  * have maximal skill). Correct is @see \DrdPlus\Tables\Armaments\Shields\MissingShieldSkillTable
  * Note about shield: shield is always used as a shield for cover, even if is used for desperate attack.
  *
  * @param PositiveInteger $weaponTypeSkillRank
  * @param WeaponlikeCode $weaponOrShield
  * @return int
  * @throws \DrdPlus\Tables\Armaments\Partials\Exceptions\UnexpectedSkillRank
  */
 public function getCoverMalusForSkillRank(PositiveInteger $weaponTypeSkillRank, WeaponlikeCode $weaponOrShield)
 {
     if ($weaponOrShield->isWeapon()) {
         return $this->tables->getMissingWeaponSkillTable()->getCoverMalusForSkillRank($weaponTypeSkillRank->getValue());
     }
     assert($weaponOrShield->isShield());
     /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
     return $this->tables->getMissingShieldSkillTable()->getCoverMalusForSkillRank($weaponTypeSkillRank->getValue());
 }
 /**
  * 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);
 }