La dépense de rêve de sort se faisait en parallèle de la fermeture de fenêtre des TMRs, qui modifiait la fatigue. Du coup, l'update de la dépense de rêve ne se faisait pas
156 lines
4.8 KiB
JavaScript
156 lines
4.8 KiB
JavaScript
import { RollBasicParts } from "../roll/roll-basic-parts.mjs"
|
|
|
|
const ACTOR_EMBEDDED_DOCTYPES = ['Item', 'ActiveEffect']
|
|
/**
|
|
* class designed to store actor modification instructions, to apply them in a single operation, and have the ability to revert these
|
|
*/
|
|
export class ActorImpacts {
|
|
static $newDocumentImpacts(docType) {
|
|
return { creates: [], deletes: [], updates: [], docType: docType }
|
|
}
|
|
static $checkDocType(docType) {
|
|
if (!ACTOR_EMBEDDED_DOCTYPES.includes(docType)) {
|
|
throw `Unsupported document type ${docType}`
|
|
}
|
|
}
|
|
|
|
constructor(actorToken) {
|
|
this.actorToken = actorToken
|
|
this.updates = []
|
|
this.deltas = []
|
|
ACTOR_EMBEDDED_DOCTYPES.forEach(
|
|
docType => this[docType] = ActorImpacts.$newDocumentImpacts(docType)
|
|
)
|
|
}
|
|
|
|
addActorUpdate(path, value) {
|
|
this.updates.push([path, value])
|
|
}
|
|
|
|
addActorDelta(path, value) {
|
|
const intValue = Number.parseInt(value)
|
|
if (Number.isInteger(intValue) && intValue != 0) {
|
|
const delta = [path, intValue]
|
|
this.deltas.push(delta)
|
|
}
|
|
else {
|
|
console.error('Cannot use non integer value {} for delta update', value)
|
|
}
|
|
}
|
|
|
|
addDeleted(docType, document) {
|
|
ActorImpacts.$checkDocType(docType)
|
|
this[docType].deletes.push(document)
|
|
}
|
|
|
|
addCreated(docType, document) {
|
|
ActorImpacts.$checkDocType(docType)
|
|
this[docType].creates.push(document)
|
|
}
|
|
|
|
addUpdate(docType, document, path, value) {
|
|
ActorImpacts.$checkDocType(docType)
|
|
const update = [path, value]
|
|
const existing = this[docType].updates.find(it => it.id == document.id)
|
|
if (existing) {
|
|
existing.updates.push(update)
|
|
}
|
|
else {
|
|
this[docType].updates.push({ id: document.id, updates: [update], deltas: [] })
|
|
}
|
|
}
|
|
|
|
addDelta(document, path, value) {
|
|
ActorImpacts.$checkDocType(document)
|
|
const intValue = Number.parseInt(value)
|
|
if (Number.isInteger(intValue)) {
|
|
if (intValue != 0){
|
|
const delta = [path, intValue]
|
|
const existing = this[docType].updates.find(it => it.id == document.id)
|
|
if (existing) {
|
|
existing.deltas.push(delta)
|
|
}
|
|
else {
|
|
this[docType].updates.push({ id: document.id, updates: [], deltas: [delta] })
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
console.error('Cannot use non-integer value {} for delta update', value)
|
|
}
|
|
}
|
|
|
|
reverseImpacts() {
|
|
const reverse = ActorImpacts.$computeReverts(new ActorImpacts(this.actorToken), this, __ => this.actorToken.actor)
|
|
ACTOR_EMBEDDED_DOCTYPES.forEach(
|
|
docType => {
|
|
reverse[docType].creates = this[docType].deletes.map(it => foundry.utils.duplicate(it))
|
|
reverse[docType].deletes = this[docType].creates.map(it => { return { id: it.id } })
|
|
reverse[docType].updates = this[docType].updates.map(it => ActorImpacts.$computeReverts({ id: it.id }, it, id => this.$getEmbeddedDocument(docType, id)))
|
|
}
|
|
)
|
|
return reverse
|
|
}
|
|
|
|
toStorable() {
|
|
delete this.actorToken
|
|
return this
|
|
}
|
|
|
|
async applyImpacts() {
|
|
const actor = this.actorToken.actor
|
|
for (let docType of ACTOR_EMBEDDED_DOCTYPES) {
|
|
await this.$applyDocumentsImpacts(actor, docType)
|
|
}
|
|
const updates = ActorImpacts.$computeUpdates(this, id => actor)
|
|
await actor.update(updates, { render: true })
|
|
}
|
|
|
|
|
|
async $applyDocumentsImpacts(actor, docType) {
|
|
if (this[docType].deletes.length > 0) {
|
|
const deletes = this[docType].deletes.map(it => it.id)
|
|
await actor.deleteEmbeddedDocuments(docType, deletes, { render: false })
|
|
}
|
|
|
|
if (this[docType].creates.length > 0) {
|
|
const creates = this[docType].creates
|
|
const created = await actor.createEmbeddedDocuments(docType, creates, { render: false })
|
|
for (let i = 0; i < creates.length; i++) {
|
|
creates[i].createdId = created[i].id
|
|
}
|
|
}
|
|
|
|
if (this[docType].updates.length > 0) {
|
|
const updates = this[docType].updates.map(u => ActorImpacts.$computeUpdates(u, id => this.$getEmbeddedDocument(docType, id)))
|
|
await actor.updateEmbeddedDocuments(docType, updates, { render: false })
|
|
}
|
|
}
|
|
|
|
findCreatedId(docType, origId) {
|
|
return this[docType].creates.find(it => it.id = origId)?.createdId
|
|
}
|
|
|
|
$getEmbeddedDocument(docType, id) {
|
|
return this.actorToken.actor.getEmbeddedDocument(docType, id)
|
|
}
|
|
|
|
static $computeUpdates(u, getSource) {
|
|
if (u.updates.length == 0 && u.deltas.length == 0) {
|
|
return {}
|
|
}
|
|
const source = getSource(u.id)
|
|
const instruction = { _id: u.id }
|
|
u.updates.forEach(u => instruction[u[0]] = u[1])
|
|
u.deltas.forEach(u => instruction[u[0]] = foundry.utils.getProperty(source, u[0]) + u[1])
|
|
return instruction
|
|
}
|
|
|
|
static $computeReverts(target, u, getSource) {
|
|
const source = getSource(u.id)
|
|
target.updates = u.updates.map(u => [u[0], foundry.utils.getProperty(source, u[0])])
|
|
target.deltas = u.deltas.map(d => [d[0], -d[1]])
|
|
return target
|
|
}
|
|
}
|