- Profils raciaux appliqués automatiquement - DsN opératonnel - Gestion plus fine des fils/orbes
This commit is contained in:
@@ -4,6 +4,7 @@ import { LesOubliesRolls } from "./les-oublies-rolls.js"
|
||||
|
||||
export class LesOubliesActor extends Actor {
|
||||
static CREATION_ITEM_TYPES = new Set(["race", "tribu", "metier"])
|
||||
static THREAD_RESOURCE_KEYS = new Set(["songesThreads", "cauchemarThreads", "emptyGlobes"])
|
||||
|
||||
prepareDerivedData() {
|
||||
super.prepareDerivedData()
|
||||
@@ -22,6 +23,18 @@ export class LesOubliesActor extends Actor {
|
||||
system.cauchemar.max = totals.cauchemarPoints
|
||||
system.songes.points = Math.clamp(Number(system.songes.points ?? totals.songesPoints), 0, totals.songesPoints)
|
||||
system.cauchemar.points = Math.clamp(Number(system.cauchemar.points ?? totals.cauchemarPoints), 0, totals.cauchemarPoints)
|
||||
system.reserves.songesThreads = Math.max(Number(system.reserves?.songesThreads ?? 0), 0)
|
||||
system.reserves.cauchemarThreads = Math.max(Number(system.reserves?.cauchemarThreads ?? 0), 0)
|
||||
system.reserves.emptyGlobes = Math.max(Number(system.reserves?.emptyGlobes ?? 0), 0)
|
||||
return
|
||||
}
|
||||
|
||||
if (this.type === "compagnie") {
|
||||
const system = this.system
|
||||
system.power.sharedDreamPoints = Math.max(Number(system.power?.sharedDreamPoints ?? 0), 0)
|
||||
system.reserves.songesThreads = Math.max(Number(system.reserves?.songesThreads ?? 0), 0)
|
||||
system.reserves.cauchemarThreads = Math.max(Number(system.reserves?.cauchemarThreads ?? 0), 0)
|
||||
system.reserves.emptyGlobes = Math.max(Number(system.reserves?.emptyGlobes ?? 0), 0)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -62,6 +75,7 @@ export class LesOubliesActor extends Actor {
|
||||
async assignCreationItem(sourceItem) {
|
||||
if (!sourceItem || !LesOubliesActor.CREATION_ITEM_TYPES.has(sourceItem.type)) return null
|
||||
|
||||
const previousItem = this.getCreationItem(sourceItem.type)
|
||||
const itemData = sourceItem.toObject()
|
||||
delete itemData._id
|
||||
|
||||
@@ -77,12 +91,19 @@ export class LesOubliesActor extends Actor {
|
||||
[`system.references.${sourceItem.type}Id`]: createdItem.id,
|
||||
})
|
||||
|
||||
if (sourceItem.type === "race") {
|
||||
await this.syncRaceProfiles({ currentRace: createdItem })
|
||||
await this.syncRaceDomains({ currentRace: createdItem, previousRace: previousItem })
|
||||
}
|
||||
|
||||
return createdItem
|
||||
}
|
||||
|
||||
async clearCreationItem(type) {
|
||||
if (!LesOubliesActor.CREATION_ITEM_TYPES.has(type)) return
|
||||
|
||||
const previousItem = this.getCreationItem(type)
|
||||
|
||||
const existingIds = this.getEmbeddedItems(type).map((item) => item.id)
|
||||
if (existingIds.length) {
|
||||
await this.deleteEmbeddedDocuments("Item", existingIds, { renderSheet: false })
|
||||
@@ -91,6 +112,11 @@ export class LesOubliesActor extends Actor {
|
||||
await this.update({
|
||||
[`system.references.${type}Id`]: "",
|
||||
})
|
||||
|
||||
if (type === "race") {
|
||||
await this.syncRaceProfiles({ currentRace: null })
|
||||
await this.syncRaceDomains({ currentRace: null, previousRace: previousItem })
|
||||
}
|
||||
}
|
||||
|
||||
getCompagnie() {
|
||||
@@ -98,10 +124,94 @@ export class LesOubliesActor extends Actor {
|
||||
return compagnieId ? game.actors.get(compagnieId) ?? null : null
|
||||
}
|
||||
|
||||
getThreadReserveOwner(source = "actor") {
|
||||
if (source === "company" || source === "compagnie") return this.getCompagnie()
|
||||
return this
|
||||
}
|
||||
|
||||
getThreadReserves(source = "actor") {
|
||||
const owner = this.getThreadReserveOwner(source)
|
||||
return {
|
||||
owner,
|
||||
songesThreads: Math.max(Number(owner?.system?.reserves?.songesThreads ?? 0), 0),
|
||||
cauchemarThreads: Math.max(Number(owner?.system?.reserves?.cauchemarThreads ?? 0), 0),
|
||||
emptyGlobes: Math.max(Number(owner?.system?.reserves?.emptyGlobes ?? 0), 0),
|
||||
}
|
||||
}
|
||||
|
||||
async transferThreadReserve(resourceKey, amount, direction = "toCompany") {
|
||||
if (!LesOubliesActor.THREAD_RESOURCE_KEYS.has(resourceKey)) return false
|
||||
const company = this.getCompagnie()
|
||||
if (!company) return false
|
||||
|
||||
const transferAmount = Math.max(Math.trunc(Number(amount ?? 0)), 0)
|
||||
if (transferAmount < 1) return false
|
||||
|
||||
const fromActor = direction === "toCompany" ? this : company
|
||||
const toActor = direction === "toCompany" ? company : this
|
||||
const current = Math.max(Number(fromActor.system?.reserves?.[resourceKey] ?? 0), 0)
|
||||
if (current < transferAmount) return false
|
||||
|
||||
const path = `system.reserves.${resourceKey}`
|
||||
const targetCurrent = Math.max(Number(toActor.system?.reserves?.[resourceKey] ?? 0), 0)
|
||||
|
||||
await fromActor.update({ [path]: current - transferAmount })
|
||||
await toActor.update({ [path]: targetCurrent + transferAmount })
|
||||
return true
|
||||
}
|
||||
|
||||
getCompetenceByKey(skillKey) {
|
||||
return this.getEmbeddedItems("competence").find((item) => item.system.key === skillKey) ?? null
|
||||
}
|
||||
|
||||
getRaceLanguageDomains(race = this.getCreationItem("race")) {
|
||||
return LesOubliesUtility.uniqueStrings(race?.system?.languageDomains ?? [])
|
||||
}
|
||||
|
||||
getRaceProfiles(race = this.getCreationItem("race")) {
|
||||
const profiles = LesOubliesUtility.createEmptyProfiles()
|
||||
for (const key of Object.keys(profiles)) {
|
||||
profiles[key] = Math.trunc(Number(race?.system?.profiles?.[key] ?? 0))
|
||||
}
|
||||
return profiles
|
||||
}
|
||||
|
||||
async syncRaceProfiles({ currentRace = this.getCreationItem("race") } = {}) {
|
||||
if (this.type !== "personnage") return false
|
||||
const profiles = this.getRaceProfiles(currentRace)
|
||||
const updateData = Object.fromEntries(
|
||||
Object.entries(profiles).map(([key, value]) => [`system.profils.${key}`, value]),
|
||||
)
|
||||
await this.update(updateData)
|
||||
if (currentRace) {
|
||||
ui.notifications.info(`Profils raciaux appliqués depuis ${currentRace.name}.`)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
async syncRaceDomains({ currentRace = this.getCreationItem("race"), previousRace = null } = {}) {
|
||||
if (this.type !== "personnage") return false
|
||||
|
||||
const competence = this.getCompetenceByKey("langues")
|
||||
if (!competence) return false
|
||||
|
||||
const currentAutoDomains = LesOubliesUtility.uniqueStrings(competence.system.fixedDomains ?? [])
|
||||
const previousRaceDomains = previousRace
|
||||
? this.getRaceLanguageDomains(previousRace)
|
||||
: currentAutoDomains
|
||||
const autoDomainsToReplace = currentAutoDomains.length ? currentAutoDomains : previousRaceDomains
|
||||
const nextAutoDomains = this.getRaceLanguageDomains(currentRace)
|
||||
const manualDomains = LesOubliesUtility.uniqueStrings(
|
||||
(competence.system.domains ?? []).filter((domain) => !autoDomainsToReplace.includes(domain)),
|
||||
)
|
||||
|
||||
await competence.update({
|
||||
"system.fixedDomains": nextAutoDomains,
|
||||
"system.domains": LesOubliesUtility.uniqueStrings([...manualDomains, ...nextAutoDomains]),
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
getSkillScoreByKey(skillKey) {
|
||||
const competence = this.getCompetenceByKey(skillKey)
|
||||
return competence ? this.computeSkillValue(competence) : 0
|
||||
@@ -119,6 +229,8 @@ export class LesOubliesActor extends Actor {
|
||||
item,
|
||||
finalValue: this.computeSkillValue(item),
|
||||
profileLabel: LESOUBLIES_CONFIG.profileLabels[item.system.profileKey] ?? item.system.profileKey,
|
||||
domains: LesOubliesUtility.uniqueStrings(item.system.domains ?? []),
|
||||
fixedDomains: LesOubliesUtility.uniqueStrings(item.system.fixedDomains ?? []),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -146,6 +258,8 @@ export class LesOubliesActor extends Actor {
|
||||
cauchemarMax: this.system.cauchemar?.max ?? this.system.cauchemar?.points ?? 0,
|
||||
songesPoints: this.system.songes?.points ?? 0,
|
||||
cauchemarPoints: this.system.cauchemar?.points ?? 0,
|
||||
reserves: this.getThreadReserves(),
|
||||
companyReserves: this.getThreadReserves("company"),
|
||||
race: this.getCreationItem("race"),
|
||||
tribu: this.getCreationItem("tribu"),
|
||||
metier: this.getCreationItem("metier"),
|
||||
|
||||
Reference in New Issue
Block a user