Add missing docblocks
This commit is contained in:
+35
-28
@@ -9,7 +9,8 @@ use Symfony\Component\Yaml\Yaml;
|
||||
use LotGD\Core\ComposerManager;
|
||||
|
||||
/**
|
||||
* BootConfiguration
|
||||
* Represents the configuration of a LotGD package (core, crate or module),
|
||||
* with its configuration parameters.
|
||||
* @author sauterb
|
||||
*/
|
||||
class BootConfiguration
|
||||
@@ -25,15 +26,21 @@ class BootConfiguration
|
||||
private $models;
|
||||
private $daenerysCommands;
|
||||
private $cwd;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a configuration.
|
||||
* @param ComposerManager $composerManager
|
||||
* @param PackageInterface $package
|
||||
* @param string $cwd
|
||||
*/
|
||||
public function __construct(ComposerManager $composerManager, PackageInterface $package, string $cwd)
|
||||
{
|
||||
$this->composerManager = $composerManager;
|
||||
$this->package = $package;
|
||||
$this->cwd = $cwd;
|
||||
|
||||
|
||||
$installationManager = $composerManager->getComposer()->getInstallationManager();
|
||||
|
||||
|
||||
// only lotgd-modules are installed in the vendor directory
|
||||
if ($package->getType() === "lotgd-module") {
|
||||
$confFile = $installationManager->getInstallPath($package) . DIRECTORY_SEPARATOR . "lotgd.yml";
|
||||
@@ -41,7 +48,7 @@ class BootConfiguration
|
||||
else {
|
||||
$confFile = $cwd . DIRECTORY_SEPARATOR . "lotgd.yml";
|
||||
}
|
||||
|
||||
|
||||
$this->rootNamespace = $this->findRootNamespace($package);
|
||||
if (file_exists($confFile)) {
|
||||
$this->rawConfig = Yaml::parse(file_get_contents($confFile));
|
||||
@@ -51,14 +58,14 @@ class BootConfiguration
|
||||
$type = $package->getType();
|
||||
throw new \Exception("Package {$name} of type {$type} does not have a lotgd.yml in it's root ($confFile).");
|
||||
}
|
||||
|
||||
|
||||
$this->findEntityDirectory();
|
||||
$this->findDaenerysCommands();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searches for a root namespace
|
||||
*
|
||||
*
|
||||
* This function searches the package's configuration to find it's root namespace.
|
||||
* For this, it uses the following order:
|
||||
* - check psr-4 autoload configuration. If used, it takes the first element
|
||||
@@ -73,15 +80,15 @@ class BootConfiguration
|
||||
if (isset($autoload["psr-4"]) && count($autoload["psr-4"]) > 0) {
|
||||
return key($autoload["psr-4"]);
|
||||
}
|
||||
|
||||
|
||||
if (isset($autoload["psr-0"]) && count($autoload["psr-0"]) > 0) {
|
||||
return key($autoload["psr-0"]);
|
||||
}
|
||||
|
||||
|
||||
$name = $package->getName();
|
||||
throw new \Exception("{$name} has no valid namespace.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a subkey if it exists or null.
|
||||
* @param array $arguments
|
||||
@@ -90,7 +97,7 @@ class BootConfiguration
|
||||
protected function getSubKeyIfItExists(array $arguments)
|
||||
{
|
||||
$parent = $this->rawConfig;
|
||||
|
||||
|
||||
foreach ($arguments as $argument){
|
||||
if (isset($parent[$argument])) {
|
||||
$parent = $parent[$argument];
|
||||
@@ -99,10 +106,10 @@ class BootConfiguration
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $parent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tries to iterate an array element given by the arguments
|
||||
* @param scalar $argument1,... array keys, by increasing depth
|
||||
@@ -110,14 +117,14 @@ class BootConfiguration
|
||||
protected function iterateKey(...$arguments)
|
||||
{
|
||||
$result = $this->getSubKeyIfItExists($arguments);
|
||||
|
||||
|
||||
if (is_array($result)) {
|
||||
foreach ($result as $key => $val) {
|
||||
yield $key => $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a subkey of an array if it exists or null
|
||||
* @param scalar $argument1,... array keys, by increasing depth
|
||||
@@ -128,28 +135,28 @@ class BootConfiguration
|
||||
$result = $this->getSubKeyIfItExists($arguments);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* internal function. Adds models to the boot configuration.
|
||||
*/
|
||||
protected function findEntityDirectory()
|
||||
{
|
||||
$this->entityDirectory = null;
|
||||
|
||||
|
||||
$entityNamespace = $this->getConfig("bootstrap", "entityNamespace");
|
||||
$entityNamespace = $this->rootNamespace . $entityNamespace;
|
||||
|
||||
|
||||
if (is_null($entityNamespace) === false) {
|
||||
$entityDirectory = $this->composerManager->translateNamespaceToPath($entityNamespace, $this->cwd);
|
||||
|
||||
|
||||
if (is_dir($entityDirectory) === false) {
|
||||
throw new \Exception("{$entityDirectory}, generated from {$entityNamespace}, is not a valid directory.");
|
||||
}
|
||||
|
||||
|
||||
$this->entityDirectory = $entityDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if there are any models to add.
|
||||
* @return type
|
||||
@@ -158,7 +165,7 @@ class BootConfiguration
|
||||
{
|
||||
return $this->entityDirectory === null ? false : true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of fqcn for all models added by packages.
|
||||
* @return array<string>
|
||||
@@ -167,7 +174,7 @@ class BootConfiguration
|
||||
{
|
||||
return $this->entityDirectory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searches the config file for daenerys commands and, if found, adds the class name to a list
|
||||
* @return type
|
||||
@@ -176,12 +183,12 @@ class BootConfiguration
|
||||
{
|
||||
$list = $this->iterateKey("bootstrap", "daenerysCommands");
|
||||
$this->daenerysCommands = [];
|
||||
|
||||
|
||||
foreach ($list as $command) {
|
||||
$this->daenerysCommands = $this->rootNamespace . $command;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this configuration has daenerys commands
|
||||
* @return bool
|
||||
@@ -189,8 +196,8 @@ class BootConfiguration
|
||||
public function hasDaenerysCommands(): bool
|
||||
{
|
||||
return count($this->daenerysCommands) > 0 ? true : false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of daenerys commands
|
||||
*/
|
||||
|
||||
@@ -6,27 +6,35 @@ use Symfony\Component\Console\Application;
|
||||
|
||||
use LotGD\Core\ComposerManager;
|
||||
|
||||
/**
|
||||
* Handle the boot configurations for the installed core, crate and modules.
|
||||
*/
|
||||
class BootConfigurationManager
|
||||
{
|
||||
private $cwd;
|
||||
/** @var array<BootConfiguration> */
|
||||
private $configurations = null;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a manager.
|
||||
* @param ComposerManager $composerManager
|
||||
* @param string $cwd
|
||||
*/
|
||||
public function __construct(ComposerManager $composerManager, string $cwd)
|
||||
{
|
||||
$this->cwd = $cwd;
|
||||
|
||||
$packages = $composerManager->getPackages();
|
||||
|
||||
$packages = $composerManager->getPackages();
|
||||
$this->configurations = [];
|
||||
|
||||
|
||||
foreach($packages as $package)
|
||||
{
|
||||
{
|
||||
if ($package->getType() === "lotgd-crate" || $package->getType() === "lotgd-module") {
|
||||
$this->configurations[] = new BootConfiguration($composerManager, $package, $cwd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of all entity directories from lotgd packages
|
||||
* @return array
|
||||
@@ -34,16 +42,16 @@ class BootConfigurationManager
|
||||
public function getEntityDirectories(): array
|
||||
{
|
||||
$entityDirectories = [];
|
||||
|
||||
|
||||
foreach ($this->configurations as $config) {
|
||||
if ($config->hasEntityDirectory()) {
|
||||
$entityDirectories[] = $config->getEntityDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $entityDirectories;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds commands from packages to daenerys
|
||||
* @param \LotGD\Core\Game $game
|
||||
@@ -58,4 +66,4 @@ class BootConfigurationManager
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+29
-26
@@ -23,13 +23,16 @@ use LotGD\Core\ {
|
||||
Exceptions\InvalidConfigurationException
|
||||
};
|
||||
|
||||
/**
|
||||
* The entry point for constructing a properly configured LotGD Game object.
|
||||
*/
|
||||
class Bootstrap
|
||||
{
|
||||
private $rootDir;
|
||||
private $game;
|
||||
private $bootConfigurationManager = [];
|
||||
private $annotationDirectories = [];
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Game object, with all the necessary configuration.
|
||||
* @param string $rootDir The root directory if it is different from getcwd()
|
||||
@@ -40,7 +43,7 @@ class Bootstrap
|
||||
$game = new self();
|
||||
return $game->getGame($rootDir);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts the game kernel with the most important classes and returns the object
|
||||
* @param string $rootDir The root directory if it is different from getcwd()
|
||||
@@ -49,23 +52,23 @@ class Bootstrap
|
||||
public function getGame(string $rootDir = null): Game
|
||||
{
|
||||
$this->rootDir = $rootDir ?? getcwd();
|
||||
|
||||
|
||||
$composer = $this->createComposerManager();
|
||||
$this->bootConfigurationManager = $this->createBootConfigurationManager($composer, $this->rootDir);
|
||||
|
||||
|
||||
$config = $this->createConfiguration();
|
||||
$logger = $this->createLogger($config, "lotgd");
|
||||
|
||||
|
||||
$pdo = $this->connectToDatabase($config);
|
||||
$entityManager = $this->createEntityManager($pdo);
|
||||
|
||||
|
||||
$eventManager = $this->createEventManager($entityManager);
|
||||
|
||||
|
||||
$this->game = new Game($config, $logger, $entityManager, $eventManager);
|
||||
|
||||
|
||||
return $this->game;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates the boot configuration manager
|
||||
* @param ComposerManager $composerManager
|
||||
@@ -73,12 +76,12 @@ class Bootstrap
|
||||
* @return \LotGD\Core\BootConfigurationManager
|
||||
*/
|
||||
protected function createBootConfigurationManager(
|
||||
ComposerManager $composerManager,
|
||||
ComposerManager $composerManager,
|
||||
string $cwd
|
||||
): BootConfigurationManager {
|
||||
return new BootConfigurationManager($composerManager, $cwd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Connects to a database using pdo
|
||||
* @param \LotGD\Core\Configuration $config
|
||||
@@ -88,7 +91,7 @@ class Bootstrap
|
||||
{
|
||||
return new \PDO($config->getDatabaseDSN(), $config->getDatabaseUser(), $config->getDatabasePassword());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates and returns an instance of ComposerManager
|
||||
* @param Logger $logger
|
||||
@@ -96,10 +99,10 @@ class Bootstrap
|
||||
*/
|
||||
protected function createComposerManager(): ComposerManager
|
||||
{
|
||||
$composer = new ComposerManager();
|
||||
$composer = new ComposerManager();
|
||||
return $composer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a configuration object reading from the file located at the path stored in LOTGD_CONFIG.
|
||||
* @return \LotGD\Core\Configuration
|
||||
@@ -108,22 +111,22 @@ class Bootstrap
|
||||
protected function createConfiguration(): Configuration
|
||||
{
|
||||
$configFilePath = getenv('LOTGD_CONFIG');
|
||||
|
||||
|
||||
if (empty($configFilePath)) {
|
||||
$configFilePath = implode(DIRECTORY_SEPARATOR, [$this->rootDir, "config", "lotgd.yml"]);
|
||||
}
|
||||
else {
|
||||
$configFilePath = $this->rootDir . $configFilePath;
|
||||
}
|
||||
|
||||
|
||||
if ($configFilePath === false || strlen($configFilePath) == 0 || is_file($configFilePath) === false) {
|
||||
throw new InvalidConfigurationException("Invalid or missing configuration file: {$configFilePath}.");
|
||||
}
|
||||
|
||||
|
||||
$config = new Configuration($configFilePath, $this->rootDir);
|
||||
return $config;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a logger instance
|
||||
* @param type $name
|
||||
@@ -137,10 +140,10 @@ class Bootstrap
|
||||
|
||||
$v = Game::getVersion();
|
||||
$logger->info("Bootstrap constructing game (Daenerys 🐲{$v}).");
|
||||
|
||||
|
||||
return $logger;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates and returns an instance of the EventManager
|
||||
* @param EntityManagerInterface $entityManager
|
||||
@@ -150,7 +153,7 @@ class Bootstrap
|
||||
{
|
||||
return new EventManager($entityManager);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates the EntityManager using the pdo connection given in it's argument
|
||||
* @param \PDO $pdo
|
||||
@@ -171,7 +174,7 @@ class Bootstrap
|
||||
$metaData = $entityManager->getMetadataFactory()->getAllMetadata();
|
||||
$schemaTool = new SchemaTool($entityManager);
|
||||
$schemaTool->updateSchema($metaData);
|
||||
|
||||
|
||||
return $entityManager;
|
||||
}
|
||||
|
||||
@@ -184,13 +187,13 @@ class Bootstrap
|
||||
{
|
||||
// Read db annotations from our own model files.
|
||||
$directories = [__DIR__ . DIRECTORY_SEPARATOR . 'Models'];
|
||||
|
||||
|
||||
// Get additional annotation directories from bootstrap classes
|
||||
$packageDirectories = $this->bootConfigurationManager->getEntityDirectories();
|
||||
|
||||
|
||||
return array_merge($directories, $packageDirectories);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return all directories used for reading annotations.
|
||||
* @return array<string>
|
||||
@@ -199,7 +202,7 @@ class Bootstrap
|
||||
{
|
||||
return $this->annotationDirectories;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds console commands to a given console application from bootstrapping packages.
|
||||
* @param Application $application
|
||||
|
||||
+70
-67
@@ -34,7 +34,7 @@ class BuffList
|
||||
protected $activeBuffs = [];
|
||||
/** @var Doctrine\Common\Collections\ArrayCollection */
|
||||
protected $usedBuffs;
|
||||
|
||||
|
||||
/** @var boolean True of the modifiers have already been calculated */
|
||||
protected $modifiersCalculated = false;
|
||||
/** @var boolean True if the badguy is invulnurable */
|
||||
@@ -53,10 +53,10 @@ class BuffList
|
||||
protected $goodguyAttackModifier = 1.;
|
||||
/** @var float */
|
||||
protected $goodguyDefenseModifier = 1.;
|
||||
|
||||
|
||||
protected $events;
|
||||
protected $loaded = false;
|
||||
|
||||
|
||||
/**
|
||||
* Initiates some variables
|
||||
* @param Collection $buffs
|
||||
@@ -67,7 +67,7 @@ class BuffList
|
||||
$this->events = new ArrayCollection();
|
||||
$this->usedBuffs = new ArrayCollection();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads all buffs (since it's a lazy correlation)
|
||||
*/
|
||||
@@ -79,7 +79,7 @@ class BuffList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the given buff has already been used this round.
|
||||
* @param Buff $buff
|
||||
@@ -93,10 +93,10 @@ class BuffList
|
||||
else {
|
||||
$used = false;
|
||||
}
|
||||
|
||||
|
||||
return $used;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Marks the given buff as used
|
||||
* @param Buff $buff
|
||||
@@ -105,7 +105,7 @@ class BuffList
|
||||
{
|
||||
$this->usedBuffs->add($buff);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the buff's start or round message
|
||||
* @param Buff $buff
|
||||
@@ -122,10 +122,10 @@ class BuffList
|
||||
elseif($used === false) {
|
||||
$return = $buff->getRoundMessage();
|
||||
}
|
||||
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resets the buff usage for a new round
|
||||
*/
|
||||
@@ -135,12 +135,15 @@ class BuffList
|
||||
$this->usedBuffs = new ArrayCollection();
|
||||
$this->modifiersCalculated = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether any buffs are in use.
|
||||
*/
|
||||
public function hasBuffsInUse(): bool
|
||||
{
|
||||
return count($this->usedBuffs) > 0 ? true : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Activates all buffs that activate upon the given activation parameter.
|
||||
* @param int $activation
|
||||
@@ -153,37 +156,37 @@ class BuffList
|
||||
if ($activation%2 !== 0 && $activation !== 1) {
|
||||
throw new ArgumentException("You can only activate one activation type at a time.");
|
||||
}
|
||||
|
||||
|
||||
if (!empty($this->activeBuffs[$activation])) {
|
||||
throw new BuffListAlreadyActivatedException("You can activate the buff list for the given activation step only once.");
|
||||
}
|
||||
|
||||
|
||||
$this->activeBuffs[$activation] = new ArrayCollection();
|
||||
$activationEvents = new ArrayCollection();
|
||||
|
||||
|
||||
foreach ($this->iterateBuffList() as $buff) {
|
||||
// Continue to next buff if the activation is not in this round.
|
||||
if ($buff->getsActivatedAt($activation) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$this->activeBuffs[$activation]->add($buff);
|
||||
|
||||
|
||||
// Returns start or roundMessage if the buff has not been used yet.
|
||||
$buffMessage = $this->getBuffMessage($buff);
|
||||
if ($buffMessage !== "") {
|
||||
$activationEvents->add(new BuffMessageEvent($buffMessage));
|
||||
}
|
||||
|
||||
|
||||
// Needs to come at the end
|
||||
if ($this->hasBuffBeenUsed($buff) === false) {
|
||||
$this->useBuff($buff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $activationEvents;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decreases the rounds left on all used buffs
|
||||
* @return Collection A Collection containing expire messages (if there are any)
|
||||
@@ -192,27 +195,27 @@ class BuffList
|
||||
{
|
||||
/* @var $endEvents Collection */
|
||||
$endEvents = new ArrayCollection();
|
||||
|
||||
|
||||
foreach($this->usedBuffs as $buff) {
|
||||
/* @var $roundsLeft int */
|
||||
$roundsLeft = $buff->getRounds() - 1;
|
||||
$buff->setRounds($roundsLeft);
|
||||
|
||||
|
||||
if ($roundsLeft === 0) {
|
||||
/* @var $endMessage string */
|
||||
$endMessage = $buff->getEndMessage();
|
||||
|
||||
|
||||
if ($endMessage !== "") {
|
||||
$endEvents->add(new BuffMessageEvent($endMessage));
|
||||
}
|
||||
|
||||
|
||||
$this->remove($buff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $endEvents;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a buff from the buff list.
|
||||
* @param Buff $buff
|
||||
@@ -223,7 +226,7 @@ class BuffList
|
||||
$this->buffs->removeElement($buff);
|
||||
$this->usedBuffs->removeElement($buff);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a buff to the buff list, occupying the slot.
|
||||
* @param Buff $buff
|
||||
@@ -233,15 +236,15 @@ class BuffList
|
||||
{
|
||||
$this->loadBuffs();
|
||||
$slot = $buff->getSlot();
|
||||
|
||||
|
||||
if (isset($this->buffsBySlot[$buff->getSlot()])) {
|
||||
throw new BuffSlotOccupiedException("The slot {$slot} is already occupied.");
|
||||
}
|
||||
|
||||
|
||||
$this->buffs->add($buff);
|
||||
$this->buffsBySlot[$buff->getSlot()] = $buff;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renews a buff.
|
||||
* @param Buff $buff
|
||||
@@ -250,15 +253,15 @@ class BuffList
|
||||
{
|
||||
$this->loadBuffs();
|
||||
$slot = $buff->getSlot();
|
||||
|
||||
|
||||
if (isset($this->buffsBySlot[$buff->getSlot()])) {
|
||||
$this->buffs->removeElement($buff);
|
||||
}
|
||||
|
||||
|
||||
$this->buffs->add($buff);
|
||||
$this->buffsBySlot[$buff->getSlot()] = $buff;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates all total modifiers
|
||||
* @return type
|
||||
@@ -268,7 +271,7 @@ class BuffList
|
||||
if ($this->modifiersCalculated === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$this->badguyAttackModifier = 1.;
|
||||
$this->badguyDamageModifier = 1.;
|
||||
$this->badguyDefenseModifier = 1.;
|
||||
@@ -277,7 +280,7 @@ class BuffList
|
||||
$this->goodguyDamageModifier = 1.;
|
||||
$this->goodguyDefenseModifier = 1.;
|
||||
$this->goodguyInvulnurable = false;
|
||||
|
||||
|
||||
/* @var $buff \LotGD\Core\Model\Buff */
|
||||
foreach ($this->iterateBuffList() as $buff) {
|
||||
$this->badguyAttackModifier *= $buff->getBadguyAttackModifier();
|
||||
@@ -290,7 +293,7 @@ class BuffList
|
||||
$this->goodguyInvulnurable = $this->goodguyInvulnurable || $buff->goodguyIsInvulnurable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterates over every buff that gets activated at one point during a round.
|
||||
* @return Generator|\LotGD\Core\Model\Buff[]
|
||||
@@ -307,7 +310,7 @@ class BuffList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the badguy attack modifier calculated over the whole bufflist
|
||||
* @return float
|
||||
@@ -317,7 +320,7 @@ class BuffList
|
||||
$this->calculateModifiers();
|
||||
return $this->badguyAttackModifier;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the badguy defense modifier calculated over the whole bufflist
|
||||
* @return float
|
||||
@@ -327,7 +330,7 @@ class BuffList
|
||||
$this->calculateModifiers();
|
||||
return $this->badguyDefenseModifier;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the badguy damage modifier calculated over the whole bufflist
|
||||
* @return float
|
||||
@@ -337,7 +340,7 @@ class BuffList
|
||||
$this->calculateModifiers();
|
||||
return $this->badguyDamageModifier;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the badguy is invulnurable
|
||||
* @return bool
|
||||
@@ -347,7 +350,7 @@ class BuffList
|
||||
$this->calculateModifiers();
|
||||
return $this->badguyInvulnurable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the badguy attack modifier calculated over the whole bufflist
|
||||
* @return float
|
||||
@@ -357,7 +360,7 @@ class BuffList
|
||||
$this->calculateModifiers();
|
||||
return $this->goodguyAttackModifier;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the badguy defense modifier calculated over the whole bufflist
|
||||
* @return float
|
||||
@@ -367,7 +370,7 @@ class BuffList
|
||||
$this->calculateModifiers();
|
||||
return $this->goodguyDefenseModifier;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the badguy damage modifier calculated over the whole bufflist
|
||||
* @return float
|
||||
@@ -377,7 +380,7 @@ class BuffList
|
||||
$this->calculateModifiers();
|
||||
return $this->goodguyDamageModifier;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the goodguy is invulnurable
|
||||
* @return bool
|
||||
@@ -387,7 +390,7 @@ class BuffList
|
||||
$this->calculateModifiers();
|
||||
return $this->goodguyInvulnurable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes buffs that do direct damage or regeneration
|
||||
* @param int $activation
|
||||
@@ -403,7 +406,7 @@ class BuffList
|
||||
FighterInterface $badguy
|
||||
): Collection {
|
||||
$events = [];
|
||||
|
||||
|
||||
foreach ($this->activeBuffs[$activation] as $buff) {
|
||||
// Add good guy regeneration
|
||||
if ($buff->getGoodguyRegeneration() !== 0) {
|
||||
@@ -414,7 +417,7 @@ class BuffList
|
||||
$buff->getNoEffectMessage()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Add bad guy regeneration
|
||||
if ($buff->getBadguyRegeneration() !== 0) {
|
||||
$events[] = new RegenerationBuffEvent(
|
||||
@@ -424,23 +427,23 @@ class BuffList
|
||||
$buff->getNoEffectMessage()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Minion buff
|
||||
if ($buff->getNumberOfMinions() > 0) {
|
||||
/* @var $n int */
|
||||
$n = $buff->getNumberOfMinions();
|
||||
/* @var $attacksOne bool */
|
||||
$attacksOne = ($buff->getMinionMinGoodguyDamage() || $buff->getMinionMaxGoodguyDamage() !== 0)
|
||||
$attacksOne = ($buff->getMinionMinGoodguyDamage() || $buff->getMinionMaxGoodguyDamage() !== 0)
|
||||
|| ($buff->getMinionMinBadguyDamage() || $buff->getMinionMaxBadguyDamage() !== 0);
|
||||
/* @var $attacksBoth bool */
|
||||
$attacksBoth = ($buff->getMinionMinGoodguyDamage() || $buff->getMinionMaxGoodguyDamage() !== 0)
|
||||
$attacksBoth = ($buff->getMinionMinGoodguyDamage() || $buff->getMinionMaxGoodguyDamage() !== 0)
|
||||
&& ($buff->getMinionMinBadguyDamage() || $buff->getMinionMaxBadguyDamage() !== 0);
|
||||
|
||||
|
||||
// Faulty buff - if minions attack no one, it's better to have no minions at all. Or they will just do... nothing.
|
||||
if ($attacksOne === false) {
|
||||
$n = 0;
|
||||
}
|
||||
|
||||
|
||||
// Add a minion event for every single minion
|
||||
for ($i = 0; $i < $n; $i++) {
|
||||
// If the buff is setup to attack both good and badguy, we throw a dice to decide who the minion attacks
|
||||
@@ -459,7 +462,7 @@ class BuffList
|
||||
else {
|
||||
$who = -1;
|
||||
}
|
||||
|
||||
|
||||
if ($who === 1) {
|
||||
// Minion does damage to the goodguy
|
||||
$damage = $game->getDiceBag()->normal($buff->getMinionMinGoodguyDamage(), $buff->getMinionMaxGoodguyDamage());
|
||||
@@ -470,7 +473,7 @@ class BuffList
|
||||
$damage = $game->getDiceBag()->normal($buff->getMinionMinBadguyDamage(), $buff->getMinionMaxBadguyDamage());
|
||||
$target = $badguy;
|
||||
}
|
||||
|
||||
|
||||
if ($damage < 0) {
|
||||
$message = $buff->getEffectFailsMessage();
|
||||
}
|
||||
@@ -489,12 +492,12 @@ class BuffList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new ArrayCollection(
|
||||
$events
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes buffs that are dependant on the damage done in one round
|
||||
* @param int $activation
|
||||
@@ -512,7 +515,7 @@ class BuffList
|
||||
FighterInterface $badguy
|
||||
): Collection {
|
||||
$events = [];
|
||||
|
||||
|
||||
foreach($this->activeBuffs[$activation] as $buff) {
|
||||
if ($buff->getGoodguyDamageReflection() !== 0.) {
|
||||
if ($damage > 0) {
|
||||
@@ -532,14 +535,14 @@ class BuffList
|
||||
$message = $buff->getEffectSucceedsMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$events[] = new DamageReflectionEvent(
|
||||
$badguy,
|
||||
$badguy,
|
||||
$reflectedDamage,
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if ($buff->getBadguyDamageReflection() !== 0.) {
|
||||
if ($damage > 0) {
|
||||
// Damage is > 0, so badguy takes damage, we can normally reflect
|
||||
@@ -558,14 +561,14 @@ class BuffList
|
||||
$reflectedDamage = 0;
|
||||
$message = $buff->getEffectFailsMessage();
|
||||
}
|
||||
|
||||
|
||||
$events[] = new DamageReflectionEvent(
|
||||
$goodguy,
|
||||
$goodguy,
|
||||
$reflectedDamage,
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if ($buff->getGoodguyLifetap() !== 0.) {
|
||||
if ($damage > 0) {
|
||||
// Damage is > 0, badguy takes damage. Goodguy lifetap works only upon damage to the goodguy.
|
||||
@@ -586,14 +589,14 @@ class BuffList
|
||||
$healAmount = 0;
|
||||
$message = $buff->getNoEffectMessage();
|
||||
}
|
||||
|
||||
|
||||
$events[] = new DamageLifetapEvent(
|
||||
$badguy,
|
||||
$healAmount,
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if ($buff->getBadguyLifetap() !== 0.) {
|
||||
if ($damage > 0) {
|
||||
// Damage is > 0, badguy takes damage. We act upon this to heal goodguy.
|
||||
@@ -614,7 +617,7 @@ class BuffList
|
||||
$healAmount = 0;
|
||||
$message = $buff->getNoEffectMessage();
|
||||
}
|
||||
|
||||
|
||||
$events[] = new DamageLifetapEvent(
|
||||
$goodguy,
|
||||
$healAmount,
|
||||
@@ -622,7 +625,7 @@ class BuffList
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new ArrayCollection($events);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +173,10 @@ class Configuration
|
||||
return $this->gameDaysPerDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a textual representation of the configuration, for debugging
|
||||
* purposes.
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
$s = "";
|
||||
|
||||
@@ -7,13 +7,20 @@ use Symfony\Component\Console\Command\Command;
|
||||
|
||||
use LotGD\Core\Game;
|
||||
|
||||
/**
|
||||
* Parent class for daenerys tool commands.
|
||||
*/
|
||||
abstract class BaseCommand extends Command
|
||||
{
|
||||
protected $game;
|
||||
|
||||
|
||||
/**
|
||||
* Construct the command, using the provided Game.
|
||||
* @param Game $game
|
||||
*/
|
||||
public function __construct(Game $game)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->game = $game;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,23 @@ namespace LotGD\Core\Console\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Daenerys command to start a PHP REPL with a basic game set up.
|
||||
*/
|
||||
class ConsoleCommand extends BaseCommand
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('console')
|
||||
->setDescription('Start a shell to interact with the game.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
print("Daenerys console, the dragon prompt. lotgd/core " . \LotGD\Core\Game::getVersion() . ".\n");
|
||||
|
||||
@@ -10,14 +10,23 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
use LotGD\Core\Console\Main;
|
||||
use LotGD\Core\Game;
|
||||
|
||||
/**
|
||||
* Danerys command to initiate the database with default values.
|
||||
*/
|
||||
class DatabaseInitCommand extends BaseCommand
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('database:init')
|
||||
->setDescription('Initiates database with default values.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->game->getEntityManager()->flush();
|
||||
|
||||
@@ -9,14 +9,23 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
use LotGD\Core\Exceptions\ClassNotFoundException;
|
||||
use LotGD\Core\Exceptions\ModuleAlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Danerys command to register and initiate any newly installed modules.
|
||||
*/
|
||||
class ModuleRegisterCommand extends BaseCommand
|
||||
{
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('module:register')
|
||||
->setDescription('Register and initialize any newly installed modules');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$modules = $this->game->getComposerManager()->getModulePackages();
|
||||
|
||||
@@ -6,14 +6,23 @@ namespace LotGD\Core\Console\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Danerys command to validate installed modules.
|
||||
*/
|
||||
class ModuleValidateCommand extends BaseCommand
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('module:validate')
|
||||
->setDescription('Validate installed modules');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$results = $this->game->getModuleManager()->validate();
|
||||
|
||||
+18
-6
@@ -14,11 +14,17 @@ use LotGD\Core\Console\Command\{
|
||||
ConsoleCommand
|
||||
};
|
||||
|
||||
/**
|
||||
* Main execution class for the daenerys tool.
|
||||
*/
|
||||
class Main {
|
||||
private $application;
|
||||
private $bootstrap;
|
||||
private $game;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new daenerys tool instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->application = new Application();
|
||||
@@ -26,27 +32,33 @@ class Main {
|
||||
$this->application->setName("daenerys 🐲 ");
|
||||
$this->application->setVersion("0.0.1 (lotgd/core version " . \LotGD\Core\Game::getVersion() . ")");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add supported commands, including those configured from lotgd.yml files.
|
||||
*/
|
||||
protected function addCommands()
|
||||
{
|
||||
$this->application->add(new ModuleValidateCommand($this->game));
|
||||
$this->application->add(new ModuleRegisterCommand($this->game));
|
||||
$this->application->add(new DatabaseInitCommand($this->game));
|
||||
$this->application->add(new ConsoleCommand($this->game));
|
||||
|
||||
|
||||
// Add additional ones
|
||||
$this->bootstrap->addDaenerysCommands($this->application);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run the danerys tool.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Bootstrap application
|
||||
$this->bootstrap = new Bootstrap();
|
||||
$this->game = $this->bootstrap->getGame();
|
||||
|
||||
|
||||
// Add commands
|
||||
$this->addCommands();
|
||||
|
||||
|
||||
// Run
|
||||
$this->application->run();
|
||||
}
|
||||
|
||||
+21
-4
@@ -4,8 +4,15 @@ declare (strict_types = 1);
|
||||
|
||||
namespace LotGD\Core;
|
||||
|
||||
/**
|
||||
* A collection of random number generators, with various distributions.
|
||||
*/
|
||||
class DiceBag
|
||||
{
|
||||
/**
|
||||
* Returns true $p percent of the time, where $p is between 0 and 1.
|
||||
* @param float $p
|
||||
*/
|
||||
public function chance(float $p): bool
|
||||
{
|
||||
$r = $this->uniform(0., 1.);
|
||||
@@ -13,11 +20,21 @@ class DiceBag
|
||||
return $r < $p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a uniformly randomly number between $min and $max.
|
||||
* @param float $min
|
||||
* @param float $max
|
||||
*/
|
||||
public function uniform(float $min, float $max): float
|
||||
{
|
||||
return (mt_rand(0, 100) / 100.0) * ($max - $min) + $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a normally distributed random number between $min and $max.
|
||||
* @param float $min
|
||||
* @param float $max
|
||||
*/
|
||||
public function normal(float $min, float $max): float
|
||||
{
|
||||
if ($min > $max) {
|
||||
@@ -38,7 +55,7 @@ class DiceBag
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function has uniform distribution except for the extreme values, which are
|
||||
* half as likely to happen.
|
||||
@@ -53,14 +70,14 @@ class DiceBag
|
||||
if (is_null($min)) {
|
||||
return mt_rand();
|
||||
}
|
||||
|
||||
|
||||
$min *= 1000;
|
||||
|
||||
|
||||
if (is_null($max)) {
|
||||
return (int)round(mt_rand($min)/1000, 0);
|
||||
}
|
||||
$max *= 1000;
|
||||
|
||||
|
||||
if ($min === $max) {
|
||||
return (int)round($min/1000, 0);
|
||||
}
|
||||
|
||||
+7
-1
@@ -8,6 +8,9 @@ use Monolog\Logger;
|
||||
|
||||
use LotGD\Core\Models\Character;
|
||||
|
||||
/**
|
||||
* The main game class.
|
||||
*/
|
||||
class Game
|
||||
{
|
||||
private $entityManager;
|
||||
@@ -16,7 +19,10 @@ class Game
|
||||
private $moduleManager;
|
||||
private $logger;
|
||||
private $configuration;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a game. You probably want to use Bootstrap to do this.
|
||||
*/
|
||||
public function __construct(
|
||||
Configuration $configuration,
|
||||
Logger $logger,
|
||||
|
||||
@@ -6,12 +6,12 @@ namespace LotGD\Core\Models\BattleEvents;
|
||||
use LotGD\Core\Exceptions\BattleEventException;
|
||||
|
||||
/**
|
||||
* BattleEvent
|
||||
* A representation of something that happened in battle.
|
||||
*/
|
||||
class BattleEvent
|
||||
{
|
||||
{
|
||||
private $applied = false;
|
||||
|
||||
|
||||
/**
|
||||
* Applies the event.
|
||||
* @throws BattleEventException
|
||||
@@ -21,10 +21,10 @@ class BattleEvent
|
||||
if ($this->applied === true) {
|
||||
throw new BattleEventException("Cannot apply an event more than once.");
|
||||
}
|
||||
|
||||
|
||||
$this->applied = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string describing the event.
|
||||
* @param \LotGD\Core\Models\BattleEvents\Game $game
|
||||
@@ -36,7 +36,7 @@ class BattleEvent
|
||||
if ($this->applied === false) {
|
||||
throw new BattleEventException("Buff needs to get applied before decoration.");
|
||||
}
|
||||
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,21 +6,32 @@ namespace LotGD\Core\Models\BattleEvents;
|
||||
use LotGD\Core\Exceptions\BattleEventException;
|
||||
|
||||
/**
|
||||
* BattleEvent
|
||||
* A battle event representing a message generated by a buff.
|
||||
*/
|
||||
class BuffMessageEvent extends BattleEvent
|
||||
{
|
||||
{
|
||||
private $message = "";
|
||||
|
||||
|
||||
/**
|
||||
* Create a new BuffMessageEvent.
|
||||
* @param string $message The message from the buff.
|
||||
*/
|
||||
public function __construct(string $message) {
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the message.
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage(): string
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
return $message;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace LotGD\Core\Models\BattleEvents;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
* Description of CriticalHitEvent
|
||||
* Battle event representing a stronger than average attack.
|
||||
*/
|
||||
class CriticalHitEvent extends BattleEvent
|
||||
{
|
||||
@@ -14,17 +14,25 @@ class CriticalHitEvent extends BattleEvent
|
||||
protected $attacker;
|
||||
/** @var int */
|
||||
protected $criticalAttackValue;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a CriticalHitEvent with attacker $attacker.
|
||||
* @param FighterInterface $attacker
|
||||
* @param int $criticalAttackValue
|
||||
*/
|
||||
public function __construct(FighterInterface $attacker, int $criticalAttackValue)
|
||||
{
|
||||
$this->attacker = $attacker;
|
||||
$this->criticalAttackValue = $criticalAttackValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
$pureAttackersAttack = $this->attacker->getAttack($game, true);
|
||||
|
||||
|
||||
if ($this->criticalAttackValue > $pureAttackersAttack * 4) {
|
||||
return "You execute a MEGA power move!!!";
|
||||
} elseif ($this->criticalAttackValue > $pureAttackersAttack * 3) {
|
||||
|
||||
@@ -9,24 +9,30 @@ use LotGD\Core\Models\FighterInterface;
|
||||
* BattleEvent
|
||||
*/
|
||||
class DamageEvent extends BattleEvent
|
||||
{
|
||||
{
|
||||
/** @var FighterInstance */
|
||||
protected $attacker;
|
||||
/** @var FighterInstance */
|
||||
protected $defender;
|
||||
/** @var int Damage applied */
|
||||
protected $damage;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new DamageEvent of $attacker attacking $defender.
|
||||
* @param FighterInterface $attacker
|
||||
* @param FighterInterface $defender
|
||||
* @param int $damage
|
||||
*/
|
||||
public function __construct(FighterInterface $attacker, FighterInterface $defender, int $damage)
|
||||
{
|
||||
$this->attacker = $attacker;
|
||||
$this->defender = $defender;
|
||||
$this->damage = $damage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the damage that is applied in this fight.
|
||||
*
|
||||
*
|
||||
* If the damage is > 0, the damage is applied to the defender. If it's < 0, it's applied to the attacker.
|
||||
* @return int
|
||||
*/
|
||||
@@ -34,33 +40,31 @@ class DamageEvent extends BattleEvent
|
||||
{
|
||||
return $this->damage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies the damage.
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function apply()
|
||||
{
|
||||
parent::apply();
|
||||
|
||||
|
||||
if ($this->damage !== 0) {
|
||||
// Only damage the victim if there is an actual effect
|
||||
$victim = $this->damage > 0 ? $this->defender : $this->attacker;
|
||||
$victim->damage(abs($this->damage));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string describing the event.
|
||||
* @param \LotGD\Core\Models\BattleEvents\Game $game
|
||||
* @return string
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
parent::decorate($game);
|
||||
|
||||
|
||||
$attackersName = $this->attacker->getDisplayName();
|
||||
$defendersName = $this->defender->getDisplayName();
|
||||
|
||||
|
||||
if ($this->damage === 0) {
|
||||
if ($this->attacker === $game->getCharacter()) {
|
||||
return "You try to hit {$defendersName} but MISS!";
|
||||
|
||||
@@ -6,33 +6,49 @@ namespace LotGD\Core\Models\BattleEvents;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
* BattleEvent
|
||||
* Damage event where damage is the result of a life tap.
|
||||
*/
|
||||
class DamageLifetapEvent extends BattleEvent
|
||||
{
|
||||
{
|
||||
/** @var \LotGD\Core\Models\FighterInterface */
|
||||
protected $target;
|
||||
/** @var int */
|
||||
protected $healAmount;
|
||||
/** @var string */
|
||||
protected $message;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new DamageLifetapEvent where healing amount is $healAmount and
|
||||
* target is $target.
|
||||
* $message can contain '{target}' and '{damage}'
|
||||
* which will be replaced by the name of the target and the damage, respectively.
|
||||
* @param FighterInterface $target
|
||||
* @param int $healAmount
|
||||
* @param string $message
|
||||
*/
|
||||
public function __construct(FighterInterface $target, int $healAmount, string $message)
|
||||
{
|
||||
$this->target = $target;
|
||||
$this->healAmount = $healAmount;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the heal amount.
|
||||
* @return int
|
||||
*/
|
||||
public function getHealAmount(): int
|
||||
{
|
||||
return $this->healAmount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function apply()
|
||||
{
|
||||
parent::apply();
|
||||
|
||||
|
||||
if ($this->healAmount === 0) {
|
||||
return;
|
||||
} elseif ($this->healAmount > 0) {
|
||||
@@ -41,14 +57,17 @@ class DamageLifetapEvent extends BattleEvent
|
||||
$this->target->setHealth($this->target->getHealth() + $this->healAmount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
parent::decorate($game);
|
||||
|
||||
|
||||
return str_replace(
|
||||
[
|
||||
"{target}",
|
||||
"{target}",
|
||||
"{damage}"
|
||||
],
|
||||
[
|
||||
|
||||
@@ -6,24 +6,33 @@ namespace LotGD\Core\Models\BattleEvents;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
* BattleEvent
|
||||
* A battle event representing damage being reflected back on the attacker.
|
||||
*/
|
||||
class DamageReflectionEvent extends BattleEvent
|
||||
{
|
||||
{
|
||||
/** @var \LotGD\Core\Models\FighterInterface */
|
||||
protected $target;
|
||||
/** @var int */
|
||||
protected $damage;
|
||||
/** @var string */
|
||||
protected $message;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a DamageReflectionEvent with the target $target, damage amount
|
||||
* $damage and the message $message.
|
||||
* $message can contain '{target}' and '{damage}'
|
||||
* which will be replaced by the name of the target and the damage, respectively.
|
||||
* @param FighterInterface $target
|
||||
* @param int $damage
|
||||
* @param string $message
|
||||
*/
|
||||
public function __construct(FighterInterface $target, int $damage, string $message)
|
||||
{
|
||||
$this->target = $target;
|
||||
$this->damage = $damage;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the damage
|
||||
* @return int
|
||||
@@ -32,14 +41,14 @@ class DamageReflectionEvent extends BattleEvent
|
||||
{
|
||||
return $this->damage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Applies the damage
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function apply()
|
||||
{
|
||||
parent::apply();
|
||||
|
||||
|
||||
if ($this->damage === 0) {
|
||||
return;
|
||||
} elseif ($this->damage > 0) {
|
||||
@@ -48,19 +57,17 @@ class DamageReflectionEvent extends BattleEvent
|
||||
$this->target->setHealth($this->target->getHealth() - $this->damage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string describing the event
|
||||
* @param \LotGD\Core\Models\BattleEvents\Game $game
|
||||
* @return string
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
parent::decorate($game);
|
||||
|
||||
|
||||
return str_replace(
|
||||
[
|
||||
"{target}",
|
||||
"{target}",
|
||||
"{damage}"
|
||||
],
|
||||
[
|
||||
|
||||
@@ -6,22 +6,32 @@ namespace LotGD\Core\Models\BattleEvents;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
* BattleEvent
|
||||
* BattleEvent representing a fighter's death.
|
||||
*/
|
||||
class DeathEvent extends BattleEvent
|
||||
{
|
||||
{
|
||||
protected $victim;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a DeathEvent for victim $victim.
|
||||
* @param FighterInterface $victim
|
||||
*/
|
||||
public function __construct(FighterInterface $victim)
|
||||
{
|
||||
$this->victim = $victim;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function apply()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
return "";
|
||||
|
||||
@@ -7,14 +7,23 @@ use LotGD\Core\Exceptions\BattleEventException;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
* BattleEvent
|
||||
* Battle event that represents damage to a minion.
|
||||
*/
|
||||
class MinionDamageEvent extends BattleEvent
|
||||
{
|
||||
protected $target;
|
||||
protected $damage;
|
||||
protected $message;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a MinionDamageEvent against $target, with damage $damage
|
||||
* and message $message.
|
||||
* $message can contain '{target}' and '{amount}'
|
||||
* which will be replaced by the name of the target and the damage, respectively.
|
||||
* @param FighterInterface $target
|
||||
* @param int $damage
|
||||
* @param string $message
|
||||
*/
|
||||
public function __construct(
|
||||
FighterInterface $target,
|
||||
int $damage,
|
||||
@@ -24,11 +33,14 @@ class MinionDamageEvent extends BattleEvent
|
||||
$this->damage = $damage;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
parent::decorate();
|
||||
|
||||
|
||||
return str_replace(
|
||||
[
|
||||
"{target}",
|
||||
@@ -41,7 +53,10 @@ class MinionDamageEvent extends BattleEvent
|
||||
$this->message
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function apply()
|
||||
{
|
||||
parent::apply();
|
||||
|
||||
@@ -7,7 +7,7 @@ use LotGD\Core\Exceptions\BattleEventException;
|
||||
use LotGD\Core\Models\FighterInterface;
|
||||
|
||||
/**
|
||||
* BattleEvent
|
||||
* Battle event that represents regenerating health.
|
||||
*/
|
||||
class RegenerationBuffEvent extends BattleEvent
|
||||
{
|
||||
@@ -15,7 +15,18 @@ class RegenerationBuffEvent extends BattleEvent
|
||||
protected $regeneration;
|
||||
protected $effectMessage;
|
||||
protected $noEffectMessage;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a RegenerationBuffEvent against $target, with regenerating value
|
||||
* $regeneration. $effectMessage is shown if there is an effect of
|
||||
* regeneration, and $noEffectMessage is shown if the $regeneation is 0.
|
||||
* $effectMessage and $noEffectMessage can contain '{target}' and '{amount}'
|
||||
* which will be replaced by the name of the target and the damage, respectively.
|
||||
* @param FighterInterface $target
|
||||
* @param int $regeneration
|
||||
* @param string $effectMessage
|
||||
* @param string $noEffectMessage
|
||||
*/
|
||||
public function __construct(
|
||||
FighterInterface $target,
|
||||
int $regeneration,
|
||||
@@ -27,11 +38,14 @@ class RegenerationBuffEvent extends BattleEvent
|
||||
$this->effectMessage = $effectMessage;
|
||||
$this->noEffectMessage = $noEffectMessage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function decorate(Game $game): string
|
||||
{
|
||||
parent::decorate();
|
||||
|
||||
|
||||
if ($this->regeneration === 0) {
|
||||
return str_replace(
|
||||
"{target}",
|
||||
@@ -53,14 +67,17 @@ class RegenerationBuffEvent extends BattleEvent
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function apply()
|
||||
{
|
||||
parent::apply();
|
||||
|
||||
|
||||
$healthLacking = $this->target->getMaxHealth() - $this->target->getHealth();
|
||||
$healthLeft = $this->target->getHealth();
|
||||
|
||||
|
||||
if ($this->regeneration > 0) {
|
||||
// Healing
|
||||
if ($healthLacking === 0) {
|
||||
@@ -79,7 +96,7 @@ class RegenerationBuffEvent extends BattleEvent
|
||||
$this->regeneration = - $healthLeft;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->target->setHealth($this->target->getHealth() + $this->regeneration);
|
||||
}
|
||||
}
|
||||
|
||||
+31
-28
@@ -32,7 +32,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
use Creator;
|
||||
use SoftDeletable;
|
||||
use PropertyManager;
|
||||
|
||||
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
/** @Column(type="string", length=50); */
|
||||
@@ -49,7 +49,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
private $properties;
|
||||
/** @OneToMany(targetEntity="CharacterViewpoint", mappedBy="owner", cascade={"persist"}) */
|
||||
private $characterViewpoint;
|
||||
/**
|
||||
/**
|
||||
* @ManyToMany(targetEntity="MessageThread", inversedBy="participants", cascade={"persist"})
|
||||
* @JoinTable(
|
||||
* name="message_threads_x_characters",
|
||||
@@ -66,14 +66,14 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
private $buffs;
|
||||
/** @var BuffList */
|
||||
private $buffList;
|
||||
|
||||
|
||||
/** @var array */
|
||||
private static $fillable = [
|
||||
"name",
|
||||
"maxHealth",
|
||||
"level",
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Creates a character at full health
|
||||
*/
|
||||
@@ -83,7 +83,10 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
$newCharacter->setHealth($newCharacter->getMaxHealth());
|
||||
return $newCharacter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct an empty character.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->properties = new ArrayCollection();
|
||||
@@ -91,7 +94,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
$this->buffs = new ArrayCollection();
|
||||
$this->messageThreads = new ArrayCollection();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the entity's id
|
||||
* @return int The id
|
||||
@@ -100,7 +103,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the character's name and generates the display name
|
||||
* @param string $name The name to set
|
||||
@@ -110,7 +113,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
$this->name = $name;
|
||||
$this->generateDisplayName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the character's name
|
||||
* @return string The name
|
||||
@@ -119,7 +122,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates the display name which is a composition of title and name.
|
||||
*/
|
||||
@@ -127,7 +130,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
$this->displayName = $this->name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns displayName, a combination of title, name and suffix, mixed with colour codes
|
||||
* @return string The displayName
|
||||
@@ -136,7 +139,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
return $this->displayName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the maximum health of a character to a given value. It also sets the
|
||||
* health if none has been set yet.
|
||||
@@ -146,7 +149,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
$this->maxHealth = $maxHealth;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the maximum health
|
||||
* @return int
|
||||
@@ -155,7 +158,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
return $this->maxHealth;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets current health
|
||||
* @param int $health
|
||||
@@ -164,7 +167,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
$this->health = $health;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns current health
|
||||
* @return int
|
||||
@@ -173,7 +176,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
return $this->health;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Does damage to the entity.
|
||||
* @param int $damage
|
||||
@@ -181,12 +184,12 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
public function damage(int $damage)
|
||||
{
|
||||
$this->health -= $damage;
|
||||
|
||||
|
||||
if ($this->health < 0) {
|
||||
$this->health = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Heals the enemy
|
||||
* @param int $heal
|
||||
@@ -195,12 +198,12 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
public function heal(int $heal, bool $overheal = false)
|
||||
{
|
||||
$this->health += $heal;
|
||||
|
||||
|
||||
if ($this->health > $this->getMaxHealth() && $overheal === false) {
|
||||
$this->health = $this->getMaxHealth();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the character is alive.
|
||||
* @return bool
|
||||
@@ -209,7 +212,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
return $this->getHealth() > 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the character's level
|
||||
* @return int
|
||||
@@ -218,7 +221,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the character's virtual attribute "attack"
|
||||
*/
|
||||
@@ -226,7 +229,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
return $this->level * 2;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the character's virtual attribute "defense"
|
||||
*/
|
||||
@@ -234,7 +237,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
return $this->level * 2;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the character's level
|
||||
* @param int $level
|
||||
@@ -243,7 +246,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
{
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current character scene and creates one if it is non-existant
|
||||
* @return \LotGD\Core\Models\CharacterViewpoint
|
||||
@@ -254,10 +257,10 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
$characterScene = CharacterViewpoint::Create(["owner" => $this]);
|
||||
$this->characterViewpoint->add($characterScene);
|
||||
}
|
||||
|
||||
|
||||
return $this->characterViewpoint->first();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of buffs
|
||||
*/
|
||||
@@ -266,7 +269,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
$this->buffList = $this->buffList ?? new BuffList($this->buffs);
|
||||
return $this->buffList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a buff to the buffList
|
||||
*/
|
||||
@@ -278,7 +281,7 @@ class Character implements CharacterInterface, CreateableInterface
|
||||
$this->getBuffs()->renew($buff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of message threads this user has created.
|
||||
* @return Collection
|
||||
|
||||
@@ -47,6 +47,11 @@ class EventSubscription implements CreateableInterface
|
||||
return $this->pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pattern used to match against event names.
|
||||
* Format is PHP regular expressions.
|
||||
* @param string $pattern
|
||||
*/
|
||||
public function setPattern(string $pattern)
|
||||
{
|
||||
$this->pattern = $pattern;
|
||||
@@ -61,6 +66,10 @@ class EventSubscription implements CreateableInterface
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the class name subscribed to this event.
|
||||
* @param string $class
|
||||
*/
|
||||
public function setClass(string $class)
|
||||
{
|
||||
$this->class = $class;
|
||||
@@ -75,6 +84,10 @@ class EventSubscription implements CreateableInterface
|
||||
return $this->library;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the library that this subscription is part of, in vendor/module format.
|
||||
* @param string $library
|
||||
*/
|
||||
public function setLibrary(string $library)
|
||||
{
|
||||
$this->library = $library;
|
||||
|
||||
@@ -27,6 +27,9 @@ class Module implements SaveableInterface
|
||||
/** @Column(type="datetime") */
|
||||
private $createdAt;
|
||||
|
||||
/**
|
||||
* Construct a new module entry.
|
||||
*/
|
||||
public function __construct(string $library)
|
||||
{
|
||||
$this->createdAt = new \DateTime();
|
||||
|
||||
@@ -11,17 +11,20 @@ use Doctrine\ORM\QueryBuilder;
|
||||
use LotGD\Core\Models\Character;
|
||||
|
||||
/**
|
||||
* Description of CharacterRepository
|
||||
* Convenience methods to query for characters.
|
||||
*/
|
||||
class CharacterRepository extends EntityRepository
|
||||
{
|
||||
const SKIP_SOFTDELETED = 0;
|
||||
const INCLUDE_SOFTDELETED = 1;
|
||||
const ONLY_SOFTDELETED = 2;
|
||||
|
||||
protected function modifyQuery(QueryBuilder $queryBuilder, int $level)
|
||||
|
||||
/**
|
||||
* Change the provided query to handle the specified deletion mode.
|
||||
*/
|
||||
protected function modifyQuery(QueryBuilder $queryBuilder, int $deletes)
|
||||
{
|
||||
switch ($level) {
|
||||
switch ($deletes) {
|
||||
case self::SKIP_SOFTDELETED:
|
||||
$queryBuilder->andWhere(
|
||||
$queryBuilder->expr()->orX(
|
||||
@@ -30,7 +33,7 @@ class CharacterRepository extends EntityRepository
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
|
||||
case self::ONLY_SOFTDELETED:
|
||||
$queryBuilder->andWhere(
|
||||
$queryBuilder->expr()->lte('c.deletedAt', 'CURRENT_TIMESTAMP()')
|
||||
@@ -38,32 +41,38 @@ class CharacterRepository extends EntityRepository
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function find($id, int $level = self::SKIP_SOFTDELETED)
|
||||
|
||||
/**
|
||||
* Find a character by ID.
|
||||
*/
|
||||
public function find($id, int $deletes = self::SKIP_SOFTDELETED)
|
||||
{
|
||||
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
|
||||
$queryBuilder->select("c")
|
||||
->from(Character::class, "c")
|
||||
->where($queryBuilder->expr()->eq("c.id", ":id"))
|
||||
->setParameter("id", $id);
|
||||
|
||||
$this->modifyQuery($queryBuilder, $level);
|
||||
|
||||
|
||||
$this->modifyQuery($queryBuilder, $deletes);
|
||||
|
||||
try {
|
||||
return $queryBuilder->getQuery()->getSingleResult();
|
||||
} catch (NoResultException $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function findAll(int $level = self::SKIP_SOFTDELETED)
|
||||
|
||||
/**
|
||||
* Return all characters.
|
||||
*/
|
||||
public function findAll(int $deletes = self::SKIP_SOFTDELETED)
|
||||
{
|
||||
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
|
||||
$queryBuilder->select("c")
|
||||
->from(Character::class, "c");
|
||||
|
||||
$this->modifyQuery($queryBuilder, $level);
|
||||
|
||||
|
||||
$this->modifyQuery($queryBuilder, $deletes);
|
||||
|
||||
return $queryBuilder->getQuery()->getResult();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,35 +7,48 @@ namespace LotGD\Core\Models;
|
||||
use LotGD\Core\Tools\Model\MockCharacter;
|
||||
|
||||
/**
|
||||
* Provides a basic system character to provide system information.
|
||||
*
|
||||
* Whenever a message should be sent by the System instead of a standard character,
|
||||
* Provides a basic system character to serve as an anonymous user.
|
||||
*
|
||||
* Whenever a message should be sent by the System instead of a standard character,
|
||||
* this class is returned by the entity containing the message instead of a standard
|
||||
* character instance.
|
||||
*/
|
||||
class SystemCharacter implements CharacterInterface
|
||||
{
|
||||
use MockCharacter;
|
||||
|
||||
|
||||
static $instance = null;
|
||||
static $characterName = "System";
|
||||
|
||||
|
||||
/**
|
||||
* Return an instance of SystemCharacter.
|
||||
* @return SystemCharacter
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
self::$instance = self::$instance ?? new self();
|
||||
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Private constructor. Use the static method getInstance().
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getDisplayName(): string
|
||||
{
|
||||
return self::$characterName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return self::$characterName;
|
||||
|
||||
@@ -19,6 +19,7 @@ class ModuleManager
|
||||
private $g;
|
||||
|
||||
/**
|
||||
* Construct a module manager.
|
||||
* @param Game $g The game.
|
||||
*/
|
||||
public function __construct(Game $g)
|
||||
@@ -26,6 +27,9 @@ class ModuleManager
|
||||
$this->g = $g;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the package's event subscriptions as an array of regex patterns.
|
||||
*/
|
||||
private static function getPackageSubscriptions(PackageInterface $package): array
|
||||
{
|
||||
$name = $package->getName();
|
||||
|
||||
@@ -5,6 +5,9 @@ namespace LotGD\Core;
|
||||
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* Configurable way to convert back and forth between real time and game time.
|
||||
*/
|
||||
class TimeKeeper
|
||||
{
|
||||
private $adjustedEpoch;
|
||||
@@ -19,6 +22,12 @@ class TimeKeeper
|
||||
private $secondsPerGameMinute;
|
||||
private $secondsPerGameSecond;
|
||||
|
||||
/**
|
||||
* Construct a TimeKeeper with required configuration.
|
||||
* @param DateTime $gameEpoch When in real time is game day 0.
|
||||
* @param int $gameOffsetSeconds How many seconds from midnight on the epoch should the first game day start.
|
||||
* @param int $gameDaysPerDay How many game days are in one real day.
|
||||
*/
|
||||
public function __construct(DateTime $gameEpoch, int $gameOffsetSeconds, int $gameDaysPerDay)
|
||||
{
|
||||
$gameEpochCopy = clone($gameEpoch);
|
||||
@@ -34,6 +43,11 @@ class TimeKeeper
|
||||
$this->secondsPerGameSecond = $this->secondsPerGameMinute / 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a user who is interating with the game now and last
|
||||
* interacted at $lastInteractionTime should experience a New Day event.
|
||||
* @param DateTime $lastInteractionTime
|
||||
*/
|
||||
public function isNewDay(DateTime $lastInteractionTime): bool
|
||||
{
|
||||
if ($lastInteractionTime == null) {
|
||||
@@ -47,11 +61,20 @@ class TimeKeeper
|
||||
return $d1 != $d2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current game time.
|
||||
* @return DateTime
|
||||
*/
|
||||
public function gameTime(): DateTime
|
||||
{
|
||||
return $this->convertToGameTime(new DateTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a game time, convert it to a real time.
|
||||
* @param DateTime $time Game time to convert.
|
||||
* @return DateTime Real time corresponding to game time $time.
|
||||
*/
|
||||
public function convertFromGameTime(
|
||||
DateTime $time
|
||||
): DateTime {
|
||||
@@ -68,6 +91,11 @@ class TimeKeeper
|
||||
return $ret->add($this->interval(0, 0, 0, 0, (int) $seconds));
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a real time, convert it to a game time.
|
||||
* @param DateTime $time Real time to convert.
|
||||
* @return DateTime Game time corresponding to real time $time.
|
||||
*/
|
||||
public function convertToGameTime(
|
||||
DateTime $time
|
||||
): DateTime {
|
||||
@@ -97,6 +125,9 @@ class TimeKeeper
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to generate a DateInterval from an exploded date.
|
||||
*/
|
||||
private function interval(
|
||||
int $years,
|
||||
int $days,
|
||||
|
||||
@@ -11,6 +11,9 @@ use LotGD\Core\Exceptions\KeyNotFoundException;
|
||||
use LotGD\Core\Exceptions\NotImplementedException;
|
||||
use LotGD\Core\Exceptions\WrongTypeException;
|
||||
|
||||
/**
|
||||
* A one-to-many relation between two entities.
|
||||
*/
|
||||
class OneToManyCollection implements Collection
|
||||
{
|
||||
/** @var string */
|
||||
@@ -21,9 +24,9 @@ class OneToManyCollection implements Collection
|
||||
private $collection;
|
||||
/** @var int */
|
||||
private $numberOfRows;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor for a one to many colelction of type $typeClass.
|
||||
* @param EntityManagerInterface $entityManager
|
||||
* @param string $typeClass
|
||||
* @throws ClassNotFoundException
|
||||
@@ -33,26 +36,25 @@ class OneToManyCollection implements Collection
|
||||
if(class_exists($typeClass) === false) {
|
||||
throw new ClassNotFoundException(sprintf("The class %s has not been found.", $typeClass));
|
||||
}
|
||||
|
||||
|
||||
$this->entityManager = $entityManager;
|
||||
$this->typeClass = $typeClass;
|
||||
|
||||
|
||||
// Load eagerly everything.
|
||||
$this->collection = $this->entityManager->getRepository($this->typeClass)->findAll();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns the class this collection consists of.
|
||||
* Returns the class this collection consists of.
|
||||
* @return string
|
||||
*/
|
||||
public function getTypeClass(): ClassMetadata
|
||||
{
|
||||
return $this->entityManager->getClassMetadata($this->typeClass);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Counts the number of settings stored
|
||||
* @return int
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
@@ -64,7 +66,7 @@ class OneToManyCollection implements Collection
|
||||
->getQuery()
|
||||
->getSingleScalarResult();
|
||||
}
|
||||
|
||||
|
||||
if ($this->collection === null) {
|
||||
return $this->numberOfRows;
|
||||
}
|
||||
@@ -74,7 +76,7 @@ class OneToManyCollection implements Collection
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the element matches the typeClass of this collection
|
||||
* Checks if the element matches the type of this collection.
|
||||
* @param mixed $element
|
||||
* @throws WrongTypeException
|
||||
*/
|
||||
@@ -84,25 +86,24 @@ class OneToManyCollection implements Collection
|
||||
throw new WrongTypeException(sprintf('$element needs to be of type %s', $this->typeClass));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds an element to the collection
|
||||
* @param mixed $element
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function add($element)
|
||||
{
|
||||
$this->checkElementType($element);
|
||||
|
||||
|
||||
if ($this->collection === null) {
|
||||
$this->collection = [];
|
||||
}
|
||||
|
||||
|
||||
$this->collection[] = $element;
|
||||
$this->entityManager->persist($element);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears the collection
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
@@ -112,11 +113,9 @@ class OneToManyCollection implements Collection
|
||||
->execute();
|
||||
$this->collection = [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if a item is contained in this collection
|
||||
* @param type $element
|
||||
* @return bool
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function contains($element): bool
|
||||
{
|
||||
@@ -126,22 +125,20 @@ class OneToManyCollection implements Collection
|
||||
catch (WrongTypeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return in_array($element, $this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if this the collection is empty
|
||||
* @return bool
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes an element from this collection by the given key
|
||||
* @param int|string $key
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function remove($key)
|
||||
{
|
||||
@@ -150,10 +147,9 @@ class OneToManyCollection implements Collection
|
||||
$this->removeElement($element);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes an element from this collection
|
||||
* @param type $element
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function removeElement($element)
|
||||
{
|
||||
@@ -163,18 +159,17 @@ class OneToManyCollection implements Collection
|
||||
unset($this->collection[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if this collection contains a certain key
|
||||
* @param int|string $key
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function containsKey($key)
|
||||
{
|
||||
return isset($this->collection[$key]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the element saved at the given position
|
||||
* Returns the element saved with the given key.
|
||||
* @param int|string $key
|
||||
* @return type
|
||||
* @throws KeyNotFoundException
|
||||
@@ -188,136 +183,174 @@ class OneToManyCollection implements Collection
|
||||
throw new KeyNotFoundException(sprintf("The key %s has not been found within the collection", $key));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all collection keys
|
||||
* @return array
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getKeys(): array
|
||||
{
|
||||
return array_keys($this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all collection values
|
||||
* @return array
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getValues(): array
|
||||
{
|
||||
return array_values($this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the element at position $key to $value.
|
||||
* @param int|string $key
|
||||
* @param mixed $value
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function set($key, $element)
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->checkElementType($element);
|
||||
|
||||
$this->checkElementType($value);
|
||||
|
||||
$this->remove($key);
|
||||
$this->collection[$key] = $element;
|
||||
$this->entityManager->persist($element);
|
||||
$this->collection[$key] = $value;
|
||||
$this->entityManager->persist($value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array representation of this collection
|
||||
* @return array
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->collection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
return first($this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
return last($this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return key($this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
return next($this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return current($this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function exists(\Closure $p): bool
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function filter(\Closure $p)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function forAll(\Closure $p)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function map(\Closure $p)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function partition(\Closure $p)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the index of a specific element
|
||||
* @param mixed $element
|
||||
* @return int|string
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function indexOf($element)
|
||||
{
|
||||
$this->checkElementType($element);
|
||||
return array_search($element, $this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function slice($offset, $length = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a Iterator over this collection
|
||||
* Gets a Iterator over this collection.
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetGet($key) {
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetSet($key, $element) {
|
||||
$this->set($key, $element);
|
||||
$this->set($key, $element);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetUnset($key) {
|
||||
$this->remove($key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetExists($key) {
|
||||
return isset($this->collection[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user