Add attack/defense/damage modifiers and invuln.

Adds attack, defense and damage modifiers for both "goodguy" (self) and
"badguy" (target) as well as a handler for goodguy/badguy invulnurability.

Modified the battle calculation to not recalculate if noone does damage as
long as at least 1 buff is active. This prevets infinite loops.
This commit is contained in:
Basilius Sauter
2016-06-04 23:12:27 +02:00
parent 4badaea249
commit 7b609e3b5c
5 changed files with 828 additions and 68 deletions
+173 -18
View File
@@ -12,11 +12,12 @@ use LotGD\Core\{
Exceptions\BattleNotOverException,
Models\FighterInterface
};
use LotGD\Core\Models\BattleEvents\{
BuffMessageEvent,
CriticalHitEvent,
DamageEvent,
DeathEvent
use LotGD\Core\Models\{
Buff,
BattleEvents\BuffMessageEvent,
BattleEvents\CriticalHitEvent,
BattleEvents\DamageEvent,
BattleEvents\DeathEvent
};
/**
@@ -41,6 +42,15 @@ class Battle
protected $result = 0;
protected $round = 0;
/**
* Battle Configuration
* @var type
*/
protected $configuration = [
"riposteEnabled" => true,
"levelAdjustementEnabled" => true,
];
public function __construct(Game $game, FighterInterface $player, FighterInterface $monster)
{
$this->game = $game;
@@ -65,14 +75,72 @@ class Battle
}
/**
* Returns true if the battle is over.
* @return type
* Disables ripostes
*/
public function isOver()
public function disableRiposte()
{
$this->configuration["riposteEnabled"] = false;
}
/**
* Enables ripostes
*/
public function enableRiposte()
{
$this->configuration["riposteEnabled"] = true;
}
/**
* Returns true if ripostes are enabled
* @return bool
*/
public function isRiposteEnabled(): bool
{
return $this->configuration["riposteEnabled"];
}
public function enableLevelAdjustement()
{
$this->configuration["levelAdjustementEnabled"] = true;
}
public function disableLevelAdjustement()
{
$this->configuration["levelAdjustementEnabled"] = false;
}
public function isLevelAdjustementEnabled(): bool
{
return $this->configuration["levelAdjustementEnabled"];
}
/**
* Returns true if the battle is over.
* @return bool
*/
public function isOver(): bool
{
return $this->result !== self::RESULT_UNDECIDED;
}
/**
* Returns the player instance
* @return FighterInterface
*/
public function getPlayer(): FighterInterface
{
return $this->player;
}
/**
* Returns the montser instance
* @return FighterInterface
*/
public function getMonster(): FighterInterface
{
return $this->monster;
}
/**
* Returns the winner of this fight
* @return FighterInterface
@@ -87,7 +155,7 @@ class Battle
}
/**
* Returns the looser of this fight
* Returns the loser of this fight
* @return FighterInterface
*/
public function getLoser(): FighterInterface
@@ -136,15 +204,23 @@ class Battle
{
$damageHasBeenDone = false;
$playerBuffStartEvents = $this->player->getBuffs()->activate();
$monsterBuffStartEvents = $this->monster->getBuffs()->activate();
$this->player->getBuffs()->resetBuffUsage();
$this->monster->getBuffs()->resetBuffUsage();
$playerBuffStartEvents = $this->player->getBuffs()->activate(Buff::ACTIVATE_ROUNDSTART);
$monsterBuffStartEvents = $this->monster->getBuffs()->activate(Buff::ACTIVATE_ROUNDSTART);
do {
$offenseTurnEvents = $firstDamageRound & self::DAMAGEROUND_PLAYER ? $this->turn($this->player, $this->monster) : new ArrayCollection();
$defenseTurnEvents = $firstDamageRound & self::DAMAGEROUND_MONSTER ? $this->turn($this->monster, $this->player) : new ArrayCollection();
$events = new ArrayCollection(array_merge($offenseTurnEvents->toArray(), $defenseTurnEvents->toArray()));
$eventsToAdd = new ArrayCollection();
if ($this->player->getBuffs()->hasBuffsInUse() || $this->monster->getBuffs()->hasBuffsInUse()) {
// If there are active buffs, we still need to count the round even if there has not been any damage done.
$damageHasBeenDone = true;
}
foreach($events as $event) {
$event->apply();
@@ -199,9 +275,42 @@ class Battle
$attackersBuffs = $attacker->getBuffs();
$defendersBuffs = $defender->getBuffs();
$attackersAttack = $attacker->getAttack($this->game);
$defendersDefense = $defender->getDefense($this->game);
// Adjustement makes fights versus monsters with lower level easier,
// and more difficult if the monster has a higher level by adjusting
// the monster's defense value.
// For example, if a level 10 player attacks a level 9 monster, the
// defenseAdjustement value for the monster is 0.81, reducing the monster's
// defense by 20% and making it more likely for the player to land a hit.
// On the other hand, the player's defense is increased by ~ 10%, making it
// less likely for the enemy to hit the player.
$adjustement = 1.0;
$defenseAdjustement = 1.0;
if ($attacker === $this->player && $this->isLevelAdjustementEnabled()) {
if ($attacker->getLevel() > 1 && $defender->getLevel() > 1) {
$adjustement = $attacker->getLevel() / $defender->getLevel();
$defenseAdjustement = 1. / ($adjustement * $adjustement);
}
}
elseif ($defender === $this->player && $this->isLevelAdjustementEnabled()) {
if ($attacker->getLevel() > 1 && $defender->getLevel() > 1) {
$adjustement = $defender->getLevel() / $attacker->getLevel();
$defenseAdjustement = $adjustement;
}
}
// Apply buff scaling for the attacker's attack - this needs to take into
// account the attacker's goodguyAttackModifier and the defenders badguyAttackModifier
$attackersAttack = $attacker->getAttack($this->game)
* $attackersBuffs->getGoodguyAttackModifier()
* $defendersBuffs->getBadguyAttackModifier();
// It's the opposite for the defender's defense - it needs to take into account the
// defender's goodguyDefenseModifier as well as the attacker's badguyDefenseModifier.
$defendersDefense = $defender->getDefense($this->game)
* $defendersBuffs->getGoodguyDefenseModifier()
* $attackersBuffs->getBadguyDefenseModifier()
* $defenseAdjustement;
// If the player is the attacker, we enable critical hits with a chance of 25%.
if ($attacker === $this->game->getCharacter()) {
// Players can land critical hits
if ($this->game->getDiceBag()->chance(0.25)) {
@@ -209,21 +318,67 @@ class Battle
}
}
// Conversion from float to int, since the random number generator takes int values.
$attackersAttack = (int) round($attackersAttack, 0);
$defendersDefense = (int) round($defendersDefense, 0);
// Lets roll the
$attackersAtkRoll = $this->game->getDiceBag()->normal(0, $attackersAttack);
$defendersDefRoll = $this->game->getDiceBag()->normal(0, $defendersDefense);
$damage = $attackersAtkRoll - $defendersDefRoll;
if ($attackersAttack > $attacker->getAttack($this->game, true)) {
// If the attacker's attack after modification is bigger than before,
// we call it a critical hit and apply the CriticalHitEvent.
if ($attackersAttack > $attacker->getAttack($this->game)) {
$events->add(new CriticalHitEvent($attacker, $attackersAttack));
}
if ($damage < 0) {
// RIPOSTE are only half as damaging than normal attacks
$damage /= 2;
// Set damage to 0 if riposte has been disabled
if ($this->isRiposteEnabled() === false && $damage < 0) {
$damage = 0;
}
// Here, we take invulnurable buffs into account. There are 4 possible values coming from the
// 2 buff lists, so we must take care a bit.
$attackerIsInvulnurable = $attackersBuffs->goodguyIsInvulnurable() || $defendersBuffs->badguyIsInvulnurable();
$defenderIsInvulnurable = $defendersBuffs->goodguyIsInvulnurable() || $attackersBuffs->badguyIsInvulnurable();
if ($attackerIsInvulnurable && $defenderIsInvulnurable) {
// Both are invulnurable, damage is 0.
$damage = 0;
}
elseif ($attackerIsInvulnurable) {
// Attaker is invulnurable, damage is always > 0 (there is no riposte)
$damage = abs($damage);
}
elseif ($defenderIsInvulnurable) {
// Defender is invulnurable, damage is always < 0 (defender always ripostes)
$damage = - abs($damage);
}
if ($damage < 0) {
// If the damage is less then 0, it's a RIPOSTE. They are only half
// as damaging than normal attacks.
$damage /= 2;
// Apply damage modification. It's a RIPOSTE, so the defenders makes the
// damage. Therefore, we take defender's goodguyDamageModifier into account,
// and the attacker's badguyDamageModifier.
$damage *= $defendersBuffs->getGoodguyDamageModifier()
* $attackersBuffs->getBadguyDamageModifier();
}
else {
// Apply damage modification. It's a normal attack - meaning the attacker does
// the damage. Therefore, we take the attacker's goodguyDamageModifier and
// the defender's badguyDamageModifier into account.
$damage *= $attackersBuffs->getGoodguyDamageModifier()
* $defendersBuffs->getBadguyDamageModifier();
}
// Round the damage value and convert to int.
$damage = (int)round($damage, 0);
// Add the damage event
$events->add(new DamageEvent($attacker, $defender, $damage));
return $events;
+271 -30
View File
@@ -8,12 +8,16 @@ use Doctrine\Common\Collections\{
Collection
};
use LotGD\Core\Exceptions\{
ArgumentException
};
use LotGD\Core\Models\{
Buff,
Character,
BattleEvents\BuffMessageEvent
};
/**
* Description of BuffList
*/
@@ -21,27 +25,46 @@ class BuffList
{
protected $buffs;
protected $buffsBySlot;
protected $activeBuffs;
protected $activeBuffs = [];
/** @var Doctrine\Common\Collections\ArrayCollection */
protected $usedBuffs;
protected $activated = false;
/** @var boolean True of the modifiers have already been calculated */
protected $modifiersCalculated = false;
/** @var boolean True if the badguy is invulnurable */
protected $badguyInvulnurable = false;
protected $badguyDamageModifier = 1;
protected $badguyAttackModifier = 1;
protected $badguyDefenseModifier = 1;
/** @var float */
protected $badguyDamageModifier = 1.;
/** @var float */
protected $badguyAttackModifier = 1.;
/** @var float */
protected $badguyDefenseModifier = 1.;
/** @var boolean True if the goodguy is invulnurable */
protected $goodguyInvulnurable = false;
protected $goodguyDamageModifier = 1;
protected $goodguyAttackModifier = 1;
protected $goodguyDefenseModifier = 1;
/** @var float */
protected $goodguyDamageModifier = 1.;
/** @var float */
protected $goodguyAttackModifier = 1.;
/** @var float */
protected $goodguyDefenseModifier = 1.;
protected $events;
protected $loaded = false;
/**
* Initiates some variables
* @param Collection $buffs
*/
public function __construct(Collection $buffs)
{
$this->buffs = $buffs;
$this->events = new ArrayCollection();
$this->usedBuffs = new ArrayCollection();
}
/**
* Loads all buffs (since it's a lazy correlation)
*/
public function loadBuffs()
{
if ($this->loaded === false) {
@@ -51,50 +74,126 @@ class BuffList
}
}
public function activate(): Collection
/**
* Returns true if the given buff has already been used this round.
* @param Buff $buff
* @return bool
*/
protected function hasBuffBeenUsed(Buff $buff): bool
{
if ($this->activated === true) {
throw new BuffListAlreadyActivatedException("You can activate the buff list only once.");
if ($this->usedBuffs->contains($buff)) {
$used = true;
}
else {
$used = false;
}
$this->activeBuffs = new ArrayCollection();
return $used;
}
/**
* Marks the given buff as used
* @param Buff $buff
*/
protected function useBuff(Buff $buff)
{
$this->usedBuffs->add($buff);
}
/**
* Returns the buff's start or round message
* @param Buff $buff
* @return string
*/
protected function getBuffMessage(Buff $buff): string
{
$return = "";
$used = $this->hasBuffBeenUsed($buff);
if ($buff->hasBeenStarted() === false && $used === false) {
$return = $buff->getStartMessage();
$buff->setHasBeenStarted();
}
elseif($used === false) {
$return = $buff->getRoundMessage();
}
return $return;
}
/**
* Resets the buff usage for a new round
*/
public function resetBuffUsage()
{
$this->activeBuffs = [];
$this->usedBuffs = new ArrayCollection();
$this->modifiersCalculated = false;
}
public function hasBuffsInUse(): bool
{
return count($this->usedBuffs) > 0 ? true : false;
}
/**
* Activates all buffs that activate upon the given activation parameter.
* @param int $activation
* @return Collection
* @throws ArgumentException
* @throws BuffListAlreadyActivatedException
*/
public function activate(int $activation): Collection
{
if ($activation%2 !== 0 && $activation !== 1) {
throw new ArgumentException("You can only activate one activation type at a time.");
}
if (!empty($this->activeBuffs[$activation])) {
throw new BuffListAlreadyActivatedException("You can activate the buff list for the given activation step only once.");
}
$this->activeBuffs[$activation] = new ArrayCollection();
$activationEvents = new ArrayCollection();
foreach ($this->buffs as $buff) {
// Only look at buffs that are activated in battle.
if ($buff->getsActivatedAt(Buff::ACTIVATE_NONE)) {
foreach ($this->iterateBuffList() as $buff) {
// Continue to next buff if the activation is not in this round.
if ($buff->getsActivatedAt($activation) === false) {
continue;
}
$this->activeBuffs->add($buff);
if ($buff->hasBeenStarted() === false) {
$activationMessage = $buff->getStartMessage();
if ($activationMessage !== "") {
$activationEvents->add(new BuffMessageEvent($activationMessage));
}
$buff->setHasBeenStarted();
$this->activeBuffs[$activation]->add($buff);
// Returns start or roundMessage if the buff has not been used yet.
$buffMessage = $this->getBuffMessage($buff);
if ($buffMessage !== "") {
$activationEvents->add(new BuffMessageEvent($buffMessage));
}
else {
$roundMessage = $buff->getRoundMessage();
if ($roundMessage !== "") {
$activationEvents->add(new BuffMessageEvent($roundMessage));
}
// Needs to come at the end
if ($this->hasBuffBeenUsed($buff) === false) {
$this->useBuff($buff);
}
}
return $activationEvents;
}
/**
* Decreases the rounds left on all used buffs
* @return Collection A Collection containing expire messages (if there are any)
*/
public function expireOneRound(): Collection
{
/* @var $endEvents Collection */
$endEvents = new ArrayCollection();
foreach($this->activeBuffs as $buff) {
foreach($this->usedBuffs as $buff) {
/* @var $roundsLeft int */
$roundsLeft = $buff->getRounds() - 1;
$buff->setRounds($roundsLeft);
if ($roundsLeft === 0) {
/* @var $endMessage string */
$endMessage = $buff->getEndMessage();
if ($endMessage !== "") {
@@ -108,13 +207,22 @@ class BuffList
return $endEvents;
}
/**
* Removes a buff from the buff list.
* @param Buff $buff
*/
public function remove(Buff $buff)
{
unset($this->buffsBySlot[$buff->getSlot()]);
$this->buffs->removeElement($buff);
$this->activeBuffs->removeElement($buff);
$this->usedBuffs->removeElement($buff);
}
/**
* Adds a buff to the buff list, occupying the slot.
* @param Buff $buff
* @throws BuffSlotOccupiedException if the slot is already occupied. Use renew instead.
*/
public function add(Buff $buff)
{
$this->loadBuffs();
@@ -128,6 +236,10 @@ class BuffList
$this->buffsBySlot[$buff->getSlot()] = $buff;
}
/**
* Renews a buff.
* @param Buff $buff
*/
public function renew(Buff $buff)
{
$this->loadBuffs();
@@ -140,4 +252,133 @@ class BuffList
$this->buffs->add($buff);
$this->buffsBySlot[$buff->getSlot()] = $buff;
}
/**
* Calculates all total modifiers
* @return type
*/
protected function calculateModifiers()
{
if ($this->modifiersCalculated === true) {
return;
}
$this->badguyAttackModifier = 1.;
$this->badguyDamageModifier = 1.;
$this->badguyDefenseModifier = 1.;
$this->badguyInvulnurable = false;
$this->goodguyAttackModifier = 1.;
$this->goodguyDamageModifier = 1.;
$this->goodguyDefenseModifier = 1.;
$this->goodguyInvulnurable = false;
/* @var $buff \LotGD\Core\Model\Buff */
foreach ($this->iterateBuffList() as $buff) {
$this->badguyAttackModifier *= $buff->getBadguyAttackModifier();
$this->badguyDefenseModifier *= $buff->getBadguyDefenseModifier();
$this->badguyDamageModifier *= $buff->getBadguyDamageModifier();
$this->badguyInvulnurable = $this->badguyInvulnurable || $buff->badguyIsInvulnurable();
$this->goodguyAttackModifier *= $buff->getGoodguyAttackModifier();
$this->goodguyDefenseModifier *= $buff->getGoodguyDefenseModifier();
$this->goodguyDamageModifier *= $buff->getGoodguyDamageModifier();
$this->goodguyInvulnurable = $this->goodguyInvulnurable || $buff->goodguyIsInvulnurable();
}
}
/**
* Iterates over every buff that gets activated at one point during a round.
* @return Generator|\LotGD\Core\Model\Buff[]
*/
protected function iterateBuffList()
{
foreach ($this->buffs as $buff) {
// Only look at buffs that are activated in battle.
if ($buff->getsActivatedAt(Buff::ACTIVATE_NONE)) {
continue;
}
else {
yield $buff;
}
}
}
/**
* Returns the badguy attack modifier calculated over the whole bufflist
* @return float
*/
public function getBadguyAttackModifier(): float
{
$this->calculateModifiers();
return $this->badguyAttackModifier;
}
/**
* Returns the badguy defense modifier calculated over the whole bufflist
* @return float
*/
public function getBadguyDefenseModifier(): float
{
$this->calculateModifiers();
return $this->badguyDefenseModifier;
}
/**
* Returns the badguy damage modifier calculated over the whole bufflist
* @return float
*/
public function getBadguyDamageModifier(): float
{
$this->calculateModifiers();
return $this->badguyDamageModifier;
}
/**
* Returns true if the badguy is invulnurable
* @return bool
*/
public function badguyIsInvulnurable(): bool
{
$this->calculateModifiers();
return $this->badguyInvulnurable;
}
/**
* Returns the badguy attack modifier calculated over the whole bufflist
* @return float
*/
public function getGoodguyAttackModifier(): float
{
$this->calculateModifiers();
return $this->goodguyAttackModifier;
}
/**
* Returns the badguy defense modifier calculated over the whole bufflist
* @return float
*/
public function getGoodguyDefenseModifier(): float
{
$this->calculateModifiers();
return $this->goodguyDefenseModifier;
}
/**
* Returns the badguy damage modifier calculated over the whole bufflist
* @return float
*/
public function getGoodguyDamageModifier(): float
{
$this->calculateModifiers();
return $this->goodguyDamageModifier;
}
/**
* Returns true if the goodguy is invulnurable
* @return bool
*/
public function goodguyIsInvulnurable(): bool
{
$this->calculateModifiers();
return $this->goodguyInvulnurable;
}
}
+21 -11
View File
@@ -43,49 +43,49 @@ class Buff
* @var string
* @Column(type="text")
*/
private $startMessage;
private $startMessage = "";
/**
* The message given every round
* @var string
* @Column(type="text")
*/
private $roundMessage;
private $roundMessage = "";
/**
* The message given if the buff ends
* @var string
* @Column(type="text")
*/
private $endMessage;
private $endMessage = "";
/**
* The message given if the effect has success
* @var string
* @Column(type="text")
*/
private $effectSucceedsMessage;
private $effectSucceedsMessage = "";
/**
* The message given if the effect fails
* @var string
* @Column(type="text")
*/
private $effectFailsMessage;
private $effectFailsMessage = "";
/**
* The message given if the effect has no effect
* @var string
* @Column(type="text")
*/
private $noEffectMessage;
private $noEffectMessage = "";
/**
* Message that gets displayed every new day.
* @var string
* @Column(type="text")
*/
private $newDayMessage;
private $newDayMessage = "";
/**
* A value determining when the buffs activates
* @var int
* @Column(type="integer")
*/
private $activateAt;
private $activateAt = self::ACTIVATE_NONE;
/**
* True if the buff survives a new day
* @var bool
@@ -293,7 +293,12 @@ class Buff
case "float":
if (is_float($value) === false) {
throw new ArgumentException("{$attribute} needs to be a float.");
// Convert to float if it is an integer.
if (is_int($value) === false) {
throw new ArgumentException("{$attribute} needs to be a float.");
}
$value = (float)$value;
}
break;
@@ -444,7 +449,12 @@ class Buff
*/
public function getsActivatedAt(int $flag): bool
{
return ($flag === self::ACTIVATE_NONE ? $this->activateAt === self::ACTIVATE_NONE : $this->activateAt & $flag);
if ($flag === self::ACTIVATE_NONE) {
return $this->activateAt == self::ACTIVATE_NONE ? true : false;
}
else {
return ($this->activateAt & $flag > 0) === 1;
}
}
/**
@@ -662,7 +672,7 @@ class Buff
* Returns true if the goodguy is invulnurable
* @return bool
*/
public function getGoodguyIsInvulnurable(): bool
public function goodguyIsInvulnurable(): bool
{
return $this->goodguyInvulnurable;
}
+329 -8
View File
@@ -121,9 +121,9 @@ class BattleTest extends ModelTestCase
}
/**
* Tests a fight which the player has to loose (lvl 1 vs lvl 100)
* Tests a fight which the player has to lose (lvl 1 vs lvl 100)
*/
public function testPlayerLooseBattle()
public function testPlayerLoseBattle()
{
$em = $this->getEntityManager();
@@ -171,7 +171,7 @@ class BattleTest extends ModelTestCase
/**
* @expectedException LotGD\Core\Exceptions\BattleNotOverException
*/
public function testBattleNotOverExceptionFromLooser()
public function testBattleNotOverExceptionFromLoser()
{
$em = $this->getEntityManager();
@@ -196,25 +196,54 @@ class BattleTest extends ModelTestCase
$battle = new Battle($this->getMockGame($character), $character, $monster);
// Fighting for 99 rounds should be enough for determining a looser - and to
// Fighting for 99 rounds should be enough for determining a loser - and to
// throw the exception.
for ($n = 0; $n < 99; $n++) {
$battle->fightNRounds(1);
}
}
private function provideBuffBattleParticipants(Buff $buff): Battle
private function provideBuffBattleParticipants(Buff $buff, int $participantsType): Battle
{
$em = $this->getEntityManager();
$em->clear();
$character = $em->getRepository(Character::class)->find(4);
$monster = $em->getRepository(Monster::class)->find(3);
switch ($participantsType) {
default:
case 0:
// Fair Battle
$character = $em->getRepository(Character::class)->find(1);
$monster = $em->getRepository(Monster::class)->find(1);
break;
case 1:
// very long battle
$character = $em->getRepository(Character::class)->find(4);
$monster = $em->getRepository(Monster::class)->find(3);
break;
case 2:
// player should win battle
$character = $em->getRepository(Character::class)->find(13);
$monster = $em->getRepository(Monster::class)->find(11);
break;
case 3:
// player should lose battle
$character = $em->getRepository(Character::class)->find(11);
$monster = $em->getRepository(Monster::class)->find(13);
break;
}
$character->addBuff($buff);
return new Battle($this->getMockGame($character), $character, $monster);
}
/**
* Asserts that a certain BuffMessageEvent with a specific text is contained in the lst of events
* @param Collection $events The list of events
* @param string $battleEventText The text to test for
* @param int $timesAtLeast Mininum number of times the message is expected to be in the event list
* @param int? $timesAtMax Maximum number of times the message is expected to be in the event list, or $timesAtLeast if null.
*/
protected function assertBuffEventMessageExists(
Collection $events,
string $battleEventText,
@@ -238,6 +267,10 @@ class BattleTest extends ModelTestCase
$this->assertLessThanOrEqual($timesAtMax, $eventCounter);
}
/**
* Tests normal buff messages - message upon start of the buff, message every
* round (except when it's started), and the message displayed if the buff expires.
*/
public function testBattleBuffMessages()
{
$battle = $this->provideBuffBattleParticipants(new Buff([
@@ -247,8 +280,9 @@ class BattleTest extends ModelTestCase
"roundMessage" => "The buff is still activate",
"endMessage" => "The buff is ending.",
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
]), 1);
// We fight for 5 rounds - this ensures that the buff is started and expired.
$battle->fightNRounds(5);
$this->assertBuffEventMessageExists($battle->getEvents(), "And this buff starts!", 1);
@@ -278,4 +312,291 @@ class BattleTest extends ModelTestCase
}
}
public function testBattleBuffPlayerGoodguyModifier()
{
// Get a battle ready
$battle = $this->provideBuffBattleParticipants(new Buff([
"slot" => "test",
"rounds" => 99,
"goodguyAttackModifier" => 0.0,
"goodguyDefenseModifier" => 0.0,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]), 2);
$rounds = $battle->fightNRounds(99);
$this->assertTrue($battle->isOver());
$this->assertSame($battle->getPlayer(), $battle->getLoser());
// Get a battle that the player should lose and apply a buff that the player forces to win
$battle = $this->provideBuffBattleParticipants(new Buff([
"slot" => "test",
"rounds" => 99,
"goodguyAttackModifier" => 2,
"goodguyDefenseModifier" => 2,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]), 3);
$battle->fightNRounds(99);
$this->assertTrue($battle->isOver());
$this->assertSame($battle->getPlayer(), $battle->getWinner());
}
public function testBattleBuffPlayerBadguyModifier()
{
// Get a battle that the player should win and apply a buff that the player forces to lose.
$battle = $this->provideBuffBattleParticipants(new Buff([
"slot" => "test",
"rounds" => 99,
"badguyAttackModifier" => 10,
"badguyDefenseModifier" => 10,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]), 2);
$rounds = $battle->fightNRounds(99);
$this->assertTrue($battle->isOver());
$this->assertSame($battle->getPlayer(), $battle->getLoser());
// Get a battle that the player should lose and apply a buff that the player forces to win
$battle = $this->provideBuffBattleParticipants(new Buff([
"slot" => "test",
"rounds" => 99,
"badguyAttackModifier" => 0,
"badguyDefenseModifier" => 0,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]), 3);
$battle->fightNRounds(99);
$this->assertTrue($battle->isOver());
$this->assertSame($battle->getPlayer(), $battle->getWinner());
}
public function testBattleBuffPlayerDamageModifier()
{
// Get a battle that the player should win and apply a buff that the player forces to lose
$battle = $this->provideBuffBattleParticipants(new Buff([
"slot" => "test",
"rounds" => 99,
"goodguyDamageModifier" => 0.0,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]), 0);
$rounds = $battle->fightNRounds(10);
$this->assertSame($battle->getMonster()->getMaxHealth(), $battle->getMonster()->getHealth());
// Get a battle that the player should lose and apply a buff that the player forces to win
$battle = $this->provideBuffBattleParticipants(new Buff([
"slot" => "test",
"rounds" => 99,
"badguyDamageModifier" => 0.0,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]), 0);
$battle->fightNRounds(10);
$this->assertSame($battle->getPlayer()->getMaxHealth(), $battle->getPlayer()->getHealth());
}
public function testBattleBuffPlayerInvulnurability()
{
// Get a battle that the player should win and apply a buff that the player forces to lose
$battle = $this->provideBuffBattleParticipants(new Buff([
"slot" => "test",
"rounds" => 99,
"badguyInvulnurable" => true,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]), 0);
$rounds = $battle->fightNRounds(99);
$this->assertSame($battle->getMonster()->getMaxHealth(), $battle->getMonster()->getHealth());
$this->assertTrue($battle->isOver());
$this->assertSame($battle->getMonster(), $battle->getWinner());
// Get a battle that the player should lose and apply a buff that the player forces to win
$battle = $this->provideBuffBattleParticipants(new Buff([
"slot" => "test",
"rounds" => 99,
"goodguyInvulnurable" => true,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]), 0);
$rounds = $battle->fightNRounds(99);
$this->assertSame($battle->getPlayer()->getMaxHealth(), $battle->getPlayer()->getHealth());
$this->assertTrue($battle->isOver());
$this->assertSame($battle->getPlayer(), $battle->getWinner());
}
public function testBufflistGoodguyAttackModifier()
{
$em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1);
$game = $this->getMockGame($player);
$player->addBuff(new Buff([
"slot" => "test1",
"rounds" => 1,
"goodguyAttackModifier" => 1.23,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test2",
"rounds" => 1,
"goodguyAttackModifier" => 0.126,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test3",
"rounds" => 1,
"goodguyAttackModifier" => 13.4,
]));
$modifier = $player->getBuffs()->getGoodguyAttackModifier();
$this->assertEquals(0.15498, $modifier, '', 0.001);
}
public function testBufflistGoodguyDefenseModifier()
{
$em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1);
$game = $this->getMockGame($player);
$player->addBuff(new Buff([
"slot" => "test1",
"rounds" => 1,
"goodguyDefenseModifier" => 1.293,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test2",
"rounds" => 1,
"goodguyDefenseModifier" => 5.6,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test3",
"rounds" => 1,
"goodguyDefenseModifier" => 0,
]));
$modifier = $player->getBuffs()->getGoodguyDefenseModifier();
$this->assertEquals(7.2408, $modifier, '', 0.001);
}
public function testBufflistGoodguyDamageModifier()
{
$em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1);
$game = $this->getMockGame($player);
$player->addBuff(new Buff([
"slot" => "test1",
"rounds" => 1,
"goodguyDamageModifier" => 10,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test2",
"rounds" => 1,
"goodguyDamageModifier" => 0.25,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test3",
"rounds" => 1,
"goodguyDamageModifier" => 3.5,
]));
$modifier = $player->getBuffs()->getGoodguyDamageModifier();
$this->assertEquals(2.5, $modifier, '', 0.001);
}
public function testBufflistBadguyAttackModifier()
{
$em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1);
$game = $this->getMockGame($player);
$player->addBuff(new Buff([
"slot" => "test1",
"rounds" => 1,
"badguyAttackModifier" => 1.23,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test2",
"rounds" => 1,
"badguyAttackModifier" => 0.126,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test3",
"rounds" => 1,
"badguyAttackModifier" => 13.4,
]));
$modifier = $player->getBuffs()->getBadguyAttackModifier();
$this->assertEquals(0.15498, $modifier, '', 0.001);
}
public function testBufflistBadguyDefenseModifier()
{
$em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1);
$game = $this->getMockGame($player);
$player->addBuff(new Buff([
"slot" => "test1",
"rounds" => 1,
"badguyDefenseModifier" => 1.293,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test2",
"rounds" => 1,
"badguyDefenseModifier" => 5.6,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test3",
"rounds" => 1,
"badguyDefenseModifier" => 0,
]));
$modifier = $player->getBuffs()->getBadguyDefenseModifier();
$this->assertEquals(7.2408, $modifier, '', 0.001);
}
public function testBufflistBadguyDamageModifier()
{
$em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1);
$game = $this->getMockGame($player);
$player->addBuff(new Buff([
"slot" => "test1",
"rounds" => 1,
"badguyDamageModifier" => 10,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test2",
"rounds" => 1,
"badguyDamageModifier" => 0.25,
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
]));
$player->addBuff(new Buff([
"slot" => "test3",
"rounds" => 1,
"badguyDamageModifier" => 3.5,
]));
$modifier = $player->getBuffs()->getBadguyDamageModifier();
$this->assertEquals(2.5, $modifier, '', 0.001);
}
}
+34 -1
View File
@@ -27,6 +27,27 @@ characters:
health: 500
maxhealth: 500
level: 0
-
id: 10
name: "Level 10 Character"
displayName: "Level 10 Character"
health: 100
maxhealth: 100
level: 10
-
id: 11
name: "Level 11 Character"
displayName: "Level 11 Character"
health: 110
maxhealth: 110
level: 11
-
id: 13
name: "Level 13 Character"
displayName: "Level 13 Character"
health: 130
maxhealth: 130
level: 13
monsters:
-
id: 1
@@ -39,4 +60,16 @@ monsters:
-
id: 3
name: "Stone"
level: 1
level: 1
-
id: 10
name: "Level 10 Monster"
level: 10
-
id: 11
name: "Level 11 Monster"
level: 11
-
id: 13
name: "Level 13 Monster"
level: 13