Introduce general buff handling and tests
This commit introduces basic buff handling: Adding buffs, removing buffs, expiring buffs. The Battle procedure controls the buffs and activates them every round, expires them one round per round and removes the buff if the number of rounds left is 0. The BattleTest suite tests for the correct sequence and the correct messages.
This commit is contained in:
+29
-3
@@ -13,6 +13,7 @@ use LotGD\Core\{
|
||||
Models\FighterInterface
|
||||
};
|
||||
use LotGD\Core\Models\BattleEvents\{
|
||||
BuffMessageEvent,
|
||||
CriticalHitEvent,
|
||||
DamageEvent,
|
||||
DeathEvent
|
||||
@@ -58,6 +59,11 @@ class Battle
|
||||
|
||||
}
|
||||
|
||||
public function getEvents()
|
||||
{
|
||||
return $this->events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the battle is over.
|
||||
* @return type
|
||||
@@ -130,6 +136,9 @@ class Battle
|
||||
{
|
||||
$damageHasBeenDone = false;
|
||||
|
||||
$playerBuffStartEvents = $this->player->getBuffs()->activate();
|
||||
$monsterBuffStartEvents = $this->monster->getBuffs()->activate();
|
||||
|
||||
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();
|
||||
@@ -147,13 +156,13 @@ class Battle
|
||||
$eventsToAdd->add($event);
|
||||
|
||||
if ($this->player->getHealth() <= 0) {
|
||||
$this->events->add(new DeathEvent($this->player));
|
||||
$deathEvent = new DeathEvent($this->player);
|
||||
$this->result = self::RESULT_PLAYERDEATH;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->monster->getHealth() <= 0) {
|
||||
$this->events->add(new DeathEvent($this->monster));
|
||||
$deathEvent = new DeathEvent($this->monster);
|
||||
$this->result = self::RESULT_MONSTERDEATH;
|
||||
break;
|
||||
}
|
||||
@@ -161,7 +170,21 @@ class Battle
|
||||
} while($damageHasBeenDone === false);
|
||||
|
||||
$this->round++;
|
||||
$this->events = new ArrayCollection(array_merge($this->events->toArray(), $eventsToAdd->toArray()));
|
||||
|
||||
$playerBuffEndEvents = $this->player->getBuffs()->expireOneRound();
|
||||
$monsterBuffEndEvents = $this->monster->getBuffs()->expireOneRound();
|
||||
|
||||
$this->events = new ArrayCollection(
|
||||
array_merge(
|
||||
$this->events->toArray(),
|
||||
$playerBuffStartEvents->toArray(),
|
||||
$monsterBuffStartEvents->toArray(),
|
||||
$eventsToAdd->toArray(),
|
||||
$playerBuffEndEvents->toArray(),
|
||||
$monsterBuffEndEvents->toArray(),
|
||||
isset($deathEvent) ? [$deathEvent] : []
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,6 +196,9 @@ class Battle
|
||||
{
|
||||
$events = new ArrayCollection();
|
||||
|
||||
$attackersBuffs = $attacker->getBuffs();
|
||||
$defendersBuffs = $defender->getBuffs();
|
||||
|
||||
$attackersAttack = $attacker->getAttack($this->game);
|
||||
$defendersDefense = $defender->getDefense($this->game);
|
||||
|
||||
|
||||
+127
-5
@@ -3,19 +3,141 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\{
|
||||
ArrayCollection,
|
||||
Collection
|
||||
};
|
||||
|
||||
use LotGD\Core\Models\Buff;
|
||||
use LotGD\Core\Models\Character;
|
||||
use LotGD\Core\Models\{
|
||||
Buff,
|
||||
Character,
|
||||
BattleEvents\BuffMessageEvent
|
||||
};
|
||||
|
||||
/**
|
||||
* Description of BuffList
|
||||
*/
|
||||
class BuffList
|
||||
{
|
||||
private $buffs;
|
||||
protected $buffs;
|
||||
protected $buffsBySlot;
|
||||
protected $activeBuffs;
|
||||
|
||||
public function __construct(Collection $buffs) {
|
||||
protected $activated = false;
|
||||
protected $badguyInvulnurable = false;
|
||||
protected $badguyDamageModifier = 1;
|
||||
protected $badguyAttackModifier = 1;
|
||||
protected $badguyDefenseModifier = 1;
|
||||
protected $goodguyInvulnurable = false;
|
||||
protected $goodguyDamageModifier = 1;
|
||||
protected $goodguyAttackModifier = 1;
|
||||
protected $goodguyDefenseModifier = 1;
|
||||
|
||||
protected $events;
|
||||
protected $loaded = false;
|
||||
|
||||
public function __construct(Collection $buffs)
|
||||
{
|
||||
$this->buffs = $buffs;
|
||||
$this->events = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function loadBuffs()
|
||||
{
|
||||
if ($this->loaded === false) {
|
||||
foreach($this->buffs as $buff) {
|
||||
$this->buffsBySlot[$buff->getSlot()] = $buff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function activate(): Collection
|
||||
{
|
||||
if ($this->activated === true) {
|
||||
throw new BuffListAlreadyActivatedException("You can activate the buff list only once.");
|
||||
}
|
||||
|
||||
$this->activeBuffs = 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)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->activeBuffs->add($buff);
|
||||
|
||||
if ($buff->hasBeenStarted() === false) {
|
||||
$activationMessage = $buff->getStartMessage();
|
||||
if ($activationMessage !== "") {
|
||||
$activationEvents->add(new BuffMessageEvent($activationMessage));
|
||||
}
|
||||
$buff->setHasBeenStarted();
|
||||
}
|
||||
else {
|
||||
$roundMessage = $buff->getRoundMessage();
|
||||
if ($roundMessage !== "") {
|
||||
$activationEvents->add(new BuffMessageEvent($roundMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $activationEvents;
|
||||
}
|
||||
|
||||
public function expireOneRound(): Collection
|
||||
{
|
||||
$endEvents = new ArrayCollection();
|
||||
|
||||
foreach($this->activeBuffs as $buff) {
|
||||
$roundsLeft = $buff->getRounds() - 1;
|
||||
$buff->setRounds($roundsLeft);
|
||||
|
||||
if ($roundsLeft === 0) {
|
||||
$endMessage = $buff->getEndMessage();
|
||||
|
||||
if ($endMessage !== "") {
|
||||
$endEvents->add(new BuffMessageEvent($endMessage));
|
||||
}
|
||||
|
||||
$this->remove($buff);
|
||||
}
|
||||
}
|
||||
|
||||
return $endEvents;
|
||||
}
|
||||
|
||||
public function remove(Buff $buff)
|
||||
{
|
||||
unset($this->buffsBySlot[$buff->getSlot()]);
|
||||
$this->buffs->removeElement($buff);
|
||||
$this->activeBuffs->removeElement($buff);
|
||||
}
|
||||
|
||||
public function add(Buff $buff)
|
||||
{
|
||||
$this->loadBuffs();
|
||||
$slot = $buff->getSlot();
|
||||
|
||||
if (isset($this->buffsBySlot[$buff->getSlot()])) {
|
||||
throw new BuffSlotOccupiedException("The slot {$slot} is already occupied.");
|
||||
}
|
||||
|
||||
$this->buffs->add($buff);
|
||||
$this->buffsBySlot[$buff->getSlot()] = $buff;
|
||||
}
|
||||
|
||||
public function renew(Buff $buff)
|
||||
{
|
||||
$this->loadBuffs();
|
||||
$slot = $buff->getSlot();
|
||||
|
||||
if (isset($this->buffsBySlot[$buff->getSlot()])) {
|
||||
$this->buffs->removeElement($buff);
|
||||
}
|
||||
|
||||
$this->buffs->add($buff);
|
||||
$this->buffsBySlot[$buff->getSlot()] = $buff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Exceptions;
|
||||
|
||||
/**
|
||||
* Exception if a specific, required argument is missing
|
||||
*/
|
||||
class BattleEventException extends BattleException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Exceptions;
|
||||
|
||||
/**
|
||||
* Exception if a specific, required argument is missing
|
||||
*/
|
||||
class BuffListAlreadyActivatedException extends CoreException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -3,14 +3,22 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Exceptions\BattleEventException;
|
||||
|
||||
/**
|
||||
* BattleEvent
|
||||
*/
|
||||
class BattleEvent
|
||||
{
|
||||
private $applied = false;
|
||||
|
||||
public function apply()
|
||||
{
|
||||
if ($this->applied === true) {
|
||||
throw new BattleEventException("Cannot apply an event more than once.");
|
||||
}
|
||||
|
||||
$this->applied = true;
|
||||
}
|
||||
|
||||
public function decorate(Game $game): string
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Exceptions\BattleEventException;
|
||||
|
||||
/**
|
||||
* BattleEvent
|
||||
*/
|
||||
class BuffMessageEvent extends BattleEvent
|
||||
{
|
||||
private $message = "";
|
||||
|
||||
public function __construct(string $message) {
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
public function getMessage(): string
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,8 @@ class DamageEvent extends BattleEvent
|
||||
|
||||
public function apply()
|
||||
{
|
||||
parent::apply();
|
||||
|
||||
if ($this->damage !== 0) {
|
||||
// Only damage the victim if there is an actual effect
|
||||
$victim = $this->damage > 0 ? $this->defender : $this->attacker;
|
||||
|
||||
+149
-4
@@ -6,6 +6,8 @@ namespace LotGD\Core\Models;
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
use Doctrine\ORM\Mapping\Table;
|
||||
|
||||
use LotGD\Core\Exceptions\ArgumentException;
|
||||
|
||||
/**
|
||||
* A model representing a buff used to modify the flow of the battle.
|
||||
* @Entity
|
||||
@@ -18,6 +20,8 @@ class Buff
|
||||
const ACTIVATE_OFFENSE = 0b0100;
|
||||
const ACTIVATE_DEFENSE = 0b1000;
|
||||
const ACTIVATE_WHILEROUND = 0b1100;
|
||||
const ACTIVATE_NONE = 0b0000;
|
||||
const ACTIVATE_ANY = 0b1111;
|
||||
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
@@ -88,6 +92,12 @@ class Buff
|
||||
* @Column(type="boolean")
|
||||
*/
|
||||
private $survivesNewDay = false;
|
||||
/**
|
||||
* True if the buff should expire if the battle ended.
|
||||
* @var bool
|
||||
* @Column(type="boolean")
|
||||
*/
|
||||
private $expiresAfterBattle = false;
|
||||
/**
|
||||
* The number of rounds this buff lasts.
|
||||
*
|
||||
@@ -210,6 +220,114 @@ class Buff
|
||||
* @Column(type="boolean")
|
||||
*/
|
||||
private $goodguyInvulnurable = false;
|
||||
/**
|
||||
* True if the buff has already been started
|
||||
* @var bool
|
||||
* @Column(type="boolean")
|
||||
*/
|
||||
private $hasBeenStarted = false;
|
||||
|
||||
private $buffArrayTemplate = [
|
||||
"slot" => "string",
|
||||
"name" => "string",
|
||||
"startMessage" => "string",
|
||||
"roundMessage" => "string",
|
||||
"endMessage" => "string",
|
||||
"effectSucceedsMessage" => "string",
|
||||
"effectFailsMessage" => "string",
|
||||
"noEffectMessage" => "string",
|
||||
"newDayMessage" => "string",
|
||||
"activateAt" => "int",
|
||||
"survivesNewDay" => "bool",
|
||||
"expiresAfterBattle" => "bool",
|
||||
"rounds" => "int",
|
||||
"badguyRegeneration" => "int",
|
||||
"goodguyRegeneration" => "int",
|
||||
"badguyLifetap" => "float",
|
||||
"goodguyLifetap" => "float",
|
||||
"badguyDamageReflection" => "float",
|
||||
"goodguyDamageReflection" => "float",
|
||||
"numberOfMinions" => "int",
|
||||
"minionMinBadguyDamage" => "int",
|
||||
"minionMaxBadguyDamage" => "int",
|
||||
"minionMinGoodguyDamage" => "int",
|
||||
"minionMaxGoodguyDamage" => "int",
|
||||
"badguyDamageModifier" => "float",
|
||||
"badguyAttackModifier" => "float",
|
||||
"badguyDefenseModifier" => "float",
|
||||
"badguyInvulnurable" => "bool",
|
||||
"goodguyDamageModifier" => "float",
|
||||
"goodguyAttackModifier" => "float",
|
||||
"goodguyDefenseModifier" => "float",
|
||||
"goodguyInvulnurable" => "bool",
|
||||
];
|
||||
|
||||
private $required = [
|
||||
"slot",
|
||||
];
|
||||
|
||||
/**
|
||||
* Creates a new buff entity using an array
|
||||
* @param array $buffArray
|
||||
* @throws ArgumentException
|
||||
*/
|
||||
public function __construct(array $buffArray) {
|
||||
foreach($buffArray as $attribute => $value) {
|
||||
// Throw exception if an attribute does not exist (to prevent spelling errors)
|
||||
if (!isset($this->buffArrayTemplate[$attribute])) {
|
||||
throw new ArgumentException("{$attribute} is not a valid key for a buff.");
|
||||
}
|
||||
|
||||
switch($this->buffArrayTemplate[$attribute]) {
|
||||
case "string":
|
||||
if (is_string($value) === false) {
|
||||
throw new ArgumentException("{$attribute} needs to be a string.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "int":
|
||||
if (is_int($value) === false) {
|
||||
throw new ArgumentException("{$attribute} needs to be a int.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "float":
|
||||
if (is_float($value) === false) {
|
||||
throw new ArgumentException("{$attribute} needs to be a float.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "boolean":
|
||||
if (is_bool($value) === false) {
|
||||
throw new ArgumentException("{$attribute} needs to be boolean.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$this->{$attribute} = $value;
|
||||
|
||||
foreach($this->required as $required) {
|
||||
if (is_null($this->$required)) {
|
||||
throw new ArgumentException("{$required} needs to be inside of the buffArray!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new buff entity using another buff as the template.
|
||||
* @param \LotGD\Core\Models\Buff $buff
|
||||
* @return \LotGD\Core\Models\Buff
|
||||
*/
|
||||
public static function constructFromTemplate(Buff $buff): Buff {
|
||||
$buffArray = [];
|
||||
|
||||
foreach($this->buffArrayTemplate as $attribute => $type) {
|
||||
$buffArray[$attribute] = $buff->$attribute;
|
||||
}
|
||||
|
||||
return new Buff($buffArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the buff
|
||||
@@ -253,7 +371,7 @@ class Buff
|
||||
*/
|
||||
public function getStartMessage(): string
|
||||
{
|
||||
return $this->startMessage;
|
||||
return $this->startMessage ?? "";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,7 +380,7 @@ class Buff
|
||||
*/
|
||||
public function getRoundMessage(): string
|
||||
{
|
||||
return $this->roundMessage;
|
||||
return $this->roundMessage ?? "";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,7 +389,7 @@ class Buff
|
||||
*/
|
||||
public function getEndMessage(): string
|
||||
{
|
||||
return $this->endMessage;
|
||||
return $this->endMessage ?? "";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,7 +444,7 @@ class Buff
|
||||
*/
|
||||
public function getsActivatedAt(int $flag): bool
|
||||
{
|
||||
return $this->activateAt & $flag;
|
||||
return ($flag === self::ACTIVATE_NONE ? $this->activateAt === self::ACTIVATE_NONE : $this->activateAt & $flag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,6 +455,15 @@ class Buff
|
||||
{
|
||||
return $this->survivesNewDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the buff expires after the battle.
|
||||
* @return bool
|
||||
*/
|
||||
public function expiresAfterBattle(): bool
|
||||
{
|
||||
return $this->expiresAfterBattle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rounds left
|
||||
@@ -539,4 +666,22 @@ class Buff
|
||||
{
|
||||
return $this->goodguyInvulnurable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the buff has already been started
|
||||
* @return bool
|
||||
*/
|
||||
public function hasBeenStarted(): bool
|
||||
{
|
||||
return $this->hasBeenStarted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the buff has been started (or not).
|
||||
* @param bool $setTo
|
||||
*/
|
||||
public function setHasBeenStarted(bool $setTo = true)
|
||||
{
|
||||
$this->hasBeenStarted = $setTo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,10 @@ use Doctrine\Common\Collections\{
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
use Doctrine\ORM\Mapping\Table;
|
||||
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\{
|
||||
BuffList,
|
||||
Game
|
||||
};
|
||||
use LotGD\Core\Tools\Exceptions\BuffSlotOccupiedException;
|
||||
use LotGD\Core\Tools\Model\{
|
||||
Creator,
|
||||
@@ -61,6 +64,8 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
private $messageThreads;
|
||||
/** @OneToMany(targetEntity="Buff", mappedBy="character", cascade={"persist"}) */
|
||||
private $buffs;
|
||||
/** @var BuffList */
|
||||
private $buffList;
|
||||
|
||||
/** @var array */
|
||||
private static $fillable = [
|
||||
@@ -258,7 +263,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
*/
|
||||
public function getBuffs(): BuffList
|
||||
{
|
||||
$this->buffList ?? new BuffList($this->buffs);
|
||||
$this->buffList = $this->buffList ?? new BuffList($this->buffs);
|
||||
return $this->buffList;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Models;
|
||||
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\{
|
||||
BuffList,
|
||||
Game
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface for models that should be able to participate in fights.
|
||||
@@ -19,4 +22,5 @@ interface FighterInterface
|
||||
public function getDefense(Game $game, bool $ignoreBuffs = false): int;
|
||||
public function damage(int $damage);
|
||||
public function heal(int $heal);
|
||||
public function getBuffs(): BuffList;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Tools\Model;
|
||||
|
||||
use LotGD\Core\Game;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
use LotGD\Core\{
|
||||
BuffList,
|
||||
Game
|
||||
};
|
||||
|
||||
/**
|
||||
* Automatically calculated values based on the fighter's level
|
||||
@@ -39,4 +44,14 @@ trait AutoScaleFighter
|
||||
$level = $this->getlevel();
|
||||
return (int)floor($level*1.45);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty bufflist
|
||||
* @return BuffList
|
||||
*/
|
||||
public function getBuffs(): BuffList
|
||||
{
|
||||
$this->buffList = $this->buffList ?? new BuffList(new ArrayCollection());
|
||||
return $this->buffList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,10 @@ declare(strict_types = 1);
|
||||
|
||||
namespace LotGD\Core\Tools\Model;
|
||||
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\{
|
||||
BuffList,
|
||||
Game
|
||||
};
|
||||
use LotGD\Core\Exceptions\IsNullException;
|
||||
use LotGD\Core\Models\CharacterViewpoint;
|
||||
|
||||
@@ -81,4 +84,13 @@ trait MockCharacter
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty bufflist
|
||||
* @return BuffList
|
||||
*/
|
||||
public function getBuffs(): BuffList
|
||||
{
|
||||
throw new IsNullException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,19 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Tests\Models;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
|
||||
use LotGD\Core\{
|
||||
Battle,
|
||||
DiceBag,
|
||||
Game,
|
||||
Models\Buff,
|
||||
Models\Character,
|
||||
Models\Monster
|
||||
};
|
||||
use LotGD\Core\Models\BattleEvents\{
|
||||
BuffMessageEvent
|
||||
};
|
||||
|
||||
use LotGD\Core\Tests\ModelTestCase;
|
||||
|
||||
@@ -196,4 +202,80 @@ class BattleTest extends ModelTestCase
|
||||
$battle->fightNRounds(1);
|
||||
}
|
||||
}
|
||||
|
||||
private function provideBuffBattleParticipants(Buff $buff): Battle
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$character = $em->getRepository(Character::class)->find(4);
|
||||
$monster = $em->getRepository(Monster::class)->find(3);
|
||||
|
||||
$character->addBuff($buff);
|
||||
|
||||
return new Battle($this->getMockGame($character), $character, $monster);
|
||||
}
|
||||
|
||||
protected function assertBuffEventMessageExists(
|
||||
Collection $events,
|
||||
string $battleEventText,
|
||||
int $timesAtLeast = 1,
|
||||
int $timesAtMax = null
|
||||
) {
|
||||
$eventCounter = 0;
|
||||
foreach($events as $event) {
|
||||
if ($event instanceof BuffMessageEvent) {
|
||||
if ($battleEventText === $event->getMessage()) {
|
||||
$eventCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($timesAtMax === null) {
|
||||
$timesAtMax = $timesAtLeast;
|
||||
}
|
||||
|
||||
$this->assertGreaterThanOrEqual($timesAtLeast, $eventCounter);
|
||||
$this->assertLessThanOrEqual($timesAtMax, $eventCounter);
|
||||
}
|
||||
|
||||
public function testBattleBuffMessages()
|
||||
{
|
||||
$battle = $this->provideBuffBattleParticipants(new Buff([
|
||||
"slot" => "test",
|
||||
"rounds" => 3,
|
||||
"startMessage" => "And this buff starts!",
|
||||
"roundMessage" => "The buff is still activate",
|
||||
"endMessage" => "The buff is ending.",
|
||||
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
|
||||
]));
|
||||
|
||||
$battle->fightNRounds(5);
|
||||
|
||||
$this->assertBuffEventMessageExists($battle->getEvents(), "And this buff starts!", 1);
|
||||
$this->assertBuffEventMessageExists($battle->getEvents(), "The buff is ending.", 1);
|
||||
$this->assertBuffEventMessageExists($battle->getEvents(), "The buff is still activate", 1, 2);
|
||||
|
||||
$expectedEvents = [
|
||||
BuffMessageEvent::class, // Activation round
|
||||
\LotGD\Core\Models\BattleEvents\DamageEvent::class, // Round 1
|
||||
\LotGD\Core\Models\BattleEvents\DamageEvent::class,
|
||||
BuffMessageEvent::class, // message every round
|
||||
\LotGD\Core\Models\BattleEvents\DamageEvent::class, // Round 2
|
||||
\LotGD\Core\Models\BattleEvents\DamageEvent::class,
|
||||
BuffMessageEvent::class, // message every round
|
||||
\LotGD\Core\Models\BattleEvents\DamageEvent::class, // Round 3
|
||||
\LotGD\Core\Models\BattleEvents\DamageEvent::class,
|
||||
BuffMessageEvent::class, // message expires
|
||||
\LotGD\Core\Models\BattleEvents\DamageEvent::class, // Round 4
|
||||
\LotGD\Core\Models\BattleEvents\DamageEvent::class,
|
||||
\LotGD\Core\Models\BattleEvents\DamageEvent::class, // Round 5
|
||||
\LotGD\Core\Models\BattleEvents\DamageEvent::class,
|
||||
];
|
||||
|
||||
$numOfEvents = count($battle->getEvents());
|
||||
for ($i = 0; $i < $numOfEvents; $i++) {
|
||||
$this->assertInstanceOf($expectedEvents[$i], $battle->getEvents()[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,13 @@ characters:
|
||||
health: 10
|
||||
maxhealth: 10
|
||||
level: 1
|
||||
-
|
||||
id: 4
|
||||
name: "Low Damage Char"
|
||||
displayName: "Low Damage Char"
|
||||
health: 500
|
||||
maxhealth: 500
|
||||
level: 0
|
||||
monsters:
|
||||
-
|
||||
id: 1
|
||||
|
||||
Reference in New Issue
Block a user