362 lines
9.2 KiB
PHP
362 lines
9.2 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace LotGD\Core\Models;
|
|
|
|
use Doctrine\ORM\EntityManager;
|
|
use Doctrine\ORM\Mapping\Column;
|
|
use Doctrine\ORM\Mapping\Entity;
|
|
use Doctrine\ORM\Mapping\Id;
|
|
use Doctrine\ORM\Mapping\JoinColumn;
|
|
use Doctrine\ORM\Mapping\ManyToOne;
|
|
use Doctrine\ORM\Mapping\OneToOne;
|
|
use Doctrine\ORM\Mapping\Table;
|
|
|
|
use LotGD\Core\Action;
|
|
use LotGD\Core\ActionGroup;
|
|
use LotGD\Core\Exceptions\ArgumentException;
|
|
use LotGD\Core\Tools\Model\Creator;
|
|
use LotGD\Core\Tools\Model\SceneBasics;
|
|
use LotGD\Core\Tools\SceneDescription;
|
|
|
|
/**
|
|
* A Viewpoint is the current Scene a character is experiencing with
|
|
* all changes from modules included.
|
|
* @Entity
|
|
* @Table(name="viewpoints")
|
|
*/
|
|
class Viewpoint implements CreateableInterface
|
|
{
|
|
use Creator;
|
|
use SceneBasics;
|
|
|
|
/**
|
|
* @Id
|
|
* @OneToOne(targetEntity="Character", inversedBy="viewpoint", cascade="persist")
|
|
* @JoinColumn(fieldName="owner_id", referencedColumnName="id")
|
|
*/
|
|
private $owner;
|
|
/** @Column(type="array") */
|
|
private $actionGroups = [];
|
|
/** @Column(type="array") */
|
|
private $attachments = [];
|
|
/** @Column(type="array") */
|
|
private $data = [];
|
|
/**
|
|
* @ManyToOne(targetEntity="Scene")
|
|
* @JoinColumn(name="scene_id", referencedColumnName="id")
|
|
*/
|
|
private $scene;
|
|
|
|
/** @var SceneDescription */
|
|
private $_description;
|
|
|
|
/** @var array */
|
|
private static $fillable = [
|
|
"owner",
|
|
];
|
|
|
|
/**
|
|
* Returns the owner.
|
|
* @return \LotGD\Core\Models\Character
|
|
*/
|
|
public function getOwner(): Character
|
|
{
|
|
return $this->owner;
|
|
}
|
|
|
|
/**
|
|
* Sets the owner.
|
|
* @param \LotGD\Core\Models\Character $owner
|
|
*/
|
|
public function setOwner(Character $owner)
|
|
{
|
|
$this->owner = $owner;
|
|
}
|
|
|
|
/**
|
|
* Sets the description of this viewpoint.
|
|
* @param string $description
|
|
*/
|
|
public function setDescription(string $description): void
|
|
{
|
|
$this->description = $description;
|
|
$this->_description = new SceneDescription($description);
|
|
}
|
|
|
|
/**
|
|
* Clears the description.
|
|
*/
|
|
public function clearDescription(): void
|
|
{
|
|
$this->description = "";
|
|
$this->_description = new SceneDescription("");
|
|
}
|
|
|
|
/**
|
|
* Returns the current description as a string.
|
|
* @return string
|
|
*/
|
|
public function getDescription(): string
|
|
{
|
|
return $this->description;
|
|
}
|
|
|
|
/**
|
|
* Adds a paragraph to the existing description.
|
|
* @param string $paragraph
|
|
*/
|
|
public function addDescriptionParagraph(string $paragraph)
|
|
{
|
|
if ($this->_description === null) {
|
|
$this->_description = new SceneDescription($this->description);
|
|
}
|
|
|
|
$this->_description->addParagraph($paragraph);
|
|
$this->description = (string)$this->_description;
|
|
}
|
|
|
|
/**
|
|
* Copies the static data from a scene to this Viewpoint entity.
|
|
* @param \LotGD\Core\Models\Scene $scene
|
|
*/
|
|
public function changeFromScene(Scene $scene)
|
|
{
|
|
$this->setTitle($scene->getTitle());
|
|
$this->setDescription($scene->getDescription());
|
|
$this->setTemplate($scene->getTemplate());
|
|
$this->setScene($scene);
|
|
|
|
$this->setActionGroups([]);
|
|
$this->setAttachments([]);
|
|
$this->setData([]);
|
|
}
|
|
|
|
/**
|
|
* Returns a restoration point that can be used to reconstruct the current viewpoint.
|
|
* @return ViewpointSnapshot
|
|
*/
|
|
public function getSnapshot(): ViewpointSnapshot
|
|
{
|
|
$snapshot = new ViewpointSnapshot(
|
|
$this->getTitle(),
|
|
$this->getDescription(),
|
|
\get_class($this->getTemplate()),
|
|
$this->getActionGroups(),
|
|
$this->getAttachments(),
|
|
$this->getData()
|
|
);
|
|
|
|
return $snapshot;
|
|
}
|
|
|
|
/**
|
|
* Changes the current viewpoint to the state saved in the given restoration point.
|
|
* @param ViewpointSnapshot $snapshot
|
|
*/
|
|
public function changeFromSnapshot(EntityManager $entityManager, ViewpointSnapshot $snapshot)
|
|
{
|
|
$templateInstance = $entityManager->getRepository(SceneTemplate::class)->find($snapshot->getTemplate());
|
|
|
|
$this->setTitle($snapshot->getTitle());
|
|
$this->setDescription($snapshot->getDescription());
|
|
$this->setTemplate($templateInstance);
|
|
$this->setActionGroups($snapshot->getActionGroups());
|
|
$this->setAttachments($snapshot->getAttachments());
|
|
$this->setData($snapshot->getData());
|
|
}
|
|
|
|
/**
|
|
* Sets the template scene used to create this viewpoint.
|
|
* @param Scene $scene
|
|
*/
|
|
public function setScene(Scene $scene)
|
|
{
|
|
$this->scene = $scene;
|
|
}
|
|
|
|
/**
|
|
* Returns the template scene used to create this viewpoint.
|
|
* @return Scene|null
|
|
*/
|
|
public function getScene(): ?Scene
|
|
{
|
|
return $this->scene;
|
|
}
|
|
|
|
/**
|
|
* Returns all action groups.
|
|
* @return ActionGroup[]
|
|
*/
|
|
public function getActionGroups(): array
|
|
{
|
|
return $this->actionGroups;
|
|
}
|
|
|
|
/**
|
|
* Sets action groups.
|
|
* @param ActionGroup[] $actionGroups
|
|
*/
|
|
public function setActionGroups(array $actionGroups)
|
|
{
|
|
$this->actionGroups = $actionGroups;
|
|
}
|
|
|
|
/**
|
|
* Adds a new action group to a viewpoint.
|
|
* @param ActionGroup $group The new group to add.
|
|
* @param string|null $after Optional group id that comes before.
|
|
* @throws ArgumentException
|
|
*/
|
|
public function addActionGroup(ActionGroup $group, ?string $after = null): void
|
|
{
|
|
$groupId = $group->getId();
|
|
if ($this->findActionGroupById($groupId) == true) {
|
|
throw new ArgumentException("Group {$group} is already contained in this viewpoint.");
|
|
}
|
|
|
|
if ($after === null) {
|
|
$this->actionGroups[] = $group;
|
|
} else {
|
|
$groups = [];
|
|
foreach ($this->actionGroups as $g) {
|
|
if ($g->getId() == $after) {
|
|
$groups[] = $group;
|
|
}
|
|
$groups[] = $g;
|
|
}
|
|
$this->actionGroups = $groups;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns an action group by id or fails.
|
|
* @param string $actionGroupId
|
|
* @return ActionGroup|null
|
|
*/
|
|
public function findActionGroupById(string $actionGroupId): ?ActionGroup
|
|
{
|
|
$groups = $this->getActionGroups();
|
|
foreach ($groups as $g) {
|
|
if ($g->getId() == $actionGroupId) {
|
|
return $g;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Add the specified action to the group with the provided id. Does nothing
|
|
* if the id is not present.
|
|
* @param Action $action
|
|
* @param string $actionGroupId
|
|
*/
|
|
public function addActionToGroupId(Action $action, string $actionGroupId)
|
|
{
|
|
$actionGroups = $this->getActionGroups();
|
|
foreach ($actionGroups as $group) {
|
|
if ($group->getId() == $actionGroupId) {
|
|
$actions = $group->getActions();
|
|
$actions[] = $action;
|
|
$group->setActions($actions);
|
|
break;
|
|
}
|
|
}
|
|
$this->setActionGroups($actionGroups);
|
|
}
|
|
|
|
/**
|
|
* Returns all attachments.
|
|
* @return array
|
|
*/
|
|
public function getAttachments(): array
|
|
{
|
|
return $this->attachments;
|
|
}
|
|
|
|
/**
|
|
* Sets attachments.
|
|
* @param array $attachments
|
|
*/
|
|
public function setAttachments(array $attachments)
|
|
{
|
|
$this->attachments = $attachments;
|
|
}
|
|
|
|
/**
|
|
* Returns all data.
|
|
* @return array
|
|
*/
|
|
public function getData(): array
|
|
{
|
|
return $this->data;
|
|
}
|
|
|
|
/**
|
|
* Sets all data.
|
|
* @param array $data
|
|
*/
|
|
public function setData(array $data)
|
|
{
|
|
$this->data = $data;
|
|
}
|
|
|
|
/**
|
|
* Returns a single data field.
|
|
* @param string $fieldname Fieldname
|
|
* @param mixed $default Default value
|
|
* @return mixed
|
|
*/
|
|
public function getDataField(string $fieldname, $default = null)
|
|
{
|
|
return $this->data[$fieldname] ?? $default;
|
|
}
|
|
|
|
/**
|
|
* Sets a single data field.
|
|
* @param string $fieldname
|
|
* @param mixed $value
|
|
*/
|
|
public function setDataField(string $fieldname, $value)
|
|
{
|
|
$this->data[$fieldname] = $value;
|
|
}
|
|
|
|
/**
|
|
* Returns the action that corresponds to the given ID, if present.
|
|
* @param string $id
|
|
* @return Action|null
|
|
*/
|
|
public function findActionById(string $id): ?Action
|
|
{
|
|
foreach ($this->getActionGroups() as $group) {
|
|
foreach ($group->getActions() as $a) {
|
|
if ($a->getId() == $id) {
|
|
return $a;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Removes any actions that correspond to a given scene ID, if present.
|
|
* @param int $id
|
|
*/
|
|
public function removeActionsWithSceneId(string $id)
|
|
{
|
|
foreach ($this->getActionGroups() as $group) {
|
|
$actions = $group->getActions();
|
|
foreach ($actions as $key => $a) {
|
|
if ($a->getDestinationSceneId() == $id) {
|
|
unset($actions[$key]);
|
|
}
|
|
}
|
|
$actions = \array_values($actions);
|
|
$group->setActions($actions);
|
|
}
|
|
}
|
|
}
|