<?php
/**
* 攻撃
*
*/
class Attack extends Action
{
private const DAMAGE_CORRECTION_MIN = 0;
private const DAMAGE_CORRECTION_MAX = 5;
private const CRITICAL_RATE_FAIL = 1;
private const CRITICAL_RATE_SUCCESS = 2;
private const BLOCK_RATE_FAIL = 1;
private const BLOCK_RATE_SUCCESS = 0.5;
/**
* @inheritDoc
*/
public function shouldBreak(): bool
{
if ($this->target->isDead()) {
Logger::add("{$this->target->getName()}は死んでしまった。");
return true;
}
return false;
}
/**
* @inheritDoc
*/
protected function action(): void
{
$damage = $this->calculateDamage();
$this->target->subHp($damage);
Logger::add($this->getDamageMessage($damage));
}
/**
* ダメージ計算
*
* @return int
*/
private function calculateDamage(): int
{
$damageCorrection = rand(self::DAMAGE_CORRECTION_MIN, self::DAMAGE_CORRECTION_MAX);
$damageBase = $this->performer->getAtk() - $this->target->getDef() + $damageCorrection;
$damageBase = max($damageBase, 0);
$criticalRate = self::CRITICAL_RATE_FAIL;
if ($damageBase > 0 && $this->performer->lotteryCriticalHit()) {
$criticalRate = self::CRITICAL_RATE_SUCCESS;
}
$blockRate = self::BLOCK_RATE_FAIL;
if ($damageBase > 0 && $this->target->lotteryBlockSuccess()) {
$blockRate = self::BLOCK_RATE_SUCCESS;
}
return $damageBase * $criticalRate * $blockRate;
}
/**
* ダメージメッセージを取得
*
* @param int $damage
* @return string
*/
private function getDamageMessage(int $damage): string
{
$message = '';
if ($this->performer->isCriticalHit()) {
$message .= "{$this->performer->getName()}の攻撃はクリティカルヒットした。";
}
if ($this->performer->isBlockSuccess()) {
$message .= "{$this->target->getName()}は攻撃をブロックした。";
}
$message .= "{$this->performer->getName()}は{$this->target->getName()}に{$damage}のダメージ。 ";
$message .= "{$this->target->getName()}のHP: {$this->target->getHp()}/{$this->target->getHpMax()} ({$this->target->getHpRate()}%)";
return $message;
}
}