From c9e6f679c4e10c7c9f6cb4a3ec576dd1acfd16c3 Mon Sep 17 00:00:00 2001 From: Vassyli Date: Tue, 9 Jan 2018 17:16:54 +0100 Subject: [PATCH] Adds events to character->getAttack and getDefense to modify the value. Tests included. --- src/Models/Character.php | 36 ++++++++++++++++++---- tests/GameTest.php | 2 +- tests/ModelTestCase.php | 47 +++++++++++++++++++++++++++++ tests/Models/CharacterModelTest.php | 41 +++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 7 deletions(-) diff --git a/src/Models/Character.php b/src/Models/Character.php index cf94019..9dca3d3 100644 --- a/src/Models/Character.php +++ b/src/Models/Character.php @@ -11,9 +11,9 @@ use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\Table; use LotGD\Core\{ - BuffList, Game, GameAwareInterface + BuffList, Events\CharacterEventData, Game, GameAwareInterface }; -use LotGD\Core\Tools\Exceptions\BuffSlotOccupiedException; +use LotGD\Core\Exceptions\BuffSlotOccupiedException; use LotGD\Core\Tools\Model\{ Creator, ExtendableModel, GameAware, PropertyManager, SoftDeletable }; @@ -141,7 +141,7 @@ class Character implements CharacterInterface, CreateableInterface, GameAwareInt /** * Sets the maximum health of a character to a given value. It also sets the * health if none has been set yet. - * @param int $maxhealth + * @param int $maxHealth */ public function setMaxHealth(int $maxHealth) { @@ -191,7 +191,7 @@ class Character implements CharacterInterface, CreateableInterface, GameAwareInt /** * Heals the enemy * @param int $heal - * @param type $overheal True if healing bigger than maxhealth is desired. + * @param bool $overheal True if healing bigger than maxHealth is desired. */ public function heal(int $heal, bool $overheal = false) { @@ -227,7 +227,19 @@ class Character implements CharacterInterface, CreateableInterface, GameAwareInt */ public function getAttack(bool $ignoreBuffs = false): int { - return $this->level; + $baseAttack = $this->level; + + $hookData = $this->getGame()->getEventManager()->publish( + "h/lotgd/core/getCharacterAttack", + CharacterEventData::create([ + "character" => $this, + "value" => $baseAttack + ]) + ); + + $modifiedAttack = $hookData->get("value"); + + return $modifiedAttack; } /** @@ -237,7 +249,19 @@ class Character implements CharacterInterface, CreateableInterface, GameAwareInt */ public function getDefense(bool $ignoreBuffs = false): int { - return $this->level; + $baseDefense = $this->level; + + $hookData = $this->getGame()->getEventManager()->publish( + "h/lotgd/core/getCharacterDefense", + CharacterEventData::create([ + "character" => $this, + "value" => $baseDefense + ]) + ); + + $modifiedDefense = $hookData->get("value"); + + return $modifiedDefense; } /** diff --git a/tests/GameTest.php b/tests/GameTest.php index 86f8e90..325eb55 100644 --- a/tests/GameTest.php +++ b/tests/GameTest.php @@ -76,7 +76,7 @@ class GameTest extends CoreModelTestCase /** @var string default data set */ protected $dataset = "game"; - private $g; + public $g; public function setUp() { diff --git a/tests/ModelTestCase.php b/tests/ModelTestCase.php index ba99cd8..1a4957e 100644 --- a/tests/ModelTestCase.php +++ b/tests/ModelTestCase.php @@ -3,16 +3,23 @@ declare(strict_types=1); namespace LotGD\Core\Tests; +use Doctrine\Common\Annotations\AnnotationRegistry; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Events as DoctrineEvents; use Doctrine\ORM\Mapping\AnsiQuoteStrategy; use Doctrine\ORM\Tools\Setup; use Doctrine\ORM\Tools\SchemaTool; use LotGD\Core\Configuration; use LotGD\Core\ComposerManager; +use LotGD\Core\Doctrine\EntityPostLoadEventListener; +use LotGD\Core\GameBuilder; use LotGD\Core\LibraryConfigurationManager; use LotGD\Core\Exceptions\InvalidConfigurationException; +use LotGD\Core\ModelExtender; +use Monolog\Handler\NullHandler; +use Monolog\Logger; /** * Description of ModelTestCase @@ -25,6 +32,7 @@ abstract class ModelTestCase extends \PHPUnit_Extensions_Database_TestCase static private $em = null; /** @var \PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection */ private $connection = null; + public $g; /** * Returns a connection to test models @@ -76,6 +84,45 @@ abstract class ModelTestCase extends \PHPUnit_Extensions_Database_TestCase return self::$em; } + protected function setUp() + { + parent::setUp(); + + $this->getEntityManager()->flush(); + $this->getEntityManager()->clear(); + + // Make an empty logger for these tests. Feel free to change this + // to place log messages somewhere you can easily find them. + $logger = new Logger('test'); + $logger->pushHandler(new NullHandler()); + + // Create a Game object for use in these tests. + $this->g = (new GameBuilder()) + ->withConfiguration(new Configuration(getenv('LOTGD_TESTS_CONFIG_PATH'))) + ->withLogger($logger) + ->withEntityManager($this->getEntityManager()) + ->withCwd(implode(DIRECTORY_SEPARATOR, [__DIR__, '..'])) + ->create(); + + // Add Event listener to entity manager + $dem = $this->getEntityManager()->getEventManager(); + $dem->addEventListener([DoctrineEvents::postLoad], new EntityPostLoadEventListener($this->g)); + + // Run model extender + AnnotationRegistry::registerLoader("class_exists"); + + $modelExtender = new ModelExtender(); + $libraryConfigurationManager = new LibraryConfigurationManager($this->g->getComposerManager(), getcwd()); + + foreach ($libraryConfigurationManager->getConfigurations() as $config) { + $modelExtensions = $config->getSubKeyIfItExists(["modelExtensions"]); + + if ($modelExtensions) { + $modelExtender->addMore($modelExtensions); + } + } + } + protected function tearDown() { parent::tearDown(); diff --git a/tests/Models/CharacterModelTest.php b/tests/Models/CharacterModelTest.php index e8bce9e..0ec2b7b 100644 --- a/tests/Models/CharacterModelTest.php +++ b/tests/Models/CharacterModelTest.php @@ -3,6 +3,11 @@ declare(strict_types=1); namespace LotGD\Core\Tests\Models; +use LotGD\Core\EventHandler; +use LotGD\Core\EventManager; +use LotGD\Core\Events\EventContext; +use LotGD\Core\Game; +use LotGD\Core\GameBuilder; use LotGD\Core\Models\Character; use LotGD\Core\Models\CharacterProperty; use LotGD\Core\Tests\CoreModelTestCase; @@ -189,4 +194,40 @@ class CharacterModelTest extends CoreModelTestCase $this->assertSame(6, $total); } + + public function testIfAttackPublishesEvent() + { + $level = mt_rand(0, 100); + $character1 = Character::create(["name" => "Test", "maxHealth" => 10, "level" => $level]); + $character1->setGame($this->g); + $character2 = Character::create(["name" => "Test", "maxHealth" => 10, "level" => $level*2]); + $character2->setGame($this->g); + + $detectionClass = new class implements EventHandler { + static $events_called = []; + + public static function handleEvent(Game $g, EventContext $context): EventContext + { + $event = $context->getEvent(); + $value = $context->getDataField("value"); + + self::$events_called[$event] = $value; + + $context->setDataField("value", $value*2); + return $context; + } + }; + + /** @var EventManager $eventManager */ + $eventManager = $this->g->getEventManager(); + + $eventManager->subscribe("#h/lotgd/core/getCharacterAttack#", get_class($detectionClass), "test"); + $eventManager->subscribe("#h/lotgd/core/getCharacterDefense#", get_class($detectionClass), "test"); + + $this->assertSame($level*2, $character1->getAttack()); + $this->assertSame($level*4, $character2->getDefense()); + + $this->assertSame($level, $detectionClass::$events_called["h/lotgd/core/getCharacterAttack"]); + $this->assertSame($level*2, $detectionClass::$events_called["h/lotgd/core/getCharacterDefense"]); + } }