/** * @return StreamedViewResponse */ private function combat(Player $attacker, Player $target, $required_turns = 0, $options) { $error = ''; $stealthed_attack = false; $stealth_damage = false; $stealth_lost = false; $bounty_result = false; $rewarded_ki = false; $wrath = false; $loot = 0; $killpoints = 1; $rounds = 1; $victor = null; $loser = null; $starting_attacker = clone $attacker; $starting_target = clone $target; $turns_counter = $options['duel'] ? -1 : 1; $attacker_label = $attacker->name(); if (!$options['duel'] && $attacker->hasStatus(STEALTH)) { $stealthed_attack = true; $this->stealthStrike($attacker, $target); $gold_mod = self::STEALTH_GOLD_MOD; if ($target->health > 0) { $stealth_damage = true; } else { $attacker_label = 'a stealthed ninja'; $victor = $attacker; $loser = $target; } $attack_label = "attacked %s from the shadows"; } else { $gold_mod = $options['duel'] ? self::DUEL_GOLD_MOD : self::DEFAULT_GOLD_MOD; if ($attacker->hasStatus(STEALTH)) { $stealth_lost = true; } $attacker->subtractStatus(STEALTH); while ($turns_counter != 0 && $attacker->health > 0 && $target->health > 0) { $turns_counter--; $rounds++; $this->strike($attacker, $target, $options['blaze'], $options['deflect']); /** * Evasion effect: * * Break off the duel/attack if less than 10% health or * health is less than average of defender's strength */ if ($options['evade'] && ($attacker->health < $target->getStrength() * 0.5 || $attacker->health < $attacker->health * 0.1)) { break; } } $attacker->turns = $attacker->turns - max(0, $required_turns); $attack_label = $options['duel'] ? 'dueled %s' : 'attacked %s'; } if ($target->health > 0 && $attacker->health > 0) { $combat_msg = "%s {$attack_label} for %s damage, but they got away before you could kill them!"; Event::create($attacker->id(), $target->id(), sprintf($combat_msg, $attacker->name(), 'you', $starting_target->health - $target->health)); if ($attacker->hasStatus(STEALTH)) { $stealth_lost = true; } $attacker->subtractStatus(STEALTH); } else { if ($target->health < 1 && $attacker->health < 1) { $loot = 0; $this->win($attacker, $target, $loot, $killpoints); $this->win($target, $attacker, $loot, 1); $this->lose($attacker, $target, $loot); $this->lose($target, $attacker, $loot); } else { if ($target->health < 1) { $victor = $attacker; $loser = $target; $bounty_result = Combat::runBountyExchange($victor, $loser); $loot = floor($gold_mod * $loser->gold); if ($options['duel']) { $killpoints = Combat::killpointsFromDueling($attacker, $target); $skillListObj = new Skill(); if ($skillListObj->hasSkill('wrath', $attacker)) { // They'll regain some health for the kill, at the end. $attacker->heal(self::BASE_WRATH_REGAIN); $wrath = true; } } $reporting_victor = $victor; if ($victor->hasStatus(STEALTH)) { $reporting_victor = new Player(); $reporting_victor->uname = 'a stealthed ninja'; $reporting_victor->player_id = 0; } $this->lose($loser, $reporting_victor, $loot); $this->win($victor, $loser, $loot, $killpoints); } else { $victor = $target; $loser = $attacker; $loot = floor($gold_mod * $loser->gold); $this->lose($loser, $victor, $loot); $this->win($victor, $loser, $loot, $killpoints); } } } if ($options['duel']) { $this->logDuel($attacker, $target, $victor, $killpoints); } if ($rounds > self::EVEN_MATCH_ROUND_COUNT) { // Evenly matched battle! Reward some ki to the attacker, even if they die $rewarded_ki = self::EVEN_MATCH_KI_REWARD; $attacker->setKi($attacker->ki + $rewarded_ki); } $target->save(); $attacker->save(); return new StreamedViewResponse('Battle Status', 'attack_mod.tpl', get_defined_vars(), ['quickstat' => 'player']); }
if ($defenderHealthRemaining < 1 || $attackerHealthRemaining < 1) { // A kill occurred. if ($defenderHealthRemaining < 1) { // ATTACKER KILLS DEFENDER! if ($simultaneousKill = $attackerHealthRemaining < 1) { // *** If both died at the same time. *** } else { $victor = $attacker; $loser = $target; } $killed_target = true; $killpoints = 1; // Changes killpoints from zero to one. if ($duel) { // Changes killpoints amount by dueling equation. $killpoints = Combat::killpointsFromDueling($attacking_player, $target_player); $duel_log_msg = "{$attacker} has dueled {$target} and won {$killpoints} killpoints."; // Only log duels if they're better than 1 or if they're a failure. if ($killpoints > 1 || $killpoints < 0) { // Make a WIN record in the dueling log. GameLog::sendLogOfDuel($attacker, $target, 1, $killpoints); } if ($skillListObj->hasSkill('wrath')) { // They'll retain 10 health for the kill, at the end. $wrath_regain = 10; } } $attacking_player->addKills($killpoints); // Attacker gains their killpoints. $target_player->death(); if (!$simultaneousKill) {