Rework des fiches creature/PJ et Tinji/Loksyu
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
/**
|
||||
* Singleton actor utilities for Loksyu and Tin Ji.
|
||||
* Loksyu / TinJi settings-based helpers.
|
||||
*
|
||||
* Both are world-level shared trackers backed by a singleton Actor document
|
||||
* of type "loksyu" / "tinji". GMs can create them via the Actors sidebar;
|
||||
* the apps find the first one or offer to create it.
|
||||
* Data is stored as world settings instead of singleton Actor documents.
|
||||
*/
|
||||
|
||||
import { ACTOR_TYPES } from "../../config/constants.js"
|
||||
const SYSTEM_ID = "fvtt-chroniques-de-l-etrange"
|
||||
|
||||
/** Wu Xing generating cycle — [successes, auspicious, noxious, loksyu, tinji] */
|
||||
const WU_XING_CYCLE = {
|
||||
@@ -17,7 +15,6 @@ const WU_XING_CYCLE = {
|
||||
water: ["water", "wood", "metal", "fire", "earth"],
|
||||
}
|
||||
|
||||
/** Die face pairs [yin, yang] per aspect (0 = face "10") */
|
||||
const ASPECT_FACES = {
|
||||
metal: [3, 8],
|
||||
water: [1, 6],
|
||||
@@ -26,39 +23,35 @@ const ASPECT_FACES = {
|
||||
wood: [4, 9],
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first actor of the given type in the world, or create one if the
|
||||
* current user is a GM and none exists.
|
||||
*
|
||||
* @param {"loksyu"|"tinji"} type
|
||||
* @returns {Promise<Actor|null>}
|
||||
*/
|
||||
export async function getSingletonActor(type) {
|
||||
const existing = game.actors.find((a) => a.type === type)
|
||||
if (existing) return existing
|
||||
|
||||
if (!game.user.isGM) {
|
||||
ui.notifications.warn(game.i18n.localize(type === ACTOR_TYPES.loksyu ? "CDE.LoksyuNotFound" : "CDE.TinjiNotFound"))
|
||||
return null
|
||||
/** Read the current loksyu data object from world settings */
|
||||
export function getLoksyuData() {
|
||||
return game.settings.get(SYSTEM_ID, "loksyuData") ?? {
|
||||
wood: {yin:0,yang:0}, fire: {yin:0,yang:0}, earth: {yin:0,yang:0}, metal: {yin:0,yang:0}, water: {yin:0,yang:0},
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-create the singleton when the GM opens the app for the first time.
|
||||
const nameKey = type === ACTOR_TYPES.loksyu ? "CDE.UpperCaseLoksyu" : "CDE.UpperCaseTinJi"
|
||||
const actor = await Actor.create({
|
||||
name: game.i18n.localize(nameKey),
|
||||
type,
|
||||
img: type === ACTOR_TYPES.loksyu
|
||||
? "systems/fvtt-chroniques-de-l-etrange/images/loksyu_long.webp"
|
||||
: "systems/fvtt-chroniques-de-l-etrange/images/tinji.webp",
|
||||
})
|
||||
return actor ?? null
|
||||
/** Write the loksyu data object to world settings */
|
||||
export async function setLoksyuData(data) {
|
||||
await game.settings.set(SYSTEM_ID, "loksyuData", data)
|
||||
Hooks.callAll("cde:loksyuUpdated", data)
|
||||
}
|
||||
|
||||
/** Read current TinJi value from world settings */
|
||||
export function getTinjiValue() {
|
||||
return game.settings.get(SYSTEM_ID, "tinjiData") ?? 0
|
||||
}
|
||||
|
||||
/** Write TinJi value to world settings */
|
||||
export async function setTinjiValue(value) {
|
||||
await game.settings.set(SYSTEM_ID, "tinjiData", Math.max(0, value))
|
||||
Hooks.callAll("cde:tinjiUpdated", Math.max(0, value))
|
||||
}
|
||||
|
||||
/**
|
||||
* After a WuXing roll, add the loksyu faces (yin + yang) of the relevant
|
||||
* aspect to the singleton Loksyu actor.
|
||||
* aspect to the loksyu settings data.
|
||||
*
|
||||
* @param {string} activeAspect - The aspect used for the roll (e.g. "fire")
|
||||
* @param {string} activeAspect - e.g. "fire"
|
||||
* @param {Object} faces - Die face counts { 0: n, 1: n, …, 9: n }
|
||||
*/
|
||||
export async function updateLoksyuFromRoll(activeAspect, faces) {
|
||||
@@ -73,27 +66,22 @@ export async function updateLoksyuFromRoll(activeAspect, faces) {
|
||||
const yangCount = faces[yangFace] ?? 0
|
||||
if (yinCount === 0 && yangCount === 0) return
|
||||
|
||||
const actor = await getSingletonActor(ACTOR_TYPES.loksyu)
|
||||
if (!actor) return
|
||||
|
||||
const current = actor.system[lokAspect] ?? { yin: { value: 0 }, yang: { value: 0 } }
|
||||
await actor.update({
|
||||
[`system.${lokAspect}.yin.value`]: (current.yin.value ?? 0) + yinCount,
|
||||
[`system.${lokAspect}.yang.value`]: (current.yang.value ?? 0) + yangCount,
|
||||
})
|
||||
const data = getLoksyuData()
|
||||
const current = data[lokAspect] ?? { yin: 0, yang: 0 }
|
||||
data[lokAspect] = {
|
||||
yin: (current.yin ?? 0) + yinCount,
|
||||
yang: (current.yang ?? 0) + yangCount,
|
||||
}
|
||||
await setLoksyuData(data)
|
||||
}
|
||||
|
||||
/**
|
||||
* After a WuXing roll, add tinji faces to the singleton TinJi actor.
|
||||
* After a WuXing roll, add tinji faces to the TinJi settings.
|
||||
*
|
||||
* @param {number} count - Number of tinji faces rolled
|
||||
*/
|
||||
export async function updateTinjiFromRoll(count) {
|
||||
if (!count || count <= 0) return
|
||||
|
||||
const actor = await getSingletonActor(ACTOR_TYPES.tinji)
|
||||
if (!actor) return
|
||||
|
||||
const current = actor.system.value ?? 0
|
||||
await actor.update({ "system.value": current + count })
|
||||
const current = getTinjiValue()
|
||||
await setTinjiValue(current + count)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user