67 Commits

Author SHA1 Message Date
Basilius Sauter 4ca81a3789 Fixed some class documentation. 2019-04-05 13:19:33 +02:00
Basilius Sauter 353c4251c4 Allows the modulemanager to return null instead of the ModuleModel 2019-04-03 17:25:21 +02:00
Basilius Sauter 248258a8fe Adds character stats and tests. 2019-04-03 16:17:36 +02:00
Basilius Sauter 4d1ab9e763 Changed quote strategy to BasicQuoteStrategy as AnsiQuoteStrategy seems to mess up the column names. 2019-04-02 21:12:02 +02:00
Basilius Sauter d7229858cc Adds command to list all characters, and to reset a given characters viewpoint. 2019-04-01 16:50:18 +02:00
Basilius Sauter 14b1db8b82 Changes command module:register to resolve dependencies first. 2019-04-01 16:50:14 +02:00
Basilius Sauter d7100deb0f Merge branch 'master' of https://github.com/lotgd/core into feature/symfony4 2019-03-22 16:26:53 +01:00
Basilius Sauter e260a1d661 Added missing doc block 2019-03-22 16:23:50 +01:00
Basilius Sauter 2ff8d647e8 Changed a small bug causing actions to not have any titles. 2019-03-22 16:23:50 +01:00
Basilius Sauter 8d9a186b46 Small changed to documentation. 2019-03-22 16:23:50 +01:00
Basilius Sauter 8f69527764 Character model: added default parameters for name and displayName. 2019-03-22 16:23:50 +01:00
Basilius Sauter 684f86aed6 Added missing use statements in character model for doctrine annotations. 2019-03-22 16:23:50 +01:00
Basilius Sauter 55481c30b1 Adds schema-update daenerys command. 2019-03-22 16:23:50 +01:00
Basilius Sauter 6b383be1cd Added config to disable automatic database schema update. 2019-03-22 16:23:50 +01:00
Basilius Sauter d609f981aa Changed doctrine dependency 2019-03-22 16:23:50 +01:00
Basilius Sauter 4ec84dfec3 Changed dependency to symfony 4 2019-03-22 16:23:50 +01:00
Basilius Sauter 049d116028 Updated version identifier for 0.5 2018-10-10 10:12:59 +02:00
Basilius Sauter aa63259992 Updated version identifier for 0.5 2018-10-10 10:10:38 +02:00
Basilius Sauter a097c29d67 Added tests to ensure ModuleManager::register does not change anything upon error. 2018-10-08 17:29:44 +02:00
Basilius Sauter bab3e0f236 Changed viewpoint to use uuid-based primary key 2018-10-08 17:29:44 +02:00
Basilius Sauter 2f89bbc7e3 Changed buff to use uuid. 2018-10-08 17:29:44 +02:00
Basilius Sauter 6e2ba248c4 Small changes. 2018-10-08 17:29:44 +02:00
Basilius Sauter b398ffae14 Changed motd id to uuid 2018-10-08 17:29:44 +02:00
Basilius Sauter 90971d152a Changed motd id to uuid 2018-10-08 17:29:44 +02:00
Basilius Sauter 04b3b6aaf9 Changed character id to uuid 2018-10-08 17:29:44 +02:00
Vassyli 0aaba1b94b Fixes inheritance issue with CharacterRepository 2018-10-08 17:28:16 +02:00
Vassyli 2affd4803f Added missing DocBlocks 2018-10-08 17:26:44 +02:00
Vassyli c07f7b3342 Removed auto-flushing for every event from EventManager. 2018-10-08 17:26:44 +02:00
Vassyli 8a75e81431 Updated failing tests 2018-10-08 17:26:44 +02:00
Vassyli ccfb432e4d ActionGroup now implements Countable interface. 2018-04-12 19:49:10 +02:00
Vassyli 2a0bf5f038 Fixes inheritance issue with CharacterRepository 2018-04-12 19:40:57 +02:00
Vassyli 4248dad033 Hotfix for re-enabling tests. Forces to use phpunit dependency. 2018-04-12 14:43:30 +02:00
Katrina Swales b89f6d7b0c Merge branch 'master' of github.com:nekosune/core 2018-04-09 17:02:18 +01:00
nekosune 6c4b1e15f4 Made changes requested, and fixed tests 2018-04-09 16:01:37 +00:00
nekosune ddb7ae08a6 Made requested changes 2018-04-09 15:39:36 +00:00
nekosune 8ba04dade4 Added missing docblock 2018-04-07 19:24:16 +00:00
nekosune 70243f4662 Moved Message sending to Message Manager as per issue #28 2018-04-07 19:12:13 +00:00
Austen McDonald 77b33d7385 Correct typo in comment (#113 from Cousjava/typofix)
Correct typo in comment
2018-03-15 12:52:31 -07:00
Cousjava db49e63c99 Merge branch 'master' into typofix 2018-03-15 19:46:37 +00:00
Cousjava d90e4d0ba9 Correct typo in comment
Closes lotgd/core#108
2018-03-15 19:45:45 +00:00
Vassyli ccbfa0553c Replaced diceBag()->normal with diceBag()->pseudoBell, added a few fight fixes. 2018-01-27 19:33:59 +01:00
Vassyli 04a5b59ea2 Fixed an issue with PropertyManager. 2018-01-26 16:21:53 +01:00
Vassyli 846ab6018e LibraryConfiguration now also knows crate packages. 2018-01-19 17:42:33 +01:00
Vassyli efb333d08a Adds missing doc block 2018-01-10 08:27:56 +01:00
Vassyli 92c0f71ed6 Small clean-ups 2018-01-10 08:22:28 +01:00
Vassyli c9e6f679c4 Adds events to character->getAttack and getDefense to modify the value. Tests included. 2018-01-09 17:16:54 +01:00
Vassyli 17ebdbdbe5 Redesign EventData creation 2018-01-09 09:43:08 +01:00
Vassyli 55b821c8e8 Removed game dependency from FighterInterface->getAttack and getDefense 2018-01-09 09:25:40 +01:00
Vassyli 45a785a8f5 Adds documentation. 2018-01-09 09:04:04 +01:00
Vassyli ff713ac333 Adds possibility to extend certain models using annotations. 2018-01-09 09:04:04 +01:00
Vassyli aba0d53a68 postLoad eventListener adds Game object to GameAware entities. 2018-01-09 09:04:04 +01:00
Vassyli 9ddd16b4e8 Adds suggestion plus a few additional tests 2018-01-09 08:59:58 +01:00
Vassyli c0edd3ac67 Adds php 7.2 to travis 2018-01-05 10:30:59 +01:00
Vassyli 81d773720a Removes master 2018-01-05 10:30:21 +01:00
Vassyli 5ac7098f35 Adds documentation to PropertyManager trait. 2018-01-04 14:13:56 +01:00
Vassyli 41db0ddfda Adds a CharacterEventData class for events that are only character related. 2018-01-04 13:02:57 +01:00
Vassyli 003a6517ba Updated dependencies 2017-12-25 14:59:55 +01:00
Vassyli af6a6cbff0 Adds a ViewpointDecorationEventData class for hooks that want to provide a specific hook for scene manipulation. 2017-12-25 14:46:39 +01:00
Vassyli 56c80e3f8d fixup! ViewpointDescription now ignores empty lines 2017-09-27 13:22:00 +02:00
Vassyli 4b82ee4b89 ViewpointDescription now ignores empty lines 2017-09-27 13:17:26 +02:00
Vassyli 829d63d7f6 Fixes BattleEvents to accept correct game 2017-09-27 12:20:58 +02:00
Vassyli 94763f8d6e Adds the possibility to serialize a battle state for saving it 2017-09-22 13:37:54 +02:00
Vassyli a287313f6f Adds a normal dice to the dice bag 2017-09-22 12:10:11 +02:00
Vassyli 51a102f981 Changed BasicEnemy properties from private to protected in order to allow inheritance 2017-09-19 12:48:02 +02:00
Vassyli 9842fa9ace Added additional api calls to manage action groups 2017-09-18 11:36:27 +02:00
Vassyli adf4eeac5e Adds documentation 2017-09-13 18:32:14 +02:00
Vassyli 533378d006 Adds the foundation for viewpoint to be able to modify there description more easily 2017-09-13 18:24:37 +02:00
104 changed files with 3636 additions and 921 deletions
+1
View File
@@ -2,6 +2,7 @@ sudo: false
language: php language: php
php: php:
- '7.1' - '7.1'
- '7.2'
install: install:
- composer install - composer install
script: script:
+5 -3
View File
@@ -2,6 +2,7 @@
"name": "lotgd/core", "name": "lotgd/core",
"description": "Core functionality for Legend of the Green Dragon, a text-based RPG game.", "description": "Core functionality for Legend of the Green Dragon, a text-based RPG game.",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"version": "0.5.0",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"LotGD\\Core\\": "src/", "LotGD\\Core\\": "src/",
@@ -17,9 +18,10 @@
"gedmo/doctrine-extensions": "*", "gedmo/doctrine-extensions": "*",
"doctrine/orm": "^2.5", "doctrine/orm": "^2.5",
"monolog/monolog": "^1.12", "monolog/monolog": "^1.12",
"symfony/console": "^3.0", "symfony/console": "^3.0|^4.0",
"symfony/yaml": "^3.0", "symfony/yaml": "^3.0|^4.0",
"d11wtq/boris": "^1.0" "d11wtq/boris": "^1.0",
"ramsey/uuid-doctrine": "^1.5"
}, },
"repositories": [ "repositories": [
{ {
Generated
+863 -335
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -3,6 +3,7 @@ database:
name: daenerys name: daenerys
user: root user: root
password: password:
disableAutoSchemaUpdate: false
game: game:
epoch: 2016-07-01 00:00:00.0 -8 epoch: 2016-07-01 00:00:00.0 -8
offsetSeconds: 0 offsetSeconds: 0
+2 -2
View File
@@ -20,7 +20,7 @@ class Action
* @param string|null $title * @param string|null $title
* @param array $parameters * @param array $parameters
*/ */
public function __construct(int $destinationSceneId, ?string $title = null, array $parameters = []) public function __construct(string $destinationSceneId, ?string $title = null, array $parameters = [])
{ {
$this->id = bin2hex(random_bytes(8)); $this->id = bin2hex(random_bytes(8));
$this->destinationSceneId = $destinationSceneId; $this->destinationSceneId = $destinationSceneId;
@@ -43,7 +43,7 @@ class Action
* go if they take this action. * go if they take this action.
* @return int * @return int
*/ */
public function getDestinationSceneId(): int public function getDestinationSceneId(): string
{ {
return $this->destinationSceneId; return $this->destinationSceneId;
} }
+12 -3
View File
@@ -6,7 +6,7 @@ namespace LotGD\Core;
/** /**
* A grouping of navigation actions, like a submenu. * A grouping of navigation actions, like a submenu.
*/ */
class ActionGroup class ActionGroup implements \Countable
{ {
const DefaultGroup = 'lotgd/core/default'; const DefaultGroup = 'lotgd/core/default';
const HiddenGroup = 'lotgd/core/hidden'; const HiddenGroup = 'lotgd/core/hidden';
@@ -30,6 +30,15 @@ class ActionGroup
$this->actions = []; $this->actions = [];
} }
/**
* Returns the number of registered Actions for this group.
* @return int
*/
public function count(): int
{
return count($this->actions);
}
/** /**
* Returns the unique identifier for this group, in the vendor/module/group format. * Returns the unique identifier for this group, in the vendor/module/group format.
* @return string * @return string
@@ -61,7 +70,7 @@ class ActionGroup
/** /**
* Returns the ordered array of actions. * Returns the ordered array of actions.
* @return array<Action> * @return Action[]
*/ */
public function getActions(): array public function getActions(): array
{ {
@@ -70,7 +79,7 @@ class ActionGroup
/** /**
* Sets the ordered array of actions. * Sets the ordered array of actions.
* @param array<Action> $actions * @param Action[] $actions
*/ */
public function setActions(array $actions) public function setActions(array $actions)
{ {
+38 -19
View File
@@ -16,11 +16,7 @@ use LotGD\Core\{
Models\FighterInterface Models\FighterInterface
}; };
use LotGD\Core\Models\{ use LotGD\Core\Models\{
Buff, Buff, BattleEvents\BuffMessageEvent, BattleEvents\CriticalHitEvent, BattleEvents\DamageEvent, BattleEvents\DeathEvent, Scene
BattleEvents\BuffMessageEvent,
BattleEvents\CriticalHitEvent,
BattleEvents\DamageEvent,
BattleEvents\DeathEvent
}; };
/** /**
@@ -47,7 +43,7 @@ class Battle
/** /**
* Battle Configuration * Battle Configuration
* @var type * @var array
*/ */
protected $configuration = [ protected $configuration = [
"riposteEnabled" => true, "riposteEnabled" => true,
@@ -61,31 +57,50 @@ class Battle
* @param FighterInterface $player * @param FighterInterface $player
* @param FighterInterface $monster * @param FighterInterface $monster
*/ */
public function __construct(Game $game, FighterInterface $player, FighterInterface $monster) public function __construct(Game $game, FighterInterface $player, ?FighterInterface $monster)
{ {
$this->game = $game; $this->game = $game;
$this->player = $player; $this->player = $player;
$this->monster = $monster; $this->monster = $monster;
$this->events = new ArrayCollection(); $this->events = new ArrayCollection();
} }
/** /**
* @ToDo Returns at some point battle actions * Returns a string which contains the important fields that must be serialized.
* @return string
*/ */
public function getActions() public function serialize(): string
{ {
return serialize([
"monster" => $this->monster,
"result" => $this->result,
"round" => $this->round,
"configuration" => $this->configuration,
]);
} }
/** /**
* @ToDo Do some action * @param Game $game
* @param FighterInterface $player
* @param string $serialized
* @return Battle
*/ */
public function selectAction() public static function unserialize(Game $game, FighterInterface $player, string $serialized): self
{ {
$battle = new self($game, $player, null);
$unserialized = unserialize($serialized);
$battle->monster = $unserialized["monster"];
$battle->result = $unserialized["result"];
$battle->round = $unserialized["round"];
$battle->configuration = $unserialized["configuration"];
return $battle;
} }
/** /**
* Returns a list of all battle events * Returns a list of all battle events
* @return \LotGD\Core\Collection * @return Collection
*/ */
public function getEvents(): Collection public function getEvents(): Collection
{ {
@@ -197,6 +212,7 @@ class Battle
/** /**
* Returns the winner of this fight * Returns the winner of this fight
* @return FighterInterface * @return FighterInterface
* @throws BattleNotOverException if battle is not over.
*/ */
public function getWinner(): FighterInterface public function getWinner(): FighterInterface
{ {
@@ -210,6 +226,7 @@ class Battle
/** /**
* Returns the loser of this fight * Returns the loser of this fight
* @return FighterInterface * @return FighterInterface
* @throws BattleNotOverException if battle is not over.
*/ */
public function getLoser(): FighterInterface public function getLoser(): FighterInterface
{ {
@@ -226,6 +243,8 @@ class Battle
* @param int $n * @param int $n
* @param bool $firstDamageRound Which damage rounds are calculated. Cannot be 0. * @param bool $firstDamageRound Which damage rounds are calculated. Cannot be 0.
* @return int Number of fights fought. * @return int Number of fights fought.
* @throws ArgumentException if firstDamageRound is 0.
* @throws BattleIsOverException
*/ */
public function fightNRounds(int $n = 1, int $firstDamageRound = self::DAMAGEROUND_BOTH): int public function fightNRounds(int $n = 1, int $firstDamageRound = self::DAMAGEROUND_BOTH): int
{ {
@@ -346,12 +365,12 @@ class Battle
// Apply buff scaling for the attacker's attack - this needs to take into // Apply buff scaling for the attacker's attack - this needs to take into
// account the attacker's goodguyAttackModifier and the defenders badguyAttackModifier // account the attacker's goodguyAttackModifier and the defenders badguyAttackModifier
$attackersAttack = $attacker->getAttack($this->game) $attackersAttack = $attacker->getAttack()
* $attackersBuffs->getGoodguyAttackModifier() * $attackersBuffs->getGoodguyAttackModifier()
* $defendersBuffs->getBadguyAttackModifier(); * $defendersBuffs->getBadguyAttackModifier();
// It's the opposite for the defender's defense - it needs to take into account the // 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. // defender's goodguyDefenseModifier as well as the attacker's badguyDefenseModifier.
$defendersDefense = $defender->getDefense($this->game) $defendersDefense = $defender->getDefense()
* $defendersBuffs->getGoodguyDefenseModifier() * $defendersBuffs->getGoodguyDefenseModifier()
* $attackersBuffs->getBadguyDefenseModifier() * $attackersBuffs->getBadguyDefenseModifier()
* $defenseAdjustement; * $defenseAdjustement;
@@ -369,13 +388,13 @@ class Battle
$defendersDefense = (int) round($defendersDefense, 0); $defendersDefense = (int) round($defendersDefense, 0);
// Lets roll the // Lets roll the
$attackersAtkRoll = $this->game->getDiceBag()->normal(0, $attackersAttack); $attackersAtkRoll = $this->game->getDiceBag()->pseudoBell(0, $attackersAttack);
$defendersDefRoll = $this->game->getDiceBag()->normal(0, $defendersDefense); $defendersDefRoll = $this->game->getDiceBag()->pseudoBell(0, $defendersDefense);
$damage = $attackersAtkRoll - $defendersDefRoll; $damage = $attackersAtkRoll - $defendersDefRoll;
// If the attacker's attack after modification is bigger than before, // If the attacker's attack after modification is bigger than before,
// we call it a critical hit and apply the CriticalHitEvent. // we call it a critical hit and apply the CriticalHitEvent.
if ($attackersAttack > $attacker->getAttack($this->game) && $this->isCriticalHitEnabled()) { if ($attackersAttack > $attacker->getAttack() && $this->isCriticalHitEnabled()) {
$events->add(new CriticalHitEvent($attacker, $attackersAttack)); $events->add(new CriticalHitEvent($attacker, $attackersAttack));
} }
+46 -13
View File
@@ -3,6 +3,11 @@ declare(strict_types=1);
namespace LotGD\Core; namespace LotGD\Core;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\EventManager as DoctrineEventManager;
use Doctrine\Common\Util\Debug;
use Doctrine\DBAL\DBALException;
use Doctrine\ORM\Events as DoctrineEvents;
use Doctrine\ORM\ { use Doctrine\ORM\ {
EntityManager, EntityManager,
EntityManagerInterface, EntityManagerInterface,
@@ -17,10 +22,8 @@ use Monolog\ {
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Application; use Symfony\Component\Console\Application;
use LotGD\Core\ { use LotGD\Core\{
ComposerManager, ComposerManager, BootstrapInterface, Doctrine\EntityPostLoadEventListener, Exceptions\InvalidConfigurationException
BootstrapInterface,
Exceptions\InvalidConfigurationException
}; };
/** /**
@@ -30,7 +33,8 @@ class Bootstrap
{ {
private $logger; private $logger;
private $game; private $game;
private $libraryConfigurationManager = []; /** @var LibraryConfigurationManager */
private $libraryConfigurationManager;
private $annotationDirectories = []; private $annotationDirectories = [];
/** /**
@@ -62,7 +66,7 @@ class Bootstrap
list($dsn, $user, $password) = $config->getDatabaseConnectionDetails($cwd); list($dsn, $user, $password) = $config->getDatabaseConnectionDetails($cwd);
$pdo = $this->connectToDatabase($dsn, $user, $password); $pdo = $this->connectToDatabase($dsn, $user, $password);
$entityManager = $this->createEntityManager($pdo); $entityManager = $this->createEntityManager($pdo, $config);
$this->game = (new GameBuilder()) $this->game = (new GameBuilder())
->withConfiguration($config) ->withConfiguration($config)
@@ -71,6 +75,13 @@ class Bootstrap
->withCwd($cwd) ->withCwd($cwd)
->create(); ->create();
// Add Event listener to entity manager
$dem = $entityManager->getEventManager();
$dem->addEventListener([DoctrineEvents::postLoad], new EntityPostLoadEventListener($this->game));
// Run model extender
$this->extendModels();
return $this->game; return $this->game;
} }
@@ -148,7 +159,7 @@ class Bootstrap
* @param \PDO $pdo * @param \PDO $pdo
* @return EntityManagerInterface * @return EntityManagerInterface
*/ */
protected function createEntityManager(\PDO $pdo): EntityManagerInterface protected function createEntityManager(\PDO $pdo, Configuration $config): EntityManagerInterface
{ {
$this->annotationDirectories = $this->generateAnnotationDirectories(); $this->annotationDirectories = $this->generateAnnotationDirectories();
$this->logger->addDebug("Adding annotation directories:"); $this->logger->addDebug("Adding annotation directories:");
@@ -157,16 +168,20 @@ class Bootstrap
} }
$configuration = Setup::createAnnotationMetadataConfiguration($this->annotationDirectories, true); $configuration = Setup::createAnnotationMetadataConfiguration($this->annotationDirectories, true);
// Set a quote
$configuration->setQuoteStrategy(new AnsiQuoteStrategy());
// Create entity manager // Create entity manager
$entityManager = EntityManager::create(["pdo" => $pdo], $configuration); $entityManager = EntityManager::create(["pdo" => $pdo], $configuration);
// Register uuid type
try {
\Doctrine\DBAL\Types\Type::addType('uuid', 'Ramsey\Uuid\Doctrine\UuidType');
} catch (DBALException $e) {}
// Create Schema and update database if needed // Create Schema and update database if needed
$metaData = $entityManager->getMetadataFactory()->getAllMetadata(); if ($config->getDatabaseAutoSchemaUpdate()) {
$schemaTool = new SchemaTool($entityManager); $metaData = $entityManager->getMetadataFactory()->getAllMetadata();
$schemaTool->updateSchema($metaData); $schemaTool = new SchemaTool($entityManager);
$schemaTool->updateSchema($metaData);
}
return $entityManager; return $entityManager;
} }
@@ -199,4 +214,22 @@ class Bootstrap
} }
} }
} }
/**
* Runs the code to extend models.
*/
public function extendModels()
{
AnnotationRegistry::registerLoader("class_exists");
$modelExtender = new ModelExtender();
foreach ($this->libraryConfigurationManager->getConfigurations() as $config) {
$modelExtensions = $config->getSubKeyIfItExists(["modelExtensions"]);
if ($modelExtensions) {
$modelExtender->addMore($modelExtensions);
}
}
}
} }
+1 -1
View File
@@ -536,7 +536,7 @@ class BuffList
if ($buff->getBadguyDamageReflection() !== 0.) { if ($buff->getBadguyDamageReflection() !== 0.) {
if ($damage > 0) { if ($damage > 0) {
// Damage is > 0, so badguy takes damage, we can normally reflect // Damage is > 0, so badguy takes damage, we can normally reflect
$reflectedDamage = (int)round($buff->getGoodguyDamageReflection() * $damage, 0); $reflectedDamage = (int)round($buff->getBadguyDamageReflection() * $damage, 0);
if ($reflectedDamage === 0) { if ($reflectedDamage === 0) {
$message = $buff->getNoEffectMessage(); $message = $buff->getNoEffectMessage();
} else { } else {
+3 -6
View File
@@ -4,10 +4,7 @@ declare(strict_types=1);
namespace LotGD\Core; namespace LotGD\Core;
use Composer\{ use Composer\{
Composer, Composer, Factory, IO\NullIO, Package\CompletePackageInterface, Package\PackageInterface
Factory,
IO\NullIO,
Package\CompletePackageInterface
}; };
use Monolog\Logger; use Monolog\Logger;
@@ -73,7 +70,7 @@ class ComposerManager
/** /**
* Return all the packages installed in the current setup. * Return all the packages installed in the current setup.
* @return array<Composer\PackageInterface> * @return PackageInterface[]
*/ */
public function getPackages(): array public function getPackages(): array
{ {
@@ -85,7 +82,7 @@ class ComposerManager
/** /**
* Return a list of the configured packages which are LotGD modules (type = 'lotgd-module'). * Return a list of the configured packages which are LotGD modules (type = 'lotgd-module').
* @return array Array of \Composer\PackageInterface. * @return PackageInterface[]
*/ */
public function getModulePackages(): array public function getModulePackages(): array
{ {
+16
View File
@@ -20,6 +20,7 @@ class Configuration
private $databaseName; private $databaseName;
private $databaseUser; private $databaseUser;
private $databasePassword; private $databasePassword;
private $databaseAutoSchemaUpdate;
private $logPath; private $logPath;
private $gameEpoch; private $gameEpoch;
private $gameOffsetSeconds; private $gameOffsetSeconds;
@@ -70,6 +71,12 @@ class Configuration
$this->databasePassword = $passwd; $this->databasePassword = $passwd;
$this->databaseName = $name; $this->databaseName = $name;
if (empty($rawConfig['database']['disableAutoSchemaUpdate'])) {
$this->databaseAutoSchemaUpdate = true;
} else {
$this->databaseAutoSchemaUpdate = false;
}
$gameEpoch = $rawConfig['game']['epoch']; $gameEpoch = $rawConfig['game']['epoch'];
$gameOffsetSeconds = $rawConfig['game']['offsetSeconds']; $gameOffsetSeconds = $rawConfig['game']['offsetSeconds'];
$gameDaysPerDay = $rawConfig['game']['daysPerDay']; $gameDaysPerDay = $rawConfig['game']['daysPerDay'];
@@ -157,6 +164,15 @@ class Configuration
return $this->databasePassword; return $this->databasePassword;
} }
/**
* True if doctrine should not auto update.
* @return bool
*/
public function getDatabaseAutoSchemaUpdate(): bool
{
return $this->databaseAutoSchemaUpdate;
}
/** /**
* Return the path to the directory to store log files. * Return the path to the directory to store log files.
* @return string The configured log directory path. * @return string The configured log directory path.
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Console\Command;
use LotGD\Core\Models\Character;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* Command to list all characters.
* @package LotGD\Core\Console\Command
*/
class CharacterListCommand extends BaseCommand
{
/**
* @inheritDoc
*/
protected function configure()
{
$this->setName('character:list')
->setDescription('Lists all characters');
}
/**
* @inheritDoc
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$characters = $this->game->getEntityManager()->getRepository(Character::class)->findAll();
$table = [["id", "name", "level"], []];
foreach ($characters as $character) {
$table[1][] = [
$character->getId(),
$character->getDisplayName(),
$character->getLevel()
];
}
$io->table(...$table);
}
}
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Console\Command;
use LotGD\Core\Models\Character;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* Resets the viewpoint of a given character.
* @package LotGD\Core\Console\Command
*/
class CharacterResetViewpointCommand extends BaseCommand
{
/**
* @inheritDoc
*/
protected function configure()
{
$this->setName('character:resetViewpoint')
->setDescription('Resets the viewpoint of a given character.')
->setDefinition(
new InputDefinition([
new InputOption('id', null, InputOption::VALUE_REQUIRED)
])
);
}
/**
* @inheritDoc
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$id = $input->getOption("id");
/* @var $character \LotGD\Core\Models\Character */
$character = $this->game->getEntityManager()->getRepository(Character::class)->find($id);
if ($character === null) {
$io->error("Character not found.");
return;
}
$this->game->getEntityManager()->remove($character->getViewpoint());
$character->setViewpoint(null);
$this->game->getEntityManager()->flush();
}
}
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Console\Command;
use Doctrine\ORM\Tools\SchemaTool;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use LotGD\Core\Console\Main;
use LotGD\Core\Game;
/**
* Danerys command to initiate the database with default values.
*/
class DatabaseSchemaUpdateCommand extends BaseCommand
{
/**
* @inheritDoc
*/
protected function configure()
{
$this->setName('database:schemaUpdate')
->setDescription('Updates the database schema manually.');
}
/**
* @inheritDoc
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$entityManager = $this->game->getEntityManager();
$metaData = $entityManager->getMetadataFactory()->getAllMetadata();
$schemaTool = new SchemaTool($entityManager);
$schemaTool->updateSchema($metaData);
$entityManager->flush();
}
}
+51 -12
View File
@@ -3,12 +3,15 @@ declare(strict_types=1);
namespace LotGD\Core\Console\Command; namespace LotGD\Core\Console\Command;
use Composer\Repository\RepositoryInterface;
use LotGD\Core\ModuleManager;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use LotGD\Core\Exceptions\ClassNotFoundException; use LotGD\Core\Exceptions\ClassNotFoundException;
use LotGD\Core\Exceptions\ModuleAlreadyExistsException; use LotGD\Core\Exceptions\ModuleAlreadyExistsException;
use LotGD\Core\LibraryConfiguration; use LotGD\Core\LibraryConfiguration;
use Symfony\Component\Console\Style\SymfonyStyle;
/** /**
* Danerys command to register and initiate any newly installed modules. * Danerys command to register and initiate any newly installed modules.
@@ -29,21 +32,57 @@ class ModuleRegisterCommand extends BaseCommand
*/ */
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
$io = new SymfonyStyle($input, $output);
$modules = $this->game->getComposerManager()->getModulePackages(); $modules = $this->game->getComposerManager()->getModulePackages();
$registered = [];
foreach ($modules as $p) { foreach ($modules as $p) {
$library = new LibraryConfiguration($this->game->getComposerManager(), $p, $this->game->getCWD()); $this->registerModule($p->getName(), $io, $registered);
$name = $library->getName();
try {
$this->game->getModuleManager()->register($library);
$output->writeln("<info>Registered new module {$name}</info>");
} catch (ModuleAlreadyExistsException $e) {
$output->writeln("Skipping already registered module {$name}");
} catch (ClassNotFoundException $e) {
$output->writeln("<error>Error installing module {$name}: " . $e->getMessage() . "</error>");
}
} }
} }
/**
* Register a given package as a module if it is of type lotdg-module. Resolves dependencies and skips already registered packages.
* @param string $packageName
* @param OutputInterface $output
* @param array $registered
* @throws \LotGD\Core\Exceptions\InvalidConfigurationException
* @throws \LotGD\Core\Exceptions\WrongTypeException
*/
protected function registerModule(
string $packageName,
SymfonyStyle $io,
array &$registered
) {
$composerRepository = $this->game->getComposerManager()->getComposer()
->getRepositoryManager()->getLocalRepository();
$package = $composerRepository->findPackage($packageName, "*");
if ($package->getType() !== "lotgd-module") {
return;
}
if (!empty($registered[$packageName])) {
return;
}
$io->text("Reading module {$packageName} {$package->getPrettyVersion()}");
$library = new LibraryConfiguration($this->game->getComposerManager(), $package, $this->game->getCWD());
$dependencies = $package->getRequires();
foreach ($dependencies as $dependency) {
$this->registerModule($dependency->getTarget(), $io, $registered);
}
try {
$this->game->getModuleManager()->register($library);
$io->success("\tRegistered new module {$packageName}");
} catch (ModuleAlreadyExistsException $e) {
$io->note("\tSkipping already registered module {$packageName}");
} catch (ClassNotFoundException $e) {
$io->error("\tError installing module {$packageName}: {$e->getMessage()}");
}
$registered[$packageName] = true;
}
} }
+6
View File
@@ -8,7 +8,10 @@ use Symfony\Component\Console\Application;
use LotGD\Core\Bootstrap; use LotGD\Core\Bootstrap;
use LotGD\Core\Game; use LotGD\Core\Game;
use LotGD\Core\Console\Command\{ use LotGD\Core\Console\Command\{
CharacterListCommand,
CharacterResetViewpointCommand,
DatabaseInitCommand, DatabaseInitCommand,
DatabaseSchemaUpdateCommand,
ModuleValidateCommand, ModuleValidateCommand,
ModuleRegisterCommand, ModuleRegisterCommand,
ConsoleCommand ConsoleCommand
@@ -42,7 +45,10 @@ class Main
$this->application->add(new ModuleValidateCommand($this->game)); $this->application->add(new ModuleValidateCommand($this->game));
$this->application->add(new ModuleRegisterCommand($this->game)); $this->application->add(new ModuleRegisterCommand($this->game));
$this->application->add(new DatabaseInitCommand($this->game)); $this->application->add(new DatabaseInitCommand($this->game));
$this->application->add(new DatabaseSchemaUpdateCommand($this->game));
$this->application->add(new ConsoleCommand($this->game)); $this->application->add(new ConsoleCommand($this->game));
$this->application->add(new CharacterListCommand($this->game));
$this->application->add(new CharacterResetViewpointCommand($this->game));
// Add additional ones // Add additional ones
$this->bootstrap->addDaenerysCommands($this->application); $this->bootstrap->addDaenerysCommands($this->application);
+25 -2
View File
@@ -1,6 +1,5 @@
<?php <?php
declare(strict_types=1);
declare (strict_types = 1);
namespace LotGD\Core; namespace LotGD\Core;
@@ -12,6 +11,7 @@ class DiceBag
/** /**
* Returns true $p percent of the time, where $p is between 0 and 1. * Returns true $p percent of the time, where $p is between 0 and 1.
* @param float $p * @param float $p
* @return bool True if you are lucky, False if not.
*/ */
public function chance(float $p): bool public function chance(float $p): bool
{ {
@@ -24,16 +24,39 @@ class DiceBag
* Generates a uniformly randomly number between $min and $max. * Generates a uniformly randomly number between $min and $max.
* @param float $min * @param float $min
* @param float $max * @param float $max
* @return float random number between $min and $max
*/ */
public function uniform(float $min, float $max): float public function uniform(float $min, float $max): float
{ {
return (mt_rand(0, 100) / 100.0) * ($max - $min) + $min; return (mt_rand(0, 100) / 100.0) * ($max - $min) + $min;
} }
/**
* Generates a uniformly randomly integer between $min and $max.
* @param int $min
* @param int $max
* @return int random number between $min and $max
*/
public function dice(int $min, int $max): int
{
if ($min == $max) {
return $min;
}
if ($min > $max) {
$a = $min;
$min = $max;
$max = $a;
}
return mt_rand($min, $max);
}
/** /**
* Generates a normally distributed random number between $min and $max. * Generates a normally distributed random number between $min and $max.
* @param float $min * @param float $min
* @param float $max * @param float $max
* @return float normally distributed random number
*/ */
public function normal(float $min, float $max): float public function normal(float $min, float $max): float
{ {
+51
View File
@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Doctrine\Annotations;
use Doctrine\Common\Annotations\Annotation;
use Doctrine\Common\Annotations\Annotation\Attributes;
use Doctrine\Common\Annotations\Annotation\Attribute;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Models\ExtendableModelInterface;
/**
* Annotation that is used to flag which entity a class extends.
* @package LotGD\Core\Doctrine
* @Annotation
* @Target("CLASS")
* @Attributes({
* @Attribute("of", type = "string")
* })
*/
class Extension
{
/** @var string */
private $modelClass;
/**
* Extension constructor.
* @param array $attributes
* @throws ArgumentException
*/
public function __construct(array $attributes) {
$this->modelClass = $attributes["of"];
if (!class_exists($this->modelClass)) {
throw new ArgumentException("The class given in of must be a valid class.");
}
if (!in_array(ExtendableModelInterface::class, class_implements($this->modelClass))) {
throw new ArgumentException("The class given in of must implement the ExtendableModelInterface.");
}
}
/**
* Returns the model class name.
* @return string
*/
public function getModelClass(): string
{
return $this->modelClass;
}
}
@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Doctrine\Annotations;
use Doctrine\Common\Annotations\Annotation;
use Doctrine\Common\Annotations\Annotation\Attributes;
use Doctrine\Common\Annotations\Annotation\Attribute;
use LotGD\Core\Exceptions\ArgumentException;
/**
* Annotation that is used to link a static method to a model entity.
* @package LotGD\Core\Doctrine\Annotations
* @Annotation
* @Target("METHOD")
* @Attributes({
* @Attribute("as", type = "string")
* })
*/
class ExtensionMethod
{
/** @var string */
private $methodName = "";
/**
* ExtensionMethod constructor.
* @param array $attributes
* @throws ArgumentException
*/
public function __construct(array $attributes) {
$this->methodName = $attributes["as"];
if (!is_string($this->methodName)) {
throw new ArgumentException("Property 'as' must be a string.");
}
if (strlen($this->methodName) == 0) {
throw new ArgumentException("Property 'as' must not be an empty string.");
}
}
/**
* Returns the method name.
* @return string
*/
public function getMethodName(): string
{
return $this->methodName;
}
}
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Doctrine;
use Doctrine\Common\Util\Debug;
use Doctrine\ORM\Event\LifecycleEventArgs;
use LotGD\Core\Game;
use LotGD\Core\GameAwareInterface;
/**
* Class EntityPostLoadEventListener
* @package LotGD\Core\Doctrine
*/
class EntityPostLoadEventListener
{
/** @var Game $game */
private $game;
/**
* EntityPostLoadEventListener constructor.
* @param Game $g
*/
public function __construct(Game $g)
{
$this->game = $g;
}
/**
* Called upon event postLoad.
* @param LifecycleEventArgs $args
*/
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof GameAwareInterface) {
$entity->setGame($this->game);
}
}
}
+2 -3
View File
@@ -10,9 +10,8 @@ interface EventHandler
* Called when an event is published that is handled by this class. * Called when an event is published that is handled by this class.
* *
* @param Game $g The game. * @param Game $g The game.
* @param string $event Name of this event. * @param EventContext $context Arbitrary dictionary representing context around this event.
* @param array $context Arbitrary dictionary representing context around this event. * @return EventContext Return an array if you want to make changes to the $context before
* @return array|null Return an array if you want to make changes to the $context before
* the next handler is called. Otherwise, return null. Any changes made will be propogated * the next handler is called. Otherwise, return null. Any changes made will be propogated
* to the event publisher as well. * to the event publisher as well.
*/ */
+2 -1
View File
@@ -111,7 +111,8 @@ class EventManager
'class' => $class, 'class' => $class,
'library' => $library 'library' => $library
]); ]);
$e->save($this->g->getEntityManager());
$this->g->getEntityManager()->persist($e);
} }
/** /**
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace LotGD\Core\Events;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Models\Character;
/**
* Class CharacterEventData
* @package LotGD\Core\Events
*/
class CharacterEventData extends EventContextData
{
protected static $argumentConfig = [
"character" => ["type" => Character::class, "required" => true],
"value" => ["type" => "mixed", "required" => false]
];
}
+45 -2
View File
@@ -6,7 +6,7 @@ namespace LotGD\Core\Events;
use LotGD\Core\Exceptions\ArgumentException; use LotGD\Core\Exceptions\ArgumentException;
/** /**
* EventContextDataContainer to provide a basic structure for managing contextual data of an event. * EventContextData to provide a basic structure for managing contextual data of an event.
* *
* This class must be immutable and returns always a new instance of itself for any change. * This class must be immutable and returns always a new instance of itself for any change.
* @package LotGD\Core\Events * @package LotGD\Core\Events
@@ -25,9 +25,52 @@ class EventContextData
*/ */
public static function create(array $data): self public static function create(array $data): self
{ {
if (isset(static::$argumentConfig)) {
static::checkConfiguration($data);
}
return new static($data); return new static($data);
} }
/**
* Checks a field configuration given in self::$argumentConfig.
* @param $data
* @throws ArgumentException
*/
public static function checkConfiguration($data)
{
$configuration = static::$argumentConfig;
$types = [
"mixed" => function ($x) {return true;},
"int" => function ($x) {return is_int($x);},
"float" => function ($x) {return is_float($x);},
"numeric" => function($x) {return is_numeric($x);},
"string" => function($x) {return is_string($x);},
];
$keys = array_keys($data);
foreach ($keys as $key) {
if (!isset($configuration[$key])) {
throw new ArgumentException(sprintf("%s does not accept a field called %s", static::class, $key));
}
}
foreach ($configuration as $key => $config) {
if ($config["required"] === true and !isset($data[$key])) {
throw new ArgumentException(sprintf("%s must have a field called %s.", static::class, $key));
}
if (isset($types[$config["type"]])) {
if ($types[$config["type"]]($data[$key]) === false) {
throw new ArgumentException(sprintf("The field %s of %s must be of type %s.", $key, static::class, $config["type"]));
}
} else {
if (!$data[$key] instanceof $config["type"]) {
throw new ArgumentException(sprintf("The field %s of %s must be of type %s", $key, static::class, $config["type"]));
}
}
}
}
/** /**
* protected constructor.. * protected constructor..
* @see self::create * @see self::create
@@ -133,4 +176,4 @@ class EventContextData
"{$field} is not valid in this context, only {$this->getFormattedListOfFields()} are allowed." "{$field} is not valid in this context, only {$this->getFormattedListOfFields()} are allowed."
); );
} }
} }
@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Events;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Models\Viewpoint;
/**
* Class ViewpointDecorationEventData
* @package LotGD\Core\Events
*/
class ViewpointDecorationEventData extends EventContextData
{
protected static $argumentConfig = [
"viewpoint" => ["type" => Viewpoint::class, "required" => true]
];
}
+15
View File
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Class CharacterStatException
* @package LotGD\Core\Exceptions
*/
class CharacterStatException extends CoreException
{
}
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Class CharacterStatExistsException
* @package LotGD\Core\Exceptions
*/
class CharacterStatExistsException extends CharacterStatException
{
}
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Class CharacterStatGroupExistsException
* @package LotGD\Core\Exceptions
*/
class CharacterStatGroupExistsException extends CharacterStatException
{
}
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Class CharacterStatGroupNotFoundException
* @package LotGD\Core\Exceptions
*/
class CharacterStatGroupNotFoundException extends CharacterStatException
{
}
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Class CharacterStatNotFoundException
* @package LotGD\Core\Exceptions
*/
class CharacterStatNotFoundException extends CharacterStatException
{
}
+23 -2
View File
@@ -4,6 +4,7 @@ declare (strict_types=1);
namespace LotGD\Core; namespace LotGD\Core;
use DateTime; use DateTime;
use Doctrine\Common\Util\Debug;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use LotGD\Core\Events\NavigateToSceneData; use LotGD\Core\Events\NavigateToSceneData;
use LotGD\Core\Events\NewViewpointData; use LotGD\Core\Events\NewViewpointData;
@@ -25,6 +26,7 @@ class Game
private $eventManager; private $eventManager;
private $composerManager; private $composerManager;
private $moduleManager; private $moduleManager;
private $messageManager;
private $logger; private $logger;
private $configuration; private $configuration;
private $character; private $character;
@@ -32,6 +34,7 @@ class Game
private $cwd; private $cwd;
private $timeKeeper; private $timeKeeper;
/** /**
* Construct a game. You probably want to use Bootstrap to do this. * Construct a game. You probably want to use Bootstrap to do this.
* @param Configuration $configuration * @param Configuration $configuration
@@ -57,7 +60,7 @@ class Game
*/ */
public static function getVersion(): string public static function getVersion(): string
{ {
return '0.1.0'; return '0.5.0';
} }
/** /**
@@ -184,6 +187,24 @@ class Game
return $this->timeKeeper; return $this->timeKeeper;
} }
/**
* Returns the Message manager
* @return MessageManager
*/
public function getMessageManager(): MessageManager
{
return $this->messageManager;
}
/**
* Sets the Message Manager
* @param MessageManager $messageManager
*/
public function setMessageManager(MessageManager $messageManager): void
{
$this->messageManager = $messageManager;
}
/** /**
* Returns the currently configured user character. * Returns the currently configured user character.
* @return Character * @return Character
@@ -289,7 +310,7 @@ class Game
} }
$this->getLogger()->addDebug(" Adding navigation action for child sceneId={$connectedScene->getId()}"); $this->getLogger()->addDebug(" Adding navigation action for child sceneId={$connectedScene->getId()}");
$action = new Action($connectedScene->getId()); $action = new Action($connectedScene->getId(), $connectedScene->getTitle());
if ($connectionGroupName === null) { if ($connectionGroupName === null) {
$actionGroups[ActionGroup::DefaultGroup]->addAction($action); $actionGroups[ActionGroup::DefaultGroup]->addAction($action);
+14
View File
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace LotGD\Core;
/**
* Interface for classes that are aware of the game
* @package LotGD\Core
*/
interface GameAwareInterface
{
public function setGame(Game $g);
public function getGame(): Game;
}
+14 -1
View File
@@ -27,6 +27,7 @@ class GameBuilder
private $composerManagerClass; private $composerManagerClass;
private $eventManagerClass; private $eventManagerClass;
private $diceBagClass; private $diceBagClass;
private $messageManagerClass;
/** /**
* Creates the game instance with the prepared parameters. * Creates the game instance with the prepared parameters.
@@ -62,7 +63,8 @@ class GameBuilder
$diceBag = $this->diceBagClass ?? DiceBag::class; $diceBag = $this->diceBagClass ?? DiceBag::class;
$game->setDiceBag(new $diceBag()); $game->setDiceBag(new $diceBag());
$messageManager=$this->messageManagerClass ?? MessageManager::class;
$game->setMessageManager(new $messageManager());
return $game; return $game;
} }
@@ -110,6 +112,17 @@ class GameBuilder
return $this; return $this;
} }
/**
* Sets the fqcn for the message manager to be used
* @param string $messageManagerFqcn
* @return self
*/
public function withMessageManager(string $messageManagerFqcn): self
{
$this->messageManagerClass=$messageManagerFqcn;
return $this;
}
/** /**
* Sets the fqcn for the module manager to be used. * Sets the fqcn for the module manager to be used.
* @param string $moduleManagerFqcn * @param string $moduleManagerFqcn
+4 -4
View File
@@ -43,7 +43,7 @@ class LibraryConfiguration
if ($basePackage && $basePackage->getName() === $package->getName()) { if ($basePackage && $basePackage->getName() === $package->getName()) {
// Whatever the base package is in this repo is at $cwd. // Whatever the base package is in this repo is at $cwd.
$path = $cwd; $path = $cwd;
} else if ($package->getType() === "lotgd-module") { } elseif (in_array($package->getType(), ["lotgd-module", "lotgd-crate"])) {
// lotgd-modules are installed in the vendor directory. // lotgd-modules are installed in the vendor directory.
$installationManager = $composerManager->getComposer()->getInstallationManager(); $installationManager = $composerManager->getComposer()->getInstallationManager();
$path = $installationManager->getInstallPath($package); $path = $installationManager->getInstallPath($package);
@@ -124,9 +124,9 @@ class LibraryConfiguration
/** /**
* Returns a subkey if it exists or null. * Returns a subkey if it exists or null.
* @param array $arguments * @param array $arguments
* @return type * @return mixed
*/ */
protected function getSubKeyIfItExists(array $arguments) public function getSubKeyIfItExists(array $arguments)
{ {
$parent = $this->rawConfig; $parent = $this->rawConfig;
@@ -145,7 +145,7 @@ class LibraryConfiguration
* Tries to iterate an array element given by the arguments * Tries to iterate an array element given by the arguments
* @param scalar $argument1,... array keys, by increasing depth * @param scalar $argument1,... array keys, by increasing depth
*/ */
protected function iterateKey(...$arguments) public function iterateKey(...$arguments)
{ {
$result = $this->getSubKeyIfItExists($arguments); $result = $this->getSubKeyIfItExists($arguments);
+1 -1
View File
@@ -52,7 +52,7 @@ class LibraryConfigurationManager
/** /**
* Return an array of the library configurations. * Return an array of the library configurations.
* @return array<LibraryConfiguration> * @return LibraryConfiguration[]
*/ */
public function getConfigurations(): array { public function getConfigurations(): array {
return $this->configurations; return $this->configurations;
+54
View File
@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace LotGD\Core;
use LotGD\Core\Models\Character;
use LotGD\Core\Models\Message;
use LotGD\Core\Models\MessageThread;
use LotGD\Core\Models\SystemCharacter;
/**
* Manages the message system overall
* Class MessageManager
* @package LotGD\Core
*/
class MessageManager
{
/**
* Sends a message to a MessageThread
* @param \LotGD\Core\Models\Character $from
* @param string $message
* @param \LotGD\Core\Models\MessageThread $thread
* @param bool $systemMessage
* @return \LotGD\Core\Models\Message
* @throws Exceptions\CoreException
*/
public function send(
Character $from,
string $message,
MessageThread $thread,
bool $systemMessage = false
) {
$message = new Message($from, $message, $thread, $systemMessage);
$thread->addMessage($message);
return $message;
}
/**
* Sends a system message to a MessageThread
* @param string $message
* @param \LotGD\Core\Models\MessageThread $thread
* @return \LotGD\Core\Models\Message
* @throws Exceptions\ArgumentException
* @throws Exceptions\CoreException
*/
public function sendSystemMessage(
string $message,
MessageThread $thread
) {
$message = new Message(SystemCharacter::getInstance(), $message, $thread, true);
$thread->addMessage($message);
return $message;
}
}
+95
View File
@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace LotGD\Core;
use LotGD\Core\Doctrine\Annotations\ExtensionMethod;
use LotGD\Core\Exceptions\ArgumentException;
use ReflectionClass;
use Doctrine\Common\Annotations\AnnotationReader;
use LotGD\Core\Doctrine\Annotations\Extension;
/**
* Contains method to help the extension of a model.
* @package LotGD\Core
*/
class ModelExtender
{
/** @var AnnotationReader */
private $reader;
/** @var array */
private static $classes = [];
/**
* ModelExtender constructor.
*/
public function __construct()
{
$this->reader = new AnnotationReader();
}
/**
* @param string[] $classes
*/
public function addMore(array $classes): void {
foreach($classes as $class) {
$this->add($class);
}
}
/**
* @param string $class
* @throws ArgumentException if the given class is not properly annotated.
*/
public function add(string $class): void
{
$reflectionClass = new ReflectionClass($class);
/** @var Extension $extensionAnnotation */
$extensionAnnotation = $this->reader->getClassAnnotation($reflectionClass, Extension::class);
if ($extensionAnnotation === null) {
throw new ArgumentException(sprintf("Class %s must have the class Annotation %s", $class, Extension::class));
}
$modelClass = $extensionAnnotation->getModelClass();
if (empty(self::$classes[$modelClass])) {
self::$classes[$modelClass] = [];
}
// Run through static methods
$reflectionMethods = $reflectionClass->getMethods();
foreach ($reflectionMethods as $method) {
if ($method->isStatic() === false) {
throw new ArgumentException(sprintf("Method %s must be static.", $method->getName()));
}
/** @var ExtensionMethod $extensionMethodAnnotation */
$extensionMethodAnnotation = $this->reader->getMethodAnnotation($method, ExtensionMethod::class);
$methodName = $method->getName();
self::$classes[$modelClass][$extensionMethodAnnotation->getMethodName()] = [$class, $methodName];
}
}
/**
* Returns a callback registered in the model extender globally.
* @param string $modelClassName
* @param string $methodName
* @return callable|null
*/
public static function get(string $modelClassName, string $methodName): ?callable
{
if (empty(self::$classes[$modelClassName])) {
return null;
}
if (empty(self::$classes[$modelClassName][$methodName])) {
return null;
}
return self::$classes[$modelClassName][$methodName];
}
}
+16 -6
View File
@@ -4,26 +4,36 @@ declare(strict_types=1);
namespace LotGD\Core\Models; namespace LotGD\Core\Models;
use Doctrine\ORM\Mapping\MappedSuperclass; use Doctrine\ORM\Mapping\MappedSuperclass;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
/** /**
* @MappedSuperclass * @MappedSuperclass
*/ */
abstract class BasicEnemy implements FighterInterface abstract class BasicEnemy implements FighterInterface
{ {
/** @Id @Column(type="integer") @GeneratedValue */ /** @Id @Column(type="uuid", unique=True) */
private $id; protected $id;
/** @Column(type="string", length=50); */ /** @Column(type="string", length=50); */
private $name; protected $name;
/** @Column(type="integer"); */ /** @Column(type="integer"); */
private $level; protected $level;
/** @var int */ /** @var int */
private $health; protected $health;
/**
* BasicEnemy constructor. Sets uuid upon creation.
* @throws \Exception
*/
public function __construct() {
$this->id = Uuid::uuid4();
}
/** /**
* Returns the enemy's id * Returns the enemy's id
* @return int * @return int
*/ */
public function getId(): int public function getId(): UuidInterface
{ {
return $this->id; return $this->id;
} }
+1
View File
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace LotGD\Core\Models\BattleEvents; namespace LotGD\Core\Models\BattleEvents;
use LotGD\Core\Exceptions\BattleEventException; use LotGD\Core\Exceptions\BattleEventException;
use LotGD\Core\Game;
/** /**
* A representation of something that happened in battle. * A representation of something that happened in battle.
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace LotGD\Core\Models\BattleEvents; namespace LotGD\Core\Models\BattleEvents;
use LotGD\Core\Exceptions\BattleEventException; use LotGD\Core\Exceptions\BattleEventException;
use LotGD\Core\Game;
/** /**
* A battle event representing a message generated by a buff. * A battle event representing a message generated by a buff.
+2 -1
View File
@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace LotGD\Core\Models\BattleEvents; namespace LotGD\Core\Models\BattleEvents;
use LotGD\Core\Game;
use LotGD\Core\Models\FighterInterface; use LotGD\Core\Models\FighterInterface;
/** /**
@@ -31,7 +32,7 @@ class CriticalHitEvent extends BattleEvent
*/ */
public function decorate(Game $game): string public function decorate(Game $game): string
{ {
$pureAttackersAttack = $this->attacker->getAttack($game, true); $pureAttackersAttack = $this->attacker->getAttack(true);
if ($this->criticalAttackValue > $pureAttackersAttack * 4) { if ($this->criticalAttackValue > $pureAttackersAttack * 4) {
return "You execute a MEGA power move!!!"; return "You execute a MEGA power move!!!";
+1
View File
@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace LotGD\Core\Models\BattleEvents; namespace LotGD\Core\Models\BattleEvents;
use LotGD\Core\Game;
use LotGD\Core\Models\FighterInterface; use LotGD\Core\Models\FighterInterface;
/** /**
@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace LotGD\Core\Models\BattleEvents; namespace LotGD\Core\Models\BattleEvents;
use LotGD\Core\Game;
use LotGD\Core\Models\FighterInterface; use LotGD\Core\Models\FighterInterface;
/** /**
@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace LotGD\Core\Models\BattleEvents; namespace LotGD\Core\Models\BattleEvents;
use LotGD\Core\Game;
use LotGD\Core\Models\FighterInterface; use LotGD\Core\Models\FighterInterface;
/** /**
+1
View File
@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace LotGD\Core\Models\BattleEvents; namespace LotGD\Core\Models\BattleEvents;
use LotGD\Core\Game;
use LotGD\Core\Models\FighterInterface; use LotGD\Core\Models\FighterInterface;
/** /**
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace LotGD\Core\Models\BattleEvents; namespace LotGD\Core\Models\BattleEvents;
use LotGD\Core\Exceptions\BattleEventException; use LotGD\Core\Exceptions\BattleEventException;
use LotGD\Core\Game;
use LotGD\Core\Models\FighterInterface; use LotGD\Core\Models\FighterInterface;
/** /**
@@ -39,7 +40,7 @@ class MinionDamageEvent extends BattleEvent
*/ */
public function decorate(Game $game): string public function decorate(Game $game): string
{ {
parent::decorate(); parent::decorate($game);
return str_replace( return str_replace(
[ [
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace LotGD\Core\Models\BattleEvents; namespace LotGD\Core\Models\BattleEvents;
use LotGD\Core\Exceptions\BattleEventException; use LotGD\Core\Exceptions\BattleEventException;
use LotGD\Core\Game;
use LotGD\Core\Models\FighterInterface; use LotGD\Core\Models\FighterInterface;
/** /**
@@ -44,7 +45,7 @@ class RegenerationBuffEvent extends BattleEvent
*/ */
public function decorate(Game $game): string public function decorate(Game $game): string
{ {
parent::decorate(); parent::decorate($game);
if ($this->regeneration === 0) { if ($this->regeneration === 0) {
return str_replace( return str_replace(
+10 -6
View File
@@ -7,6 +7,8 @@ use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table; use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Exceptions\ArgumentException; use LotGD\Core\Exceptions\ArgumentException;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
/** /**
* A model representing a buff used to modify the flow of the battle. * A model representing a buff used to modify the flow of the battle.
@@ -23,7 +25,7 @@ class Buff
const ACTIVATE_NONE = 0b0000; const ACTIVATE_NONE = 0b0000;
const ACTIVATE_ANY = 0b1111; const ACTIVATE_ANY = 0b1111;
/** @Id @Column(type="integer") @GeneratedValue */ /** @Id @Column(type="uuid", unique=True) */
private $id; private $id;
/** /**
* @ManyToOne(targetEntity="Character", inversedBy="buffs") * @ManyToOne(targetEntity="Character", inversedBy="buffs")
@@ -231,7 +233,7 @@ class Buff
* Allowed buff values and their type * Allowed buff values and their type
* @var array * @var array
*/ */
private $buffArrayTemplate = [ private static $buffArrayTemplate = [
"slot" => "string", "slot" => "string",
"name" => "string", "name" => "string",
"startMessage" => "string", "startMessage" => "string",
@@ -282,13 +284,15 @@ class Buff
*/ */
public function __construct(array $buffArray) public function __construct(array $buffArray)
{ {
$this->id = Uuid::uuid4();
foreach ($buffArray as $attribute => $value) { foreach ($buffArray as $attribute => $value) {
// Throw exception if an attribute does not exist (to prevent spelling errors) // Throw exception if an attribute does not exist (to prevent spelling errors)
if (!isset($this->buffArrayTemplate[$attribute])) { if (!isset(self::$buffArrayTemplate[$attribute])) {
throw new ArgumentException("{$attribute} is not a valid key for a buff."); throw new ArgumentException("{$attribute} is not a valid key for a buff.");
} }
switch ($this->buffArrayTemplate[$attribute]) { switch (self::$buffArrayTemplate[$attribute]) {
case "string": case "string":
if (is_string($value) === false) { if (is_string($value) === false) {
throw new ArgumentException("{$attribute} needs to be a string."); throw new ArgumentException("{$attribute} needs to be a string.");
@@ -338,7 +342,7 @@ class Buff
{ {
$buffArray = []; $buffArray = [];
foreach ($this->buffArrayTemplate as $attribute => $type) { foreach (self::$buffArrayTemplate as $attribute => $type) {
$buffArray[$attribute] = $buff->$attribute; $buffArray[$attribute] = $buff->$attribute;
} }
@@ -349,7 +353,7 @@ class Buff
* Returns the id of the buff * Returns the id of the buff
* @return int * @return int
*/ */
public function getId(): int public function getId(): UuidInterface
{ {
return $this->id; return $this->id;
} }
+58 -18
View File
@@ -7,19 +7,25 @@ use Doctrine\Common\Collections\{
ArrayCollection, ArrayCollection,
Collection Collection
}; };
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\JoinTable;
use Doctrine\ORM\Mapping\ManyToMany;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\OneToOne;
use Doctrine\ORM\Mapping\Table; use Doctrine\ORM\Mapping\Table;
use LotGD\Core\{ use LotGD\Core\{
BuffList, BuffList, Events\CharacterEventData, Game, GameAwareInterface
Game
}; };
use LotGD\Core\Tools\Exceptions\BuffSlotOccupiedException; use LotGD\Core\Exceptions\BuffSlotOccupiedException;
use LotGD\Core\Tools\Model\{ use LotGD\Core\Tools\Model\{
Creator, Creator, ExtendableModel, GameAware, PropertyManager, SoftDeletable
PropertyManager,
SoftDeletable
}; };
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
/** /**
* Model for a character * Model for a character
@@ -27,18 +33,20 @@ use LotGD\Core\Tools\Model\{
* @Entity(repositoryClass="LotGD\Core\Models\Repositories\CharacterRepository") * @Entity(repositoryClass="LotGD\Core\Models\Repositories\CharacterRepository")
* @Table(name="characters") * @Table(name="characters")
*/ */
class Character implements CharacterInterface, CreateableInterface class Character implements CharacterInterface, CreateableInterface, GameAwareInterface, ExtendableModelInterface
{ {
use Creator; use Creator;
use SoftDeletable; use SoftDeletable;
use PropertyManager; use PropertyManager;
use GameAware;
use ExtendableModel;
/** @Id @Column(type="integer") @GeneratedValue */ /** @Id @Column(type="uuid", unique=True) */
private $id; private $id;
/** @Column(type="string", length=50); */ /** @Column(type="string", length=50); */
private $name; private $name = "";
/** @Column(type="text"); */ /** @Column(type="text"); */
private $displayName; private $displayName = "";
/** @Column(type="integer", options={"default":10}) */ /** @Column(type="integer", options={"default":10}) */
private $maxHealth = 10; private $maxHealth = 10;
/** @Column(type="integer", options={"default":10}) */ /** @Column(type="integer", options={"default":10}) */
@@ -74,6 +82,8 @@ class Character implements CharacterInterface, CreateableInterface
"level", "level",
]; ];
private $propertyClass = CharacterProperty::class;
/** /**
* Creates a character at full health * Creates a character at full health
*/ */
@@ -89,6 +99,8 @@ class Character implements CharacterInterface, CreateableInterface
*/ */
public function __construct() public function __construct()
{ {
$this->id = Uuid::uuid4();
$this->properties = new ArrayCollection(); $this->properties = new ArrayCollection();
$this->buffs = new ArrayCollection(); $this->buffs = new ArrayCollection();
$this->messageThreads = new ArrayCollection(); $this->messageThreads = new ArrayCollection();
@@ -98,7 +110,7 @@ class Character implements CharacterInterface, CreateableInterface
* Returns the entity's id * Returns the entity's id
* @return int The id * @return int The id
*/ */
public function getId(): int public function getId(): UuidInterface
{ {
return $this->id; return $this->id;
} }
@@ -142,7 +154,7 @@ class Character implements CharacterInterface, CreateableInterface
/** /**
* Sets the maximum health of a character to a given value. It also sets the * Sets the maximum health of a character to a given value. It also sets the
* health if none has been set yet. * health if none has been set yet.
* @param int $maxhealth * @param int $maxHealth
*/ */
public function setMaxHealth(int $maxHealth) public function setMaxHealth(int $maxHealth)
{ {
@@ -192,7 +204,7 @@ class Character implements CharacterInterface, CreateableInterface
/** /**
* Heals the enemy * Heals the enemy
* @param int $heal * @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) public function heal(int $heal, bool $overheal = false)
{ {
@@ -223,18 +235,46 @@ class Character implements CharacterInterface, CreateableInterface
/** /**
* Returns the character's virtual attribute "attack" * Returns the character's virtual attribute "attack"
* @param bool $ignoreBuffs
* @return int
*/ */
public function getAttack(Game $game, bool $ignoreBuffs = false): int public function getAttack(bool $ignoreBuffs = false): int
{ {
return $this->level * 2; $baseAttack = $this->level;
$hookData = $this->getGame()->getEventManager()->publish(
"h/lotgd/core/getCharacterAttack",
CharacterEventData::create([
"character" => $this,
"value" => $baseAttack
])
);
$modifiedAttack = $hookData->get("value");
return $modifiedAttack;
} }
/** /**
* Returns the character's virtual attribute "defense" * Returns the character's virtual attribute "defense"
* @param bool $ignoreBuffs
* @return int
*/ */
public function getDefense(Game $game, bool $ignoreBuffs = false): int public function getDefense(bool $ignoreBuffs = false): int
{ {
return $this->level * 2; $baseDefense = $this->level;
$hookData = $this->getGame()->getEventManager()->publish(
"h/lotgd/core/getCharacterDefense",
CharacterEventData::create([
"character" => $this,
"value" => $baseDefense
])
);
$modifiedDefense = $hookData->get("value");
return $modifiedDefense;
} }
/** /**
@@ -258,7 +298,7 @@ class Character implements CharacterInterface, CreateableInterface
/** /**
* Sets the current character viewpoint. * Sets the current character viewpoint.
*/ */
public function setViewpoint(Viewpoint $v) public function setViewpoint(?Viewpoint $v)
{ {
$this->viewpoint = $v; $this->viewpoint = $v;
} }
+3 -1
View File
@@ -3,12 +3,14 @@ declare(strict_types=1);
namespace LotGD\Core\Models; namespace LotGD\Core\Models;
use Ramsey\Uuid\UuidInterface;
/** /**
* Interface for the character model and all objects that mimick such a model. * Interface for the character model and all objects that mimick such a model.
*/ */
interface CharacterInterface extends FighterInterface interface CharacterInterface extends FighterInterface
{ {
public function getId(): int; public function getId(): UuidInterface;
public function getName(): string; public function getName(): string;
public function getDisplayName(): string; public function getDisplayName(): string;
public function getHealth(): int; public function getHealth(): int;
+119
View File
@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
use LotGD\Core\Exceptions\CharacterStatExistsException;
use LotGD\Core\Exceptions\CharacterStatNotFoundException;
use LotGD\Core\Models\CharacterStats\CharacterStatInterface;
/**
* Class CharacterStatGroup
* @package LotGD\Core\Models
*/
class CharacterStatGroup
{
private $id;
private $name;
private $stats = [];
private $weight;
private $sorted = true;
/**
* CharacterStatGroup constructor.
* @param string $id
* @param string $name
*/
public function __construct(string $id, string $name, int $weight = 0)
{
$this->id = $id;
$this->name = $name;
$this->weight = $weight;
}
/**
* @return string
*/
public function getId(): string
{
return $this->id;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @return int
*/
public function getWeight(): int
{
return $this->weight;
}
/**
* @param CharacterStatInterface $characterStat
* @throws CharacterStatExistsException
*/
public function addCharacterStat(CharacterStatInterface $characterStat)
{
if (isset($this->stats[$characterStat->getId()])) {
throw new CharacterStatExistsException("There is already a character stat registered to this group with the id {$characterStat->getId()}");
}
$this->stats[$characterStat->getId()] = $characterStat;
$this->sorted = false;
}
/**
* @param string $id
* @return CharacterStatInterface
* @throws CharacterStatNotFoundException
*/
public function getCharacterStat(string $id): CharacterStatInterface
{
if (empty($this->stats[$id])) {
throw new CharacterStatNotFoundException("Character stat with id {$id} not found.");
}
return $this->stats[$id];
}
/**
* @param string $id
* @return bool
*/
public function hasCharacterStat(string $id): bool
{
if (isset($this->stats[$id])) {
return true;
}
return false;
}
/**
* @return \Generator|CharacterStatInterface[]
*/
public function iterate(): \Generator
{
// First, sort stat set by weight if not sorted
if (!$this->sorted) {
uasort($this->stats, function (CharacterStatInterface $a, CharacterStatInterface $b) {
return $a->getWeight() <=> $b->getWeight();
});
$this->sorted = true;
}
// Now, iterate.
foreach ($this->stats as $stat) {
yield $stat;
}
}
}
+100
View File
@@ -0,0 +1,100 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
use LotGD\Core\Events\EventContextData;
use LotGD\Core\Exceptions\CharacterStatGroupExistsException;
use LotGD\Core\Exceptions\CharacterStatGroupNotFoundException;
use LotGD\Core\Game;
/**
* Class CharacterStats
* @package LotGD\Core\Models
*/
class CharacterStats
{
private $game;
private $character;
private $stat_groups;
private $sorted = true;
/**
* CharacterStats constructor.
* @param Game $game
* @param Character $character
*/
public function __construct(Game $game, Character $character)
{
$this->game = $game;
$this->character = $character;
// Hook
$eventData = $this->game->getEventManager()->publish(
"h/lotgd/core/characterStats/populate",
EventContextData::create(["character" => $character, "stats" => $this])
);
}
/**
* @return \Generator|CharacterStatGroup[]
*/
public function iterate(): \Generator
{
// First, sort stat set by weight if not sorted yet
if (!$this->sorted) {
uasort($this->stat_groups, function (CharacterStatGroup $a, CharacterStatGroup $b) {
return $a->getWeight() <=> $b->getWeight();
});
$this->sorted = true;
}
// Now, iterate.
foreach ($this->stat_groups as $id => $stat_group) {
yield $stat_group;
}
}
/**
* @param CharacterStatGroup $group
* @throws CharacterStatGroupExistsException
*/
public function addCharacterStatGroup(CharacterStatGroup $group)
{
if (isset($this->stat_groups[$group->getId()])) {
throw new CharacterStatGroupExistsException("Character stat {$group->getId()} already exists.");
}
$this->stat_groups[$group->getId()] = $group;
$this->sorted = false;
}
/**
* @param string $id
* @return CharacterStatGroup
* @throws CharacterStatGroupNotFoundException
*/
public function getCharacterStatGroup(string $id): CharacterStatGroup
{
if (empty($this->stat_groups[$id])) {
throw new CharacterStatGroupNotFoundException("Character stat {$id} does not exists.");
}
return $this->stat_groups[$id];
}
/**
* @param string $id
* @return bool
*/
public function hasCharacterStatGroup(string $id): bool
{
if (isset($this->stat_groups[$id])) {
return true;
}
return false;
}
}
@@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models\CharacterStats;
/**
* Class BaseCharacterStat
* @package LotGD\Core\Models\CharacterStats
*/
class BaseCharacterStat implements CharacterStatInterface
{
private $id;
private $name;
private $value;
private $weight;
/**
* BaseCharacterStat constructor.
* @param string $id
* @param string $name
* @param $value
*/
public function __construct(string $id, string $name, $value, int $weight = 0)
{
$this->id = $id;
$this->name = $name;
$this->value = $value;
$this->weight = $weight;
}
/** @inheritdoc */
public function getId(): string
{
return $this->id;
}
/** @inheritdoc */
public function getName(): string
{
return $this->name;
}
/** @inheritdoc */
public function setName(string $name)
{
$this->name = $name;
}
/** @inheritdoc */
public function getValue()
{
return $this->value;
}
/** @inheritdoc */
public function setValue($value)
{
$this->value = $value;
}
/** @inheritdoc */
public function getValueAsString(): string
{
return sprintf("%s", $this->getValue());
}
/** @inheritdoc */
public function setWeight(int $weight)
{
$this->weight = $weight;
}
/** @inheritdoc */
public function getWeight(): int
{
return $this->weight;
}
}
@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models\CharacterStats;
interface CharacterStatInterface
{
/**
* CharacterStatInterface constructor.
* @param string $id
* @param string $name
* @param $value
*/
public function __construct(string $id, string $name, $value, int $weight = 0);
/**
* @return string
*/
public function getId(): string;
/**
* @return string
*/
public function getName(): string;
/**
* @param string $name
* @return mixed
*/
public function setName(string $name);
/**
* @return mixed
*/
public function getValue();
/**
* @param $value
* @return mixed
*/
public function setValue($value);
/**
* @return string
*/
public function getValueAsString(): string;
/**
* @return int
*/
public function getWeight(): int;
/**
* @param int $weight
* @return mixed
*/
public function setWeight(int $weight);
}
+10
View File
@@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
interface ExtendableModelInterface
{
public function __call($method, $arguments);
}
+2 -2
View File
@@ -18,8 +18,8 @@ interface FighterInterface
public function getMaxHealth(): int; public function getMaxHealth(): int;
public function getHealth(): int; public function getHealth(): int;
public function isAlive(): bool; public function isAlive(): bool;
public function getAttack(Game $game, bool $ignoreBuffs = false): int; public function getAttack(bool $ignoreBuffs = false): int;
public function getDefense(Game $game, bool $ignoreBuffs = false): int; public function getDefense(bool $ignoreBuffs = false): int;
public function damage(int $damage); public function damage(int $damage);
public function heal(int $heal); public function heal(int $heal);
public function setHealth(int $amount); public function setHealth(int $amount);
+4 -2
View File
@@ -18,10 +18,12 @@ class GameConfiguration
/** @var ArrayCollection */ /** @var ArrayCollection */
private $properties; private $properties;
/** /**
* Constructor. * Constructor.
* @param EntityManagerInterface $em * @param EntityManagerInterface $entityManager
*/ */
public function __construct(EntityManagerInterface $entityManager) public function __construct(EntityManagerInterface $entityManager)
{ {
@@ -42,7 +44,7 @@ class GameConfiguration
/** /**
* Sets and overwrites a configuration value saved by the name * Sets and overwrites a configuration value saved by the name
* @param string $configurationName * @param string $configurationName
* @param type $configurationValue * @param mixed $configurationValue
*/ */
public function set(string $configurationName, $configurationValue) public function set(string $configurationName, $configurationValue)
{ {
-20
View File
@@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Tools\Model\AutoScaleFighter;
/**
* The Monster entity
*
* @Entity
* @Table(name="masters")
*/
class Master extends BasicEnemy
{
use AutoScaleFighter;
}
+6 -36
View File
@@ -11,6 +11,7 @@ use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Exceptions\InvalidModelException; use LotGD\Core\Exceptions\InvalidModelException;
use LotGD\Core\Exceptions\ArgumentException; use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Exceptions\ParentAlreadySetException;
use LotGD\Core\Tools\Model\Deletor; use LotGD\Core\Tools\Model\Deletor;
use LotGD\Core\Tools\Model\Saveable; use LotGD\Core\Tools\Model\Saveable;
@@ -37,48 +38,17 @@ class Message
/** @Column(type="boolean", nullable=false) */ /** @Column(type="boolean", nullable=false) */
private $systemMessage = false; private $systemMessage = false;
/**
* Sends a message to a MessageThread
* @param \LotGD\Core\Models\Character $from
* @param string $message
* @param \LotGD\Core\Models\MessageThread $thread
* @param bool $systemMessage
* @return \LotGD\Core\Models\Message
*/
public static function send(
Character $from,
string $message,
MessageThread $thread,
bool $systemMessage = false
) {
$thread->addMessage(new self($from, $message, $thread, $systemMessage));
}
/**
* Sends a system message to a MessageThread
* @param string $message
* @param \LotGD\Core\Models\MessageThread $thread
* @return \LotGD\Core\Models\Message
*/
public static function sendSystemMessage(
string $message,
MessageThread $thread
) {
$thread->addMessage(new self(SystemCharacter::getInstance(), $message, $thread, true));
}
/** /**
* Constructs the message. * Constructs the message.
* * Use the Message Manager methods send() and sendSystemMessage() instead.
* This method has been made protected to prevent from accessing it directly. Use * @param CharacterInterface $from
* the static methods self::send() and self::sendSystemMessage() instead.
* @param \LotGD\Core\Models\Character $from
* @param string $message * @param string $message
* @param \LotGD\Core\Models\Thread $thread * @param MessageThread $thread
* @param bool $systemMessage * @param bool $systemMessage
* @throws ArgumentException * @throws ArgumentException
*/ */
protected function __construct(CharacterInterface $from, string $message, MessageThread $thread, bool $systemMessage) public function __construct(CharacterInterface $from, string $message, MessageThread $thread, bool $systemMessage)
{ {
if ($from instanceof Character) { if ($from instanceof Character) {
if ($from->isDeleted() === true) { if ($from->isDeleted() === true) {
+3 -3
View File
@@ -36,10 +36,10 @@ class MessageThread implements SaveableInterface
/** /**
* Constructor. Sets the (unique) threadKey. * Constructor. Sets the (unique) threadKey.
* @param string $threadKey * @param string $threadKey
* @param type $participants * @param array $participants
* @param type $readonly * @param bool $readonly
*/ */
public function __construct(string $threadKey, array $participants, $readonly = false) public function __construct(string $threadKey, array $participants, bool $readonly = false)
{ {
$this->threadKey = $threadKey; $this->threadKey = $threadKey;
$this->readonly = $readonly; $this->readonly = $readonly;
+5 -2
View File
@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace LotGD\Core\Models; namespace LotGD\Core\Models;
use DateTime;
use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table; use Doctrine\ORM\Mapping\Table;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
@@ -33,13 +34,15 @@ class Module implements SaveableInterface
/** @OneToMany(targetEntity="ModuleProperty", mappedBy="owner", cascade={"persist", "remove"}) */ /** @OneToMany(targetEntity="ModuleProperty", mappedBy="owner", cascade={"persist", "remove"}) */
private $properties; private $properties;
private $propertyClass = ModuleProperty::class;
/** /**
* Construct a new module entry. * Construct a new module entry.
*/ */
public function __construct(string $library) public function __construct(string $library)
{ {
$this->properties = new ArrayCollection(); $this->properties = new ArrayCollection();
$this->createdAt = new \DateTime(); $this->createdAt = new DateTime();
$this->library = $library; $this->library = $library;
} }
@@ -47,7 +50,7 @@ class Module implements SaveableInterface
* Returns the time this module was added to the system. * Returns the time this module was added to the system.
* @return DateTime * @return DateTime
*/ */
public function getCreatedAt(): \DateTime public function getCreatedAt(): DateTime
{ {
return $this->createdAt; return $this->createdAt;
} }
+8 -5
View File
@@ -8,6 +8,8 @@ use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Tools\Model\Creator; use LotGD\Core\Tools\Model\Creator;
use LotGD\Core\Tools\Model\Deletor; use LotGD\Core\Tools\Model\Deletor;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
/** /**
* Model for the message of the day * Model for the message of the day
@@ -20,7 +22,7 @@ class MotD implements CreateableInterface
use Creator; use Creator;
use Deletor; use Deletor;
/** @Id @Column(type="integer") @GeneratedValue */ /** @Id @Column(type="uuid", unique=True) */
private $id; private $id;
/** /**
* @ManyToOne(targetEntity="Character", cascade={"persist"}, fetch="EAGER") * @ManyToOne(targetEntity="Character", cascade={"persist"}, fetch="EAGER")
@@ -49,6 +51,7 @@ class MotD implements CreateableInterface
*/ */
public function __construct() public function __construct()
{ {
$this->id = Uuid::uuid4();
$this->creationTime = new \DateTime("now"); $this->creationTime = new \DateTime("now");
} }
@@ -56,7 +59,7 @@ class MotD implements CreateableInterface
* Returns the entities ID * Returns the entities ID
* @return int * @return int
*/ */
public function getId(): int public function getId(): UuidInterface
{ {
return $this->id; return $this->id;
} }
@@ -67,7 +70,7 @@ class MotD implements CreateableInterface
* Returns always the real author of the message, even if it is a * Returns always the real author of the message, even if it is a
* system message. Use $this->getSystemMessage() to check if it is a system * system message. Use $this->getSystemMessage() to check if it is a system
* message or $this->getAppearentAuthor() to get the appearent author. * message or $this->getAppearentAuthor() to get the appearent author.
* @return \LotGD\Core\Models\Character * @return CharacterInterface
*/ */
public function getAuthor(): CharacterInterface public function getAuthor(): CharacterInterface
{ {
@@ -76,7 +79,7 @@ class MotD implements CreateableInterface
/** /**
* Returns the appearent author of this message. * Returns the appearent author of this message.
* @return \LotGD\Core\Models\CharacterInterface * @return CharacterInterface
*/ */
public function getApparantAuthor(): CharacterInterface public function getApparantAuthor(): CharacterInterface
{ {
@@ -89,7 +92,7 @@ class MotD implements CreateableInterface
/** /**
* Sets the author of this motd * Sets the author of this motd
* @param \LotGD\Core\Models\Character $author * @param Character $author
*/ */
public function setAuthor(Character $author) public function setAuthor(Character $author)
{ {
+1
View File
@@ -46,6 +46,7 @@ class Permission implements CreateableInterface
/** /**
* Sets this entity's id if it's not set yet. * Sets this entity's id if it's not set yet.
* @param string $id * @param string $id
* @throws ArgumentException
*/ */
public function setId(string $id) public function setId(string $id)
{ {
@@ -43,9 +43,9 @@ class CharacterRepository extends EntityRepository
} }
/** /**
* Find a character by ID. * Find a character by ID, excluding soft deleted ones.
*/ */
public function find($id, int $deletes = self::SKIP_SOFTDELETED) public function find($id, $lockMode=null, $lockVersion=null)
{ {
$queryBuilder = $this->getEntityManager()->createQueryBuilder(); $queryBuilder = $this->getEntityManager()->createQueryBuilder();
$queryBuilder->select("c") $queryBuilder->select("c")
@@ -53,7 +53,29 @@ class CharacterRepository extends EntityRepository
->where($queryBuilder->expr()->eq("c.id", ":id")) ->where($queryBuilder->expr()->eq("c.id", ":id"))
->setParameter("id", $id); ->setParameter("id", $id);
$this->modifyQuery($queryBuilder, $deletes); $this->modifyQuery($queryBuilder, self::SKIP_SOFTDELETED);
try {
return $queryBuilder->getQuery()->getSingleResult();
} catch (NoResultException $e) {
return null;
}
}
/**
* Finds a character id ID, including soft deleted ones.
* @param $id
* @return mixed|null
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function findWithSoftDeleted($id) {
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$queryBuilder->select("c")
->from(Character::class, "c")
->where($queryBuilder->expr()->eq("c.id", ":id"))
->setParameter("id", $id);
$this->modifyQuery($queryBuilder, self::INCLUDE_SOFTDELETED);
try { try {
return $queryBuilder->getQuery()->getSingleResult(); return $queryBuilder->getQuery()->getSingleResult();
@@ -4,6 +4,7 @@ declare(strict_types = 1);
namespace LotGD\Core\Models\Repositories; namespace LotGD\Core\Models\Repositories;
use Doctrine\Common\Util\Debug;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException; use Doctrine\ORM\NoResultException;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
+7 -3
View File
@@ -12,6 +12,8 @@ use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Tools\Model\Creator; use LotGD\Core\Tools\Model\Creator;
use LotGD\Core\Tools\Model\Deletor; use LotGD\Core\Tools\Model\Deletor;
use LotGD\Core\Tools\Model\SceneBasics; use LotGD\Core\Tools\Model\SceneBasics;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
/** /**
* A scene is a location within the game, such as the Village or the Tavern. Designed * A scene is a location within the game, such as the Village or the Tavern. Designed
@@ -26,8 +28,8 @@ class Scene implements CreateableInterface, SceneConnectable
use Deletor; use Deletor;
use SceneBasics; use SceneBasics;
/** @Id @Column(type="integer") @GeneratedValue */ /** @Id @Column(type="string", length=36, unique=True, name="id", options={"fixed" = true}) */
private $id; protected $id;
/** /**
* @OneToMany(targetEntity="SceneConnectionGroup", mappedBy="scene", cascade={"persist", "remove"}) * @OneToMany(targetEntity="SceneConnectionGroup", mappedBy="scene", cascade={"persist", "remove"})
@@ -61,6 +63,8 @@ class Scene implements CreateableInterface, SceneConnectable
*/ */
public function __construct() public function __construct()
{ {
$this->id = Uuid::uuid4()->toString();
$this->connectionGroups = new ArrayCollection(); $this->connectionGroups = new ArrayCollection();
$this->outgoingConnections = new ArrayCollection(); $this->outgoingConnections = new ArrayCollection();
$this->incomingConnections = new ArrayCollection(); $this->incomingConnections = new ArrayCollection();
@@ -70,7 +74,7 @@ class Scene implements CreateableInterface, SceneConnectable
* Returns the primary ID for this scene. * Returns the primary ID for this scene.
* @return int * @return int
*/ */
public function getId(): int public function getId(): string
{ {
return $this->id; return $this->id;
} }
+2 -2
View File
@@ -15,14 +15,14 @@ class SceneConnection
{ {
/** /**
* @Id * @Id
* @ManyToOne(targetEntity="Scene") * @ManyToOne(targetEntity="Scene", inversedBy="outgoingConnections")
* @JoinColumn(name="outgoingScene", referencedColumnName="id") * @JoinColumn(name="outgoingScene", referencedColumnName="id")
*/ */
private $outgoingScene; private $outgoingScene;
/** /**
* @Id * @Id
* @ManyToOne(targetEntity="Scene") * @ManyToOne(targetEntity="Scene", inversedBy="incomingConnections")
* @JoinColumn(name="incomingScene", referencedColumnName="id") * @JoinColumn(name="incomingScene", referencedColumnName="id")
*/ */
private $incomingScene; private $incomingScene;
+99 -9
View File
@@ -3,12 +3,20 @@ declare(strict_types=1);
namespace LotGD\Core\Models; namespace LotGD\Core\Models;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\OneToOne;
use Doctrine\ORM\Mapping\Table; use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Action; use LotGD\Core\Action;
use LotGD\Core\ActionGroup;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Tools\Model\Creator; use LotGD\Core\Tools\Model\Creator;
use LotGD\Core\Tools\Model\SceneBasics; use LotGD\Core\Tools\Model\SceneBasics;
use LotGD\Core\Tools\SceneDescription;
/** /**
* A Viewpoint is the current Scene a character is experiencing with * A Viewpoint is the current Scene a character is experiencing with
@@ -21,7 +29,11 @@ class Viewpoint implements CreateableInterface
use Creator; use Creator;
use SceneBasics; use SceneBasics;
/** @Id @OneToOne(targetEntity="Character", inversedBy="viewpoint", cascade="persist") */ /**
* @Id
* @OneToOne(targetEntity="Character", inversedBy="viewpoint", cascade="persist")
* @JoinColumn(fieldName="owner_id", referencedColumnName="id")
*/
private $owner; private $owner;
/** @Column(type="array") */ /** @Column(type="array") */
private $actionGroups = []; private $actionGroups = [];
@@ -29,9 +41,15 @@ class Viewpoint implements CreateableInterface
private $attachments = []; private $attachments = [];
/** @Column(type="array") */ /** @Column(type="array") */
private $data = []; private $data = [];
/** @ManyToOne(targetEntity="Scene") */ /**
* @ManyToOne(targetEntity="Scene")
* @JoinColumn(name="scene_id", referencedColumnName="id")
*/
private $scene; private $scene;
/** @var SceneDescription */
private $_description;
/** @var array */ /** @var array */
private static $fillable = [ private static $fillable = [
"owner" "owner"
@@ -55,6 +73,48 @@ class Viewpoint implements CreateableInterface
$this->owner = $owner; $this->owner = $owner;
} }
/**
* Sets the description of this viewpoint.
* @param string $description
*/
public function setDescription(string $description): void
{
$this->description = $description;
$this->_description = new SceneDescription($description);
}
/**
* Clears the description
*/
public function clearDescription(): void
{
$this->description = "";
$this->_description = new SceneDescription("");
}
/**
* Returns the current description as a string
* @return string
*/
public function getDescription(): string
{
return $this->description;
}
/**
* Adds a paragraph to the existing description
* @param string $paragraph
*/
public function addDescriptionParagraph(string $paragraph)
{
if ($this->_description === null) {
$this->_description = new SceneDescription($this->description);
}
$this->_description->addParagraph($paragraph);
$this->description = (string)$this->_description;
}
/** /**
* Copies the static data from a scene to this Viewpoint entity. * Copies the static data from a scene to this Viewpoint entity.
* @param \LotGD\Core\Models\Scene $scene * @param \LotGD\Core\Models\Scene $scene
@@ -123,7 +183,7 @@ class Viewpoint implements CreateableInterface
/** /**
* Returns all action groups. * Returns all action groups.
* @return array * @return ActionGroup[]
*/ */
public function getActionGroups(): array public function getActionGroups(): array
{ {
@@ -132,7 +192,7 @@ class Viewpoint implements CreateableInterface
/** /**
* Sets action groups. * Sets action groups.
* @param array $actionGroups * @param ActionGroup[] $actionGroups
*/ */
public function setActionGroups(array $actionGroups) public function setActionGroups(array $actionGroups)
{ {
@@ -140,11 +200,38 @@ class Viewpoint implements CreateableInterface
} }
/** /**
* Finds an action group by id. * Adds a new action group to a viewpoint
* @param ActionGroup $group The new group to add.
* @param null|string $after, optional group id that comes before.
* @throws ArgumentException
*/
public function addActionGroup(ActionGroup $group, ?string $after = null): void
{
$groupId = $group->getId();
if ($this->findActionGroupById($groupId) == true) {
throw new ArgumentException("Group {$group} is already contained in this viewpoint.");
}
if ($after === null) {
$this->actionGroups[] = $group;
} else {
$groups = [];
foreach ($this->actionGroups as $g) {
if ($g->getId() == $after) {
$groups[] = $group;
}
$groups[] = $g;
}
$this->actionGroups = $groups;
}
}
/**
* Returns an action group by id or fails.
* @param $actionGroupId * @param $actionGroupId
* @return ActionGroup|null * @return ActionGroup|null
*/ */
public function findActionGroupById(string $actionGroupId) public function findActionGroupById(string $actionGroupId): ?ActionGroup
{ {
$groups = $this->getActionGroups(); $groups = $this->getActionGroups();
foreach ($groups as $g) { foreach ($groups as $g) {
@@ -152,6 +239,7 @@ class Viewpoint implements CreateableInterface
return $g; return $g;
} }
} }
return null; return null;
} }
@@ -214,7 +302,7 @@ class Viewpoint implements CreateableInterface
/** /**
* Returns a single data field * Returns a single data field
* @param string $fieldname Fieldname * @param string $fieldname Fieldname
* @param type $default default value * @param mixed $default default value
* @return mixed * @return mixed
*/ */
public function getDataField(string $fieldname, $default = null) public function getDataField(string $fieldname, $default = null)
@@ -233,9 +321,10 @@ class Viewpoint implements CreateableInterface
/** /**
* Returns the action that corresponds to the given ID, if present. * Returns the action that corresponds to the given ID, if present.
* @param string $id
* @return Action|null * @return Action|null
*/ */
public function findActionById(string $id) public function findActionById(string $id): ?Action
{ {
foreach ($this->getActionGroups() as $group) { foreach ($this->getActionGroups() as $group) {
foreach ($group->getActions() as $a) { foreach ($group->getActions() as $a) {
@@ -244,6 +333,7 @@ class Viewpoint implements CreateableInterface
} }
} }
} }
return null; return null;
} }
@@ -251,7 +341,7 @@ class Viewpoint implements CreateableInterface
* Removes any actions that correspond to a given scene ID, if present. * Removes any actions that correspond to a given scene ID, if present.
* @param int $id * @param int $id
*/ */
public function removeActionsWithSceneId(int $id) public function removeActionsWithSceneId(string $id)
{ {
foreach ($this->getActionGroups() as $group) { foreach ($this->getActionGroups() as $group) {
$actions = $group->getActions(); $actions = $group->getActions();
+25 -5
View File
@@ -42,6 +42,7 @@ class ModuleManager
{ {
$name = $library->getName(); $name = $library->getName();
$package = $library->getComposerPackage(); $package = $library->getComposerPackage();
$em = $this->g->getEntityManager();
$this->g->getLogger()->debug("Registering module {$name}..."); $this->g->getLogger()->debug("Registering module {$name}...");
@@ -53,6 +54,8 @@ class ModuleManager
$this->g->getLogger()->debug("Creating module model for {$name}"); $this->g->getLogger()->debug("Creating module model for {$name}");
$m = new ModuleModel($name); $m = new ModuleModel($name);
$em->beginTransaction();
$class = $library->getRootNamespace() . 'Module'; $class = $library->getRootNamespace() . 'Module';
try { try {
$klass = new \ReflectionClass($class); $klass = new \ReflectionClass($class);
@@ -69,9 +72,16 @@ class ModuleManager
} }
// Subscribe to the module's events. // Subscribe to the module's events.
$subscriptions = $library->getSubscriptionPatterns(); try {
foreach ($subscriptions as $s) { $subscriptions = $library->getSubscriptionPatterns();
$this->g->getEventManager()->subscribe($s, $class, $name); foreach ($subscriptions as $s) {
$this->g->getEventManager()->subscribe($s, $class, $name);
}
} catch (\Throwable $e) {
$em->rollBack();
$em->clear();
throw $e;
} }
// Run the module's onRegister handler. // Run the module's onRegister handler.
@@ -79,10 +89,20 @@ class ModuleManager
try { try {
$class::onRegister($this->g, $m); $class::onRegister($this->g, $m);
$m->save($this->g->getEntityManager()); $this->g->getEntityManager()->persist($m);
$this->g->getEntityManager()->flush();
$em->commit();
return;
} catch (Throwable $e) { } catch (Throwable $e) {
$em->rollBack();
$em->clear();
$this->g->getLogger()->error("Calling {$class}::onRegister failed with exception: {$e->getMessage()}"); $this->g->getLogger()->error("Calling {$class}::onRegister failed with exception: {$e->getMessage()}");
unset($m); unset($m);
// Propagate the exception.
throw $e;
} }
} }
} }
@@ -142,7 +162,7 @@ class ModuleManager
* @param string $library * @param string $library
* @return Module * @return Module
*/ */
public function getModule(string $library): ModuleModel public function getModule(string $library): ?ModuleModel
{ {
return $this->g->getEntityManager()->getRepository(ModuleModel::class)->find($library); return $this->g->getEntityManager()->getRepository(ModuleModel::class)->find($library);
} }
+5 -3
View File
@@ -28,19 +28,21 @@ trait AutoScaleFighter
/** /**
* Returns the attack value based on the fighter's level * Returns the attack value based on the fighter's level
* @param bool $ignoreBuffs
* @return int * @return int
*/ */
public function getAttack(Game $game, bool $ignoreBuffs = false): int public function getAttack(bool $ignoreBuffs = false): int
{ {
$level = $this->getLevel(); $level = $this->getLevel();
return (int)$level * 2 - 1; return (int)$level * 2 - 1;
} }
/** /**
* Returns the defense value based on the fighter's level * Returns the defense value based on the fighter's level
* @param bool $ignoreBuffs
* @return int * @return int
*/ */
public function getDefense(Game $game, bool $ignoreBuffs = false): int public function getDefense(bool $ignoreBuffs = false): int
{ {
$level = $this->getlevel(); $level = $this->getlevel();
return (int)floor($level*1.45); return (int)floor($level*1.45);
+22
View File
@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tools\Model;
use LotGD\Core\ModelExtender;
/**
* Trait to add the __call class required for extendable models.
* @package LotGD\Core\Tools\Model
*/
trait ExtendableModel
{
public function __call($method, $arguments)
{
$callback = ModelExtender::get(self::class, $method);
if ($callback) {
return call_user_func_array($callback, array_merge([$this], $arguments));
}
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tools\Model;
use LotGD\Core\Game;
/**
* Helper trait to implement public setGame from GameAwareInterface and private getGame for internal use.
* @package LotGD\Core\Tools\Model
*/
trait GameAware
{
private $game;
public function setGame(Game $game) {
$this->game = $game;
}
public function getGame(): Game {
return $this->game;
}
}
+4 -3
View File
@@ -10,6 +10,7 @@ use LotGD\Core\{
}; };
use LotGD\Core\Exceptions\IsNullException; use LotGD\Core\Exceptions\IsNullException;
use LotGD\Core\Models\Viewpoint; use LotGD\Core\Models\Viewpoint;
use Ramsey\Uuid\UuidInterface;
/** /**
* Provides basic implementation to mock CharacterInterface. * Provides basic implementation to mock CharacterInterface.
@@ -21,7 +22,7 @@ trait MockCharacter
throw new IsNullException(); throw new IsNullException();
} }
public function getId(): int public function getId(): UuidInterface
{ {
throw new IsNullException(); throw new IsNullException();
} }
@@ -71,12 +72,12 @@ trait MockCharacter
throw new IsNullException(); throw new IsNullException();
} }
public function getAttack(Game $game, bool $ignoreBuffs = false): int public function getAttack(bool $ignoreBuffs = false): int
{ {
throw new IsNullException(); throw new IsNullException();
} }
public function getDefense(Game $game, bool $ignoreBuffs = false): int public function getDefense(bool $ignoreBuffs = false): int
{ {
throw new IsNullException(); throw new IsNullException();
} }
+26 -4
View File
@@ -10,7 +10,10 @@ trait PropertyManager
{ {
private $propertyStorage = null; private $propertyStorage = null;
public function loadProperties() /**
* Loads properties
*/
public function loadProperties(): void
{ {
if ($this->propertyStorage !== null) { if ($this->propertyStorage !== null) {
return; return;
@@ -21,6 +24,12 @@ trait PropertyManager
} }
} }
/**
* Returns a property with its stored type.
* @param string $name
* @param mixed $default
* @return mixed
*/
public function getProperty(string $name, $default = null) public function getProperty(string $name, $default = null)
{ {
$this->loadProperties(); $this->loadProperties();
@@ -32,7 +41,11 @@ trait PropertyManager
} }
} }
public function unsetProperty(string $name) /**
* Deletes a property.
* @param string $name
*/
public function unsetProperty(string $name): void
{ {
$this->loadProperties(); $this->loadProperties();
@@ -43,14 +56,23 @@ trait PropertyManager
} }
} }
public function setProperty(string $name, $value) /**
* Sets a property to a given value
* @param string $name
* @param mixed $value
*/
public function setProperty(string $name, $value): void
{ {
$this->loadProperties(); $this->loadProperties();
if (isset($this->propertyStorage[$name])) { if (isset($this->propertyStorage[$name])) {
$this->propertyStorage[$name]->setValue($value); $this->propertyStorage[$name]->setValue($value);
} else { } else {
$className = $this->properties->getTypeClass()->name; if (isset($this->propertyClass)) {
$className = $this->propertyClass;
} else {
$className = $this->properties->getTypeClass()->name;
}
$property = new $className(); $property = new $className();
if (method_exists($property, "setOwner")) { if (method_exists($property, "setOwner")) {
$property->setOwner($this); $property->setOwner($this);
+73
View File
@@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tools;
/**
* Abstracts a scene description and provides tools to modify the text more easily.
* Class SceneDescription
* @package LotGD\Core\Tools
*/
class SceneDescription
{
private $description = [];
/**
* SceneDescription constructor.
* @param string $description
*/
public function __construct(string $description)
{
$this->description = $this->splitIntoParagraphs($description);
}
/**
* Converts the description to a string
* @return string
*/
public function __toString(): string
{
return $this->getDescriptionBack();
}
/**
* Converts the description to a string.
* @return string
*/
public function getDescriptionBack(): string
{
return implode("\n\n", $this->description);
}
/**
* Adds a paragraph to the description. If the paragraph contains \n\n, it gets broken into multiple paragraphs first.
* @param string $paragraph
*/
public function addParagraph(string $paragraph): void
{
$paragraph = $this->splitIntoParagraphs($paragraph);
$this->description = array_merge($this->description, $paragraph);
}
/**
* Splits a given string into an array ("paragraphs")
*
* This method takes a string, normalizes line ends and then splits it at every double line break (\n\n).
* @param string $input
* @return array
*/
private function splitIntoParagraphs(string $input): array
{
$input = str_replace("\r\n", "\n", $input);
$input = str_replace("\r", "\n", $input);
$parts = explode("\n\n", $input);
foreach ($parts as $key => $part) {
if (strlen($part) === 0) {
unset($parts[$key]);
}
}
return $parts;
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/bash -ex #!/bin/bash -ex
phpunit --stop-on-failure ./vendor/bin/phpunit --stop-on-failure
./vendor/bin/phpdoccheck -d src --no-ansi ./vendor/bin/phpdoccheck -d src --no-ansi
+77 -32
View File
@@ -5,6 +5,7 @@ namespace LotGD\Core\Tests\Models;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Util\Debug;
use LotGD\Core\{ use LotGD\Core\{
Battle, Battle,
DiceBag, DiceBag,
@@ -25,6 +26,9 @@ use LotGD\Core\Models\BattleEvents\{
}; };
use LotGD\Core\Tests\CoreModelTestCase; use LotGD\Core\Tests\CoreModelTestCase;
use Ramsey\Uuid\Codec\OrderedTimeCodec;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidFactory;
class BattleTest extends CoreModelTestCase class BattleTest extends CoreModelTestCase
{ {
@@ -33,6 +37,7 @@ class BattleTest extends CoreModelTestCase
public function getMockGame(Character $character): Game public function getMockGame(Character $character): Game
{ {
mt_srand(0);
$game = $this->getMockBuilder(Game::class) $game = $this->getMockBuilder(Game::class)
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
@@ -51,13 +56,13 @@ class BattleTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$character = $em->getRepository(Character::class)->find(1); $character = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$monster = $em->getRepository(Monster::class)->find(1); $monster = $em->getRepository(Monster::class)->find("de84c507-9673-44e7-b665-9e43416b9c2f");
$this->assertSame(5, $monster->getLevel()); $this->assertSame(5, $monster->getLevel());
$this->assertSame(52, $monster->getMaxHealth()); $this->assertSame(52, $monster->getMaxHealth());
$this->assertSame(9, $monster->getAttack($this->getMockGame($character))); $this->assertSame(9, $monster->getAttack());
$this->assertSame(7, $monster->getDefense($this->getMockGame($character))); $this->assertSame(7, $monster->getDefense());
$this->assertSame($monster->getMaxHealth(), $monster->getHealth()); $this->assertSame($monster->getMaxHealth(), $monster->getHealth());
} }
@@ -68,11 +73,14 @@ class BattleTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$character = $em->getRepository(Character::class)->find(1); $character = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$monster = $em->getRepository(Monster::class)->find(1); $monster = $em->getRepository(Monster::class)->find("de84c507-9673-44e7-b665-9e43416b9c2f");
$battle = new Battle($this->getMockGame($character), $character, $monster); $battle = new Battle($this->getMockGame($character), $character, $monster);
$this->assertSame($character, $battle->getPlayer());
$this->assertSame($monster, $battle->getMonster());
for ($n = 0; $n < 99; $n++) { for ($n = 0; $n < 99; $n++) {
$oldPlayerHealth = $character->getHealth(); $oldPlayerHealth = $character->getHealth();
$oldMonsterHealth = $monster->getHealth(); $oldMonsterHealth = $monster->getHealth();
@@ -85,12 +93,49 @@ class BattleTest extends CoreModelTestCase
if ($battle->isOver()) { if ($battle->isOver()) {
break; break;
} }
foreach ($battle->getEvents() as $event) {
$this->assertNotNull($event->decorate($this->getMockGame($character)));
}
} }
$this->assertTrue($battle->isOver()); $this->assertTrue($battle->isOver());
$this->assertTrue($character->isAlive() xor $monster->isAlive()); $this->assertTrue($character->isAlive() xor $monster->isAlive());
} }
/**
* Tests if a fight can happen if it is serialized between each round.
*/
public function testFairBattleWithSerializationBetweenRounds()
{
$em = $this->getEntityManager();
$character = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$monster = $em->getRepository(Monster::class)->find("de84c507-9673-44e7-b665-9e43416b9c2f");
$battle = new Battle($this->getMockGame($character), $character, $monster);
$battle = $battle->serialize();
for ($n = 0; $n < 99; $n++) {
$battle = Battle::unserialize($this->getMockGame($character), $character, $battle);
$battle->fightNRounds(1);
if ($battle->isOver()) {
break;
}
foreach ($battle->getEvents() as $event) {
$this->assertNotNull($event->decorate($this->getMockGame($character)));
}
$battle = $battle->serialize();
}
$this->assertTrue($battle->isOver());
$this->assertTrue($battle->getPlayer()->isAlive() xor $battle->getMonster()->isAlive());
}
/** /**
* Tests a fight which the player has to win (lvl 100 vs lvl 1) * Tests a fight which the player has to win (lvl 100 vs lvl 1)
*/ */
@@ -98,8 +143,8 @@ class BattleTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$highLevelPlayer = $em->getRepository(Character::class)->find(2); $highLevelPlayer = $em->getRepository(Character::class)->find("4d01c29b-d825-4bc7-9e6e-63525155fd37");
$lowLevelMonster = $em->getRepository(Monster::class)->find(3); $lowLevelMonster = $em->getRepository(Monster::class)->find("c004bcb6-a7c1-4f9a-abc2-1711c64e23a0");
$battle = new Battle($this->getMockGame($highLevelPlayer), $highLevelPlayer, $lowLevelMonster); $battle = new Battle($this->getMockGame($highLevelPlayer), $highLevelPlayer, $lowLevelMonster);
@@ -131,8 +176,8 @@ class BattleTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$lowLevelPlayer = $em->getRepository(Character::class)->find(3); $lowLevelPlayer = $em->getRepository(Character::class)->find("c3792b61-4e34-4710-9871-65a68ac30bb4");
$highLevelMonster = $em->getRepository(Monster::class)->find(2); $highLevelMonster = $em->getRepository(Monster::class)->find("b636df29-f72d-4e2d-9850-982e783a9e94");
$battle = new Battle($this->getMockGame($lowLevelPlayer), $lowLevelPlayer, $highLevelMonster); $battle = new Battle($this->getMockGame($lowLevelPlayer), $lowLevelPlayer, $highLevelMonster);
@@ -164,8 +209,8 @@ class BattleTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$character = $em->getRepository(Character::class)->find(1); $character = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$monster = $em->getRepository(Monster::class)->find(1); $monster = $em->getRepository(Monster::class)->find("de84c507-9673-44e7-b665-9e43416b9c2f");
$battle = new Battle($this->getMockGame($character), $character, $monster); $battle = new Battle($this->getMockGame($character), $character, $monster);
@@ -179,8 +224,8 @@ class BattleTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$character = $em->getRepository(Character::class)->find(1); $character = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$monster = $em->getRepository(Monster::class)->find(1); $monster = $em->getRepository(Monster::class)->find("de84c507-9673-44e7-b665-9e43416b9c2f");
$battle = new Battle($this->getMockGame($character), $character, $monster); $battle = new Battle($this->getMockGame($character), $character, $monster);
@@ -195,8 +240,8 @@ class BattleTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$character = $em->getRepository(Character::class)->find(1); $character = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$monster = $em->getRepository(Monster::class)->find(1); $monster = $em->getRepository(Monster::class)->find("de84c507-9673-44e7-b665-9e43416b9c2f");
$battle = new Battle($this->getMockGame($character), $character, $monster); $battle = new Battle($this->getMockGame($character), $character, $monster);
@@ -216,23 +261,23 @@ class BattleTest extends CoreModelTestCase
default: default:
case 0: case 0:
// Fair Battle // Fair Battle
$character = $em->getRepository(Character::class)->find(1); $character = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$monster = $em->getRepository(Monster::class)->find(1); $monster = $em->getRepository(Monster::class)->find("de84c507-9673-44e7-b665-9e43416b9c2f");
break; break;
case 1: case 1:
// very long battle // very long battle
$character = $em->getRepository(Character::class)->find(4); $character = $em->getRepository(Character::class)->find("6565b418-55f5-4a6b-8d92-a9ef81329912");
$monster = $em->getRepository(Monster::class)->find(3); $monster = $em->getRepository(Monster::class)->find("c004bcb6-a7c1-4f9a-abc2-1711c64e23a0");
break; break;
case 2: case 2:
// player should win battle // player should win battle
$character = $em->getRepository(Character::class)->find(13); $character = $em->getRepository(Character::class)->find("1a9f63f2-3006-4e12-b272-4fd6be518a93");
$monster = $em->getRepository(Monster::class)->find(11); $monster = $em->getRepository(Monster::class)->find("7ca9c141-aaf8-44a5-9d04-b6f9923f3c66");
break; break;
case 3: case 3:
// player should lose battle // player should lose battle
$character = $em->getRepository(Character::class)->find(11); $character = $em->getRepository(Character::class)->find("24d71c26-f915-401c-8b3e-1932edf650ce");
$monster = $em->getRepository(Monster::class)->find(13); $monster = $em->getRepository(Monster::class)->find("09540b93-63c9-4d82-8501-f569f63dfc4c");
break; break;
} }
@@ -1187,8 +1232,8 @@ class BattleTest extends CoreModelTestCase
$battle = $this->provideBuffBattleParticipants(new Buff([ $battle = $this->provideBuffBattleParticipants(new Buff([
"slot" => "test", "slot" => "test",
"rounds" => 99, "rounds" => 99,
"goodguyAttackModifier" => 2, "goodguyAttackModifier" => 10,
"goodguyDefenseModifier" => 2, "goodguyDefenseModifier" => 10,
"activateAt" => Buff::ACTIVATE_ROUNDSTART, "activateAt" => Buff::ACTIVATE_ROUNDSTART,
]), 3); ]), 3);
@@ -1290,7 +1335,7 @@ class BattleTest extends CoreModelTestCase
public function testBufflistGoodguyAttackModifier() public function testBufflistGoodguyAttackModifier()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1); $player = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$game = $this->getMockGame($player); $game = $this->getMockGame($player);
$player->addBuff(new Buff([ $player->addBuff(new Buff([
@@ -1319,7 +1364,7 @@ class BattleTest extends CoreModelTestCase
public function testBufflistGoodguyDefenseModifier() public function testBufflistGoodguyDefenseModifier()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1); $player = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$game = $this->getMockGame($player); $game = $this->getMockGame($player);
$player->addBuff(new Buff([ $player->addBuff(new Buff([
@@ -1348,7 +1393,7 @@ class BattleTest extends CoreModelTestCase
public function testBufflistGoodguyDamageModifier() public function testBufflistGoodguyDamageModifier()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1); $player = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$game = $this->getMockGame($player); $game = $this->getMockGame($player);
$player->addBuff(new Buff([ $player->addBuff(new Buff([
@@ -1377,7 +1422,7 @@ class BattleTest extends CoreModelTestCase
public function testBufflistBadguyAttackModifier() public function testBufflistBadguyAttackModifier()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1); $player = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$game = $this->getMockGame($player); $game = $this->getMockGame($player);
$player->addBuff(new Buff([ $player->addBuff(new Buff([
@@ -1406,7 +1451,7 @@ class BattleTest extends CoreModelTestCase
public function testBufflistBadguyDefenseModifier() public function testBufflistBadguyDefenseModifier()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1); $player = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$game = $this->getMockGame($player); $game = $this->getMockGame($player);
$player->addBuff(new Buff([ $player->addBuff(new Buff([
@@ -1435,7 +1480,7 @@ class BattleTest extends CoreModelTestCase
public function testBufflistBadguyDamageModifier() public function testBufflistBadguyDamageModifier()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$player = $em->getRepository(Character::class)->find(1); $player = $em->getRepository(Character::class)->find("d363c077-234a-433d-834e-f1a1d3b281d8");
$game = $this->getMockGame($player); $game = $this->getMockGame($player);
$player->addBuff(new Buff([ $player->addBuff(new Buff([
+63
View File
@@ -89,4 +89,67 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase
$this->assertInternalType("string", $user->getName()); $this->assertInternalType("string", $user->getName());
$this->assertSame("Monthy", $user->getName()); $this->assertSame("Monthy", $user->getName());
} }
public function testIfGameAwareEntitiesHaveAGAmeInstanceAssociatedAfterLoading()
{
$installationManager = $this->getMockBuilder(InstallationManager::class)
->disableOriginalConstructor()
->setMethods(["getInstallPath"])
->getMock();
$installationManager->method("getInstallPath")->willReturn(__DIR__ . "/FakeModule");
$composer = $this->getMockBuilder(\Composer\Composer::class)
->disableOriginalConstructor()
->setMethods(["getInstallationManager"])
->getMock();
$composer->method("getInstallationManager")->willReturn($installationManager);
$fakeModulePackage = $this->getMockBuilder(AliasPackage::class)
->disableOriginalConstructor()
->setMethods(["getType", "getAutoload"])
->getMock();
$fakeModulePackage->method("getType")->willReturn("lotgd-module");
$fakeModulePackage->method("getAutoload")->willReturn([
"psr-4" => [
"LotGD\\Core\\Tests\\FakeModule\\" => "FakeModule/"
]
]);
$composerManager = $this->getMockBuilder(ComposerManager::class)
->disableOriginalConstructor()
->setMethods(["getPackages", "getComposer", "translateNamespaceToPath"])
->getMock();
$composerManager->method("getPackages")->willReturn([$fakeModulePackage]);
$composerManager->method("getComposer")->willReturn($composer);
$composerManager
->expects($this->exactly(1))
->method("translateNamespaceToPath")
->with("LotGD\\Core\\Tests\\FakeModule\\Models\\")
->willReturn(__DIR__ . "/FakeModule/Models");
$bootstrap = $this->getMockBuilder(Bootstrap::class)
->setMethods(["createComposerManager"])
->getMock();
$bootstrap->method("createComposerManager")->willReturn($composerManager);
// run tests
$game = $bootstrap->getGame(implode(DIRECTORY_SEPARATOR, [__DIR__, '..']));
// A freshly created user entity should not rely
$user = new UserEntity();
$user->setName("Testus");
$user->setGame($game);
$this->assertSame($game, $user->returnGame());
$game->getEntityManager()->persist($user);
$game->getEntityManager()->flush();
$id = $user->getId();
$this->assertInternalType("int", $id);
$game->getEntityManager()->clear();
$user = $game->getEntityManager()->getRepository(UserEntity::class)->find($id);
$this->assertSame($game, $user->returnGame());
$this->assertSame([$user->getName()], $user->getNameAsArray());
}
} }
+4
View File
@@ -5,6 +5,7 @@ namespace LotGD\Core\Tests\DefectiveModule;
use LotGD\Core\Exceptions\CoreException; use LotGD\Core\Exceptions\CoreException;
use LotGD\Core\Game; use LotGD\Core\Game;
use LotGD\Core\Events\EventContext; use LotGD\Core\Events\EventContext;
use LotGD\Core\Models\Character;
use LotGD\Core\Module as ModuleInterface; use LotGD\Core\Module as ModuleInterface;
use LotGD\Core\Models\Module as ModuleModel; use LotGD\Core\Models\Module as ModuleModel;
@@ -18,6 +19,9 @@ class Module implements ModuleInterface {
public static function onRegister(Game $g, ModuleModel $module) public static function onRegister(Game $g, ModuleModel $module)
{ {
$character = Character::create(["name" => "Test"]);
$character->save($g->getEntityManager());
throw new DefectiveModuleException("Exception"); throw new DefectiveModuleException("Exception");
} }
+2 -1
View File
@@ -1,3 +1,4 @@
entityNamespace: "LotGD\\Core\\Tests\\FakeModule\\Models\\" entityNamespace: "LotGD\\Core\\Tests\\FakeModule\\Models\\"
subscriptionPatterns: subscriptionPatterns:
- "e/lotgd/core/tests/event" - "e/lotgd/core/tests/defective-event"
- "e/lotgd/core/tests/gom-event"
+19
View File
@@ -51,4 +51,23 @@ class DiceBagTests extends \PHPUnit_Framework_TestCase
$this->assertGreaterThanOrEqual(1, $value); $this->assertGreaterThanOrEqual(1, $value);
$this->assertLessThanOrEqual(3, $value); $this->assertLessThanOrEqual(3, $value);
} }
public function testDice()
{
$db = new DiceBag();
$value = $db->dice(1, 6);
$this->assertGreaterThanOrEqual(1, $value);
$this->assertLessThanOrEqual(6, $value);
$value = $db->dice(5, 5);
$this->assertSame(5, $value);
$value = $db->dice(1, 3);
$this->assertGreaterThanOrEqual(1, $value);
$this->assertLessThanOrEqual(3, $value);
$value = $db->dice(3, 1);
$this->assertGreaterThanOrEqual(1, $value);
$this->assertLessThanOrEqual(3, $value);
}
} }
+1
View File
@@ -96,6 +96,7 @@ class EventManagerTest extends CoreModelTestCase
$library = 'lotgd/tests'; $library = 'lotgd/tests';
$em->subscribe($pattern, $class, $library); $em->subscribe($pattern, $class, $library);
$this->getEntityManager()->flush();
$sub = EventSubscription::create([ $sub = EventSubscription::create([
'pattern' => $pattern, 'pattern' => $pattern,
+14 -1
View File
@@ -5,13 +5,21 @@ namespace LotGD\Core\Tests\FakeModule\Models;
use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table; use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Game;
use LotGD\Core\GameAwareInterface;
use LotGD\Core\Models\ExtendableModelInterface;
use LotGD\Core\Tools\Model\ExtendableModel;
use LotGD\Core\Tools\Model\GameAware;
/** /**
* @Entity * @Entity
* @Table(name="Users") * @Table(name="Users")
*/ */
class UserEntity class UserEntity implements GameAwareInterface, ExtendableModelInterface
{ {
use GameAware;
use ExtendableModel;
/** @Id @Column(type="integer") @GeneratedValue */ /** @Id @Column(type="integer") @GeneratedValue */
private $id; private $id;
/** @Column(type="string", length=50); */ /** @Column(type="string", length=50); */
@@ -31,4 +39,9 @@ class UserEntity
{ {
$this->name = $name; $this->name = $name;
} }
public function returnGame(): Game
{
return $this->getGame();
}
} }
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tests\FakeModule\Models;
use LotGD\Core\Doctrine\Annotations\Extension;
use LotGD\Core\Doctrine\Annotations\ExtensionMethod;
use LotGD\Core\Models\Character;
/**
* Class CharacterTestExtension
* @package LotGD\Core\Tests\FakeModule\Models
* @Extension(of="LotGD\Core\Tests\FakeModule\Models\UserEntity")
*/
class UserTestExtension
{
/**
* @param UserEntity $user
* @return array
* @ExtensionMethod(as="getNameAsArray")
*/
public static function returnNameAsArrayForUser(UserEntity $user): array
{
$g = $user->getGame();
if ($g !== null) {
return [$user->getName()];
} else {
return [];
}
}
}
+2
View File
@@ -1,3 +1,5 @@
entityNamespace: "LotGD\\Core\\Tests\\FakeModule\\Models\\" entityNamespace: "LotGD\\Core\\Tests\\FakeModule\\Models\\"
subscriptionPatterns: subscriptionPatterns:
- "e/lotgd/core/tests/event" - "e/lotgd/core/tests/event"
modelExtensions:
- "LotGD\\Core\\Tests\\FakeModule\\Models\\UserTestExtension"
+27 -20
View File
@@ -37,15 +37,16 @@ class DefaultSceneProvider implements EventHandler
)); ));
} }
$context->setDataField("scene", $g->getEntityManager()->getRepository(Scene::class)->find(1)); $context->setDataField("scene", $g->getEntityManager()->getRepository(Scene::class)
->find("30000000-0000-0000-0000-000000000001"));
break; break;
case 'h/lotgd/core/navigate-to/lotgd/tests/village': case 'h/lotgd/core/navigate-to/lotgd/tests/village':
$v = $context->getDataField('viewpoint'); $v = $context->getDataField('viewpoint');
self::$actionGroups = [new ActionGroup('default', 'Title', 0)]; self::$actionGroups = [new ActionGroup('default', 'Title', 0)];
self::$actionGroups[0]->setActions([ self::$actionGroups[0]->setActions([
new Action(2), // This is a real sceneId in game.yml new Action("30000000-0000-0000-0000-000000000002"), // This is a real sceneId in game.yml
new Action(101), new Action("30000000-0000-0000-0000-000000000101"),
]); ]);
$v->setActionGroups(self::$actionGroups); $v->setActionGroups(self::$actionGroups);
@@ -76,7 +77,7 @@ class GameTest extends CoreModelTestCase
/** @var string default data set */ /** @var string default data set */
protected $dataset = "game"; protected $dataset = "game";
private $g; public $g;
public function setUp() public function setUp()
{ {
@@ -128,7 +129,7 @@ class GameTest extends CoreModelTestCase
public function testSetGetCharacter() public function testSetGetCharacter()
{ {
$c = $this->getEntityManager()->getRepository(Character::class)->find(1); $c = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$this->g->setCharacter($c); $this->g->setCharacter($c);
$this->assertEquals($c, $this->g->getCharacter()); $this->assertEquals($c, $this->g->getCharacter());
@@ -136,7 +137,7 @@ class GameTest extends CoreModelTestCase
public function testGetViewpointException() public function testGetViewpointException()
{ {
$c = $this->getEntityManager()->getRepository(Character::class)->find(1); $c = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$this->g->setCharacter($c); $this->g->setCharacter($c);
// There should'nt be any listeners to provide a default scene. // There should'nt be any listeners to provide a default scene.
@@ -146,7 +147,7 @@ class GameTest extends CoreModelTestCase
public function testGetViewpointStored() public function testGetViewpointStored()
{ {
$c = $this->getEntityManager()->getRepository(Character::class)->find(2); $c = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$this->g->setCharacter($c); $this->g->setCharacter($c);
$this->assertNotNull($this->g->getViewpoint()); $this->assertNotNull($this->g->getViewpoint());
@@ -154,11 +155,12 @@ class GameTest extends CoreModelTestCase
public function testGetViewpointDefault() public function testGetViewpointDefault()
{ {
$c = $this->getEntityManager()->getRepository(Character::class)->find(1); $c = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$this->g->setCharacter($c); $this->g->setCharacter($c);
$this->g->getEventManager()->subscribe('/h\/lotgd\/core\/default-scene/', DefaultSceneProvider::class, 'lotgd/core/tests'); $this->g->getEventManager()->subscribe('/h\/lotgd\/core\/default-scene/', DefaultSceneProvider::class, 'lotgd/core/tests');
$this->g->getEventManager()->subscribe('/h\/lotgd\/core\/navigate-to\/.*/', DefaultSceneProvider::class, 'lotgd/core/tests'); $this->g->getEventManager()->subscribe('/h\/lotgd\/core\/navigate-to\/.*/', DefaultSceneProvider::class, 'lotgd/core/tests');
$this->getEntityManager()->flush();
$v = $this->g->getViewpoint(); $v = $this->g->getViewpoint();
// Run it twice to make sure no additional DB operations happen. // Run it twice to make sure no additional DB operations happen.
@@ -175,7 +177,7 @@ class GameTest extends CoreModelTestCase
public function testTakeActionNonExistant() public function testTakeActionNonExistant()
{ {
$c = $this->getEntityManager()->getRepository(Character::class)->find(1); $c = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$this->g->setCharacter($c); $this->g->setCharacter($c);
// For now, I cant seem to serialize a proper ActionGroup to store in // For now, I cant seem to serialize a proper ActionGroup to store in
@@ -188,7 +190,7 @@ class GameTest extends CoreModelTestCase
public function testTakeActionNavigate() public function testTakeActionNavigate()
{ {
$c = $this->getEntityManager()->getRepository(Character::class)->find(3); $c = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000003");
$this->g->setCharacter($c); $this->g->setCharacter($c);
// For now, I cant seem to serialize a proper ActionGroup to store in // For now, I cant seem to serialize a proper ActionGroup to store in
@@ -209,13 +211,14 @@ class GameTest extends CoreModelTestCase
public function testIfActionParametersAreRelayedToEvent() public function testIfActionParametersAreRelayedToEvent()
{ {
/* @var $c Character */ /* @var $c Character */
$c = $this->getEntityManager()->getRepository(Character::class)->find(2); $c = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$this->g->setCharacter($c); $this->g->setCharacter($c);
// subscribe event // subscribe event
$this->g->getEventManager()->subscribe('#h/lotgd/core/navigate-to/lotgd/tests/paramaters#', DefaultSceneProvider::class, 'lotgd/core/tests'); $this->g->getEventManager()->subscribe('#h/lotgd/core/navigate-to/lotgd/tests/paramaters#', DefaultSceneProvider::class, 'lotgd/core/tests');
$this->getEntityManager()->flush();
$action = new Action(7, null, ["foo" => "baz"]); $action = new Action("30000000-0000-0000-0000-000000000007", null, ["foo" => "baz"]);
$actionId = $action->getId(); $actionId = $action->getId();
$ag = new ActionGroup("group1", "Group 1", 5); $ag = new ActionGroup("group1", "Group 1", 5);
@@ -238,13 +241,14 @@ class GameTest extends CoreModelTestCase
public function testIfActionParametersTakePriorityToOtherParameters() public function testIfActionParametersTakePriorityToOtherParameters()
{ {
/* @var $c Character */ /* @var $c Character */
$c = $this->getEntityManager()->getRepository(Character::class)->find(2); $c = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$this->g->setCharacter($c); $this->g->setCharacter($c);
// subscribe event // subscribe event
$this->g->getEventManager()->subscribe('#h/lotgd/core/navigate-to/lotgd/tests/paramaters#', DefaultSceneProvider::class, 'lotgd/core/tests'); $this->g->getEventManager()->subscribe('#h/lotgd/core/navigate-to/lotgd/tests/paramaters#', DefaultSceneProvider::class, 'lotgd/core/tests');
$this->getEntityManager()->flush();
$action = new Action(7, null, ["foo" => "baz"]); $action = new Action("30000000-0000-0000-0000-000000000007", null, ["foo" => "baz"]);
$actionId = $action->getId(); $actionId = $action->getId();
$ag = new ActionGroup("group1", "Group 1", 5); $ag = new ActionGroup("group1", "Group 1", 5);
@@ -285,7 +289,7 @@ class GameTest extends CoreModelTestCase
return $values; return $values;
}; };
$c = $this->getEntityManager()->getRepository(Character::class)->find(3); $c = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000003");
$this->g->setCharacter($c); $this->g->setCharacter($c);
$v0 = $this->g->getViewpoint(); $v0 = $this->g->getViewpoint();
@@ -295,9 +299,9 @@ class GameTest extends CoreModelTestCase
$this->assertSame([ $this->assertSame([
"Parent Scene", "Parent Scene",
[ [
ActionGroup::DefaultGroup => [1], ActionGroup::DefaultGroup => ["30000000-0000-0000-0000-000000000001"],
"lotgd/tests/none/child1" => [5], "lotgd/tests/none/child1" => ["30000000-0000-0000-0000-000000000005"],
"lotgd/tests/none/child2" => [6], "lotgd/tests/none/child2" => ["30000000-0000-0000-0000-000000000006"],
ActionGroup::HiddenGroup => [], ActionGroup::HiddenGroup => [],
] ]
], $viewpointToArray($v1)); ], $viewpointToArray($v1));
@@ -307,7 +311,10 @@ class GameTest extends CoreModelTestCase
$this->assertSame([ $this->assertSame([
"Child Scene 1", "Child Scene 1",
[ [
ActionGroup::DefaultGroup => [6, 4], ActionGroup::DefaultGroup => [
"30000000-0000-0000-0000-000000000006",
"30000000-0000-0000-0000-000000000004"
],
ActionGroup::HiddenGroup => [], ActionGroup::HiddenGroup => [],
] ]
], $viewpointToArray($v2)); ], $viewpointToArray($v2));
@@ -317,7 +324,7 @@ class GameTest extends CoreModelTestCase
$this->assertSame([ $this->assertSame([
"Child Scene 2", "Child Scene 2",
[ [
ActionGroup::DefaultGroup => [4], ActionGroup::DefaultGroup => ["30000000-0000-0000-0000-000000000004"],
ActionGroup::HiddenGroup => [], ActionGroup::HiddenGroup => [],
] ]
], $viewpointToArray($v3)); ], $viewpointToArray($v3));
+50 -1
View File
@@ -3,16 +3,23 @@ declare(strict_types=1);
namespace LotGD\Core\Tests; namespace LotGD\Core\Tests;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Events as DoctrineEvents;
use Doctrine\ORM\Mapping\AnsiQuoteStrategy; use Doctrine\ORM\Mapping\AnsiQuoteStrategy;
use Doctrine\ORM\Tools\Setup; use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\Tools\SchemaTool; use Doctrine\ORM\Tools\SchemaTool;
use LotGD\Core\Configuration; use LotGD\Core\Configuration;
use LotGD\Core\ComposerManager; use LotGD\Core\ComposerManager;
use LotGD\Core\Doctrine\EntityPostLoadEventListener;
use LotGD\Core\GameBuilder;
use LotGD\Core\LibraryConfigurationManager; use LotGD\Core\LibraryConfigurationManager;
use LotGD\Core\Exceptions\InvalidConfigurationException; use LotGD\Core\Exceptions\InvalidConfigurationException;
use LotGD\Core\ModelExtender;
use Monolog\Handler\NullHandler;
use Monolog\Logger;
/** /**
* Description of ModelTestCase * Description of ModelTestCase
@@ -25,6 +32,7 @@ abstract class ModelTestCase extends \PHPUnit_Extensions_Database_TestCase
static private $em = null; static private $em = null;
/** @var \PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection */ /** @var \PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection */
private $connection = null; private $connection = null;
public $g;
/** /**
* Returns a connection to test models * Returns a connection to test models
@@ -51,10 +59,12 @@ abstract class ModelTestCase extends \PHPUnit_Extensions_Database_TestCase
// Read db annotations from model files // Read db annotations from model files
$configuration = Setup::createAnnotationMetadataConfiguration($directories, true); $configuration = Setup::createAnnotationMetadataConfiguration($directories, true);
$configuration->setQuoteStrategy(new AnsiQuoteStrategy());
self::$em = EntityManager::create(["pdo" => self::$pdo], $configuration); self::$em = EntityManager::create(["pdo" => self::$pdo], $configuration);
// Register uuid type
\Doctrine\DBAL\Types\Type::addType('uuid', 'Ramsey\Uuid\Doctrine\UuidType');
// Create Schema // Create Schema
$metaData = self::$em->getMetadataFactory()->getAllMetadata(); $metaData = self::$em->getMetadataFactory()->getAllMetadata();
$schemaTool = new SchemaTool(self::$em); $schemaTool = new SchemaTool(self::$em);
@@ -76,6 +86,45 @@ abstract class ModelTestCase extends \PHPUnit_Extensions_Database_TestCase
return self::$em; 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() { protected function tearDown() {
parent::tearDown(); parent::tearDown();
+51 -5
View File
@@ -3,10 +3,16 @@ declare(strict_types=1);
namespace LotGD\Core\Tests\Models; 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\Character;
use LotGD\Core\Models\CharacterProperty; use LotGD\Core\Models\CharacterProperty;
use LotGD\Core\Tests\CoreModelTestCase; use LotGD\Core\Tests\CoreModelTestCase;
use LotGD\Core\Models\Repositories\CharacterRepository; use LotGD\Core\Models\Repositories\CharacterRepository;
use Ramsey\Uuid\UuidInterface;
/** /**
* Tests the management of Characters * Tests the management of Characters
@@ -21,13 +27,13 @@ class CharacterModelTest extends CoreModelTestCase
*/ */
public function testSoftDeletion() public function testSoftDeletion()
{ {
$chars = $this->getEntityManager()->getRepository(Character::class)->find(3); $chars = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000003");
$this->assertSame(null, $chars); $this->assertSame(null, $chars);
$allChars = $this->getEntityManager()->getRepository(Character::class)->findAll(); $allChars = $this->getEntityManager()->getRepository(Character::class)->findAll();
$this->assertSame(2, count($allChars)); $this->assertSame(2, count($allChars));
$char = $this->getEntityManager()->getRepository(Character::class)->find(1); $char = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$char->delete($this->getEntityManager()); $char->delete($this->getEntityManager());
$this->getEntityManager()->flush(); $this->getEntityManager()->flush();
$this->getEntityManager()->clear(); $this->getEntityManager()->clear();
@@ -90,11 +96,14 @@ class CharacterModelTest extends CoreModelTestCase
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$characterEntity = Character::create($characterData); $characterEntity = Character::create($characterData);
$characterEntity->setProperty("a property", 16);
$this->assertSame(16, $characterEntity->getProperty("a property"));
$characterEntity->save($em); $characterEntity->save($em);
$em->flush(); $em->flush();
$this->assertInternalType("int", $characterEntity->getId()); $this->assertInstanceOf(UuidInterface::class, $characterEntity->getId());
$this->assertSame(16, $characterEntity->getProperty("a property"));
$em->flush(); $em->flush();
} }
@@ -134,7 +143,7 @@ class CharacterModelTest extends CoreModelTestCase
$rowsBefore = count($em->getRepository(Character::class)->findAll()); $rowsBefore = count($em->getRepository(Character::class)->findAll());
// Delete one row // Delete one row
$character = $em->getRepository(Character::class)->find(1); $character = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$character->delete($em); $character->delete($em);
$em->clear(); $em->clear();
@@ -155,7 +164,7 @@ class CharacterModelTest extends CoreModelTestCase
$em = $this->getEntityManager(); $em = $this->getEntityManager();
// test default values // test default values
$firstCharacter = $em->getRepository(Character::class)->find(1); $firstCharacter = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$this->assertSame(5, $firstCharacter->getProperty("dragonkills", 5)); $this->assertSame(5, $firstCharacter->getProperty("dragonkills", 5));
$this->assertNotSame(5, $firstCharacter->getProperty("dragonkills", "5")); $this->assertNotSame(5, $firstCharacter->getProperty("dragonkills", "5"));
$this->assertSame("hanniball", $firstCharacter->getProperty("petname", "hanniball")); $this->assertSame("hanniball", $firstCharacter->getProperty("petname", "hanniball"));
@@ -189,4 +198,41 @@ class CharacterModelTest extends CoreModelTestCase
$this->assertSame(6, $total); $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->getEntityManager()->flush();
$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"]);
}
} }
+269
View File
@@ -0,0 +1,269 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tests\Models;
use LotGD\Core\EventHandler;
use LotGD\Core\Events\EventContext;
use LotGD\Core\Exceptions\CharacterStatExistsException;
use LotGD\Core\Exceptions\CharacterStatGroupExistsException;
use LotGD\Core\Exceptions\CharacterStatGroupNotFoundException;
use LotGD\Core\Exceptions\CharacterStatNotFoundException;
use LotGD\Core\Game;
use LotGD\Core\Models\Character;
use LotGD\Core\Models\CharacterStatGroup;
use LotGD\Core\Models\CharacterStats;
use LotGD\Core\Tests\CoreModelTestCase;
class TestEventProvider implements EventHandler
{
static $called = 0;
static $last_context;
public static function handleEvent(Game $g, EventContext $context): EventContext
{
$stats = $context->getDataField("stats");
$character = $context->getDataField("character");
self::$called++;
self::$last_context = $context;
return $context;
}
}
class CharaterStatsTest extends CoreModelTestCase
{
/** @var string default data set */
protected $dataset = "character_stats";
public function setUp()
{
parent::setUp();
$game = $this->g;
$game->getEventManager()->subscribe("#h/lotgd/core/characterStats/populate#", TestEventProvider::class, "lotgd/test");
$this->getEntityManager()->flush();
}
public function tearDown()
{
$game = $this->g;
$game->getEventManager()->unsubscribe("#h/lotgd/core/characterStats/populate#", TestEventProvider::class, "lotgd/test");
$this->getEntityManager()->flush();
parent::tearDown();
}
public function testICharacterStatPopulationEventGetsCalled()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$this->assertSame(1, TestEventProvider::$called);
}
public function testIfCharacterStatPopulationEventUsesCorrectTypes()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$this->assertInstanceOf(CharacterStats::class, TestEventProvider::$last_context->getDataField("stats"));
$this->assertInstanceOf(Character::class, TestEventProvider::$last_context->getDataField("character"));
}
public function testIfCharacterStatGroupCanGetAddedToCharacterStats()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$group = new CharacterStatGroup("vendor/test", "Test");
$stats->addCharacterStatGroup($group);
$this->assertSame($group, $stats->getCharacterStatGroup("vendor/test"));
}
public function testIfAddingCharacterStatGroupWithSameIdResultsInException()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$group = new CharacterStatGroup("vendor/test", "Test");
$stats->addCharacterStatGroup($group);
$this->assertTrue($stats->hasCharacterStatGroup($group->getId()));
$this->expectException(CharacterStatGroupExistsException::class);
$group2 = new CharacterStatGroup("vendor/test", "Test");
$stats->addCharacterStatGroup($group2);
}
public function testIfGettingUnknownCharacterStatGroupResultsInException()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$group = new CharacterStatGroup("vendor/test", "Test");
$this->assertFalse($stats->hasCharacterStatGroup($group->getId()));
$this->expectException(CharacterStatGroupNotFoundException::class);
$stats->getCharacterStatGroup($group->getId());
}
public function testIfIteratingCharacterStatsYieldsAllStatGroups()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$groups = [
new CharacterStatGroup("vendor/test-0", "Test 1"),
new CharacterStatGroup("vendor/test-1", "Test 2"),
new CharacterStatGroup("vendor/test-2", "Test 3")
];
foreach ($groups as $group) {
$stats->addCharacterStatGroup($group);
}
$i = 0;
foreach($stats->iterate() as $statGroup)
{
$this->assertInstanceOf(CharacterStatGroup::class, $statGroup);
$this->assertTrue($stats->hasCharacterStatGroup($statGroup->getId()));
$this->assertSame($groups[$i], $statGroup);
$i++;
}
}
public function testIfIteratingCharacterStatsYieldsAllStatGroupsSortedAccordingToTheirWeight()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$groups = [
new CharacterStatGroup("vendor/test-0", "Test 1", 100),
new CharacterStatGroup("vendor/test-1", "Test 2", 0),
new CharacterStatGroup("vendor/test-2", "Test 3", -100)
];
foreach ($groups as $group) {
$stats->addCharacterStatGroup($group);
}
$i = 0;
foreach($stats->iterate() as $statGroup)
{
$this->assertInstanceOf(CharacterStatGroup::class, $statGroup);
$this->assertTrue($stats->hasCharacterStatGroup($statGroup->getId()));
$this->assertSame($groups[2-$i], $statGroup);
$i++;
}
}
public function testIfCharacterStatCanGetAddedToCharacterStatGroup()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$group = new CharacterStatGroup("vendor/test", "Test");
$stats->addCharacterStatGroup($group);
$stat = new CharacterStats\BaseCharacterStat("vendor/test/item", "Item", 17);
$group->addCharacterStat($stat);
$this->assertSame($stat, $group->getCharacterStat("vendor/test/item"));
}
public function testIfAddingCharacterStatWithSameIdResultsInException()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$group = new CharacterStatGroup("vendor/test", "Test");
$stats->addCharacterStatGroup($group);
$stat = new CharacterStats\BaseCharacterStat("vendor/test/item", "Item", 17);
$group->addCharacterStat($stat);
$this->assertTrue($group->hasCharacterStat($stat->getId()));
$this->expectException(CharacterStatExistsException::class);
$stat2 = new CharacterStats\BaseCharacterStat("vendor/test/item", "Item", 17);
$group->addCharacterStat($stat2);
}
public function testIfGettingUnknownCharacterStatResultsInException()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$group = new CharacterStatGroup("vendor/test", "Test");
$stats->addCharacterStatGroup($group);
$stat = new CharacterStats\BaseCharacterStat("vendor/test/item", "Item", 17);
$this->assertFalse($group->hasCharacterStat($stat->getId()));
$this->expectException(CharacterStatNotFoundException::class);
$group->getCharacterStat($group->getId());
}
public function testIfIteratingCharacterGroupYieldsAllStatGroups()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$stats = [
new CharacterStats\BaseCharacterStat("vendor/test/item-0", "Item 1", 17),
new CharacterStats\BaseCharacterStat("vendor/test/item-1", "Item 2", 18),
new CharacterStats\BaseCharacterStat("vendor/test/item-2", "Item 3", 19),
];
$group = new CharacterStatGroup("vendor/test", "Test-Group");
foreach ($stats as $stat) {
$group->addCharacterStat($stat);
}
$i = 0;
foreach($group->iterate() as $stat) {
$this->assertInstanceOf(CharacterStats\BaseCharacterStat::class, $stat);
$this->assertTrue($group->hasCharacterStat($stat->getId()));
$this->assertSame($stats[$i], $stat);
$i++;
}
}
public function testIfIteratingCharacterGroupYieldsAllStatGroupsIfWeightsAreGiven()
{
$character = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$stats = new CharacterStats($this->g, $character);
$stats = [
new CharacterStats\BaseCharacterStat("vendor/test/item-0", "Item 1", 17, 100),
new CharacterStats\BaseCharacterStat("vendor/test/item-1", "Item 2", 18, 0),
new CharacterStats\BaseCharacterStat("vendor/test/item-2", "Item 3", 19, -1),
];
$group = new CharacterStatGroup("vendor/test", "Test-Group");
foreach ($stats as $stat) {
$group->addCharacterStat($stat);
}
$i = 0;
foreach($group->iterate() as $stat) {
$this->assertInstanceOf(CharacterStats\BaseCharacterStat::class, $stat);
$this->assertTrue($group->hasCharacterStat($stat->getId()));
$this->assertSame($stats[2-$i], $stat);
$i++;
}
}
}
+49 -43
View File
@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace LotGD\Core\Tests\Models; namespace LotGD\Core\Tests\Models;
use LotGD\Core\MessageManager;
use LotGD\Core\Models\Character; use LotGD\Core\Models\Character;
use LotGD\Core\Models\MessageThread; use LotGD\Core\Models\MessageThread;
use LotGD\Core\Models\Message; use LotGD\Core\Models\Message;
@@ -14,24 +15,26 @@ use LotGD\Core\Tests\CoreModelTestCase;
*/ */
class MessageModelTest extends CoreModelTestCase class MessageModelTest extends CoreModelTestCase
{ {
/** @var string default data set */ /** @var string default data set */
protected $dataset = "messages"; protected $dataset = "messages";
public function testSendMessageToSingleCharacter() public function testSendMessageToSingleCharacter()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$mm=new MessageManager();
$character1 = $em->getRepository(Character::class)->find(1);
$character2 = $em->getRepository(Character::class)->find(4); $character1 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$character2 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000004");
$thread1 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2]); $thread1 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2]);
$thread2 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character2, $character1]); $thread2 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character2, $character1]);
$this->assertSame($thread1, $thread2); $this->assertSame($thread1, $thread2);
Message::send($character1, "Hi, how are you?", $thread1); $mm->send($character1, "Hi, how are you?", $thread1);
Message::send($character2, "I'm fine, and you?", $thread1); $mm->send($character2, "I'm fine, and you?", $thread1);
Message::send($character1, "Sorry, I need to leave~", $thread1); $mm->send($character1, "Sorry, I need to leave~", $thread1);
$this->assertSame(3, count($thread1->getMessages())); $this->assertSame(3, count($thread1->getMessages()));
@@ -39,8 +42,8 @@ class MessageModelTest extends CoreModelTestCase
$em->flush(); $em->flush();
$em->clear(); $em->clear();
$character1 = $em->getRepository(Character::class)->find(1); $character1 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$character2 = $em->getRepository(Character::class)->find(4); $character2 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000004");
$thread1 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2]); $thread1 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2]);
@@ -57,25 +60,26 @@ class MessageModelTest extends CoreModelTestCase
public function testSendMessageToMultipleCharacters() public function testSendMessageToMultipleCharacters()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$mm=new MessageManager();
$character1 = $em->getRepository(Character::class)->find(1);
$character2 = $em->getRepository(Character::class)->find(2); $character1 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$character3 = $em->getRepository(Character::class)->find(3, CharacterRepository::INCLUDE_SOFTDELETED); $character2 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$character4 = $em->getRepository(Character::class)->find(4); $character3 = $em->getRepository(Character::class)->findWithSoftDeleted("10000000-0000-0000-0000-000000000003");
$character4 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000004");
$thread1 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2, $character3, $character4]); $thread1 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2, $character3, $character4]);
$thread2 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character4, $character2, $character1, $character3]); $thread2 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character4, $character2, $character1, $character3]);
$this->assertSame($thread1, $thread2); $this->assertSame($thread1, $thread2);
Message::send($character1, "Multi-User-Message", $thread1); $mm->send($character1, "Multi-User-Message", $thread1);
Message::send($character2, "Multi-User-Message", $thread1); $mm->send($character2, "Multi-User-Message", $thread1);
try { try {
$exception = false; $exception = false;
Message::send($character3, "Multi-User-Message", $thread1); $mm->send($character3, "Multi-User-Message", $thread1);
} catch(\LotGD\Core\Exceptions\ArgumentException $e) { } catch(\LotGD\Core\Exceptions\ArgumentException $e) {
$exception = true; $exception = true;
} }
Message::send($character4, "Multi-User-Message", $thread1); $mm->send($character4, "Multi-User-Message", $thread1);
$this->assertTrue($exception); $this->assertTrue($exception);
$this->assertSame(3, count($thread1->getMessages())); $this->assertSame(3, count($thread1->getMessages()));
@@ -85,11 +89,11 @@ class MessageModelTest extends CoreModelTestCase
$this->assertSame(1, count($character4->getMessageThreads())); $this->assertSame(1, count($character4->getMessageThreads()));
$em->flush(); $em->flush();
$character1 = $em->getRepository(Character::class)->find(1); $character1 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$character2 = $em->getRepository(Character::class)->find(2); $character2 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$character3 = $em->getRepository(Character::class)->find(3, CharacterRepository::INCLUDE_SOFTDELETED); $character3 = $em->getRepository(Character::class)->findWithSoftDeleted("10000000-0000-0000-0000-000000000003");
$character4 = $em->getRepository(Character::class)->find(4); $character4 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000004");
$thread1 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2, $character3, $character4]); $thread1 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2, $character3, $character4]);
@@ -105,23 +109,24 @@ class MessageModelTest extends CoreModelTestCase
public function testSendSystemMessageToSingleCharacter() public function testSendSystemMessageToSingleCharacter()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$mm=new MessageManager();
$character1 = $em->getRepository(Character::class)->find(1);
$character2 = $em->getRepository(Character::class)->find(2); $character1 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$character2 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$thread1 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character1]); $thread1 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character1]);
$thread2 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character2]); $thread2 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character2]);
$this->assertNotSame($thread1, $thread2); $this->assertNotSame($thread1, $thread2);
Message::sendSystemMessage("This is a Systemmessage for Character 1.", $thread1); $mm->sendSystemMessage("This is a Systemmessage for Character 1.", $thread1);
Message::sendSystemMessage("This is a Systemmessage for Character 2.", $thread2); $mm->sendSystemMessage("This is a Systemmessage for Character 2.", $thread2);
$em->flush(); $em->flush();
$em->clear(); $em->clear();
$character1 = $em->getRepository(Character::class)->find(1); $character1 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$character2 = $em->getRepository(Character::class)->find(2); $character2 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$thread1 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character1]); $thread1 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character1]);
$thread2 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character2]); $thread2 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character2]);
@@ -133,12 +138,12 @@ class MessageModelTest extends CoreModelTestCase
// needs to be able to get attached // needs to be able to get attached
try { try {
$exception = false; $exception = false;
Message::send($character1, "A normal message", $thread1); $mm->send($character1, "A normal message", $thread1);
} catch (\LotGD\Core\Exceptions\CoreException $ex) { } catch (\LotGD\Core\Exceptions\CoreException $ex) {
$exception = true; $exception = true;
} }
Message::sendSystemMessage("A second system Message", $thread1); $mm->sendSystemMessage("A second system Message", $thread1);
$this->assertTrue($exception); $this->assertTrue($exception);
$this->assertSame(2, count($thread1->getMessages())); $this->assertSame(2, count($thread1->getMessages()));
@@ -147,22 +152,23 @@ class MessageModelTest extends CoreModelTestCase
public function testSendSystemMessageToMultipleCharacters() public function testSendSystemMessageToMultipleCharacters()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$mm=new MessageManager();
$character1 = $em->getRepository(Character::class)->find(1);
$character2 = $em->getRepository(Character::class)->find(2); $character1 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$character2 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$thread1 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character1, $character2]); $thread1 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character1, $character2]);
$thread2 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2]); $thread2 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2]);
$this->assertNotSame($thread1, $thread2); $this->assertNotSame($thread1, $thread2);
Message::sendSystemMessage("A system message to 2 recipients", $thread1); $mm->sendSystemMessage("A system message to 2 recipients", $thread1);
$em->flush(); $em->flush();
$em->clear(); $em->clear();
$character1 = $em->getRepository(Character::class)->find(1); $character1 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$character2 = $em->getRepository(Character::class)->find(2); $character2 = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$thread1 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character1, $character2]); $thread1 = $em->getRepository(MessageThread::class)->findOrCreateReadonlyFor([$character1, $character2]);
+10
View File
@@ -5,6 +5,7 @@ namespace LotGD\Core\Tests\Models;
use LotGD\Core\Models\Module; use LotGD\Core\Models\Module;
use LotGD\Core\Models\ModuleProperty; use LotGD\Core\Models\ModuleProperty;
use LotGD\Core\ModuleManager;
use LotGD\Core\Tests\CoreModelTestCase; use LotGD\Core\Tests\CoreModelTestCase;
/** /**
@@ -29,6 +30,15 @@ class ModuleTest extends CoreModelTestCase
$em->flush(); $em->flush();
} }
public function testSetter()
{
$em = $this->getEntityManager();
$module = new Module("lotgd/test/blah");
$module->setProperty("test", 15);
$this->assertSame(15, $module->getProperty("test"));
}
public function testProperties() public function testProperties()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
+9 -10
View File
@@ -19,10 +19,10 @@ class MotDModelTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$author = $em->getRepository(Character::class)->find(1); $author = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
// Test normal message // Test normal message
$motd1 = $em->getRepository(MotD::class)->find(1); $motd1 = $em->getRepository(MotD::class)->find("20000000-0000-0000-0000-000000000001");
$this->assertSame("This is the title", $motd1->getTitle()); $this->assertSame("This is the title", $motd1->getTitle());
$this->assertSame("This is the body of the message", $motd1->getBody()); $this->assertSame("This is the body of the message", $motd1->getBody());
$this->assertSame($author, $motd1->getAuthor()); $this->assertSame($author, $motd1->getAuthor());
@@ -30,14 +30,14 @@ class MotDModelTest extends CoreModelTestCase
$this->assertFalse($motd1->getSystemMessage()); $this->assertFalse($motd1->getSystemMessage());
// Test System message // Test System message
$motd2 = $em->getRepository(MotD::class)->find(2); $motd2 = $em->getRepository(MotD::class)->find("20000000-0000-0000-0000-000000000002");
$this->assertTrue($motd2->getSystemMessage()); $this->assertTrue($motd2->getSystemMessage());
$this->assertNotSame($motd2->getAuthor(), $motd2->getApparantAuthor()); $this->assertNotSame($motd2->getAuthor(), $motd2->getApparantAuthor());
$this->assertSame($author, $motd2->getAuthor()); $this->assertSame($author, $motd2->getAuthor());
$this->assertNotSame("Deleted Character Name", $motd2->getAuthor()->getDisplayName()); $this->assertNotSame("Deleted Character Name", $motd2->getAuthor()->getDisplayName());
// Test message with unknown author // Test message with unknown author
$motd3 = $em->getRepository(Motd::class)->find(3); $motd3 = $em->getRepository(Motd::class)->find("20000000-0000-0000-0000-000000000003");
$this->assertSame("Deleted Testcharacter", $motd3->getAuthor()->getDisplayName()); $this->assertSame("Deleted Testcharacter", $motd3->getAuthor()->getDisplayName());
} }
@@ -45,7 +45,7 @@ class MotDModelTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$time1 = $em->getRepository(MotD::class)->find(1)->getCreationTime(); $time1 = $em->getRepository(MotD::class)->find("20000000-0000-0000-0000-000000000001")->getCreationTime();
$time2 = new \DateTime("2016-05-03 14:19:12"); $time2 = new \DateTime("2016-05-03 14:19:12");
$time3 = $time2->setTimezone(new \DateTimeZone("Europe/Zurich")); $time3 = $time2->setTimezone(new \DateTimeZone("Europe/Zurich"));
$time4 = new \DateTime("2016-05-03 14:19:12"); $time4 = new \DateTime("2016-05-03 14:19:12");
@@ -63,13 +63,13 @@ class MotDModelTest extends CoreModelTestCase
{ {
return [ return [
[[ [[
"author" => 1, "author" => "10000000-0000-0000-0000-000000000001",
"title" => "ABC_\"EFG", "title" => "ABC_\"EFG",
"body" => "Lorem îpsum etc pp", "body" => "Lorem îpsum etc pp",
"systemMessage" => false, "systemMessage" => false,
]], ]],
[[ [[
"author" => 1, "author" => "10000000-0000-0000-0000-000000000001",
"title" => "AnotherOne", "title" => "AnotherOne",
"body" => "Test a Second One", "body" => "Test a Second One",
"systemMessage" => true, "systemMessage" => true,
@@ -87,10 +87,9 @@ class MotDModelTest extends CoreModelTestCase
$motdCreationArguments["author"] = $em->getRepository(Character::class)->find($motdCreationArguments["author"]); $motdCreationArguments["author"] = $em->getRepository(Character::class)->find($motdCreationArguments["author"]);
$motd = MotD::create($motdCreationArguments); $motd = MotD::create($motdCreationArguments);
$motd->save($em);
$id = $motd->getId(); $id = $motd->getId();
$em->persist($motd);
$em->flush(); $em->flush();
$em->clear(); $em->clear();
+37 -33
View File
@@ -3,8 +3,6 @@ declare(strict_types=1);
namespace LotGD\Core\Tests\Models; namespace LotGD\Core\Tests\Models;
use Doctrine\Common\Collections\ArrayCollection;
use LotGD\Core\Exceptions\ArgumentException; use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Models\{Scene, SceneConnection, SceneConnectionGroup}; use LotGD\Core\Models\{Scene, SceneConnection, SceneConnectionGroup};
use LotGD\Core\Tests\CoreModelTestCase; use LotGD\Core\Tests\CoreModelTestCase;
@@ -54,6 +52,8 @@ class SceneModelTest extends CoreModelTestCase
// create new scene, flush and clear. Number of scenes in db should be +1 // create new scene, flush and clear. Number of scenes in db should be +1
$newScene = Scene::create($this->getTestSceneData()); $newScene = Scene::create($this->getTestSceneData());
$id = $newScene->getId();
$newScene->save($em); $newScene->save($em);
$this->flushAndClear(); $this->flushAndClear();
unset($newScene); unset($newScene);
@@ -63,7 +63,7 @@ class SceneModelTest extends CoreModelTestCase
$this->assertSame($n1 + 1, $n2); $this->assertSame($n1 + 1, $n2);
// fetch new scene, delete, flush and clear. // fetch new scene, delete, flush and clear.
$newScene = $em->getRepository(Scene::class)->findOneBy($this->getTestSceneData()); $newScene = $em->getRepository(Scene::class)->find($id);
$newScene->delete($em); $newScene->delete($em);
$this->flushAndClear(); $this->flushAndClear();
@@ -87,7 +87,7 @@ class SceneModelTest extends CoreModelTestCase
// create new scene, connect to another one. Number of scenes must be +1, number of connections must be +1 // create new scene, connect to another one. Number of scenes must be +1, number of connections must be +1
// this tests for cascade=persist // this tests for cascade=persist
$scene = Scene::create($this->getTestSceneData()); $scene = Scene::create($this->getTestSceneData());
$scene->connect($em->getRepository(Scene::class)->find(1)); $scene->connect($em->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001"));
$scene->save($em); $scene->save($em);
$this->flushAndClear(); $this->flushAndClear();
unset($scene); unset($scene);
@@ -144,7 +144,7 @@ class SceneModelTest extends CoreModelTestCase
public function testGetters() public function testGetters()
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$scene = $em->getRepository(Scene::class)->find(2); $scene = $em->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000002");
$this->assertEquals("The Forest", $scene->getTitle()); $this->assertEquals("The Forest", $scene->getTitle());
$this->assertEquals("This is a very dangerous and dark forest", $scene->getDescription()); $this->assertEquals("This is a very dangerous and dark forest", $scene->getDescription());
@@ -154,7 +154,7 @@ class SceneModelTest extends CoreModelTestCase
public function testIfHasConnectionGroupReturnsTrueIfConnectionGroupExists() public function testIfHasConnectionGroupReturnsTrueIfConnectionGroupExists()
{ {
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene = $this->getEntityManager()->getRepository(Scene::class)->find( "30000000-0000-0000-0000-000000000001");
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/outside")); $this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/outside"));
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/market")); $this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/market"));
@@ -163,14 +163,14 @@ class SceneModelTest extends CoreModelTestCase
public function testIfHasConnectionGroupReturnsFalseIfConnectionGroupDoesNotExist() public function testIfHasConnectionGroupReturnsFalseIfConnectionGroupDoesNotExist()
{ {
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2); $scene2 = $this->getEntityManager()->getRepository(Scene::class)->find( "30000000-0000-0000-0000-000000000002");
$this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/outside")); $this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/outside"));
$this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/market")); $this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/market"));
$this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/empty")); $this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/empty"));
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene1 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$this->assertFalse($scene1->hasConnectionGroup("lotgd/tests/village/23426")); $this->assertFalse($scene1->hasConnectionGroup("lotgd/tests/village/23426"));
} }
@@ -178,7 +178,7 @@ class SceneModelTest extends CoreModelTestCase
public function testIfAddConnectionGroupWorks() public function testIfAddConnectionGroupWorks()
{ {
$connectionGroup = new SceneConnectionGroup("lotgd/tests/village/new", "New Street"); $connectionGroup = new SceneConnectionGroup("lotgd/tests/village/new", "New Street");
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$this->assertFalse($scene->hasConnectionGroup("lotgd/tests/village/new")); $this->assertFalse($scene->hasConnectionGroup("lotgd/tests/village/new"));
@@ -191,8 +191,9 @@ class SceneModelTest extends CoreModelTestCase
public function testIfAddConnectionGroupThrowsArgumentExceptionIfGroupIsAlreadyAssignedToItself() public function testIfAddConnectionGroupThrowsArgumentExceptionIfGroupIsAlreadyAssignedToItself()
{ {
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]); $connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)
->findOneBy(["scene" => "30000000-0000-0000-0000-000000000001", "name" => "lotgd/tests/village/outside"]);
$this->expectException(ArgumentException::class); $this->expectException(ArgumentException::class);
$scene->addConnectionGroup($connectionGroup); $scene->addConnectionGroup($connectionGroup);
@@ -200,8 +201,9 @@ class SceneModelTest extends CoreModelTestCase
public function testIfAddConnectionGroupThrowsArgumentExceptionIfGroupIsAlreadyAssignedToSomwhereElse() public function testIfAddConnectionGroupThrowsArgumentExceptionIfGroupIsAlreadyAssignedToSomwhereElse()
{ {
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(2); $scene = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000002");
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]); $connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)
->findOneBy(["scene" => "30000000-0000-0000-0000-000000000001", "name" => "lotgd/tests/village/outside"]);
$this->expectException(ArgumentException::class); $this->expectException(ArgumentException::class);
$scene->addConnectionGroup($connectionGroup); $scene->addConnectionGroup($connectionGroup);
@@ -209,8 +211,9 @@ class SceneModelTest extends CoreModelTestCase
public function testifDropConnectionGroupWorks() public function testifDropConnectionGroupWorks()
{ {
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]); $connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)
->findOneBy(["scene" => "30000000-0000-0000-0000-000000000001", "name" => "lotgd/tests/village/outside"]);
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/outside")); $this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/outside"));
@@ -223,8 +226,9 @@ class SceneModelTest extends CoreModelTestCase
public function testIfDropConnectionGroupThrowsArgumentExceptionIfEntityIsRemovedFromNonOwningScene() public function testIfDropConnectionGroupThrowsArgumentExceptionIfEntityIsRemovedFromNonOwningScene()
{ {
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(2); $scene = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000002");
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]); $connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)
->findOneBy(["scene" => "30000000-0000-0000-0000-000000000001", "name" => "lotgd/tests/village/outside"]);
$this->expectException(ArgumentException::class); $this->expectException(ArgumentException::class);
$scene->dropConnectionGroup($connectionGroup); $scene->dropConnectionGroup($connectionGroup);
@@ -232,8 +236,8 @@ class SceneModelTest extends CoreModelTestCase
public function testIfGetConnectedScenesReturnsConnectedScenes() public function testIfGetConnectedScenesReturnsConnectedScenes()
{ {
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene1 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2); $scene2 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000002");
$this->assertCount(3, $scene1->getConnectedScenes()); $this->assertCount(3, $scene1->getConnectedScenes());
$this->assertCount(1, $scene2->getConnectedScenes()); $this->assertCount(1, $scene2->getConnectedScenes());
@@ -246,9 +250,9 @@ class SceneModelTest extends CoreModelTestCase
public function testIfIsConnectedToReturnsExpectedReturnValue() public function testIfIsConnectedToReturnsExpectedReturnValue()
{ {
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene1 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2); $scene2 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000002");
$scene5 = $this->getEntityManager()->getRepository(Scene::class)->find(5); $scene5 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000005");
$this->assertTrue($scene1->isConnectedTo($scene2)); $this->assertTrue($scene1->isConnectedTo($scene2));
$this->assertTrue($scene2->isConnectedTo($scene1)); $this->assertTrue($scene2->isConnectedTo($scene1));
@@ -260,8 +264,8 @@ class SceneModelTest extends CoreModelTestCase
public function testIfTwoScenesCanGetConnected() public function testIfTwoScenesCanGetConnected()
{ {
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(2); $scene1 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000002");
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5); $scene2 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000005");
$scene1->connect($scene2); $scene1->connect($scene2);
@@ -275,8 +279,8 @@ class SceneModelTest extends CoreModelTestCase
public function testIfASceneConnectionGroupCanGetConnectedToAScene() public function testIfASceneConnectionGroupCanGetConnectedToAScene()
{ {
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene1 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5); $scene2 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000005");
$scene1->getConnectionGroup("lotgd/tests/village/outside")->connect($scene2); $scene1->getConnectionGroup("lotgd/tests/village/outside")->connect($scene2);
@@ -290,8 +294,8 @@ class SceneModelTest extends CoreModelTestCase
public function testIfASceneCanGetConnectedToASceneConnectionGroup() public function testIfASceneCanGetConnectedToASceneConnectionGroup()
{ {
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene1 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5); $scene2 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000005");
$scene2->connect($scene1->getConnectionGroup("lotgd/tests/village/outside")); $scene2->connect($scene1->getConnectionGroup("lotgd/tests/village/outside"));
@@ -305,8 +309,8 @@ class SceneModelTest extends CoreModelTestCase
public function testIfASceneConnectionGroupCanGetConnectedToAnotherSceneConnectionGroup() public function testIfASceneConnectionGroupCanGetConnectedToAnotherSceneConnectionGroup()
{ {
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene1 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5); $scene2 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000005");
$scene2->addConnectionGroup(new SceneConnectionGroup("test/orphaned", "Orphan group")); $scene2->addConnectionGroup(new SceneConnectionGroup("test/orphaned", "Orphan group"));
$scene1 $scene1
@@ -325,7 +329,7 @@ class SceneModelTest extends CoreModelTestCase
public function testIfConnectingASceneToItselfThrowsAnException() public function testIfConnectingASceneToItselfThrowsAnException()
{ {
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene1 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$this->expectException(ArgumentException::class); $this->expectException(ArgumentException::class);
$scene1->connect($scene1); $scene1->connect($scene1);
@@ -344,8 +348,8 @@ class SceneModelTest extends CoreModelTestCase
public function testIfConnectingASceneToAnotherAlreadyConnectedSceneThrowsAnException() public function testIfConnectingASceneToAnotherAlreadyConnectedSceneThrowsAnException()
{ {
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1); $scene1 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000001");
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2); $scene2 = $this->getEntityManager()->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000002");
$this->expectException(ArgumentException::class); $this->expectException(ArgumentException::class);
$scene1->connect($scene2); $scene1->connect($scene2);
+110 -22
View File
@@ -40,8 +40,8 @@ class ViewpointTest extends CoreModelTestCase
$em = $this->getEntityManager(); $em = $this->getEntityManager();
// Test character with a characterScene // Test character with a characterScene
$testCharacter = $em->getRepository(Character::class)->find(2); $testCharacter = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$this->assertSame(2, $testCharacter->getId()); $this->assertSame("10000000-0000-0000-0000-000000000002", (string)$testCharacter->getId());
$characterScene = $testCharacter->getViewpoint(); $characterScene = $testCharacter->getViewpoint();
$this->assertInstanceOf(Viewpoint::class, $characterScene); $this->assertInstanceOf(Viewpoint::class, $characterScene);
@@ -49,8 +49,8 @@ class ViewpointTest extends CoreModelTestCase
$this->assertSame("This is the village.", $characterScene->getDescription()); $this->assertSame("This is the village.", $characterScene->getDescription());
// Test character without a characterScene // Test character without a characterScene
$testCharacter = $em->getRepository(Character::class)->find(1); $testCharacter = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$this->assertSame(1, $testCharacter->getId()); $this->assertSame("10000000-0000-0000-0000-000000000001", (string)$testCharacter->getId());
$characterScene = $testCharacter->getViewpoint(); $characterScene = $testCharacter->getViewpoint();
$this->assertNull($characterScene); $this->assertNull($characterScene);
@@ -63,9 +63,9 @@ class ViewpointTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$testCharacter = $em->getRepository(Character::class)->find(2); $testCharacter = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$testScene = $em->getRepository(Scene::class)->find(2); $testScene = $em->getRepository(Scene::class)->find("30000000-0000-0000-0000-000000000002");
$this->assertSame("The Village", $testCharacter->getViewpoint()->getTitle()); $this->assertSame("The Village", $testCharacter->getViewpoint()->getTitle());
@@ -82,12 +82,12 @@ class ViewpointTest extends CoreModelTestCase
$ag1 = new ActionGroup('id1', 'title1', 42); $ag1 = new ActionGroup('id1', 'title1', 42);
$ag1->setActions([ $ag1->setActions([
new Action(1), new Action("30000000-0000-0000-0000-000000000001"),
new Action(2) new Action("30000000-0000-0000-0000-000000000002")
]); ]);
$ag2 = new ActionGroup('id2', 'title2', 101); $ag2 = new ActionGroup('id2', 'title2', 101);
$ag2->setActions([ $ag2->setActions([
new Action(3) new Action("30000000-0000-0000-0000-000000000003")
]); ]);
$actionGroups = [ $actionGroups = [
@@ -95,19 +95,19 @@ class ViewpointTest extends CoreModelTestCase
$ag2 $ag2
]; ];
$input = $em->getRepository(Viewpoint::class)->find(2); $input = $em->getRepository(Viewpoint::class)->find("10000000-0000-0000-0000-000000000002");
$input->setActionGroups($actionGroups); $input->setActionGroups($actionGroups);
$input->save($em); $input->save($em);
$em->clear(); $em->clear();
$output = $em->getRepository(Viewpoint::class)->find(2); $output = $em->getRepository(Viewpoint::class)->find("10000000-0000-0000-0000-000000000002");
$this->assertEquals($actionGroups, $output->getActionGroups()); $this->assertEquals($actionGroups, $output->getActionGroups());
$this->assertEquals($ag2, $input->findActionGroupById('id2')); $this->assertEquals($ag2, $input->findActionGroupById('id2'));
$this->assertNull($input->findActionGroupById('not-there')); $this->assertNull($input->findActionGroupById('not-there'));
$testAction = new Action(4); $testAction = new Action("30000000-0000-0000-0000-000000000004");
$input->addActionToGroupId($testAction, 'not-there'); $input->addActionToGroupId($testAction, 'not-there');
$this->assertNull($input->findActionById($testAction->getId())); $this->assertNull($input->findActionById($testAction->getId()));
@@ -124,13 +124,13 @@ class ViewpointTest extends CoreModelTestCase
$attachments = [$a1, $a2]; $attachments = [$a1, $a2];
$input = $em->getRepository(Viewpoint::class)->find(2); $input = $em->getRepository(Viewpoint::class)->find("10000000-0000-0000-0000-000000000002");
$input->setAttachments($attachments); $input->setAttachments($attachments);
$input->save($em); $input->save($em);
$em->clear(); $em->clear();
$output = $em->getRepository(Viewpoint::class)->find(2); $output = $em->getRepository(Viewpoint::class)->find("10000000-0000-0000-0000-000000000002");
$this->assertEquals($attachments, $output->getAttachments()); $this->assertEquals($attachments, $output->getAttachments());
$this->assertEquals('baz', $output->getAttachments()[0]->getFoo()); $this->assertEquals('baz', $output->getAttachments()[0]->getFoo());
$this->assertEquals('fiz', $output->getAttachments()[1]->getFoo()); $this->assertEquals('fiz', $output->getAttachments()[1]->getFoo());
@@ -140,9 +140,9 @@ class ViewpointTest extends CoreModelTestCase
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$a1 = new Action(1); $a1 = new Action("30000000-0000-0000-0000-000000000001");
$a2 = new Action(2); $a2 = new Action("30000000-0000-0000-0000-000000000002");
$a3 = new Action(3); $a3 = new Action("30000000-0000-0000-0000-000000000003");
$ag1 = new ActionGroup('id1', 'title1', 42); $ag1 = new ActionGroup('id1', 'title1', 42);
$ag1->setActions([ $ag1->setActions([
@@ -152,7 +152,7 @@ class ViewpointTest extends CoreModelTestCase
]); ]);
$ag2 = new ActionGroup('id2', 'title2', 101); $ag2 = new ActionGroup('id2', 'title2', 101);
$ag2->setActions([ $ag2->setActions([
new Action(4) new Action("30000000-0000-0000-0000-000000000004")
]); ]);
$actionGroups = [ $actionGroups = [
@@ -160,16 +160,16 @@ class ViewpointTest extends CoreModelTestCase
$ag2 $ag2
]; ];
$input = $em->getRepository(Viewpoint::class)->find(2); $input = $em->getRepository(Viewpoint::class)->find("10000000-0000-0000-0000-000000000002");
$input->setActionGroups($actionGroups); $input->setActionGroups($actionGroups);
$input->save($em); $input->save($em);
$em->clear(); $em->clear();
$output = $em->getRepository(Viewpoint::class)->find(2); $output = $em->getRepository(Viewpoint::class)->find("10000000-0000-0000-0000-000000000002");
// Not finding the scene ID should change nothing. // Not finding the scene ID should change nothing.
$output->removeActionsWithSceneId(1000); $output->removeActionsWithSceneId("30000000-0000-0000-0000-000000001000");
$this->assertEquals($actionGroups, $output->getActionGroups()); $this->assertEquals($actionGroups, $output->getActionGroups());
$ag1_output = new ActionGroup('id1', 'title1', 42); $ag1_output = new ActionGroup('id1', 'title1', 42);
@@ -182,7 +182,95 @@ class ViewpointTest extends CoreModelTestCase
$ag1_output, $ag1_output,
$ag2 $ag2
]; ];
$output->removeActionsWithSceneId(2); $output->removeActionsWithSceneId("30000000-0000-0000-0000-000000000002");
$this->assertEquals($actionGroupsWithout2, $output->getActionGroups()); $this->assertEquals($actionGroupsWithout2, $output->getActionGroups());
} }
public function testChangingSceneDescription()
{
$em = $this->getEntityManager();
$testCharacter = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$characterScene = $testCharacter->getViewpoint();
$this->assertSame("This is the village.", $characterScene->getDescription());
$characterScene->addDescriptionParagraph("You enjoy being here.");
$this->assertSame("This is the village.\n\nYou enjoy being here.", $characterScene->getDescription());
}
public function testClearingSceneDescription()
{
$em = $this->getEntityManager();
$testCharacter = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$characterScene = $testCharacter->getViewpoint();
$characterScene->clearDescription();
$this->assertSame("", $characterScene->getDescription());
$characterScene->addDescriptionParagraph("You enjoy being here.");
$this->assertSame("You enjoy being here.", $characterScene->getDescription());
}
public function testIfGetActionGroupByIdReturnsTheCorrectActionGroupOrNull()
{
$em = $this->getEntityManager();
$a1 = new Action("30000000-0000-0000-0000-000000000001");
$a2 = new Action("30000000-0000-0000-0000-000000000002");
$a3 = new Action("30000000-0000-0000-0000-000000000003");
$ag1 = new ActionGroup('id1', 'title1', 42);
$ag1->setActions([
$a1,
$a2,
$a3
]);
$ag2 = new ActionGroup('id2', 'title2', 101);
$ag2->setActions([
new Action("30000000-0000-0000-0000-000000000004")
]);
$actionGroups = [
$ag1,
$ag2
];
$input = $em->getRepository(Viewpoint::class)->find("10000000-0000-0000-0000-000000000002");
$input->setActionGroups($actionGroups);
$input->save($em);
$em->clear();
/** @var Viewpoint $viewpoint */
$viewpoint = $em->getRepository(Viewpoint::class)->find("10000000-0000-0000-0000-000000000002");
$actionGroupId1 = $viewpoint->findActionGroupById("id1");
$actionGroupId2 = $viewpoint->findActionGroupById("id2");
$actionGroupId3 = $viewpoint->findActionGroupById("id3");
$this->assertInstanceOf(ActionGroup::class, $actionGroupId1);
$this->assertInstanceOf(ActionGroup::class, $actionGroupId2);
$this->assertNull($actionGroupId3);
$actions = $actionGroupId1->getActions();
foreach ($actions as $action) {
$this->assertSame($action, $viewpoint->findActionById($action->getId()));
}
$this->assertNull($viewpoint->findActionById("anId"));
}
public function testIfViewpointCanGetRemovedAndDeleted()
{
$em = $this->getEntityManager();
$testCharacter = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000002");
$this->getEntityManager()->remove($testCharacter->getViewpoint());
$testCharacter->setViewpoint(null);
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
$viewpoint = $em->getRepository(Viewpoint::class)->findOneBy(["owner" => "10000000-0000-0000-0000-000000000002"]);
$this->assertNull($viewpoint, "Viewpoint is not null");
}
} }
+63 -5
View File
@@ -13,6 +13,7 @@ use LotGD\Core\EventHandler;
use LotGD\Core\EventManager; use LotGD\Core\EventManager;
use LotGD\Core\EventSubscription; use LotGD\Core\EventSubscription;
use LotGD\Core\LibraryConfiguration; use LotGD\Core\LibraryConfiguration;
use LotGD\Core\Models\Character;
use LotGD\Core\ModuleManager; use LotGD\Core\ModuleManager;
use LotGD\Core\Module; use LotGD\Core\Module;
use LotGD\Core\Exceptions\ModuleAlreadyExistsException; use LotGD\Core\Exceptions\ModuleAlreadyExistsException;
@@ -201,11 +202,53 @@ class ModuleManagerTest extends CoreModelTestCase
$this->assertEquals($name, $modules[1]->getLibrary()); $this->assertEquals($name, $modules[1]->getLibrary());
} }
public function testRegisterWithFailedEvents()
{
$class = FakeModule::class;
$name = 'lotgd/tests2';
$subscriptions = array(
'/pattern1/',
'#asasd/',
);
$library = $this->getMockBuilder(LibraryConfiguration::class)
->disableOriginalConstructor()
->getMock();
$library->method('getName')->willReturn($name);
$library->method('getRootNamespace')->willReturn('LotGD\\Core\\Tests\\FakeModule\\');
$library->method('getSubscriptionPatterns')->willReturn($subscriptions);
$eventManager = new EventManager($this->g);
$this->game->method('getEventManager')->willReturn($eventManager);
$eventsBefore = count($eventManager->getSubscriptions());
$subscriptionThrownException = false;
try {
$this->mm->register($library);
} catch(\Throwable $e) {
$subscriptionThrownException = true;
}
$this->assertTrue($subscriptionThrownException);
// Assert module has not been installed.
$modules = $this->mm->getModules();
$this->assertArrayNotHasKey(1, $modules);
// Assert events are not registered
$eventsAfter = count($eventManager->getSubscriptions());
// Randomly flush
$this->getEntityManager()->flush();
$this->assertSame($eventsBefore, $eventsAfter, "Events after failed subscription are actually more.");
}
public function testRegisteringDefectiveModule() public function testRegisteringDefectiveModule()
{ {
$class = DefectiveModule::class; $class = DefectiveModule::class;
$name = "lotgd/tests3"; $name = "lotgd/tests3";
$subscriptions = []; $subscriptions = ["#e/lotgd/core/tests/dat-event#"];
$library = $this->getMockBuilder(LibraryConfiguration::class) $library = $this->getMockBuilder(LibraryConfiguration::class)
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
@@ -213,11 +256,12 @@ class ModuleManagerTest extends CoreModelTestCase
$library->method('getRootNamespace')->willReturn('LotGD\\Core\\Tests\\DefectiveModule\\'); $library->method('getRootNamespace')->willReturn('LotGD\\Core\\Tests\\DefectiveModule\\');
$library->method('getSubscriptionPatterns')->willReturn($subscriptions); $library->method('getSubscriptionPatterns')->willReturn($subscriptions);
$eventManager = $this->getMockBuilder(EventManager::class) // Defective Module adds a character. Count the characters before.
->disableOriginalConstructor() $charactersBefore = count($this->getEntityManager()->getRepository(Character::class)->findAll());
->getMock();
$eventManager = new EventManager($this->g);
$this->game->method('getEventManager')->willReturn($eventManager); $this->game->method('getEventManager')->willReturn($eventManager);
$modulesBefore = $this->mm->getModules(); $modulesBefore = $this->mm->getModules();
try { try {
// onRegister throws an exception. This exception needs to be captured and handled by mm->register without actually // onRegister throws an exception. This exception needs to be captured and handled by mm->register without actually
@@ -229,7 +273,21 @@ class ModuleManagerTest extends CoreModelTestCase
} }
$modulesAfter = $this->mm->getModules(); $modulesAfter = $this->mm->getModules();
$this->assertFalse($exceptionCaptured); $this->assertTrue($exceptionCaptured);
$this->assertCount(count($modulesBefore), $modulesAfter); $this->assertCount(count($modulesBefore), $modulesAfter);
// Make sure there are no event leftovers.
$subscriptions_db = $eventManager->getSubscriptions();
$found = 0;
foreach($subscriptions_db as $subscription) {
if (in_array($subscription->getPattern(), $subscriptions)) {
$found++;
}
}
$this->assertSame(0, $found);
// Count characters. Must stay the same!
$charactersAfter = count($this->getEntityManager()->getRepository(Character::class)->findAll());
$this->assertSame($charactersBefore, $charactersAfter, "Modules flushed did not get not added to the database.");
} }
} }
+118 -118
View File
@@ -11,80 +11,80 @@ use LotGD\Core\TimeKeeper;
* @backupStaticAttributes disabled * @backupStaticAttributes disabled
*/ */
class TimeKeeperTests extends \PHPUnit_Framework_TestCase { class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
private $gameEpoch; private $gameEpoch;
private $gameOffsetSeconds; private $gameOffsetSeconds;
private $gameDaysPerDay; private $gameDaysPerDay;
public function setUp() { public function setUp() {
$this->gameEpoch = new \DateTime('2015-07-27 00:00:00 PDT');; $this->gameEpoch = new \DateTime('2015-07-27 00:00:00 PDT');;
$this->gameOffsetSeconds = 0; $this->gameOffsetSeconds = 0;
$this->gameDaysPerDay = 2; $this->gameDaysPerDay = 2;
} }
public function testConvertToBasicConversion() { public function testConvertToBasicConversion() {
$this->gameDaysPerDay = 1; $this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$date = new \DateTime('2015-07-27 23:59:59 PDT'); $date = new \DateTime('2015-07-27 23:59:59 PDT');
$converted = $keeper->convertToGameTime($date); $converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01 23:59:59', $converted->format('Y-m-d H:i:s')); $this->assertEquals('0000-01-01 23:59:59', $converted->format('Y-m-d H:i:s'));
$date = new \DateTime('2015-07-27 12:00:00 PDT'); $date = new \DateTime('2015-07-27 12:00:00 PDT');
$converted = $keeper->convertToGameTime($date); $converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01 12:00:00', $converted->format('Y-m-d H:i:s')); $this->assertEquals('0000-01-01 12:00:00', $converted->format('Y-m-d H:i:s'));
} }
public function testConvertToRespectsGameDaysPerDayUpperBound() { public function testConvertToRespectsGameDaysPerDayUpperBound() {
$date = new \DateTime('2015-07-27 05:59:59 PDT'); $date = new \DateTime('2015-07-27 05:59:59 PDT');
$this->gameDaysPerDay = 4; $this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date); $converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01', $converted->format('Y-m-d')); $this->assertEquals('0000-01-01', $converted->format('Y-m-d'));
} }
public function testConvertToRespectsGameDaysPerDayNextDay() { public function testConvertToRespectsGameDaysPerDayNextDay() {
$date = new \DateTime('2015-07-27 06:00:00 PDT'); $date = new \DateTime('2015-07-27 06:00:00 PDT');
$this->gameDaysPerDay = 4; $this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date); $converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d')); $this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
} }
public function testConvertToRespectsGameDaysPerDayNextDayUpperBound() { public function testConvertToRespectsGameDaysPerDayNextDayUpperBound() {
$date = new \DateTime('2015-07-27 11:59:59 PDT'); $date = new \DateTime('2015-07-27 11:59:59 PDT');
$this->gameDaysPerDay = 4; $this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date); $converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d')); $this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
} }
public function testIfIsNewDayReturnsTrueWithNullAsLastInteractionTime() { public function testIfIsNewDayReturnsTrueWithNullAsLastInteractionTime() {
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, 4); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, 4);
$this->assertTrue($keeper->isNewDay(null)); $this->assertTrue($keeper->isNewDay(null));
} }
public function testIfIsNewDayReturnsFalseIfLastInteractionTimeWasJustRecently() public function testIfIsNewDayReturnsFalseIfLastInteractionTimeWasJustRecently()
{ {
// game days per day: 4, each day 6h. // game days per day: 4, each day 6h.
$keeper = new TimeKeeper($this->gameEpoch, new DateTime("2017-01-02 11:59:59"), 3600*5, 4); $keeper = new TimeKeeper($this->gameEpoch, new DateTime("2017-01-02 11:59:59"), 3600*5, 4);
$time1 = new \DateTime("2017-01-02 06:00:00"); $time1 = new \DateTime("2017-01-02 06:00:00");
$time2 = new \DateTime("2017-01-02 11:59:59"); $time2 = new \DateTime("2017-01-02 11:59:59");
$time3 = new \DateTime("2017-01-02 09:00:00"); $time3 = new \DateTime("2017-01-02 09:00:00");
$time4 = new \DateTime("2017-01-02 09:59:30"); $time4 = new \DateTime("2017-01-02 09:59:30");
$this->assertFalse($keeper->isNewDay($time1)); $this->assertFalse($keeper->isNewDay($time1));
$this->assertFalse($keeper->isNewDay($time2)); $this->assertFalse($keeper->isNewDay($time2));
$this->assertFalse($keeper->isNewDay($time3)); $this->assertFalse($keeper->isNewDay($time3));
$this->assertFalse($keeper->isNewDay($time4)); $this->assertFalse($keeper->isNewDay($time4));
} }
public function testIfIsNewDayReturnsFalseIfLastInteractionTimeWasOnLastGameDay() public function testIfIsNewDayReturnsFalseIfLastInteractionTimeWasOnLastGameDay()
{ {
@@ -103,87 +103,87 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
$this->assertTrue($keeper->isNewDay($time4)); $this->assertTrue($keeper->isNewDay($time4));
} }
public function testConvertToRespectsGameOffset() { public function testConvertToRespectsGameOffset() {
$date = new \DateTime('2015-07-27 01:01:15 PDT'); $date = new \DateTime('2015-07-27 01:01:15 PDT');
$this->gameOffsetSeconds = 60*60; $this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1; $this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date); $converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01 00:01:15', $converted->format('Y-m-d H:i:s')); $this->assertEquals('0000-01-01 00:01:15', $converted->format('Y-m-d H:i:s'));
} }
public function testConvertToRespectsGameOffsetUpperBound() { public function testConvertToRespectsGameOffsetUpperBound() {
$date = new \DateTime('2015-07-28 00:59:59 PDT'); $date = new \DateTime('2015-07-28 00:59:59 PDT');
$this->gameOffsetSeconds = 60*60; $this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1; $this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date); $converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01 23:59:59', $converted->format('Y-m-d H:i:s')); $this->assertEquals('0000-01-01 23:59:59', $converted->format('Y-m-d H:i:s'));
} }
public function testConvertToRespectsGameOffsetNextDay() { public function testConvertToRespectsGameOffsetNextDay() {
$date = new \DateTime('2015-07-28 01:00:00 PDT'); $date = new \DateTime('2015-07-28 01:00:00 PDT');
$this->gameOffsetSeconds = 60*60; $this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1; $this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date); $converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d')); $this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
} }
public function testConvertToRespectsGameOffsetNextDayUpperBound() { public function testConvertToRespectsGameOffsetNextDayUpperBound() {
$date = new \DateTime('2015-07-29 00:59:59 PDT'); $date = new \DateTime('2015-07-29 00:59:59 PDT');
$this->gameOffsetSeconds = 60*60; $this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1; $this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date); $converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d')); $this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
} }
public function testConvertFromBasicConversion() { public function testConvertFromBasicConversion() {
$date = new \DateTime('0000-01-02 00:00:00 UTC'); $date = new \DateTime('0000-01-02 00:00:00 UTC');
$this->gameDaysPerDay = 1; $this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertFromGameTime($date); $converted = $keeper->convertFromGameTime($date);
$this->assertEquals("2015-07-28", $converted->format('Y-m-d')); $this->assertEquals("2015-07-28", $converted->format('Y-m-d'));
} }
public function testConvertFromRespectsGameOffsetNextDay() { public function testConvertFromRespectsGameOffsetNextDay() {
$epoch = new \DateTime('2015-07-27 00:00:00 PDT'); $epoch = new \DateTime('2015-07-27 00:00:00 PDT');
$date = new \DateTime('0000-01-02 23:59:59 UTC'); $date = new \DateTime('0000-01-02 23:59:59 UTC');
$this->gameEpoch = $epoch; $this->gameEpoch = $epoch;
$this->gameOffsetSeconds = 60*60; $this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1; $this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertFromGameTime($date); $converted = $keeper->convertFromGameTime($date);
$this->assertEquals("2015-07-29 00:59:59", $converted->format('Y-m-d H:i:s')); $this->assertEquals("2015-07-29 00:59:59", $converted->format('Y-m-d H:i:s'));
} }
public function testConvertFromRespectsGameDaysPerDayNextDay() { public function testConvertFromRespectsGameDaysPerDayNextDay() {
$epoch = new \DateTime('2015-07-27 00:00:00 PDT'); $epoch = new \DateTime('2015-07-27 00:00:00 PDT');
$date = new \DateTime('0000-01-02 23:59:59 UTC'); $date = new \DateTime('0000-01-02 23:59:59 UTC');
$this->gameEpoch = $epoch; $this->gameEpoch = $epoch;
$this->gameDaysPerDay = 4; $this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertFromGameTime($date); $converted = $keeper->convertFromGameTime($date);
$this->assertEquals("2015-07-27 11:59:59", $converted->format('Y-m-d H:i:s')); $this->assertEquals("2015-07-27 11:59:59", $converted->format('Y-m-d H:i:s'));
} }
public function testGameTimeSanity() { public function testGameTimeSanity() {
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay); $keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$this->assertNotNull($keeper->getGameTime()); $this->assertNotNull($keeper->getGameTime());
} }
} }
+13 -13
View File
@@ -1,48 +1,48 @@
characters: characters:
- -
id: 1 id: "d363c077-234a-433d-834e-f1a1d3b281d8"
name: "Player" name: "Player"
displayName: "The Player" displayName: "The Player"
health: 100 health: 100
maxhealth: 100 maxhealth: 100
level: 10 level: 10
- -
id: 2 id: "4d01c29b-d825-4bc7-9e6e-63525155fd37"
name: "High Level Char" name: "High Level Char"
displayName: "High Level Char" displayName: "High Level Char"
health: 1000 health: 1000
maxhealth: 1000 maxhealth: 1000
level: 100 level: 100
- -
id: 3 id: "c3792b61-4e34-4710-9871-65a68ac30bb4"
name: "Low Level Char" name: "Low Level Char"
displayName: "Low Level Char" displayName: "Low Level Char"
health: 10 health: 10
maxhealth: 10 maxhealth: 10
level: 1 level: 1
- -
id: 4 id: "6565b418-55f5-4a6b-8d92-a9ef81329912"
name: "Low Damage Char" name: "Low Damage Char"
displayName: "Low Damage Char" displayName: "Low Damage Char"
health: 500 health: 500
maxhealth: 500 maxhealth: 500
level: 0 level: 0
- -
id: 10 id: "539e4bb0-84d1-49ed-a697-ff449991e9b7"
name: "Level 10 Character" name: "Level 10 Character"
displayName: "Level 10 Character" displayName: "Level 10 Character"
health: 100 health: 100
maxhealth: 100 maxhealth: 100
level: 10 level: 10
- -
id: 11 id: "24d71c26-f915-401c-8b3e-1932edf650ce"
name: "Level 11 Character" name: "Level 11 Character"
displayName: "Level 11 Character" displayName: "Level 11 Character"
health: 110 health: 110
maxhealth: 110 maxhealth: 110
level: 11 level: 11
- -
id: 13 id: "1a9f63f2-3006-4e12-b272-4fd6be518a93"
name: "Level 13 Character" name: "Level 13 Character"
displayName: "Level 13 Character" displayName: "Level 13 Character"
health: 130 health: 130
@@ -50,26 +50,26 @@ characters:
level: 13 level: 13
monsters: monsters:
- -
id: 1 id: "de84c507-9673-44e7-b665-9e43416b9c2f"
name: "Evil Monster" name: "Evil Monster"
level: 5 level: 5
- -
id: 2 id: "b636df29-f72d-4e2d-9850-982e783a9e94"
name: "High Dragon" name: "High Dragon"
level: 100 level: 100
- -
id: 3 id: "c004bcb6-a7c1-4f9a-abc2-1711c64e23a0"
name: "Stone" name: "Stone"
level: 1 level: 1
- -
id: 10 id: "f1d1f672-e308-420e-939f-cbb39285b222"
name: "Level 10 Monster" name: "Level 10 Monster"
level: 10 level: 10
- -
id: 11 id: "7ca9c141-aaf8-44a5-9d04-b6f9923f3c66"
name: "Level 11 Monster" name: "Level 11 Monster"
level: 11 level: 11
- -
id: 13 id: "09540b93-63c9-4d82-8501-f569f63dfc4c"
name: "Level 13 Monster" name: "Level 13 Monster"
level: 13 level: 13
+4 -4
View File
@@ -1,18 +1,18 @@
characters: characters:
- -
id: 1 id: "10000000-0000-0000-0000-000000000001"
name: "Testcharacter 1" name: "Testcharacter 1"
displayName: "Testcharacter 1" displayName: "Testcharacter 1"
health: 0 health: 0
maxhealth: 100 maxhealth: 100
- -
id: 2 id: "10000000-0000-0000-0000-000000000002"
name: "Testcharacter 2" name: "Testcharacter 2"
displayName: "Testcharacter 2" displayName: "Testcharacter 2"
health: 90 health: 90
maxhealth: 90 maxhealth: 90
- -
id: 3 id: "10000000-0000-0000-0000-000000000003"
name: "Testcharacter 3" name: "Testcharacter 3"
displayName: "Testcharacter 3 (deleted)" displayName: "Testcharacter 3 (deleted)"
health: 90 health: 90
@@ -20,6 +20,6 @@ characters:
deletedAt: "2011-11-11 11:11:11" deletedAt: "2011-11-11 11:11:11"
character_properties: character_properties:
- -
owner_id: 1 owner_id: "10000000-0000-0000-0000-000000000001"
propertyName: "test" propertyName: "test"
propertyValue: 's:5:"hallo";' propertyValue: 's:5:"hallo";'
+15
View File
@@ -0,0 +1,15 @@
characters:
-
id: "10000000-0000-0000-0000-000000000001"
name: "Testcharacter 1"
displayName: "Testcharacter 1"
level: 1
health: 13
maxhealth: 100
-
id: "10000000-0000-0000-0000-000000000002"
name: "Testcharacter 2"
displayName: "Testcharacter 2"
level: 2
health: 90
maxhealth: 90
+25 -25
View File
@@ -1,19 +1,19 @@
characters: characters:
- -
id: 1 id: "10000000-0000-0000-0000-000000000001"
name: "Char without a Scene" name: "Char without a Scene"
displayName: "A" displayName: "A"
- -
id: 2 id: "10000000-0000-0000-0000-000000000002"
name: "Char with a Scene" name: "Char with a Scene"
displayName: "B" displayName: "B"
- -
id: 3 id: "10000000-0000-0000-0000-000000000003"
name: "Char without a Scene" name: "Char without a Scene"
displayName: "C" displayName: "C"
viewpoints: viewpoints:
- -
owner_id: 2 owner_id: "10000000-0000-0000-0000-000000000002"
title: "The Village" title: "The Village"
description: "This is the village." description: "This is the village."
template: "lotgd/tests/village" template: "lotgd/tests/village"
@@ -22,74 +22,74 @@ viewpoints:
actionGroups: "a:0:{}" actionGroups: "a:0:{}"
scenes: scenes:
- -
id: 1 id: "30000000-0000-0000-0000-000000000001"
title: "The Village" title: "The Village"
description: "This is the village." description: "This is the village."
template: "lotgd/tests/village" template: "lotgd/tests/village"
- -
id: 2 id: "30000000-0000-0000-0000-000000000002"
title: "The Forest" title: "The Forest"
description: "This is a very dangerous and dark forest" description: "This is a very dangerous and dark forest"
template: "lotgd/tests/forest" template: "lotgd/tests/forest"
- -
id: 3 id: "30000000-0000-0000-0000-000000000003"
title: "The Weaponry" title: "The Weaponry"
description: "This is the place where you can buy awesome weapons" description: "This is the place where you can buy awesome weapons"
template: "lotgd/tests/weaponry" template: "lotgd/tests/weaponry"
- -
id: 4 id: "30000000-0000-0000-0000-000000000004"
title: "Parent Scene" title: "Parent Scene"
description: "This is a parent scene that connects to two children." description: "This is a parent scene that connects to two children."
template: "lotgd/tests/none" template: "lotgd/tests/none"
- -
id: 5 id: "30000000-0000-0000-0000-000000000005"
title: "Child Scene 1" title: "Child Scene 1"
description: "This is a parent scene that connects to two children." description: "This is a parent scene that connects to two children."
template: "lotgd/tests/none" template: "lotgd/tests/none"
- -
id: 6 id: "30000000-0000-0000-0000-000000000006"
title: "Child Scene 2" title: "Child Scene 2"
description: "This is a parent scene that connects to two children." description: "This is a parent scene that connects to two children."
template: "lotgd/tests/none" template: "lotgd/tests/none"
- -
id: 7 id: "30000000-0000-0000-0000-000000000007"
title: "Parameter test" title: "Parameter test"
description: "This is a parameter test" description: "This is a parameter test"
template: "lotgd/tests/paramaters" template: "lotgd/tests/paramaters"
scene_connection_groups: scene_connection_groups:
- -
scene: 4 scene: "30000000-0000-0000-0000-000000000004"
name: "lotgd/tests/none/child1" name: "lotgd/tests/none/child1"
title: "Child 1" title: "Child 1"
- -
scene: 4 scene: "30000000-0000-0000-0000-000000000004"
name: "lotgd/tests/none/child2" name: "lotgd/tests/none/child2"
title: "Child 2" title: "Child 2"
scene_connections: scene_connections:
- -
outgoingScene: 1 outgoingScene: "30000000-0000-0000-0000-000000000001"
incomingScene: 2 incomingScene: "30000000-0000-0000-0000-000000000002"
directionality: 0 directionality: 0
- -
outgoingScene: 1 outgoingScene: "30000000-0000-0000-0000-000000000001"
incomingScene: 3 incomingScene: "30000000-0000-0000-0000-000000000003"
directionality: 0 directionality: 0
- -
outgoingScene: 1 outgoingScene: "30000000-0000-0000-0000-000000000001"
incomingScene: 4 incomingScene: "30000000-0000-0000-0000-000000000004"
directionality: 0 directionality: 0
- -
outgoingScene: 4 outgoingScene: "30000000-0000-0000-0000-000000000004"
incomingScene: 5 incomingScene: "30000000-0000-0000-0000-000000000005"
outgoingConnectionGroupName: "lotgd/tests/none/child1" outgoingConnectionGroupName: "lotgd/tests/none/child1"
directionality: 0 directionality: 0
- -
outgoingScene: 4 outgoingScene: "30000000-0000-0000-0000-000000000004"
incomingScene: 6 incomingScene: "30000000-0000-0000-0000-000000000006"
outgoingConnectionGroupName: "lotgd/tests/none/child2" outgoingConnectionGroupName: "lotgd/tests/none/child2"
directionality: 0 directionality: 0
- -
outgoingScene: 5 outgoingScene: "30000000-0000-0000-0000-000000000005"
incomingScene: 6 incomingScene: "30000000-0000-0000-0000-000000000006"
directionality: 1 directionality: 1

Some files were not shown because too many files have changed in this diff Show More