Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25341a677d | |||
| ccfb432e4d | |||
| 2a0bf5f038 | |||
| 4248dad033 | |||
| b89f6d7b0c | |||
| 6c4b1e15f4 | |||
| ddb7ae08a6 | |||
| 8ba04dade4 | |||
| 70243f4662 | |||
| 77b33d7385 | |||
| db49e63c99 | |||
| d90e4d0ba9 | |||
| ccbfa0553c | |||
| 04a5b59ea2 | |||
| 846ab6018e |
@@ -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/",
|
||||
|
||||
+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
|
||||
|
||||
+2
-2
@@ -388,8 +388,8 @@ 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,
|
||||
|
||||
+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 {
|
||||
|
||||
@@ -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
|
||||
@@ -176,4 +176,4 @@ class EventContextData
|
||||
"{$field} is not valid in this context, only {$this->getFormattedListOfFields()} are allowed."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,8 @@ class Character implements CharacterInterface, CreateableInterface, GameAwareInt
|
||||
"level",
|
||||
];
|
||||
|
||||
private $propertyClass = CharacterProperty::class;
|
||||
|
||||
/**
|
||||
* Creates a character at full health
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,8 @@ class GameConfiguration
|
||||
|
||||
/** @var ArrayCollection */
|
||||
private $properties;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
||||
+4
-32
@@ -38,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.
|
||||
* Use the Message Manager methods send() and sendSystemMessage() instead.
|
||||
* @param CharacterInterface $from
|
||||
* @param string $message
|
||||
* @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) {
|
||||
|
||||
@@ -34,6 +34,8 @@ class Module implements SaveableInterface
|
||||
/** @OneToMany(targetEntity="ModuleProperty", mappedBy="owner", cascade={"persist", "remove"}) */
|
||||
private $properties;
|
||||
|
||||
private $propertyClass = ModuleProperty::class;
|
||||
|
||||
/**
|
||||
* Construct a new module entry.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -68,7 +68,11 @@ trait PropertyManager
|
||||
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);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/bash -ex
|
||||
phpunit --stop-on-failure
|
||||
./vendor/bin/phpunit --stop-on-failure
|
||||
./vendor/bin/phpdoccheck -d src --no-ansi
|
||||
|
||||
@@ -33,6 +33,7 @@ class BattleTest extends CoreModelTestCase
|
||||
|
||||
public function getMockGame(Character $character): Game
|
||||
{
|
||||
mt_srand(0);
|
||||
$game = $this->getMockBuilder(Game::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
@@ -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();
|
||||
|
||||
@@ -95,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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user