Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25341a677d | |||
| ccfb432e4d | |||
| 2a0bf5f038 | |||
| 4248dad033 | |||
| b89f6d7b0c | |||
| 6c4b1e15f4 | |||
| ddb7ae08a6 | |||
| 8ba04dade4 | |||
| 70243f4662 | |||
| 77b33d7385 | |||
| db49e63c99 | |||
| d90e4d0ba9 | |||
| ccbfa0553c | |||
| 04a5b59ea2 | |||
| 846ab6018e | |||
| efb333d08a | |||
| 92c0f71ed6 | |||
| c9e6f679c4 | |||
| 17ebdbdbe5 | |||
| 55b821c8e8 | |||
| 45a785a8f5 | |||
| ff713ac333 | |||
| aba0d53a68 | |||
| 9ddd16b4e8 | |||
| c0edd3ac67 | |||
| 81d773720a | |||
| 5ac7098f35 | |||
| 41db0ddfda | |||
| 003a6517ba | |||
| af6a6cbff0 | |||
| 56c80e3f8d | |||
| 4b82ee4b89 | |||
| 829d63d7f6 | |||
| 94763f8d6e | |||
| a287313f6f | |||
| 51a102f981 | |||
| 9842fa9ace | |||
| adf4eeac5e | |||
| 533378d006 |
@@ -2,6 +2,7 @@ sudo: false
|
||||
language: php
|
||||
php:
|
||||
- '7.1'
|
||||
- '7.2'
|
||||
install:
|
||||
- composer install
|
||||
script:
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@
|
||||
"name": "lotgd/core",
|
||||
"description": "Core functionality for Legend of the Green Dragon, a text-based RPG game.",
|
||||
"license": "AGPL-3.0",
|
||||
"version": "0.4.1",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LotGD\\Core\\": "src/",
|
||||
@@ -15,7 +16,7 @@
|
||||
"php": "^7.1.0",
|
||||
"composer/composer": "*",
|
||||
"gedmo/doctrine-extensions": "*",
|
||||
"doctrine/orm": "^2.5",
|
||||
"doctrine/orm": "2.5.*",
|
||||
"monolog/monolog": "^1.12",
|
||||
"symfony/console": "^3.0",
|
||||
"symfony/yaml": "^3.0",
|
||||
|
||||
Generated
+268
-253
File diff suppressed because it is too large
Load Diff
+10
-1
@@ -6,7 +6,7 @@ namespace LotGD\Core;
|
||||
/**
|
||||
* A grouping of navigation actions, like a submenu.
|
||||
*/
|
||||
class ActionGroup
|
||||
class ActionGroup implements \Countable
|
||||
{
|
||||
const DefaultGroup = 'lotgd/core/default';
|
||||
const HiddenGroup = 'lotgd/core/hidden';
|
||||
@@ -30,6 +30,15 @@ class ActionGroup
|
||||
$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.
|
||||
* @return string
|
||||
|
||||
+38
-19
@@ -16,11 +16,7 @@ use LotGD\Core\{
|
||||
Models\FighterInterface
|
||||
};
|
||||
use LotGD\Core\Models\{
|
||||
Buff,
|
||||
BattleEvents\BuffMessageEvent,
|
||||
BattleEvents\CriticalHitEvent,
|
||||
BattleEvents\DamageEvent,
|
||||
BattleEvents\DeathEvent
|
||||
Buff, BattleEvents\BuffMessageEvent, BattleEvents\CriticalHitEvent, BattleEvents\DamageEvent, BattleEvents\DeathEvent, Scene
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -47,7 +43,7 @@ class Battle
|
||||
|
||||
/**
|
||||
* Battle Configuration
|
||||
* @var type
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration = [
|
||||
"riposteEnabled" => true,
|
||||
@@ -61,31 +57,50 @@ class Battle
|
||||
* @param FighterInterface $player
|
||||
* @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->player = $player;
|
||||
$this->monster = $monster;
|
||||
$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
|
||||
* @return \LotGD\Core\Collection
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEvents(): Collection
|
||||
{
|
||||
@@ -197,6 +212,7 @@ class Battle
|
||||
/**
|
||||
* Returns the winner of this fight
|
||||
* @return FighterInterface
|
||||
* @throws BattleNotOverException if battle is not over.
|
||||
*/
|
||||
public function getWinner(): FighterInterface
|
||||
{
|
||||
@@ -210,6 +226,7 @@ class Battle
|
||||
/**
|
||||
* Returns the loser of this fight
|
||||
* @return FighterInterface
|
||||
* @throws BattleNotOverException if battle is not over.
|
||||
*/
|
||||
public function getLoser(): FighterInterface
|
||||
{
|
||||
@@ -226,6 +243,8 @@ class Battle
|
||||
* @param int $n
|
||||
* @param bool $firstDamageRound Which damage rounds are calculated. Cannot be 0.
|
||||
* @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
|
||||
{
|
||||
@@ -346,12 +365,12 @@ class Battle
|
||||
|
||||
// Apply buff scaling for the attacker's attack - this needs to take into
|
||||
// account the attacker's goodguyAttackModifier and the defenders badguyAttackModifier
|
||||
$attackersAttack = $attacker->getAttack($this->game)
|
||||
$attackersAttack = $attacker->getAttack()
|
||||
* $attackersBuffs->getGoodguyAttackModifier()
|
||||
* $defendersBuffs->getBadguyAttackModifier();
|
||||
// It's the opposite for the defender's defense - it needs to take into account the
|
||||
// defender's goodguyDefenseModifier as well as the attacker's badguyDefenseModifier.
|
||||
$defendersDefense = $defender->getDefense($this->game)
|
||||
$defendersDefense = $defender->getDefense()
|
||||
* $defendersBuffs->getGoodguyDefenseModifier()
|
||||
* $attackersBuffs->getBadguyDefenseModifier()
|
||||
* $defenseAdjustement;
|
||||
@@ -369,13 +388,13 @@ class Battle
|
||||
$defendersDefense = (int) round($defendersDefense, 0);
|
||||
|
||||
// Lets roll the
|
||||
$attackersAtkRoll = $this->game->getDiceBag()->normal(0, $attackersAttack);
|
||||
$defendersDefRoll = $this->game->getDiceBag()->normal(0, $defendersDefense);
|
||||
$attackersAtkRoll = $this->game->getDiceBag()->pseudoBell(0, $attackersAttack);
|
||||
$defendersDefRoll = $this->game->getDiceBag()->pseudoBell(0, $defendersDefense);
|
||||
$damage = $attackersAtkRoll - $defendersDefRoll;
|
||||
|
||||
// If the attacker's attack after modification is bigger than before,
|
||||
// we call it a critical hit and apply the CriticalHitEvent.
|
||||
if ($attackersAttack > $attacker->getAttack($this->game) && $this->isCriticalHitEnabled()) {
|
||||
if ($attackersAttack > $attacker->getAttack() && $this->isCriticalHitEnabled()) {
|
||||
$events->add(new CriticalHitEvent($attacker, $attackersAttack));
|
||||
}
|
||||
|
||||
|
||||
+33
-5
@@ -3,6 +3,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
use Doctrine\Common\EventManager as DoctrineEventManager;
|
||||
use Doctrine\Common\Util\Debug;
|
||||
use Doctrine\ORM\Events as DoctrineEvents;
|
||||
use Doctrine\ORM\ {
|
||||
EntityManager,
|
||||
EntityManagerInterface,
|
||||
@@ -17,10 +21,8 @@ use Monolog\ {
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
use LotGD\Core\ {
|
||||
ComposerManager,
|
||||
BootstrapInterface,
|
||||
Exceptions\InvalidConfigurationException
|
||||
use LotGD\Core\{
|
||||
ComposerManager, BootstrapInterface, Doctrine\EntityPostLoadEventListener, Exceptions\InvalidConfigurationException
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -30,7 +32,8 @@ class Bootstrap
|
||||
{
|
||||
private $logger;
|
||||
private $game;
|
||||
private $libraryConfigurationManager = [];
|
||||
/** @var LibraryConfigurationManager */
|
||||
private $libraryConfigurationManager;
|
||||
private $annotationDirectories = [];
|
||||
|
||||
/**
|
||||
@@ -71,6 +74,13 @@ class Bootstrap
|
||||
->withCwd($cwd)
|
||||
->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;
|
||||
}
|
||||
|
||||
@@ -199,4 +209,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
@@ -536,7 +536,7 @@ class BuffList
|
||||
if ($buff->getBadguyDamageReflection() !== 0.) {
|
||||
if ($damage > 0) {
|
||||
// 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) {
|
||||
$message = $buff->getNoEffectMessage();
|
||||
} else {
|
||||
|
||||
+25
-2
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types = 1);
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core;
|
||||
|
||||
@@ -12,6 +11,7 @@ class DiceBag
|
||||
/**
|
||||
* Returns true $p percent of the time, where $p is between 0 and 1.
|
||||
* @param float $p
|
||||
* @return bool True if you are lucky, False if not.
|
||||
*/
|
||||
public function chance(float $p): bool
|
||||
{
|
||||
@@ -24,16 +24,39 @@ class DiceBag
|
||||
* Generates a uniformly randomly number between $min and $max.
|
||||
* @param float $min
|
||||
* @param float $max
|
||||
* @return float random number between $min and $max
|
||||
*/
|
||||
public function uniform(float $min, float $max): float
|
||||
{
|
||||
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.
|
||||
* @param float $min
|
||||
* @param float $max
|
||||
* @return float normally distributed random number
|
||||
*/
|
||||
public function normal(float $min, float $max): float
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
];
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace LotGD\Core\Events;
|
||||
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.
|
||||
* @package LotGD\Core\Events
|
||||
@@ -25,9 +25,52 @@ class EventContextData
|
||||
*/
|
||||
public static function create(array $data): self
|
||||
{
|
||||
if (isset(static::$argumentConfig)) {
|
||||
static::checkConfiguration($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..
|
||||
* @see self::create
|
||||
@@ -133,4 +176,4 @@ class EventContextData
|
||||
"{$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]
|
||||
];
|
||||
}
|
||||
@@ -4,6 +4,7 @@ declare (strict_types=1);
|
||||
namespace LotGD\Core;
|
||||
|
||||
use DateTime;
|
||||
use Doctrine\Common\Util\Debug;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use LotGD\Core\Events\NavigateToSceneData;
|
||||
use LotGD\Core\Events\NewViewpointData;
|
||||
@@ -25,6 +26,7 @@ class Game
|
||||
private $eventManager;
|
||||
private $composerManager;
|
||||
private $moduleManager;
|
||||
private $messageManager;
|
||||
private $logger;
|
||||
private $configuration;
|
||||
private $character;
|
||||
@@ -32,6 +34,7 @@ class Game
|
||||
private $cwd;
|
||||
private $timeKeeper;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a game. You probably want to use Bootstrap to do this.
|
||||
* @param Configuration $configuration
|
||||
@@ -184,6 +187,24 @@ class Game
|
||||
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.
|
||||
* @return Character
|
||||
|
||||
@@ -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
@@ -27,6 +27,7 @@ class GameBuilder
|
||||
private $composerManagerClass;
|
||||
private $eventManagerClass;
|
||||
private $diceBagClass;
|
||||
private $messageManagerClass;
|
||||
|
||||
/**
|
||||
* Creates the game instance with the prepared parameters.
|
||||
@@ -62,7 +63,8 @@ class GameBuilder
|
||||
$diceBag = $this->diceBagClass ?? DiceBag::class;
|
||||
$game->setDiceBag(new $diceBag());
|
||||
|
||||
|
||||
$messageManager=$this->messageManagerClass ?? MessageManager::class;
|
||||
$game->setMessageManager(new $messageManager());
|
||||
return $game;
|
||||
}
|
||||
|
||||
@@ -110,6 +112,17 @@ class GameBuilder
|
||||
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.
|
||||
* @param string $moduleManagerFqcn
|
||||
|
||||
@@ -43,7 +43,7 @@ class LibraryConfiguration
|
||||
if ($basePackage && $basePackage->getName() === $package->getName()) {
|
||||
// Whatever the base package is in this repo is at $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.
|
||||
$installationManager = $composerManager->getComposer()->getInstallationManager();
|
||||
$path = $installationManager->getInstallPath($package);
|
||||
@@ -124,9 +124,9 @@ class LibraryConfiguration
|
||||
/**
|
||||
* Returns a subkey if it exists or null.
|
||||
* @param array $arguments
|
||||
* @return type
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getSubKeyIfItExists(array $arguments)
|
||||
public function getSubKeyIfItExists(array $arguments)
|
||||
{
|
||||
$parent = $this->rawConfig;
|
||||
|
||||
@@ -145,7 +145,7 @@ class LibraryConfiguration
|
||||
* Tries to iterate an array element given by the arguments
|
||||
* @param scalar $argument1,... array keys, by increasing depth
|
||||
*/
|
||||
protected function iterateKey(...$arguments)
|
||||
public function iterateKey(...$arguments)
|
||||
{
|
||||
$result = $this->getSubKeyIfItExists($arguments);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class LibraryConfigurationManager
|
||||
|
||||
/**
|
||||
* Return an array of the library configurations.
|
||||
* @return array<LibraryConfiguration>
|
||||
* @return LibraryConfiguration[]
|
||||
*/
|
||||
public function getConfigurations(): array {
|
||||
return $this->configurations;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,13 @@ use Doctrine\ORM\Mapping\MappedSuperclass;
|
||||
abstract class BasicEnemy implements FighterInterface
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
protected $id;
|
||||
/** @Column(type="string", length=50); */
|
||||
private $name;
|
||||
protected $name;
|
||||
/** @Column(type="integer"); */
|
||||
private $level;
|
||||
protected $level;
|
||||
/** @var int */
|
||||
private $health;
|
||||
protected $health;
|
||||
|
||||
/**
|
||||
* Returns the enemy's id
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Exceptions\BattleEventException;
|
||||
use LotGD\Core\Game;
|
||||
|
||||
/**
|
||||
* A representation of something that happened in battle.
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Exceptions\BattleEventException;
|
||||
use LotGD\Core\Game;
|
||||
|
||||
/**
|
||||
* A battle event representing a message generated by a buff.
|
||||
|
||||
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
@@ -31,7 +32,7 @@ class CriticalHitEvent extends BattleEvent
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
$pureAttackersAttack = $this->attacker->getAttack($game, true);
|
||||
$pureAttackersAttack = $this->attacker->getAttack(true);
|
||||
|
||||
if ($this->criticalAttackValue > $pureAttackersAttack * 4) {
|
||||
return "You execute a MEGA power move!!!";
|
||||
|
||||
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Exceptions\BattleEventException;
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
@@ -39,7 +40,7 @@ class MinionDamageEvent extends BattleEvent
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
parent::decorate();
|
||||
parent::decorate($game);
|
||||
|
||||
return str_replace(
|
||||
[
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
namespace LotGD\Core\Models\BattleEvents;
|
||||
|
||||
use LotGD\Core\Exceptions\BattleEventException;
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
@@ -44,7 +45,7 @@ class RegenerationBuffEvent extends BattleEvent
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
parent::decorate();
|
||||
parent::decorate($game);
|
||||
|
||||
if ($this->regeneration === 0) {
|
||||
return str_replace(
|
||||
|
||||
+42
-13
@@ -11,14 +11,11 @@ use Doctrine\ORM\Mapping\Entity;
|
||||
use Doctrine\ORM\Mapping\Table;
|
||||
|
||||
use LotGD\Core\{
|
||||
BuffList,
|
||||
Game
|
||||
BuffList, Events\CharacterEventData, Game, GameAwareInterface
|
||||
};
|
||||
use LotGD\Core\Tools\Exceptions\BuffSlotOccupiedException;
|
||||
use LotGD\Core\Exceptions\BuffSlotOccupiedException;
|
||||
use LotGD\Core\Tools\Model\{
|
||||
Creator,
|
||||
PropertyManager,
|
||||
SoftDeletable
|
||||
Creator, ExtendableModel, GameAware, PropertyManager, SoftDeletable
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -27,11 +24,13 @@ use LotGD\Core\Tools\Model\{
|
||||
* @Entity(repositoryClass="LotGD\Core\Models\Repositories\CharacterRepository")
|
||||
* @Table(name="characters")
|
||||
*/
|
||||
class Character implements CharacterInterface, CreateableInterface
|
||||
class Character implements CharacterInterface, CreateableInterface, GameAwareInterface, ExtendableModelInterface
|
||||
{
|
||||
use Creator;
|
||||
use SoftDeletable;
|
||||
use PropertyManager;
|
||||
use GameAware;
|
||||
use ExtendableModel;
|
||||
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
@@ -74,6 +73,8 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
"level",
|
||||
];
|
||||
|
||||
private $propertyClass = CharacterProperty::class;
|
||||
|
||||
/**
|
||||
* Creates a character at full health
|
||||
*/
|
||||
@@ -142,7 +143,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
/**
|
||||
* Sets the maximum health of a character to a given value. It also sets the
|
||||
* health if none has been set yet.
|
||||
* @param int $maxhealth
|
||||
* @param int $maxHealth
|
||||
*/
|
||||
public function setMaxHealth(int $maxHealth)
|
||||
{
|
||||
@@ -192,7 +193,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
/**
|
||||
* Heals the enemy
|
||||
* @param int $heal
|
||||
* @param type $overheal True if healing bigger than maxhealth is desired.
|
||||
* @param bool $overheal True if healing bigger than maxHealth is desired.
|
||||
*/
|
||||
public function heal(int $heal, bool $overheal = false)
|
||||
{
|
||||
@@ -223,18 +224,46 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
|
||||
/**
|
||||
* 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"
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Models;
|
||||
|
||||
|
||||
interface ExtendableModelInterface
|
||||
{
|
||||
public function __call($method, $arguments);
|
||||
}
|
||||
@@ -18,8 +18,8 @@ interface FighterInterface
|
||||
public function getMaxHealth(): int;
|
||||
public function getHealth(): int;
|
||||
public function isAlive(): bool;
|
||||
public function getAttack(Game $game, bool $ignoreBuffs = false): int;
|
||||
public function getDefense(Game $game, bool $ignoreBuffs = false): int;
|
||||
public function getAttack(bool $ignoreBuffs = false): int;
|
||||
public function getDefense(bool $ignoreBuffs = false): int;
|
||||
public function damage(int $damage);
|
||||
public function heal(int $heal);
|
||||
public function setHealth(int $amount);
|
||||
|
||||
@@ -18,10 +18,12 @@ class GameConfiguration
|
||||
|
||||
/** @var ArrayCollection */
|
||||
private $properties;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param EntityManagerInterface $em
|
||||
* @param EntityManagerInterface $entityManager
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entityManager)
|
||||
{
|
||||
@@ -42,7 +44,7 @@ class GameConfiguration
|
||||
/**
|
||||
* Sets and overwrites a configuration value saved by the name
|
||||
* @param string $configurationName
|
||||
* @param type $configurationValue
|
||||
* @param mixed $configurationValue
|
||||
*/
|
||||
public function set(string $configurationName, $configurationValue)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+7
-34
@@ -11,6 +11,7 @@ use Doctrine\ORM\Mapping\Table;
|
||||
|
||||
use LotGD\Core\Exceptions\InvalidModelException;
|
||||
use LotGD\Core\Exceptions\ArgumentException;
|
||||
use LotGD\Core\Exceptions\ParentAlreadySetException;
|
||||
use LotGD\Core\Tools\Model\Deletor;
|
||||
use LotGD\Core\Tools\Model\Saveable;
|
||||
|
||||
@@ -37,48 +38,20 @@ class Message
|
||||
/** @Column(type="boolean", nullable=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.
|
||||
*
|
||||
* This method has been made protected to prevent from accessing it directly. Use
|
||||
* the static methods self::send() and self::sendSystemMessage() instead.
|
||||
* @param \LotGD\Core\Models\Character $from
|
||||
* Use the Message Manager methods send() and sendSystemMessage() instead.
|
||||
* @param CharacterInterface $from
|
||||
* @param string $message
|
||||
* @param \LotGD\Core\Models\Thread $thread
|
||||
* @param MessageThread $thread
|
||||
* @param bool $systemMessage
|
||||
* @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->isDeleted() === true) {
|
||||
|
||||
@@ -36,10 +36,10 @@ class MessageThread implements SaveableInterface
|
||||
/**
|
||||
* Constructor. Sets the (unique) threadKey.
|
||||
* @param string $threadKey
|
||||
* @param type $participants
|
||||
* @param type $readonly
|
||||
* @param array $participants
|
||||
* @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->readonly = $readonly;
|
||||
|
||||
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Models;
|
||||
|
||||
use DateTime;
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
use Doctrine\ORM\Mapping\Table;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
@@ -33,13 +34,15 @@ class Module implements SaveableInterface
|
||||
/** @OneToMany(targetEntity="ModuleProperty", mappedBy="owner", cascade={"persist", "remove"}) */
|
||||
private $properties;
|
||||
|
||||
private $propertyClass = ModuleProperty::class;
|
||||
|
||||
/**
|
||||
* Construct a new module entry.
|
||||
*/
|
||||
public function __construct(string $library)
|
||||
{
|
||||
$this->properties = new ArrayCollection();
|
||||
$this->createdAt = new \DateTime();
|
||||
$this->createdAt = new DateTime();
|
||||
$this->library = $library;
|
||||
}
|
||||
|
||||
@@ -47,7 +50,7 @@ class Module implements SaveableInterface
|
||||
* Returns the time this module was added to the system.
|
||||
* @return DateTime
|
||||
*/
|
||||
public function getCreatedAt(): \DateTime
|
||||
public function getCreatedAt(): DateTime
|
||||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
+3
-3
@@ -67,7 +67,7 @@ class MotD implements CreateableInterface
|
||||
* 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
|
||||
* message or $this->getAppearentAuthor() to get the appearent author.
|
||||
* @return \LotGD\Core\Models\Character
|
||||
* @return CharacterInterface
|
||||
*/
|
||||
public function getAuthor(): CharacterInterface
|
||||
{
|
||||
@@ -76,7 +76,7 @@ class MotD implements CreateableInterface
|
||||
|
||||
/**
|
||||
* Returns the appearent author of this message.
|
||||
* @return \LotGD\Core\Models\CharacterInterface
|
||||
* @return CharacterInterface
|
||||
*/
|
||||
public function getApparantAuthor(): CharacterInterface
|
||||
{
|
||||
@@ -89,7 +89,7 @@ class MotD implements CreateableInterface
|
||||
|
||||
/**
|
||||
* Sets the author of this motd
|
||||
* @param \LotGD\Core\Models\Character $author
|
||||
* @param Character $author
|
||||
*/
|
||||
public function setAuthor(Character $author)
|
||||
{
|
||||
|
||||
@@ -46,6 +46,7 @@ class Permission implements CreateableInterface
|
||||
/**
|
||||
* Sets this entity's id if it's not set yet.
|
||||
* @param string $id
|
||||
* @throws ArgumentException
|
||||
*/
|
||||
public function setId(string $id)
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ class CharacterRepository extends EntityRepository
|
||||
/**
|
||||
* Find a character by ID.
|
||||
*/
|
||||
public function find($id, int $deletes = self::SKIP_SOFTDELETED)
|
||||
public function find($id, $lockMode = NULL, $lockVersion = NULL, int $deletes = self::SKIP_SOFTDELETED)
|
||||
{
|
||||
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
|
||||
$queryBuilder->select("c")
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace LotGD\Core\Models\Repositories;
|
||||
|
||||
use Doctrine\Common\Util\Debug;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
@@ -7,8 +7,11 @@ use Doctrine\ORM\Mapping\Entity;
|
||||
use Doctrine\ORM\Mapping\Table;
|
||||
|
||||
use LotGD\Core\Action;
|
||||
use LotGD\Core\ActionGroup;
|
||||
use LotGD\Core\Exceptions\ArgumentException;
|
||||
use LotGD\Core\Tools\Model\Creator;
|
||||
use LotGD\Core\Tools\Model\SceneBasics;
|
||||
use LotGD\Core\Tools\SceneDescription;
|
||||
|
||||
/**
|
||||
* A Viewpoint is the current Scene a character is experiencing with
|
||||
@@ -32,6 +35,9 @@ class Viewpoint implements CreateableInterface
|
||||
/** @ManyToOne(targetEntity="Scene") */
|
||||
private $scene;
|
||||
|
||||
/** @var SceneDescription */
|
||||
private $_description;
|
||||
|
||||
/** @var array */
|
||||
private static $fillable = [
|
||||
"owner"
|
||||
@@ -55,6 +61,48 @@ class Viewpoint implements CreateableInterface
|
||||
$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.
|
||||
* @param \LotGD\Core\Models\Scene $scene
|
||||
@@ -140,11 +188,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
|
||||
* @return ActionGroup|null
|
||||
*/
|
||||
public function findActionGroupById(string $actionGroupId)
|
||||
public function findActionGroupById(string $actionGroupId): ?ActionGroup
|
||||
{
|
||||
$groups = $this->getActionGroups();
|
||||
foreach ($groups as $g) {
|
||||
@@ -152,6 +227,7 @@ class Viewpoint implements CreateableInterface
|
||||
return $g;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -214,7 +290,7 @@ class Viewpoint implements CreateableInterface
|
||||
/**
|
||||
* Returns a single data field
|
||||
* @param string $fieldname Fieldname
|
||||
* @param type $default default value
|
||||
* @param mixed $default default value
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDataField(string $fieldname, $default = null)
|
||||
@@ -233,9 +309,10 @@ class Viewpoint implements CreateableInterface
|
||||
|
||||
/**
|
||||
* Returns the action that corresponds to the given ID, if present.
|
||||
* @param string $id
|
||||
* @return Action|null
|
||||
*/
|
||||
public function findActionById(string $id)
|
||||
public function findActionById(string $id): ?Action
|
||||
{
|
||||
foreach ($this->getActionGroups() as $group) {
|
||||
foreach ($group->getActions() as $a) {
|
||||
@@ -244,6 +321,7 @@ class Viewpoint implements CreateableInterface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,19 +28,21 @@ trait AutoScaleFighter
|
||||
|
||||
/**
|
||||
* Returns the attack value based on the fighter's level
|
||||
* @param bool $ignoreBuffs
|
||||
* @return int
|
||||
*/
|
||||
public function getAttack(Game $game, bool $ignoreBuffs = false): int
|
||||
public function getAttack(bool $ignoreBuffs = false): int
|
||||
{
|
||||
$level = $this->getLevel();
|
||||
return (int)$level * 2 - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the defense value based on the fighter's level
|
||||
* @param bool $ignoreBuffs
|
||||
* @return int
|
||||
*/
|
||||
public function getDefense(Game $game, bool $ignoreBuffs = false): int
|
||||
public function getDefense(bool $ignoreBuffs = false): int
|
||||
{
|
||||
$level = $this->getlevel();
|
||||
return (int)floor($level*1.45);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -71,12 +71,12 @@ trait MockCharacter
|
||||
throw new IsNullException();
|
||||
}
|
||||
|
||||
public function getAttack(Game $game, bool $ignoreBuffs = false): int
|
||||
public function getAttack(bool $ignoreBuffs = false): int
|
||||
{
|
||||
throw new IsNullException();
|
||||
}
|
||||
|
||||
public function getDefense(Game $game, bool $ignoreBuffs = false): int
|
||||
public function getDefense(bool $ignoreBuffs = false): int
|
||||
{
|
||||
throw new IsNullException();
|
||||
}
|
||||
|
||||
@@ -10,7 +10,10 @@ trait PropertyManager
|
||||
{
|
||||
private $propertyStorage = null;
|
||||
|
||||
public function loadProperties()
|
||||
/**
|
||||
* Loads properties
|
||||
*/
|
||||
public function loadProperties(): void
|
||||
{
|
||||
if ($this->propertyStorage !== null) {
|
||||
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)
|
||||
{
|
||||
$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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
if (isset($this->propertyStorage[$name])) {
|
||||
$this->propertyStorage[$name]->setValue($value);
|
||||
} else {
|
||||
$className = $this->properties->getTypeClass()->name;
|
||||
if (isset($this->propertyClass)) {
|
||||
$className = $this->propertyClass;
|
||||
} else {
|
||||
$className = $this->properties->getTypeClass()->name;
|
||||
}
|
||||
$property = new $className();
|
||||
if (method_exists($property, "setOwner")) {
|
||||
$property->setOwner($this);
|
||||
|
||||
@@ -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,3 +1,3 @@
|
||||
#!/bin/bash -ex
|
||||
phpunit --stop-on-failure
|
||||
./vendor/bin/phpunit --stop-on-failure
|
||||
./vendor/bin/phpdoccheck -d src --no-ansi
|
||||
|
||||
+45
-4
@@ -33,6 +33,7 @@ class BattleTest extends CoreModelTestCase
|
||||
|
||||
public function getMockGame(Character $character): Game
|
||||
{
|
||||
mt_srand(0);
|
||||
$game = $this->getMockBuilder(Game::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
@@ -56,8 +57,8 @@ class BattleTest extends CoreModelTestCase
|
||||
|
||||
$this->assertSame(5, $monster->getLevel());
|
||||
$this->assertSame(52, $monster->getMaxHealth());
|
||||
$this->assertSame(9, $monster->getAttack($this->getMockGame($character)));
|
||||
$this->assertSame(7, $monster->getDefense($this->getMockGame($character)));
|
||||
$this->assertSame(9, $monster->getAttack());
|
||||
$this->assertSame(7, $monster->getDefense());
|
||||
$this->assertSame($monster->getMaxHealth(), $monster->getHealth());
|
||||
}
|
||||
|
||||
@@ -73,6 +74,9 @@ class BattleTest extends CoreModelTestCase
|
||||
|
||||
$battle = new Battle($this->getMockGame($character), $character, $monster);
|
||||
|
||||
$this->assertSame($character, $battle->getPlayer());
|
||||
$this->assertSame($monster, $battle->getMonster());
|
||||
|
||||
for ($n = 0; $n < 99; $n++) {
|
||||
$oldPlayerHealth = $character->getHealth();
|
||||
$oldMonsterHealth = $monster->getHealth();
|
||||
@@ -85,12 +89,49 @@ class BattleTest extends CoreModelTestCase
|
||||
if ($battle->isOver()) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($battle->getEvents() as $event) {
|
||||
$this->assertNotNull($event->decorate($this->getMockGame($character)));
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertTrue($battle->isOver());
|
||||
$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(1);
|
||||
$monster = $em->getRepository(Monster::class)->find(1);
|
||||
|
||||
$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)
|
||||
*/
|
||||
@@ -1187,8 +1228,8 @@ class BattleTest extends CoreModelTestCase
|
||||
$battle = $this->provideBuffBattleParticipants(new Buff([
|
||||
"slot" => "test",
|
||||
"rounds" => 99,
|
||||
"goodguyAttackModifier" => 2,
|
||||
"goodguyDefenseModifier" => 2,
|
||||
"goodguyAttackModifier" => 10,
|
||||
"goodguyDefenseModifier" => 10,
|
||||
"activateAt" => Buff::ACTIVATE_ROUNDSTART,
|
||||
]), 3);
|
||||
|
||||
|
||||
@@ -89,4 +89,67 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertInternalType("string", $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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,4 +51,23 @@ class DiceBagTests extends \PHPUnit_Framework_TestCase
|
||||
$this->assertGreaterThanOrEqual(1, $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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,21 @@ namespace LotGD\Core\Tests\FakeModule\Models;
|
||||
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
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
|
||||
* @Table(name="Users")
|
||||
*/
|
||||
class UserEntity
|
||||
class UserEntity implements GameAwareInterface, ExtendableModelInterface
|
||||
{
|
||||
use GameAware;
|
||||
use ExtendableModel;
|
||||
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
/** @Column(type="string", length=50); */
|
||||
@@ -31,4 +39,9 @@ class UserEntity
|
||||
{
|
||||
$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 [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
entityNamespace: "LotGD\\Core\\Tests\\FakeModule\\Models\\"
|
||||
subscriptionPatterns:
|
||||
- "e/lotgd/core/tests/event"
|
||||
modelExtensions:
|
||||
- "LotGD\\Core\\Tests\\FakeModule\\Models\\UserTestExtension"
|
||||
+1
-1
@@ -76,7 +76,7 @@ class GameTest extends CoreModelTestCase
|
||||
/** @var string default data set */
|
||||
protected $dataset = "game";
|
||||
|
||||
private $g;
|
||||
public $g;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
|
||||
@@ -3,16 +3,23 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Tests;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Events as DoctrineEvents;
|
||||
use Doctrine\ORM\Mapping\AnsiQuoteStrategy;
|
||||
use Doctrine\ORM\Tools\Setup;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
|
||||
use LotGD\Core\Configuration;
|
||||
use LotGD\Core\ComposerManager;
|
||||
use LotGD\Core\Doctrine\EntityPostLoadEventListener;
|
||||
use LotGD\Core\GameBuilder;
|
||||
use LotGD\Core\LibraryConfigurationManager;
|
||||
use LotGD\Core\Exceptions\InvalidConfigurationException;
|
||||
use LotGD\Core\ModelExtender;
|
||||
use Monolog\Handler\NullHandler;
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Description of ModelTestCase
|
||||
@@ -25,6 +32,7 @@ abstract class ModelTestCase extends \PHPUnit_Extensions_Database_TestCase
|
||||
static private $em = null;
|
||||
/** @var \PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection */
|
||||
private $connection = null;
|
||||
public $g;
|
||||
|
||||
/**
|
||||
* Returns a connection to test models
|
||||
@@ -76,6 +84,45 @@ abstract class ModelTestCase extends \PHPUnit_Extensions_Database_TestCase
|
||||
return self::$em;
|
||||
}
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
// Make an empty logger for these tests. Feel free to change this
|
||||
// to place log messages somewhere you can easily find them.
|
||||
$logger = new Logger('test');
|
||||
$logger->pushHandler(new NullHandler());
|
||||
|
||||
// Create a Game object for use in these tests.
|
||||
$this->g = (new GameBuilder())
|
||||
->withConfiguration(new Configuration(getenv('LOTGD_TESTS_CONFIG_PATH')))
|
||||
->withLogger($logger)
|
||||
->withEntityManager($this->getEntityManager())
|
||||
->withCwd(implode(DIRECTORY_SEPARATOR, [__DIR__, '..']))
|
||||
->create();
|
||||
|
||||
// Add Event listener to entity manager
|
||||
$dem = $this->getEntityManager()->getEventManager();
|
||||
$dem->addEventListener([DoctrineEvents::postLoad], new EntityPostLoadEventListener($this->g));
|
||||
|
||||
// Run model extender
|
||||
AnnotationRegistry::registerLoader("class_exists");
|
||||
|
||||
$modelExtender = new ModelExtender();
|
||||
$libraryConfigurationManager = new LibraryConfigurationManager($this->g->getComposerManager(), getcwd());
|
||||
|
||||
foreach ($libraryConfigurationManager->getConfigurations() as $config) {
|
||||
$modelExtensions = $config->getSubKeyIfItExists(["modelExtensions"]);
|
||||
|
||||
if ($modelExtensions) {
|
||||
$modelExtender->addMore($modelExtensions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
parent::tearDown();
|
||||
|
||||
|
||||
@@ -3,6 +3,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Tests\Models;
|
||||
|
||||
use LotGD\Core\EventHandler;
|
||||
use LotGD\Core\EventManager;
|
||||
use LotGD\Core\Events\EventContext;
|
||||
use LotGD\Core\Game;
|
||||
use LotGD\Core\GameBuilder;
|
||||
use LotGD\Core\Models\Character;
|
||||
use LotGD\Core\Models\CharacterProperty;
|
||||
use LotGD\Core\Tests\CoreModelTestCase;
|
||||
@@ -90,11 +95,14 @@ class CharacterModelTest extends CoreModelTestCase
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$characterEntity = Character::create($characterData);
|
||||
$characterEntity->setProperty("a property", 16);
|
||||
$this->assertSame(16, $characterEntity->getProperty("a property"));
|
||||
$characterEntity->save($em);
|
||||
|
||||
$em->flush();
|
||||
|
||||
$this->assertInternalType("int", $characterEntity->getId());
|
||||
$this->assertSame(16, $characterEntity->getProperty("a property"));
|
||||
|
||||
$em->flush();
|
||||
}
|
||||
@@ -189,4 +197,40 @@ class CharacterModelTest extends CoreModelTestCase
|
||||
|
||||
$this->assertSame(6, $total);
|
||||
}
|
||||
|
||||
public function testIfAttackPublishesEvent()
|
||||
{
|
||||
$level = mt_rand(0, 100);
|
||||
$character1 = Character::create(["name" => "Test", "maxHealth" => 10, "level" => $level]);
|
||||
$character1->setGame($this->g);
|
||||
$character2 = Character::create(["name" => "Test", "maxHealth" => 10, "level" => $level*2]);
|
||||
$character2->setGame($this->g);
|
||||
|
||||
$detectionClass = new class implements EventHandler {
|
||||
static $events_called = [];
|
||||
|
||||
public static function handleEvent(Game $g, EventContext $context): EventContext
|
||||
{
|
||||
$event = $context->getEvent();
|
||||
$value = $context->getDataField("value");
|
||||
|
||||
self::$events_called[$event] = $value;
|
||||
|
||||
$context->setDataField("value", $value*2);
|
||||
return $context;
|
||||
}
|
||||
};
|
||||
|
||||
/** @var EventManager $eventManager */
|
||||
$eventManager = $this->g->getEventManager();
|
||||
|
||||
$eventManager->subscribe("#h/lotgd/core/getCharacterAttack#", get_class($detectionClass), "test");
|
||||
$eventManager->subscribe("#h/lotgd/core/getCharacterDefense#", get_class($detectionClass), "test");
|
||||
|
||||
$this->assertSame($level*2, $character1->getAttack());
|
||||
$this->assertSame($level*4, $character2->getDefense());
|
||||
|
||||
$this->assertSame($level, $detectionClass::$events_called["h/lotgd/core/getCharacterAttack"]);
|
||||
$this->assertSame($level*2, $detectionClass::$events_called["h/lotgd/core/getCharacterDefense"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Tests\Models;
|
||||
|
||||
use LotGD\Core\MessageManager;
|
||||
use LotGD\Core\Models\Character;
|
||||
use LotGD\Core\Models\MessageThread;
|
||||
use LotGD\Core\Models\Message;
|
||||
@@ -14,13 +15,15 @@ use LotGD\Core\Tests\CoreModelTestCase;
|
||||
*/
|
||||
class MessageModelTest extends CoreModelTestCase
|
||||
{
|
||||
|
||||
/** @var string default data set */
|
||||
protected $dataset = "messages";
|
||||
|
||||
public function testSendMessageToSingleCharacter()
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$mm=new MessageManager();
|
||||
|
||||
$character1 = $em->getRepository(Character::class)->find(1);
|
||||
$character2 = $em->getRepository(Character::class)->find(4);
|
||||
|
||||
@@ -28,10 +31,10 @@ class MessageModelTest extends CoreModelTestCase
|
||||
$thread2 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character2, $character1]);
|
||||
|
||||
$this->assertSame($thread1, $thread2);
|
||||
|
||||
Message::send($character1, "Hi, how are you?", $thread1);
|
||||
Message::send($character2, "I'm fine, and you?", $thread1);
|
||||
Message::send($character1, "Sorry, I need to leave~", $thread1);
|
||||
|
||||
$mm->send($character1, "Hi, how are you?", $thread1);
|
||||
$mm->send($character2, "I'm fine, and you?", $thread1);
|
||||
$mm->send($character1, "Sorry, I need to leave~", $thread1);
|
||||
|
||||
$this->assertSame(3, count($thread1->getMessages()));
|
||||
|
||||
@@ -57,25 +60,26 @@ class MessageModelTest extends CoreModelTestCase
|
||||
public function testSendMessageToMultipleCharacters()
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$mm=new MessageManager();
|
||||
|
||||
$character1 = $em->getRepository(Character::class)->find(1);
|
||||
$character2 = $em->getRepository(Character::class)->find(2);
|
||||
$character3 = $em->getRepository(Character::class)->find(3, CharacterRepository::INCLUDE_SOFTDELETED);
|
||||
$character3 = $em->getRepository(Character::class)->find(3, NULL, NULL, CharacterRepository::INCLUDE_SOFTDELETED);
|
||||
$character4 = $em->getRepository(Character::class)->find(4);
|
||||
|
||||
$thread1 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2, $character3, $character4]);
|
||||
$thread2 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character4, $character2, $character1, $character3]);
|
||||
$this->assertSame($thread1, $thread2);
|
||||
|
||||
Message::send($character1, "Multi-User-Message", $thread1);
|
||||
Message::send($character2, "Multi-User-Message", $thread1);
|
||||
|
||||
$mm->send($character1, "Multi-User-Message", $thread1);
|
||||
$mm->send($character2, "Multi-User-Message", $thread1);
|
||||
try {
|
||||
$exception = false;
|
||||
Message::send($character3, "Multi-User-Message", $thread1);
|
||||
$mm->send($character3, "Multi-User-Message", $thread1);
|
||||
} catch(\LotGD\Core\Exceptions\ArgumentException $e) {
|
||||
$exception = true;
|
||||
}
|
||||
Message::send($character4, "Multi-User-Message", $thread1);
|
||||
$mm->send($character4, "Multi-User-Message", $thread1);
|
||||
|
||||
$this->assertTrue($exception);
|
||||
$this->assertSame(3, count($thread1->getMessages()));
|
||||
@@ -88,7 +92,7 @@ class MessageModelTest extends CoreModelTestCase
|
||||
|
||||
$character1 = $em->getRepository(Character::class)->find(1);
|
||||
$character2 = $em->getRepository(Character::class)->find(2);
|
||||
$character3 = $em->getRepository(Character::class)->find(3, CharacterRepository::INCLUDE_SOFTDELETED);
|
||||
$character3 = $em->getRepository(Character::class)->find(3, NULL, NULL, CharacterRepository::INCLUDE_SOFTDELETED);
|
||||
$character4 = $em->getRepository(Character::class)->find(4);
|
||||
|
||||
$thread1 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2, $character3, $character4]);
|
||||
@@ -105,7 +109,8 @@ class MessageModelTest extends CoreModelTestCase
|
||||
public function testSendSystemMessageToSingleCharacter()
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$mm=new MessageManager();
|
||||
|
||||
$character1 = $em->getRepository(Character::class)->find(1);
|
||||
$character2 = $em->getRepository(Character::class)->find(2);
|
||||
|
||||
@@ -114,8 +119,8 @@ class MessageModelTest extends CoreModelTestCase
|
||||
|
||||
$this->assertNotSame($thread1, $thread2);
|
||||
|
||||
Message::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 1.", $thread1);
|
||||
$mm->sendSystemMessage("This is a Systemmessage for Character 2.", $thread2);
|
||||
|
||||
$em->flush();
|
||||
$em->clear();
|
||||
@@ -133,12 +138,12 @@ class MessageModelTest extends CoreModelTestCase
|
||||
// needs to be able to get attached
|
||||
try {
|
||||
$exception = false;
|
||||
Message::send($character1, "A normal message", $thread1);
|
||||
$mm->send($character1, "A normal message", $thread1);
|
||||
} catch (\LotGD\Core\Exceptions\CoreException $ex) {
|
||||
$exception = true;
|
||||
}
|
||||
|
||||
Message::sendSystemMessage("A second system Message", $thread1);
|
||||
|
||||
$mm->sendSystemMessage("A second system Message", $thread1);
|
||||
|
||||
$this->assertTrue($exception);
|
||||
$this->assertSame(2, count($thread1->getMessages()));
|
||||
@@ -147,7 +152,8 @@ class MessageModelTest extends CoreModelTestCase
|
||||
public function testSendSystemMessageToMultipleCharacters()
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$mm=new MessageManager();
|
||||
|
||||
$character1 = $em->getRepository(Character::class)->find(1);
|
||||
$character2 = $em->getRepository(Character::class)->find(2);
|
||||
|
||||
@@ -155,8 +161,8 @@ class MessageModelTest extends CoreModelTestCase
|
||||
$thread2 = $em->getRepository(MessageThread::class)->findOrCreateFor([$character1, $character2]);
|
||||
|
||||
$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->clear();
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace LotGD\Core\Tests\Models;
|
||||
|
||||
use LotGD\Core\Models\Module;
|
||||
use LotGD\Core\Models\ModuleProperty;
|
||||
use LotGD\Core\ModuleManager;
|
||||
use LotGD\Core\Tests\CoreModelTestCase;
|
||||
|
||||
/**
|
||||
@@ -29,6 +30,15 @@ class ModuleTest extends CoreModelTestCase
|
||||
$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()
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
@@ -185,4 +185,78 @@ class ViewpointTest extends CoreModelTestCase
|
||||
$output->removeActionsWithSceneId(2);
|
||||
$this->assertEquals($actionGroupsWithout2, $output->getActionGroups());
|
||||
}
|
||||
|
||||
public function testChangingSceneDescription()
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
$testCharacter = $em->getRepository(Character::class)->find(2);
|
||||
$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(2);
|
||||
$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(1);
|
||||
$a2 = new Action(2);
|
||||
$a3 = new Action(3);
|
||||
|
||||
$ag1 = new ActionGroup('id1', 'title1', 42);
|
||||
$ag1->setActions([
|
||||
$a1,
|
||||
$a2,
|
||||
$a3
|
||||
]);
|
||||
$ag2 = new ActionGroup('id2', 'title2', 101);
|
||||
$ag2->setActions([
|
||||
new Action(4)
|
||||
]);
|
||||
|
||||
$actionGroups = [
|
||||
$ag1,
|
||||
$ag2
|
||||
];
|
||||
|
||||
$input = $em->getRepository(Viewpoint::class)->find(2);
|
||||
$input->setActionGroups($actionGroups);
|
||||
$input->save($em);
|
||||
|
||||
$em->clear();
|
||||
|
||||
/** @var Viewpoint $viewpoint */
|
||||
$viewpoint = $em->getRepository(Viewpoint::class)->find(2);
|
||||
|
||||
$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"));
|
||||
}
|
||||
}
|
||||
|
||||
+118
-118
@@ -11,80 +11,80 @@ use LotGD\Core\TimeKeeper;
|
||||
* @backupStaticAttributes disabled
|
||||
*/
|
||||
class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
|
||||
private $gameEpoch;
|
||||
private $gameOffsetSeconds;
|
||||
private $gameDaysPerDay;
|
||||
private $gameEpoch;
|
||||
private $gameOffsetSeconds;
|
||||
private $gameDaysPerDay;
|
||||
|
||||
public function setUp() {
|
||||
$this->gameEpoch = new \DateTime('2015-07-27 00:00:00 PDT');;
|
||||
$this->gameOffsetSeconds = 0;
|
||||
$this->gameDaysPerDay = 2;
|
||||
}
|
||||
public function setUp() {
|
||||
$this->gameEpoch = new \DateTime('2015-07-27 00:00:00 PDT');;
|
||||
$this->gameOffsetSeconds = 0;
|
||||
$this->gameDaysPerDay = 2;
|
||||
}
|
||||
|
||||
public function testConvertToBasicConversion() {
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
public function testConvertToBasicConversion() {
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$date = new \DateTime('2015-07-27 23:59:59 PDT');
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-01 23:59:59', $converted->format('Y-m-d H:i:s'));
|
||||
$date = new \DateTime('2015-07-27 23:59:59 PDT');
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$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');
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-01 12:00:00', $converted->format('Y-m-d H:i:s'));
|
||||
}
|
||||
$date = new \DateTime('2015-07-27 12:00:00 PDT');
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-01 12:00:00', $converted->format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
public function testConvertToRespectsGameDaysPerDayUpperBound() {
|
||||
$date = new \DateTime('2015-07-27 05:59:59 PDT');
|
||||
public function testConvertToRespectsGameDaysPerDayUpperBound() {
|
||||
$date = new \DateTime('2015-07-27 05:59:59 PDT');
|
||||
|
||||
$this->gameDaysPerDay = 4;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->gameDaysPerDay = 4;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-01', $converted->format('Y-m-d'));
|
||||
}
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-01', $converted->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function testConvertToRespectsGameDaysPerDayNextDay() {
|
||||
$date = new \DateTime('2015-07-27 06:00:00 PDT');
|
||||
public function testConvertToRespectsGameDaysPerDayNextDay() {
|
||||
$date = new \DateTime('2015-07-27 06:00:00 PDT');
|
||||
|
||||
$this->gameDaysPerDay = 4;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->gameDaysPerDay = 4;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
|
||||
}
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function testConvertToRespectsGameDaysPerDayNextDayUpperBound() {
|
||||
$date = new \DateTime('2015-07-27 11:59:59 PDT');
|
||||
public function testConvertToRespectsGameDaysPerDayNextDayUpperBound() {
|
||||
$date = new \DateTime('2015-07-27 11:59:59 PDT');
|
||||
|
||||
$this->gameDaysPerDay = 4;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->gameDaysPerDay = 4;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
|
||||
}
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function testIfIsNewDayReturnsTrueWithNullAsLastInteractionTime() {
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, 4);
|
||||
public function testIfIsNewDayReturnsTrueWithNullAsLastInteractionTime() {
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, 4);
|
||||
|
||||
$this->assertTrue($keeper->isNewDay(null));
|
||||
}
|
||||
$this->assertTrue($keeper->isNewDay(null));
|
||||
}
|
||||
|
||||
public function testIfIsNewDayReturnsFalseIfLastInteractionTimeWasJustRecently()
|
||||
{
|
||||
// game days per day: 4, each day 6h.
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime("2017-01-02 11:59:59"), 3600*5, 4);
|
||||
public function testIfIsNewDayReturnsFalseIfLastInteractionTimeWasJustRecently()
|
||||
{
|
||||
// game days per day: 4, each day 6h.
|
||||
$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");
|
||||
$time2 = new \DateTime("2017-01-02 11:59:59");
|
||||
$time3 = new \DateTime("2017-01-02 09:00:00");
|
||||
$time4 = new \DateTime("2017-01-02 09:59:30");
|
||||
$time1 = new \DateTime("2017-01-02 06:00:00");
|
||||
$time2 = new \DateTime("2017-01-02 11:59:59");
|
||||
$time3 = new \DateTime("2017-01-02 09:00:00");
|
||||
$time4 = new \DateTime("2017-01-02 09:59:30");
|
||||
|
||||
$this->assertFalse($keeper->isNewDay($time1));
|
||||
$this->assertFalse($keeper->isNewDay($time2));
|
||||
$this->assertFalse($keeper->isNewDay($time3));
|
||||
$this->assertFalse($keeper->isNewDay($time4));
|
||||
}
|
||||
$this->assertFalse($keeper->isNewDay($time1));
|
||||
$this->assertFalse($keeper->isNewDay($time2));
|
||||
$this->assertFalse($keeper->isNewDay($time3));
|
||||
$this->assertFalse($keeper->isNewDay($time4));
|
||||
}
|
||||
|
||||
public function testIfIsNewDayReturnsFalseIfLastInteractionTimeWasOnLastGameDay()
|
||||
{
|
||||
@@ -103,87 +103,87 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
|
||||
$this->assertTrue($keeper->isNewDay($time4));
|
||||
}
|
||||
|
||||
public function testConvertToRespectsGameOffset() {
|
||||
$date = new \DateTime('2015-07-27 01:01:15 PDT');
|
||||
public function testConvertToRespectsGameOffset() {
|
||||
$date = new \DateTime('2015-07-27 01:01:15 PDT');
|
||||
|
||||
$this->gameOffsetSeconds = 60*60;
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->gameOffsetSeconds = 60*60;
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-01 00:01:15', $converted->format('Y-m-d H:i:s'));
|
||||
}
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-01 00:01:15', $converted->format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
public function testConvertToRespectsGameOffsetUpperBound() {
|
||||
$date = new \DateTime('2015-07-28 00:59:59 PDT');
|
||||
public function testConvertToRespectsGameOffsetUpperBound() {
|
||||
$date = new \DateTime('2015-07-28 00:59:59 PDT');
|
||||
|
||||
$this->gameOffsetSeconds = 60*60;
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->gameOffsetSeconds = 60*60;
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-01 23:59:59', $converted->format('Y-m-d H:i:s'));
|
||||
}
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-01 23:59:59', $converted->format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
public function testConvertToRespectsGameOffsetNextDay() {
|
||||
$date = new \DateTime('2015-07-28 01:00:00 PDT');
|
||||
public function testConvertToRespectsGameOffsetNextDay() {
|
||||
$date = new \DateTime('2015-07-28 01:00:00 PDT');
|
||||
|
||||
$this->gameOffsetSeconds = 60*60;
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->gameOffsetSeconds = 60*60;
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
|
||||
}
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function testConvertToRespectsGameOffsetNextDayUpperBound() {
|
||||
$date = new \DateTime('2015-07-29 00:59:59 PDT');
|
||||
public function testConvertToRespectsGameOffsetNextDayUpperBound() {
|
||||
$date = new \DateTime('2015-07-29 00:59:59 PDT');
|
||||
|
||||
$this->gameOffsetSeconds = 60*60;
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->gameOffsetSeconds = 60*60;
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
|
||||
}
|
||||
$converted = $keeper->convertToGameTime($date);
|
||||
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function testConvertFromBasicConversion() {
|
||||
$date = new \DateTime('0000-01-02 00:00:00 UTC');
|
||||
public function testConvertFromBasicConversion() {
|
||||
$date = new \DateTime('0000-01-02 00:00:00 UTC');
|
||||
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$converted = $keeper->convertFromGameTime($date);
|
||||
$this->assertEquals("2015-07-28", $converted->format('Y-m-d'));
|
||||
}
|
||||
$converted = $keeper->convertFromGameTime($date);
|
||||
$this->assertEquals("2015-07-28", $converted->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function testConvertFromRespectsGameOffsetNextDay() {
|
||||
$epoch = new \DateTime('2015-07-27 00:00:00 PDT');
|
||||
$date = new \DateTime('0000-01-02 23:59:59 UTC');
|
||||
public function testConvertFromRespectsGameOffsetNextDay() {
|
||||
$epoch = new \DateTime('2015-07-27 00:00:00 PDT');
|
||||
$date = new \DateTime('0000-01-02 23:59:59 UTC');
|
||||
|
||||
$this->gameEpoch = $epoch;
|
||||
$this->gameOffsetSeconds = 60*60;
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->gameEpoch = $epoch;
|
||||
$this->gameOffsetSeconds = 60*60;
|
||||
$this->gameDaysPerDay = 1;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$converted = $keeper->convertFromGameTime($date);
|
||||
$this->assertEquals("2015-07-29 00:59:59", $converted->format('Y-m-d H:i:s'));
|
||||
}
|
||||
$converted = $keeper->convertFromGameTime($date);
|
||||
$this->assertEquals("2015-07-29 00:59:59", $converted->format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
public function testConvertFromRespectsGameDaysPerDayNextDay() {
|
||||
$epoch = new \DateTime('2015-07-27 00:00:00 PDT');
|
||||
$date = new \DateTime('0000-01-02 23:59:59 UTC');
|
||||
public function testConvertFromRespectsGameDaysPerDayNextDay() {
|
||||
$epoch = new \DateTime('2015-07-27 00:00:00 PDT');
|
||||
$date = new \DateTime('0000-01-02 23:59:59 UTC');
|
||||
|
||||
$this->gameEpoch = $epoch;
|
||||
$this->gameDaysPerDay = 4;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->gameEpoch = $epoch;
|
||||
$this->gameDaysPerDay = 4;
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
|
||||
$converted = $keeper->convertFromGameTime($date);
|
||||
$this->assertEquals("2015-07-27 11:59:59", $converted->format('Y-m-d H:i:s'));
|
||||
}
|
||||
$converted = $keeper->convertFromGameTime($date);
|
||||
$this->assertEquals("2015-07-27 11:59:59", $converted->format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
public function testGameTimeSanity() {
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->assertNotNull($keeper->getGameTime());
|
||||
}
|
||||
public function testGameTimeSanity() {
|
||||
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
|
||||
$this->assertNotNull($keeper->getGameTime());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user