public function testStealthDecreasesStrengthIncreasesStamina() { $pc = new Player(); $str = $pc->getStrength(); $stamina = $pc->getStamina(); $speed = $pc->getSpeed(); $pc->addStatus(STEALTH); $this->assertTrue($pc->hasStatus(STEALTH)); $this->assertLessThan($str, $pc->getStrength(), 'Stealth failed to affect strength.'); $this->assertGreaterThan($stamina, $pc->getStamina(), 'Stealth status failed to affect stamina.'); $this->assertGreaterThan($speed, $pc->getSpeed(), 'Stealth status failed to affect speed.'); }
/** * @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']); }