From 8335871883fbcddd152376012a42bca38df481ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Pons?= Date: Tue, 3 Feb 2026 17:39:21 +0100 Subject: [PATCH] Add action variants and cursed items. --- app/types/character.d.ts | 16 +- shared/character-config.json | 1216 +++++++++++++++++++++++++++++----- shared/character.ts | 10 +- shared/feature.ts | 151 ++++- 4 files changed, 1205 insertions(+), 188 deletions(-) diff --git a/app/types/character.d.ts b/app/types/character.d.ts index 793fa32..c636978 100644 --- a/app/types/character.d.ts +++ b/app/types/character.d.ts @@ -72,6 +72,7 @@ export type TreeStructure = { type CommonState = { capacity?: number; powercost?: number; + analysed?: boolean; }; type ArmorState = { loss: number, health?: number, absorb: { flat?: number, percent?: number } }; type WeaponState = { attack?: number | string, hit?: number }; @@ -94,17 +95,17 @@ export type CharacterConfig = { features: Record; enchantments: Record; items: Record; - action: Record; - reaction: Record; - freeaction: Record; - passive: Record; + action: Record; + reaction: Record; + freeaction: Record; + passive: Record; texts: Record; trees: Record; //Each of these groups extend an existing feature as they all use the same properties sickness: Record; //TODO - poisons: Record; //TODO - dedications: Record }>; //TODO + poison: Record; //TODO + dedication: Record }>; //TODO }; export type EnchantementConfig = { id: string; @@ -113,6 +114,7 @@ export type EnchantementConfig = { effect: Array; power: number; restrictions?: Array<'armor' | 'mundane' | 'wondrous' | 'weapon' | `armor/${ArmorConfig['type']}` | `weapon/${WeaponConfig['type'][number]}`>; // Need to respect *any* of the restriction, not every restrictions. + cursed: boolean; } export type ItemConfig = CommonItemConfig & (ArmorConfig | WeaponConfig | WondrousConfig | MundaneConfig); type CommonItemConfig = { @@ -211,7 +213,7 @@ export type FeatureEquipment = { export type FeatureList = { id: FeatureEffectID; category: "list"; - list: "spells" | "sickness" | "action" | "reaction" | "freeaction" | "passive" | "mastery"; + list: "spells" | "sickness" | "action" | "reaction" | "freeaction" | "passive" | "mastery" | "poison" | "dedication"; action: "add" | "remove"; item: string; }; diff --git a/shared/character-config.json b/shared/character-config.json index dc30d35..68164ca 100644 --- a/shared/character-config.json +++ b/shared/character-config.json @@ -97,6 +97,83 @@ "name": "Danger terrifiant", "description": "9k_l_WDZUEOX_z1eRU-iKxcK", "cost": 1 + }, + "XALPxv~Tn6aD0PmzhenFvBZ8": { + "id": "XALPxv~Tn6aD0PmzhenFvBZ8", + "name": "Soutien moral", + "description": "Rl2mNKFEpoZZn1DLbuFzaBHd", + "cost": 1 + }, + "~N23g5N~JVz32ne-2S2iERVY": { + "id": "~N23g5N~JVz32ne-2S2iERVY", + "name": "Partage de puissance", + "description": "3yZ6ADJpg3fnhKNtu-HcmEi3", + "cost": 1, + "variants": [ + "aMBkH6D0QkBL6fML1wgxa1vx", + "l7dF5BS6GlnHjbLedawYmd94", + "Z3AtRfXE9Jw.3bIFAkImhPfb", + "xIFuBk1ekDnygzW2HmrZQLeq", + "kgvJLr4AmeqM7voorijH_-RH", + "VK2J0lZUg.f0l3bdxa7d.l3M", + "sp0_jz_kaZM4iLNsKgIJznyd", + "DNYbN_FZKIidJWJcqIgIbK6p", + "diaCgaj2tRtH9gZggMeID6fx" + ] + }, + "aMBkH6D0QkBL6fML1wgxa1vx": { + "id": "aMBkH6D0QkBL6fML1wgxa1vx", + "name": "Feu", + "description": "-c05ofwtp~3RFIBPO31kWMst", + "parent": "~N23g5N~JVz32ne-2S2iERVY" + }, + "l7dF5BS6GlnHjbLedawYmd94": { + "id": "l7dF5BS6GlnHjbLedawYmd94", + "name": "Glace", + "description": "blr4ZstOXmZqcD0fy8yXh_5C", + "parent": "~N23g5N~JVz32ne-2S2iERVY" + }, + "Z3AtRfXE9Jw.3bIFAkImhPfb": { + "id": "Z3AtRfXE9Jw.3bIFAkImhPfb", + "name": "Foudre", + "description": "1BRFNSIiv6bVJln714vQP9ZZ", + "parent": "~N23g5N~JVz32ne-2S2iERVY" + }, + "xIFuBk1ekDnygzW2HmrZQLeq": { + "id": "xIFuBk1ekDnygzW2HmrZQLeq", + "name": "Terre", + "description": "X42n-QCtS7wLy73ugYMMixRe", + "parent": "~N23g5N~JVz32ne-2S2iERVY" + }, + "kgvJLr4AmeqM7voorijH_-RH": { + "id": "kgvJLr4AmeqM7voorijH_-RH", + "name": "Arcane", + "description": "FdvdnaYABNT5ifIVQoEVyMFr", + "parent": "~N23g5N~JVz32ne-2S2iERVY" + }, + "VK2J0lZUg.f0l3bdxa7d.l3M": { + "id": "VK2J0lZUg.f0l3bdxa7d.l3M", + "name": "Air", + "description": "QZ0U.xMag2jM.sMwT~p0w7nr", + "parent": "~N23g5N~JVz32ne-2S2iERVY" + }, + "sp0_jz_kaZM4iLNsKgIJznyd": { + "id": "sp0_jz_kaZM4iLNsKgIJznyd", + "name": "Nature", + "description": "MQP4cgGF.Nt4XvbLsRgoHDvp", + "parent": "~N23g5N~JVz32ne-2S2iERVY" + }, + "DNYbN_FZKIidJWJcqIgIbK6p": { + "id": "DNYbN_FZKIidJWJcqIgIbK6p", + "name": "Lumière", + "description": "OkM1RDA-Gbhpl1wMh4bImTrE", + "parent": "~N23g5N~JVz32ne-2S2iERVY" + }, + "diaCgaj2tRtH9gZggMeID6fx": { + "id": "diaCgaj2tRtH9gZggMeID6fx", + "name": "Psy", + "description": "xU66w~JOPFd-.jBRy5ulHgNC", + "parent": "~N23g5N~JVz32ne-2S2iERVY" } }, "freeaction": { @@ -109,6 +186,11 @@ "id": "RRwEdkE~DyoP820T1FGqmASK", "name": "Jet libre", "description": "ITEQoy2zuD._we4T8rt.onm1" + }, + "anN9n9S1ojkgpOpg75o4Qc3x": { + "id": "anN9n9S1ojkgpOpg75o4Qc3x", + "name": "Directions opposés", + "description": "~mTRb_.CJs~84W82JT2qcsl." } }, "passive": { @@ -542,21 +624,11 @@ "name": "Leader au combat", "description": "n9Z6N3pBrFRV-RWp_z7U97SO" }, - "Uj1a~yR5DaMRWyQ198zVQYme": { - "id": "Uj1a~yR5DaMRWyQ198zVQYme", - "name": "Connaissances sociales", - "description": "ofNAk_lWNFQ6vr9jROgD4vSo" - }, "RLXO.cGlK6Zm2~hXx6w31FGK": { "id": "RLXO.cGlK6Zm2~hXx6w31FGK", "name": "Auditoire amical", "description": "uGUHabz3O.Z1pY212n7u1xx7" }, - "_-y9HXQVFxQrCuBE.Gvj6GWe": { - "id": "_-y9HXQVFxQrCuBE.Gvj6GWe", - "name": "Analyse comportementale", - "description": "IWAW3Wjs7Kr5vIMwr9BBpkD." - }, "IYqB0TJndfefIL5WnqjSRQGM": { "id": "IYqB0TJndfefIL5WnqjSRQGM", "name": "Attentif aux entourloupes", @@ -746,6 +818,258 @@ "id": "wEVUK.UZWJdD~K0ZbH1mCdsD", "name": "Echange de savoir", "description": "K7uts-MQ6tl.TWEGmI3jToC3" + }, + "I.fl6PiCkJ~RgeoZaOtt6sUJ": { + "id": "I.fl6PiCkJ~RgeoZaOtt6sUJ", + "name": "Aucune place pour le doute", + "description": "gDC046V84hbVhAx6.WrgTjiT", + "variants": [ + "T5Ydhb6BoAmi~eVRIkJHNtqk", + "Ty0F~TawgHCw.v1ZaAVY1SMy", + "yTQHlz_9Ge44Z.vczn.7BXzk", + "MIK4~Y0.LUqT2wDkdspnISC1", + "q~D1X0LJI6y651hrwxbcbUId", + "5xvmrqw99VshQJwRicMB0-gl", + "es55TA4bQriww7t.884Bac_P" + ] + }, + "IeE14F1jLmpP0dgoibmzlrki": { + "id": "IeE14F1jLmpP0dgoibmzlrki", + "name": "Entrainement parfait", + "description": "A6KgrFEesScFzBUWnBJxIMrP", + "variants": [ + "AvUqmzwwYyfHOf47El67Thwy", + "fJNc1f9c9OF7IvrZVHaI3vbh", + "hBC273QPK7Mp56z77L0DIqoA", + ".8gE2g5Cgqy99bfXcm65AqSF", + "hEmgMSksljb3xTe_ZnPvvZzv", + "KfJemdt.y_n3cyuhjU9MhQBV", + "cf361.wAOL4eI1K_B7VJWVPj", + "S3vTN67Vpm5ZkD-dCHP2pvIv", + "vHCn_Gt0rBJcfq3ouChXiA12", + "aAOhpcc-1oYEWQgSKFa9R5rn", + "7CqiylL~RnY_.lmhqYGXPRsw", + "0LpT-92h1QbA4Gj8-7c~Vn9N", + "tYrYzZsPkFjeEzRxW0Hja9hU", + "YmHnkIgtxrJGOS9ohfon7~eZ", + "ZDAR3lj5v7BQmnZl1hWZrMTM", + "CMzU7jkM54YzkWDzYS0T3qS5", + "ligmn8hHxgl05pWv6bHK8FTq" + ] + }, + "kX8a4WRkoS0phwS-HvM.qll.": { + "id": "kX8a4WRkoS0phwS-HvM.qll.", + "name": "Maitrise élémentaire", + "description": "DilFgXEWYe~E3PV9xSLw4ssl", + "variants": [ + "Ao3-KQU9IKI2M6XXt.VtinW-", + "n03RVmIIDgz2F4HYdp6B_pqT", + "aWYwux-8iTKR~CZK~TEZiEM3", + "nT8HHMM53SgpocueRxua5qjl", + "_LAuZprDuEaWZ-TNPUX6GhfT", + "x0AEtoYvMAk4UgP1AMLtMOag", + "zEODNKpyUAcsGsFKW6mlJPc4", + "Cozzn1_fuKf8L.6O3gWMu8Bt", + "cw9HYWutoyiV5U1Am7HlwtvB" + ] + }, + "Ao3-KQU9IKI2M6XXt.VtinW-": { + "id": "Ao3-KQU9IKI2M6XXt.VtinW-", + "name": "Feu", + "description": "nGJkJqDOjZrye3BH78-zO9VR", + "parent": "kX8a4WRkoS0phwS-HvM.qll." + }, + "n03RVmIIDgz2F4HYdp6B_pqT": { + "id": "n03RVmIIDgz2F4HYdp6B_pqT", + "name": "Glace", + "description": "k9vjg8XnOSB.-ETBd9gO6keX", + "parent": "kX8a4WRkoS0phwS-HvM.qll." + }, + "aWYwux-8iTKR~CZK~TEZiEM3": { + "id": "aWYwux-8iTKR~CZK~TEZiEM3", + "name": "Foudre", + "description": "gU19Lth3t7Q5N.7cdX1yrYjH", + "parent": "kX8a4WRkoS0phwS-HvM.qll." + }, + "nT8HHMM53SgpocueRxua5qjl": { + "id": "nT8HHMM53SgpocueRxua5qjl", + "name": "Terre", + "description": "1lxVFQVSjI-SIXfM0Yg4SvWG", + "parent": "kX8a4WRkoS0phwS-HvM.qll." + }, + "_LAuZprDuEaWZ-TNPUX6GhfT": { + "id": "_LAuZprDuEaWZ-TNPUX6GhfT", + "name": "Arcane", + "description": "goPESrmJi1-5p2ljD8OZyFfy", + "parent": "kX8a4WRkoS0phwS-HvM.qll." + }, + "x0AEtoYvMAk4UgP1AMLtMOag": { + "id": "x0AEtoYvMAk4UgP1AMLtMOag", + "name": "Air", + "description": "-oP-b2vX6lsHuGlqZoq0BPqA", + "parent": "kX8a4WRkoS0phwS-HvM.qll." + }, + "zEODNKpyUAcsGsFKW6mlJPc4": { + "id": "zEODNKpyUAcsGsFKW6mlJPc4", + "name": "Nature", + "description": "xz.MsMlUk~gtmjRcERiYZMty", + "parent": "kX8a4WRkoS0phwS-HvM.qll." + }, + "Cozzn1_fuKf8L.6O3gWMu8Bt": { + "id": "Cozzn1_fuKf8L.6O3gWMu8Bt", + "name": "Lumière", + "description": "Kkm2fCo~YnzApI-.TJG5V._d", + "parent": "kX8a4WRkoS0phwS-HvM.qll." + }, + "cw9HYWutoyiV5U1Am7HlwtvB": { + "id": "cw9HYWutoyiV5U1Am7HlwtvB", + "name": "Psy", + "description": "pdyvtHIV45hs~PBnuKF6F0X-", + "parent": "kX8a4WRkoS0phwS-HvM.qll." + }, + "AvUqmzwwYyfHOf47El67Thwy": { + "id": "AvUqmzwwYyfHOf47El67Thwy", + "name": "Athlétisme", + "description": "tYOLsSl537dfNEpeNEUd5Yh2", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "fJNc1f9c9OF7IvrZVHaI3vbh": { + "id": "fJNc1f9c9OF7IvrZVHaI3vbh", + "name": "Acrobatisme", + "description": "LA7mcUGai~1S8en4Q3-OpU0G", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "hBC273QPK7Mp56z77L0DIqoA": { + "id": "hBC273QPK7Mp56z77L0DIqoA", + "name": "Intimidation", + "description": "4IJTPQozUH-8fisoQphAPm5v", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + ".8gE2g5Cgqy99bfXcm65AqSF": { + "id": ".8gE2g5Cgqy99bfXcm65AqSF", + "name": "Doigté", + "description": "l4LHPW-b2xaO7tD3spxddlmO", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "hEmgMSksljb3xTe_ZnPvvZzv": { + "id": "hEmgMSksljb3xTe_ZnPvvZzv", + "name": "Discrétion", + "description": "VaDJaP_DeYtbs653j9vD~Usv", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "KfJemdt.y_n3cyuhjU9MhQBV": { + "id": "KfJemdt.y_n3cyuhjU9MhQBV", + "name": "Survie", + "description": "AnRniyLT3s1D76M~b-Xuy5vf", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "cf361.wAOL4eI1K_B7VJWVPj": { + "id": "cf361.wAOL4eI1K_B7VJWVPj", + "name": "Enquête", + "description": "pZ_~TejUarQTh4Q.P6ngBH4U", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "S3vTN67Vpm5ZkD-dCHP2pvIv": { + "id": "S3vTN67Vpm5ZkD-dCHP2pvIv", + "name": "Histoire", + "description": "NwT6FgH6QpFlvNmYmll.wHRU", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "vHCn_Gt0rBJcfq3ouChXiA12": { + "id": "vHCn_Gt0rBJcfq3ouChXiA12", + "name": "Religion", + "description": "G_5fWJ0QVvn.RamYeSbQVSlH", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "aAOhpcc-1oYEWQgSKFa9R5rn": { + "id": "aAOhpcc-1oYEWQgSKFa9R5rn", + "name": "Arcanes", + "description": "8659kHj8-r-~KYyyxFCVS6m1", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "7CqiylL~RnY_.lmhqYGXPRsw": { + "id": "7CqiylL~RnY_.lmhqYGXPRsw", + "name": "Compréhension", + "description": "t~aQqwt0_TAIKR7cYu64MKp4", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "0LpT-92h1QbA4Gj8-7c~Vn9N": { + "id": "0LpT-92h1QbA4Gj8-7c~Vn9N", + "name": "Perception", + "description": "Bo-slpDgEyBJPzhhxg.joYWT", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "tYrYzZsPkFjeEzRxW0Hja9hU": { + "id": "tYrYzZsPkFjeEzRxW0Hja9hU", + "name": "Représentation", + "description": "~HoKRe-Re6Bf9wuDg1fdN7X2", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "YmHnkIgtxrJGOS9ohfon7~eZ": { + "id": "YmHnkIgtxrJGOS9ohfon7~eZ", + "name": "Médicine", + "description": "lV4E6~20dp-1qaWlVtQ2f3AM", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "ZDAR3lj5v7BQmnZl1hWZrMTM": { + "id": "ZDAR3lj5v7BQmnZl1hWZrMTM", + "name": "Persuasion", + "description": "WUN0aUr4IgSo4-zNj81cqCxj", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "CMzU7jkM54YzkWDzYS0T3qS5": { + "id": "CMzU7jkM54YzkWDzYS0T3qS5", + "name": "Dressage", + "description": "eImUIlgB2K~OLEalMuY78_6v", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "ligmn8hHxgl05pWv6bHK8FTq": { + "id": "ligmn8hHxgl05pWv6bHK8FTq", + "name": "Mensonge", + "description": "kS.8Hde4F.2X.fxpOycckDjJ", + "parent": "IeE14F1jLmpP0dgoibmzlrki" + }, + "T5Ydhb6BoAmi~eVRIkJHNtqk": { + "id": "T5Ydhb6BoAmi~eVRIkJHNtqk", + "name": "Force", + "description": "_0GpUc1ytU_l0-CXNFsjid-V", + "parent": "I.fl6PiCkJ~RgeoZaOtt6sUJ" + }, + "Ty0F~TawgHCw.v1ZaAVY1SMy": { + "id": "Ty0F~TawgHCw.v1ZaAVY1SMy", + "name": "Dextérité", + "description": "XzIhpY~irwZF0JM0FOX7MxIr", + "parent": "I.fl6PiCkJ~RgeoZaOtt6sUJ" + }, + "yTQHlz_9Ge44Z.vczn.7BXzk": { + "id": "yTQHlz_9Ge44Z.vczn.7BXzk", + "name": "Constitution", + "description": "uJwu394godQv2X8YYXNInBu6", + "parent": "I.fl6PiCkJ~RgeoZaOtt6sUJ" + }, + "MIK4~Y0.LUqT2wDkdspnISC1": { + "id": "MIK4~Y0.LUqT2wDkdspnISC1", + "name": "Intelligence", + "description": "uJD6wua0d9ocS9YGtV9jgQ5d", + "parent": "I.fl6PiCkJ~RgeoZaOtt6sUJ" + }, + "q~D1X0LJI6y651hrwxbcbUId": { + "id": "q~D1X0LJI6y651hrwxbcbUId", + "name": "Curiosité", + "description": "yex6bd6bTfnV~5tixWEa6vok", + "parent": "I.fl6PiCkJ~RgeoZaOtt6sUJ" + }, + "5xvmrqw99VshQJwRicMB0-gl": { + "id": "5xvmrqw99VshQJwRicMB0-gl", + "name": "Charisme", + "description": "gDkz75SRzGVjVORAxP5jVDUF", + "parent": "I.fl6PiCkJ~RgeoZaOtt6sUJ" + }, + "es55TA4bQriww7t.884Bac_P": { + "id": "es55TA4bQriww7t.884Bac_P", + "name": "Psyché", + "description": "XBX1s3XtoR3gP-ZKJpLlucUX", + "parent": "I.fl6PiCkJ~RgeoZaOtt6sUJ" } }, "texts": { @@ -1046,15 +1370,9 @@ "n9Z6N3pBrFRV-RWp_z7U97SO": { "fr_FR": "Vous offrez un bonus de +1 à l'initiative à tout votre groupe." }, - "ofNAk_lWNFQ6vr9jROgD4vSo": { - "fr_FR": "Vous gagnez un bonus de +1 à vos compétences dépendant du charisme lorsque vous les utilisez sur des personnes de votre rang social. Fonctionne sur les œuvres impliquant ces personnes." - }, "uGUHabz3O.Z1pY212n7u1xx7": { "fr_FR": "Vous apprenez à vos alliées comment fonctionnent vos œuvres et êtes capable de les prémunir contre leurs effets néfastes. Vos alliés ont un bonus égal à votre mod. de [[1. Entrainement#Le charisme|charisme]] à leurs jets de résistance aux [[7. Œuvres|œuvres]]." }, - "IWAW3Wjs7Kr5vIMwr9BBpkD.": { - "fr_FR": "Vous gagnez un bonus de +1 à vos compétences dépendant du charisme lorsque vous les utilisez sur des personnes que vous fréquentez régulièrement. Fonctionne sur les œuvres impliquant ces personnes." - }, "3wEghp7oFrOR_u8lSYzg0ol4": { "fr_FR": "En 2 points d'action, vous pouvez diriger vos alliées pour faciliter leurs déplacement. Les alliées que vous pouvez voir peuvent durant leur tour se déplacer de la moitié de leur vitesse de course gratuitement. Vous ne pouvez pas utiliser d'action libre durant ce tour." }, @@ -1572,7 +1890,7 @@ "fr_FR": "+10 mana max." }, "gl0bXqh13VbuoO47jhlrLY3W": { - "fr_FR": "Vous pouvez ajouter votre mod. d'[[1. Entrainement#L'intelligence|intelligence]] à votre initiative.\n+3 mana max." + "fr_FR": "Vous avez un bonus de +1 à vos jets de résistance d'[[1. Entrainement#L'intelligence|intelligence]].\n+3 mana max." }, "7eAhF.l4NGVvVFx0ZEapMYg~": { "fr_FR": "Lorsque vous voyez et entendez un sort être lancé, vous pouvez l'[[regles/le-combat/actions-en-combat#Analyser une situation|analyser]] avec un jet d'[[2. Compétences#Arcanes|arcanes]] (DC: 9 + rang). En cas de réussite, vous avez +2 de défense et +2 au jet de résistance contre ce sort. Vous ne pouvez en retenir qu'un seul à la fois." @@ -1614,7 +1932,7 @@ "fr_FR": "Vous pouvez lancer des [[1. Magie#Les sorts de précision|sorts de précision]] d'un rang supérieur." }, "e_Bj.WAndLCAj3g9TaxFehC8": { - "fr_FR": "Choisissez une [[1. Magie#Les éléments|classe élémentaire]]. Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.* #todo" + "fr_FR": "Choisissez une [[1. Magie#Les éléments|classe élémentaire]]. Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" }, "vgkcTC_0K3x3RLQ0dyrCcQ8l": { "fr_FR": "La difficulté des jets de résistance de vos [[1. Magie#Les sorts de savoir|sorts de savoir]] est augmentée de 1." @@ -1674,10 +1992,10 @@ "fr_FR": "+1 spécialisation." }, "-P~TazWAiGxRr44EYMDwxbk7": { - "fr_FR": "+4 points de compétence." + "fr_FR": "+6 points de compétence." }, "UPZWQ0EV55DLxytHc6L5lWFU": { - "fr_FR": "+4 points de compétence." + "fr_FR": "+6 points de compétence." }, "8nqtvZOqlQO6P7UaJ2_T890x": { "fr_FR": "Les objets que vous lancez sont considérés comme des [[4. Équipement#Les armes de jet|armes de jet]] et bénéficient des mêmes bonus." @@ -1701,7 +2019,7 @@ "fr_FR": "Lorsque vous utilisez un objet consommable, vous pouvez lancer un d12. Si vous faites 12, l'objet ne se consomme pas. Cela fonctionne également sur les objets à charges." }, "GKGvn~isEp1lq_I8elhxqWim": { - "fr_FR": "+4 points de compétence." + "fr_FR": "+6 points de compétence." }, "12azcqJK7RvoqpgF3Wf6AOE3": { "fr_FR": "Vous pouvez maitriser un nombre de [[1. Magie|sorts]] et d'[[7. Œuvres|œuvres]] supplémentaires égal à 2+mod. de [[regles/l'entrainement/entrainement#La curiosité|curiosité]]." @@ -1710,7 +2028,7 @@ "fr_FR": "Lorsque vous lancez une [[4. Équipement#Les armes de jet|armes de jet]] qui n'est pas consommable, vous pouvez la garder intacte et la récupérer en fin de combat." }, "8d9f4OXWn4ViVO11W5MVoc3s": { - "fr_FR": "+4 points de compétence." + "fr_FR": "+6 points de compétence." }, "1Vk74qwnjETjRw.e81xwk4-z": { "fr_FR": "Durant un [[2. Compétences#Jet de groupe|jet de compétence de groupe]], vous pouvez ne pas lancer de dé et offrir un bonus égal à votre mod. de curiosité à tous vos camarades." @@ -1725,7 +2043,7 @@ "fr_FR": "Vous gagnez un bonus de +2 à votre jet de progression de fabrication." }, "1HBz-7gxsRerJM7Cc2ya25.B": { - "fr_FR": "+4 points de compétence." + "fr_FR": "+6 points de compétence." }, "4taziE4AuREODPBskG3OXJ8Y": { "fr_FR": "Lorsque vous faites un [[regles/l'entrainement/competences#Jet de groupe|jet de compétence de groupe]], vous offrez un bonus de +1 aux alliées qui ont moins de points de compétences que vous dans la compétence requise." @@ -1752,7 +2070,7 @@ "fr_FR": "Une fois entre chaque [[3. Glossaire#Long repos|long repos]], vous pouvez considérer que vous avez fait 10 sur un jet de compétence." }, "CXAvsIM7BUDvjQsbw5S6bBhe": { - "fr_FR": "Choisissez une compétence. Si vous faites 6 ou moins à votre jet, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres* #todo" + "fr_FR": "Choisissez une compétence. Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" }, "KsL04sOEjIwUtfzccGir8Boz": { "fr_FR": "Lorsque vous fabriquez des [[4. Équipement#Les armes|armes]], leur dé de dégâts augmente de [[1. Les évolutions de valeur.canvas#L'evolution des dés|1 niveau]]." @@ -1779,7 +2097,7 @@ "fr_FR": "Vous offrez un bonus de +1 à l'initiative à tout votre groupe." }, "sQwPV.N~lCzgO5Ik~MgK88Kb": { - "fr_FR": "Vous gagnez un bonus de +1 à vos compétences dépendant du charisme lorsque vous les utilisez sur des personnes de votre rang social. Fonctionne sur les œuvres impliquant ces personnes." + "fr_FR": "Vous avez un bonus de +1 aux jets de résistance de [[1. Entrainement#Le charisme|charisme]]." }, "RTjPh27TinT5WZMI-VXRjAkj": { "fr_FR": "Vous apprenez à vos alliées comment fonctionnent vos œuvres et êtes capable de les prémunir contre leurs effets néfastes. Vos alliés ont un bonus égal à votre mod. de [[1. Entrainement#Le charisme|charisme]] à leurs jets de résistance aux [[7. Œuvres|œuvres]]." @@ -1788,7 +2106,7 @@ "fr_FR": "Lorsque vous avez besoin de faire un jet de compétence dépendant du charisme et que vous effectuez cette tache avec un allié, vous pouvez vous coordonner pour qu'une seule personne fasse le jet de compétence avec le bonus des deux joueurs." }, "Pbg3J5RjrDIZEiIF_ewq95RV": { - "fr_FR": "Vous gagnez un bonus de +1 à vos compétences dépendant du charisme lorsque vous les utilisez sur des personnes que vous fréquentez régulièrement. Fonctionne sur les œuvres impliquant ces personnes." + "fr_FR": "Lorsqu'un allié visible pouvant vous entendre rate un jet de résistance de [[2. Liste des effets#Apeuré|peur]], de [[2. Liste des effets#Charmé|charme]], de [[2. Liste des effets#Possédé|possession]] ou d'[[2. Liste des effets#Influencé|influence]], vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour l'aider à se ressaisir, lui offrant ainsi la possibilité de relancer son jet. Utilisable une fois par type d'effet et par combat." }, "KMRdnoJ~i82wAPLEHgg~V4aG": { "fr_FR": "Vous pouvez retenir un nombre d'œuvre supplémentaire égal à 2+mod. de [[1. Entrainement#Le charisme|charisme]]." @@ -1854,7 +2172,7 @@ "fr_FR": "Vous avez un don pour la négociation. Quelque soit les difficultés et les désaccords avec un marchand, tant qu'il accepte de commercer, vous pouvez tirer les meilleurs prix possible." }, "lBEIZYfXUN.qwORdG6xx1q82": { - "fr_FR": "#todo" + "fr_FR": "Lorsque vous [[2. Actions en combat#Communiquer|communiquez]], vous êtes capable de donner des instructions contradictoires que seuls vos alliées savent décodés, induisant vos adversaires en erreurs. Faites un jet opposé de [[2. Compétences#Mensonge|mensonge]] contre la [[2. Compétences#Compréhension|compréhension]] adverse. En cas de réussite, la première réaction de l'adversaire lui coutera un point de réaction supplémentaire." }, "GWSs932gL1n7gDBLyUoyELTZ": { "fr_FR": "Lorsque vous voyez un allié attaquer, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour lui offrir un bonus égal a votre mod. d'[[1. Entrainement#L'intelligence|intelligence]] sur son jet d'attaque." @@ -2206,52 +2524,52 @@ "fr_FR": "Vous maitrisez les [[regles/annexes/equipement#Les armures lourdes|armures lourdes]].\nDe plus, vous êtes capable de porter 13 unités de poids supplémentaire." }, "~AXG10CWcpqn8h9KNvZdv6Rx": { - "fr_FR": "En combat, au prix d'un point de [[3. Fatigue et repos#Fatigue temporaire|fatigue temporaire]], vous pouvez au choix obtenir un [[3. Glossaire#Avantage et désavantage|avantage]] au jet d'attaque ou au jet de dégâts/soin lorsque vous lancez un sort impliquant des dégâts ou des soins. #todo" + "fr_FR": "Lorsque vous faites un 1 au jet pour attaquer avec un sort, vous pouvez choisir de relancer le jet en acceptant de faire un jet de [[regles/annexes/divers#Magie anormale|magie anormale]]. *Limité à une relance par jet.*" }, "SYZepmMsAtv.BM~PxpmYlmew": { - "fr_FR": "Choisissez un sort de [[2. Liste des sorts#Rang 1|rang 1]] infligeant des dégâts coûtant jusqu'à 5 mana. Il coute maintenant 1 mana (non modifiable). Vous avez +5 - le nombre de mana réduit pour frapper avec. De plus, il ne compte pas dans votre limite de sorts maitrisés. Vous pouvez changer à chaque montée d'[[1. Entrainement#L'intelligence|intelligence]] ou de [[1. Entrainement#La psyché|psyché]]. #todo" + "fr_FR": "#todo" }, "jCk3Tsie5pa_xxaz2-MfhBaC": { - "fr_FR": "Lorsque vous lancez un sort demandant un jet d'attaque et coûtant 10 mana ou moins, vous pouvez lancer un d12. Si le résultat est inférieur au coup du sort, vous ajoutez cette valeur aux dégâts du sort. #todo" + "fr_FR": "Lorsque vous lancez un sort demandant un jet d'attaque et coûtant 10 mana ou moins, vous pouvez lancer un d12. Si le résultat est inférieur au coup du sort, vous ajoutez cette valeur aux dégâts du sort. " }, "DDXaW7HWS~n-8AHYuPN3.vPY": { - "fr_FR": "En combat, au prix d'un point de [[3. Fatigue et repos#Fatigue persistante|fatigue persistante]], vous pouvez réduire le coût d'un sort de 8 mana. *Un sort peut être gratuit avec cet effet.* #todo" + "fr_FR": "Vous obtenez un bonus à la [[regles/la-magie/magie#La concentration|concentration]] égal à votre mod. de [[regles/l'entrainement/entrainement#La psyché|psyché]]. Vous pouvez réduire ce bonus d'un point pour vous octroyer un [[regles/introduction/glossaire#Avantage et désavantage|avantage]] à la [[regles/la-magie/magie#La concentration|concentration]], jusqu'à atteindre 0. Le bonus se recharge après un [[regles/introduction/glossaire#Long repos|long repos]]." }, "R4n4WXW.stSemgv_uscpIsGq": { "fr_FR": "Vous apprenez le sort unique [[2. Liste des sorts#^a8f46f|Contresort]]." }, "UdNDTa-N4tbMqkBcysyjQzr_": { - "fr_FR": "En dépensant jusqu'à 3 points de mana supplémentaire lorsque vous lancez un sort, vous gagnez un bonus équivalent à votre dépense sur votre jet. #todo" + "fr_FR": "Choisissez un sort de [[regles/la-magie/liste-des-sorts#Rang 1|rang 1]] infligeant des dégâts coûtant jusqu'à 5 mana. Il coute maintenant 1 mana (non modifiable). Vous avez +5 - le nombre de mana réduit pour frapper avec. Vous pouvez changer à chaque montée d'[[regles/l'entrainement/entrainement#L'intelligence|intelligence]] ou de [[regles/l'entrainement/entrainement#La psyché|psyché]]." }, "Gn0-DBGCheHEWQPFbQjSCYzn": { - "fr_FR": "Vous pouvez ajouter votre mod. de [[1. Entrainement#La-psyché|psyché]] lorsque vous devez faire un jet de [[1. Magie#La concentration|concentration]]. #todo" + "fr_FR": "Vous pouvez subir un malus de -2 à l'attaque (ou -2 à la difficulté de [[regles/le-combat/resistance-aux-chocs#Le jet de résistance|jet de résistance]]) pour gagner un [[regles/introduction/glossaire#Avantage et désavantage|avantage]] aux jets de dégâts." }, "zCKt2kBE-W6DYiJ6jLZGfqaN": { - "fr_FR": "Choisissez un sort avec [[1. Magie#La concentration|concentration]]. Tant que vous le maintenez, vous avez +2 pour lancer des sorts. De plus, il ne compte pas dans votre limite de sorts maitrisés. Vous pouvez changer de sort à chaque montée d'[[1. Entrainement#L'intelligence|intelligence]] ou de [[1. Entrainement#La psyché|psyché]]. #todo" + "fr_FR": "Choisissez un sort avec [[1. Magie#La concentration|concentration]]. Tant que vous le maintenez, vous avez +2 pour lancer des sorts. De plus, il ne compte pas dans votre limite de sorts maitrisés. Vous pouvez changer de sort à chaque montée d'[[1. Entrainement#L'intelligence|intelligence]] ou de [[1. Entrainement#La psyché|psyché]]." }, "oQvU~rL72kOjIAPV1sicYAJH": { - "fr_FR": "Choisissez une classe élémentaire. Les sorts de cette classe coûtent 1 mana de moins à lancer. #todo" + "fr_FR": "Choisissez une [[regles/la-magie/magie#Les éléments|classe élémentaire]]. Les sorts de cette classe élémentaire coûtent 1 mana de moins à lancer." }, "8NwSx5qvK._Z0Ibu_8BW3h_n": { - "fr_FR": "Choisissez une classe élémentaire. Vous pouvez maitriser un nombre de sort de cette classe égale à votre modifieur d'intelligence. #todo" + "fr_FR": "Choisissez une [[regles/la-magie/magie#Les éléments|classe élémentaire]]. Vous gagnez un bonus de +2 aux [[regles/le-combat/resistance-aux-chocs#Le jet de résistance|jets de résistance]] et +2 à la défense lorsque vous subissez un sort de cette classe élémentaire." }, "rscwLYJDYLvp0YKuNACc~f7r": { - "fr_FR": "Choisissez une classe élémentaire. Vous gagnez un bonus de +1 à l'attaque avec les [[1. Magie#Les sorts de précision|sorts de précision]], un bonus de +1 à la concentration avec les [[1. Magie#Les sorts de savoir|sorts de savoir]]. #todo" + "fr_FR": "Choisissez une [[regles/la-magie/magie#Les éléments|classe élémentaire]]. Vous gagnez un bonus de +1 à l'attaque et un bonus de +1 à la [[regles/la-magie/magie#La concentration|concentration]] sur les sorts de cette classe élémentaire." }, "w3-_SA7z72E_gDURhkguMMYh": { - "fr_FR": "Choisissez une classe élémentaire. Les sorts de cette classe ignore les résistances et réduisent les immunités en résistance (non cumulable). #todo" + "fr_FR": "Choisissez une [[regles/la-magie/magie#Les éléments|classe élémentaire]]. Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." }, "Q.qd-RHbnvJSdKOlqmjnS9hz": { - "fr_FR": "Lorsque vous lancez un sort durant votre tour, vous pouvez vous déplacer de la moitié de votre vitesse de course. #todo" + "fr_FR": "Vous êtes capable de lancer des sorts de [[regles/la-magie/liste-des-sorts#Rang 1|rang 1]] en 2 actions." }, "C_qihGAHobiYUP0qbPS4UJye": { - "fr_FR": "En combat, vous êtes capable de lancer des sorts de [[2. Liste des sorts#Rang 1|rang 1]] en 2 points d'action au lieu de 3. #todo" + "fr_FR": "Vous êtes capable de lancer des sorts de [[regles/la-magie/liste-des-sorts#Rang 2|rang 2]] en 2 actions." }, "p.SxUpC2fHcpBb8J5-bMqTQD": { - "fr_FR": "En combat, au prix d'un point de [[3. Fatigue et repos#Fatigue temporaire|fatigue temporaire]], vous pouvez lancer 2 [[1. Magie#Les sorts de précision|sorts de précision]] en 3 points d'action. #todo" + "fr_FR": "En combat, vous pouvez lancer 2 sorts de [[regles/la-magie/liste-des-sorts#Rang 1|rang 1]] en 3 points d'action." }, "MDkNb.en~T4xgbSBC89wP7NI": { - "fr_FR": "Vous pouvez doubler le coût d'un sort pour le lancer en 1 point d'action. *Coût doublé **après** réduction.* Vous ne pouvez pas lancer d'autre sort durant ce tour. #todo" + "fr_FR": "Vous êtes capable de lancer des sorts de [[regles/la-magie/liste-des-sorts#Rang 3|rang 3]] en 2 actions." }, "~aSKEdh0dL7lcbGiuf75nDqw": { "fr_FR": "Vous n'êtes capable d'asséner qu'un seul coup par action d'attaque, y compris sous forme d'Aspect. #todo" @@ -2396,6 +2714,150 @@ }, "H9dC1FCgR1u~zT5HAxbG0p4r": { "fr_FR": "Octroie un bonus de +1 à la parade active." + }, + "Rl2mNKFEpoZZn1DLbuFzaBHd": { + "fr_FR": "Lorsqu'un allié visible pouvant vous entendre rate un jet de résistance de [[2. Liste des effets#Apeuré|peur]], de [[2. Liste des effets#Charmé|charme]], de [[2. Liste des effets#Possédé|possession]] ou d'[[2. Liste des effets#Influencé|influence]], vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour l'aider à se ressaisir, lui offrant ainsi la possibilité de relancer son jet. Utilisable une fois par type d'effet et par combat." + }, + "~mTRb_.CJs~84W82JT2qcsl.": { + "fr_FR": "Lorsque vous [[2. Actions en combat#Communiquer|communiquez]], vous êtes capable de donner des instructions contradictoires que seuls vos alliées savent décodés, induisant vos adversaires en erreurs. Faites un jet opposé de [[2. Compétences#Mensonge|mensonge]] contre la [[2. Compétences#Compréhension|compréhension]] adverse. En cas de réussite, la première réaction de l'adversaire lui coutera un point de réaction supplémentaire." + }, + "3yZ6ADJpg3fnhKNtu-HcmEi3": { + "fr_FR": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" + }, + "gDC046V84hbVhAx6.WrgTjiT": { + "fr_FR": "Une fois entre chaque [[3. Glossaire#Long repos|long repos]], vous pouvez considérer que vous avez fait 10 sur un jet de compétence dépendant de cette statistique." + }, + "A6KgrFEesScFzBUWnBJxIMrP": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "DilFgXEWYe~E3PV9xSLw4ssl": { + "fr_FR": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." + }, + "nGJkJqDOjZrye3BH78-zO9VR": { + "fr_FR": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." + }, + "k9vjg8XnOSB.-ETBd9gO6keX": { + "fr_FR": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." + }, + "gU19Lth3t7Q5N.7cdX1yrYjH": { + "fr_FR": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." + }, + "1lxVFQVSjI-SIXfM0Yg4SvWG": { + "fr_FR": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." + }, + "goPESrmJi1-5p2ljD8OZyFfy": { + "fr_FR": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." + }, + "-oP-b2vX6lsHuGlqZoq0BPqA": { + "fr_FR": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." + }, + "xz.MsMlUk~gtmjRcERiYZMty": { + "fr_FR": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." + }, + "Kkm2fCo~YnzApI-.TJG5V._d": { + "fr_FR": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." + }, + "pdyvtHIV45hs~PBnuKF6F0X-": { + "fr_FR": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance (non cumulable)." + }, + "tYOLsSl537dfNEpeNEUd5Yh2": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "LA7mcUGai~1S8en4Q3-OpU0G": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "4IJTPQozUH-8fisoQphAPm5v": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "l4LHPW-b2xaO7tD3spxddlmO": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "VaDJaP_DeYtbs653j9vD~Usv": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "AnRniyLT3s1D76M~b-Xuy5vf": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "pZ_~TejUarQTh4Q.P6ngBH4U": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "NwT6FgH6QpFlvNmYmll.wHRU": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "G_5fWJ0QVvn.RamYeSbQVSlH": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "8659kHj8-r-~KYyyxFCVS6m1": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "t~aQqwt0_TAIKR7cYu64MKp4": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "Bo-slpDgEyBJPzhhxg.joYWT": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "~HoKRe-Re6Bf9wuDg1fdN7X2": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "lV4E6~20dp-1qaWlVtQ2f3AM": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "WUN0aUr4IgSo4-zNj81cqCxj": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "eImUIlgB2K~OLEalMuY78_6v": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "kS.8Hde4F.2X.fxpOycckDjJ": { + "fr_FR": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6. *Ne fonctionne pas sur les jets de fabrications et les jets d'œuvres*" + }, + "_0GpUc1ytU_l0-CXNFsjid-V": { + "fr_FR": "Une fois entre chaque [[3. Glossaire#Long repos|long repos]], vous pouvez considérer que vous avez fait 10 sur un jet de compétence dépendant de cette statistique." + }, + "XzIhpY~irwZF0JM0FOX7MxIr": { + "fr_FR": "Une fois entre chaque [[3. Glossaire#Long repos|long repos]], vous pouvez considérer que vous avez fait 10 sur un jet de compétence dépendant de cette statistique." + }, + "uJwu394godQv2X8YYXNInBu6": { + "fr_FR": "Une fois entre chaque [[3. Glossaire#Long repos|long repos]], vous pouvez considérer que vous avez fait 10 sur un jet de compétence dépendant de cette statistique." + }, + "uJD6wua0d9ocS9YGtV9jgQ5d": { + "fr_FR": "Une fois entre chaque [[3. Glossaire#Long repos|long repos]], vous pouvez considérer que vous avez fait 10 sur un jet de compétence dépendant de cette statistique." + }, + "yex6bd6bTfnV~5tixWEa6vok": { + "fr_FR": "Une fois entre chaque [[3. Glossaire#Long repos|long repos]], vous pouvez considérer que vous avez fait 10 sur un jet de compétence dépendant de cette statistique." + }, + "gDkz75SRzGVjVORAxP5jVDUF": { + "fr_FR": "Une fois entre chaque [[3. Glossaire#Long repos|long repos]], vous pouvez considérer que vous avez fait 10 sur un jet de compétence dépendant de cette statistique." + }, + "XBX1s3XtoR3gP-ZKJpLlucUX": { + "fr_FR": "Une fois entre chaque [[3. Glossaire#Long repos|long repos]], vous pouvez considérer que vous avez fait 10 sur un jet de compétence dépendant de cette statistique." + }, + "-c05ofwtp~3RFIBPO31kWMst": { + "fr_FR": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" + }, + "blr4ZstOXmZqcD0fy8yXh_5C": { + "fr_FR": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" + }, + "1BRFNSIiv6bVJln714vQP9ZZ": { + "fr_FR": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" + }, + "X42n-QCtS7wLy73ugYMMixRe": { + "fr_FR": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" + }, + "FdvdnaYABNT5ifIVQoEVyMFr": { + "fr_FR": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" + }, + "QZ0U.xMag2jM.sMwT~p0w7nr": { + "fr_FR": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" + }, + "MQP4cgGF.Nt4XvbLsRgoHDvp": { + "fr_FR": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" + }, + "OkM1RDA-Gbhpl1wMh4bImTrE": { + "fr_FR": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" + }, + "xU66w~JOPFd-.jBRy5ulHgNC": { + "fr_FR": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez [[2. Actions en combat#Saisir une opportunité|saisir l'opportunité]] pour dépenser l'intégralité du coût en mana à la place du lanceur. *Vous appliquez le coût en mana du lanceur d'origine.*" } }, "peoples": { @@ -5414,7 +5876,8 @@ "id": "dFJoBM9hqmx-.W9d3skKzTey", "category": "tree", "tree": "weapon", - "option": "shield" + "option": "shield", + "priority": 3 }, { "category": "value", @@ -5556,7 +6019,8 @@ "id": "l.o2_89Rr6vAJjtMnR1CblgF", "category": "tree", "tree": "weapon", - "option": "shield" + "option": "shield", + "priority": 6 }, { "category": "value", @@ -7230,11 +7694,11 @@ "value": 3 }, { - "id": "b3Lv2.Ku0i_nce6JHtoP1cPm", + "id": "alf~rxPUMtZ39L9hLY6hP8_r", "category": "value", - "property": "initiative", + "property": "bonus/defense/intelligence", "operation": "add", - "value": "modifier/intelligence" + "value": 1 } ] }, @@ -7486,10 +7950,119 @@ "id": "SIBxJX9IA0srr9zpK7~VM.Yl", "effect": [ { - "id": "CuG3oTe8pAaMfrnSHGFrxnvz", + "id": "-w82Fj-mhVUl02Q.22BPMQaC", "category": "choice", "text": "Lorsque vous voyez un sort de cet élément être lancé à 12 cases de vous, vous pouvez saisir l'opportunité pour dépenser l'intégralité du coût en mana à la place du lanceur.", - "options": [] + "options": [ + { + "effects": [ + { + "id": "VYCv67oul9WAIE1LVN76-Dv8", + "category": "list", + "action": "add", + "list": "reaction", + "item": "aMBkH6D0QkBL6fML1wgxa1vx" + } + ], + "text": "Feu" + }, + { + "effects": [ + { + "id": "8pOlo1scfemcruV2kDt4whZ0", + "category": "list", + "action": "add", + "list": "reaction", + "item": "l7dF5BS6GlnHjbLedawYmd94" + } + ], + "text": "Glace" + }, + { + "effects": [ + { + "id": "593EYc84DA60G797bV8AK8tk", + "category": "list", + "action": "add", + "list": "reaction", + "item": "Z3AtRfXE9Jw.3bIFAkImhPfb" + } + ], + "text": "Foudre" + }, + { + "effects": [ + { + "id": "j2.sXQBgOGX8s~Sy-xX0WZhp", + "category": "list", + "action": "add", + "list": "reaction", + "item": "xIFuBk1ekDnygzW2HmrZQLeq" + } + ], + "text": "Terre" + }, + { + "effects": [ + { + "id": "AhBNukph-whvaC4OQ0U1K3Yy", + "category": "list", + "action": "add", + "list": "reaction", + "item": "kgvJLr4AmeqM7voorijH_-RH" + } + ], + "text": "Arcane" + }, + { + "effects": [ + { + "id": "vEv1bDyobZYiPuJlKw1E28f9", + "category": "list", + "action": "add", + "list": "reaction", + "item": "VK2J0lZUg.f0l3bdxa7d.l3M" + } + ], + "text": "Air" + }, + { + "effects": [ + { + "id": "qbc.JcL_7QEXv4kt9MaaSqaK", + "category": "list", + "action": "add", + "list": "reaction", + "item": "sp0_jz_kaZM4iLNsKgIJznyd" + } + ], + "text": "Nature" + }, + { + "effects": [ + { + "id": "o-axNR8TbdZLOUhT~mVkF6U0", + "category": "list", + "action": "add", + "list": "reaction", + "item": "DNYbN_FZKIidJWJcqIgIbK6p" + } + ], + "text": "Lumière" + }, + { + "effects": [ + { + "id": "5ZDhrJgw~w9rYSEHeF__UXP1", + "category": "list", + "action": "add", + "list": "reaction", + "item": "diaCgaj2tRtH9gZggMeID6fx" + } + ], + "text": "Psy" + } + ] } ] }, @@ -8898,96 +9471,103 @@ "description": "lSQeYPhi7dC2aeAOxos88AUf", "id": "w~~OZ4jKGWYAIvRhBMJp-6Qs", "effect": [ - { - "id": "z_sCql.9Bw9fXd7-6Xxf7WYS", - "category": "choice", - "text": "Une fois entre chaque [[3. Glossaire#Long repos|long repos]], vous pouvez considérer que vous avez fait 10 sur un jet de compétence dépendant de ", - "options": [ - { - "text": "Force", - "effects": [ - { - "category": "value", - "property": "modifier/strength", - "operation": "add", - "value": 1 - } - ] - }, - { - "text": "Dextérité", - "effects": [ - { - "category": "value", - "property": "modifier/dexterity", - "operation": "add", - "value": 1 - } - ] - }, - { - "text": "Constitution", - "effects": [ - { - "category": "value", - "property": "modifier/constitution", - "operation": "add", - "value": 1 - } - ] - }, - { - "text": "Intelligence", - "effects": [ - { - "category": "value", - "property": "modifier/intelligence", - "operation": "add", - "value": 1 - } - ] - }, - { - "text": "Curiosité", - "effects": [ - { - "category": "value", - "property": "modifier/curiosity", - "operation": "add", - "value": 1 - } - ] - }, - { - "text": "Charisme", - "effects": [ - { - "category": "value", - "property": "modifier/charisma", - "operation": "add", - "value": 1 - } - ] - }, - { - "text": "Psyché", - "effects": [ - { - "egory": "value", - "property": "modifier/psyche", - "operation": "add", - "value": 1 - } - ] - } - ] - }, { "id": "QnNJGeq~faM2~io3k.r-kll5", "category": "value", "property": "modifier/curiosity", "operation": "add", "value": 1 + }, + { + "id": "xXB2crOSkxqB.DcWncOk_L0N", + "category": "choice", + "text": "Une fois entre chaque long repos, vous pouvez considérer que vous avez fait 10 sur un jet de compétence dépendant de cette statistique.", + "options": [ + { + "effects": [ + { + "id": "8vbO0ui7i8r~PU14pa4xBpRz", + "category": "list", + "action": "add", + "list": "passive", + "item": "T5Ydhb6BoAmi~eVRIkJHNtqk" + } + ], + "text": "Force" + }, + { + "effects": [ + { + "id": "CdtSgF8q_E_KiUmq8aX.0aid", + "category": "list", + "action": "add", + "list": "passive", + "item": "Ty0F~TawgHCw.v1ZaAVY1SMy" + } + ], + "text": "Dextérité" + }, + { + "effects": [ + { + "id": "l2Xh2ofm9BixBtd6NjLQhHOn", + "category": "list", + "action": "add", + "list": "passive", + "item": "yTQHlz_9Ge44Z.vczn.7BXzk" + } + ], + "text": "Constitution" + }, + { + "effects": [ + { + "id": "_SMkHw9k_6~sqaBA4iN9tn80", + "category": "list", + "action": "add", + "list": "passive", + "item": "MIK4~Y0.LUqT2wDkdspnISC1" + } + ], + "text": "Intelligence" + }, + { + "effects": [ + { + "id": "jA1B3nhtvQGTkJbX-s2MwaZY", + "category": "list", + "action": "add", + "list": "passive", + "item": "q~D1X0LJI6y651hrwxbcbUId" + } + ], + "text": "Curiosité" + }, + { + "effects": [ + { + "id": "FTaoXY0lFzb.Dw~cIiekDxWG", + "category": "list", + "action": "add", + "list": "passive", + "item": "5xvmrqw99VshQJwRicMB0-gl" + } + ], + "text": "Charisme" + }, + { + "effects": [ + { + "id": "VgVF0CHXvFQCw5P1bPSkJshF", + "category": "list", + "action": "add", + "list": "passive", + "item": "es55TA4bQriww7t.884Bac_P" + } + ], + "text": "Psyché" + } + ] } ] }, @@ -9088,10 +9668,215 @@ "id": "-GXznUayirmHWQ0IWDN2pl0O", "effect": [ { - "id": "AFFEnINeRpwaqYDnI4F5PPon", + "id": "BurGI381NXwabhx7~faoLdX8", "category": "choice", - "text": "Vous ne pouvez pas faire moins de 6 sur vos jets de ", - "options": [] + "text": "Si vous faites 6 ou moins à votre jet de cette compétence, vous considérez que votre jet est un 6.", + "options": [ + { + "effects": [ + { + "id": "iSp0ek~LfhvAia0Refyr7EJc", + "category": "list", + "action": "add", + "list": "passive", + "item": "AvUqmzwwYyfHOf47El67Thwy" + } + ], + "text": "Athlétisme" + }, + { + "effects": [ + { + "id": "olRRpaWiTeExjaQ1H9E6bkkW", + "category": "list", + "action": "add", + "list": "passive", + "item": "fJNc1f9c9OF7IvrZVHaI3vbh" + } + ], + "text": "Acrobatisme" + }, + { + "effects": [ + { + "id": "kkMLza2QrsyoIRkFvIe~0bAV", + "category": "list", + "action": "add", + "list": "passive", + "item": "hBC273QPK7Mp56z77L0DIqoA" + } + ], + "text": "Intimidation" + }, + { + "effects": [ + { + "id": "m0NmdRzWF3DQ0gPW9V-NWP0q", + "category": "list", + "action": "add", + "list": "passive", + "item": ".8gE2g5Cgqy99bfXcm65AqSF" + } + ], + "text": "Doigté" + }, + { + "effects": [ + { + "id": "xYvDZHjsiURxWdj_B73GcAEt", + "category": "list", + "action": "add", + "list": "passive", + "item": "hEmgMSksljb3xTe_ZnPvvZzv" + } + ], + "text": "Discrétion" + }, + { + "effects": [ + { + "id": "vAylWAVXEE2OHchIPK~2sVSs", + "category": "list", + "action": "add", + "list": "passive", + "item": "KfJemdt.y_n3cyuhjU9MhQBV" + } + ], + "text": "Survie" + }, + { + "effects": [ + { + "id": "AiqoXSPbTw~2UskcK4lyXdR8", + "category": "list", + "action": "add", + "list": "passive", + "item": "cf361.wAOL4eI1K_B7VJWVPj" + } + ], + "text": "Enquête" + }, + { + "effects": [ + { + "id": "VEoi6Dyx1W_PKCu2dtxi0PV7", + "category": "list", + "action": "add", + "list": "passive", + "item": "S3vTN67Vpm5ZkD-dCHP2pvIv" + } + ], + "text": "Histoire" + }, + { + "effects": [ + { + "id": "1n9NYd.scPQYjh.ky~xDm0u-", + "category": "list", + "action": "add", + "list": "passive", + "item": "vHCn_Gt0rBJcfq3ouChXiA12" + } + ], + "text": "Religion" + }, + { + "effects": [ + { + "id": "3k_o4ZtBqvXtJGGcBgf9VK2T", + "category": "list", + "action": "add", + "list": "passive", + "item": "aAOhpcc-1oYEWQgSKFa9R5rn" + } + ], + "text": "Arcanes" + }, + { + "effects": [ + { + "id": "Q6azTc98FJUyB9_wV4-Mo2pL", + "category": "list", + "action": "add", + "list": "passive", + "item": "7CqiylL~RnY_.lmhqYGXPRsw" + } + ], + "text": "Compréhension" + }, + { + "effects": [ + { + "id": "M3LV5i3pscV1~nEmWXTYjtRK", + "category": "list", + "action": "add", + "list": "passive", + "item": "0LpT-92h1QbA4Gj8-7c~Vn9N" + } + ], + "text": "Perception" + }, + { + "effects": [ + { + "id": "8sDQvh8XcXRKDYr709U~oMME", + "category": "list", + "action": "add", + "list": "passive", + "item": "tYrYzZsPkFjeEzRxW0Hja9hU" + } + ], + "text": "Représentation" + }, + { + "effects": [ + { + "id": "gw7lz.iO7s9oOpnBRJtALyo4", + "category": "list", + "action": "add", + "list": "passive", + "item": "YmHnkIgtxrJGOS9ohfon7~eZ" + } + ], + "text": "Médicine" + }, + { + "effects": [ + { + "id": "xWAp~gPHRKM9Urnt1v8FKuF~", + "category": "list", + "action": "add", + "list": "passive", + "item": "ZDAR3lj5v7BQmnZl1hWZrMTM" + } + ], + "text": "Persuasion" + }, + { + "effects": [ + { + "id": "QF545HAYls_.rhOFJQ7h9Wui", + "category": "list", + "action": "add", + "list": "passive", + "item": "CMzU7jkM54YzkWDzYS0T3qS5" + } + ], + "text": "Dressage" + }, + { + "effects": [ + { + "id": "pZ.hueXqsd7DXW8uRd4fYdfU", + "category": "list", + "action": "add", + "list": "passive", + "item": "ligmn8hHxgl05pWv6bHK8FTq" + } + ], + "text": "Mensonge" + } + ] } ] }, @@ -9316,11 +10101,11 @@ "id": "U5qbX004Wd43s.Bf1cijM0yz", "effect": [ { - "id": "zM6xTbs~KOv~SA2MCKr2reJm", - "category": "list", - "list": "passive", - "action": "add", - "item": "Uj1a~yR5DaMRWyQ198zVQYme" + "id": "BZpQCk50BReucStzrAcnzqIn", + "category": "value", + "property": "bonus/defense/charisma", + "operation": "add", + "value": 1 } ] }, @@ -9361,19 +10146,19 @@ "description": "Pbg3J5RjrDIZEiIF_ewq95RV", "id": "XZZlGeVR2ReuQEpEf955eFY8", "effect": [ - { - "id": "BbumVYQ.nkdb_0w9AwnhZ0Tr", - "category": "list", - "list": "passive", - "action": "add", - "item": "_-y9HXQVFxQrCuBE.Gvj6GWe" - }, { "id": "AV.Ol3yR6BNk8gxH8xQGzvx7", "category": "value", "property": "modifier/charisma", "operation": "add", "value": 1 + }, + { + "id": "_JtvRqMLDOLpk_V-RINvCP~5", + "category": "list", + "list": "reaction", + "action": "add", + "item": "XALPxv~Tn6aD0PmzhenFvBZ8" } ] }, @@ -9700,7 +10485,15 @@ "ZWN4piR9KpIoLu4Y542CyrCI": { "description": "lBEIZYfXUN.qwORdG6xx1q82", "id": "ZWN4piR9KpIoLu4Y542CyrCI", - "effect": [] + "effect": [ + { + "id": "ta9Q27GvZk3N6IKwtTfdz7Rd", + "category": "list", + "list": "freeaction", + "action": "add", + "item": "anN9n9S1ojkgpOpg75o4Qc3x" + } + ] }, "crhn3vmhofkxbnDhvAdr_ra_": { "description": "GWSs932gL1n7gDBLyUoyELTZ", @@ -12011,7 +12804,123 @@ "Uh~LWr7r-X6pa2GhxCCTDqS1": { "id": "Uh~LWr7r-X6pa2GhxCCTDqS1", "description": "w3-_SA7z72E_gDURhkguMMYh", - "effect": [] + "effect": [ + { + "id": "zCts3H-PMy3F21MvIVg8lOx4", + "category": "choice", + "text": "Les sorts de cette classe élémentaire ignore les résistances et réduisent les immunités en résistance.", + "options": [ + { + "effects": [ + { + "id": "RQ4wzrPYCjaIRI_or5IVzup0", + "category": "list", + "action": "add", + "list": "passive", + "item": "Ao3-KQU9IKI2M6XXt.VtinW-" + } + ], + "text": "Feu" + }, + { + "effects": [ + { + "id": "sDPKtDHBaTUZd02hyYNmcafQ", + "category": "list", + "action": "add", + "list": "passive", + "item": "n03RVmIIDgz2F4HYdp6B_pqT" + } + ], + "text": "Glace" + }, + { + "effects": [ + { + "id": "hLWyINxkGKu.KHZrXz5KjzVF", + "category": "list", + "action": "add", + "list": "passive", + "item": "aWYwux-8iTKR~CZK~TEZiEM3" + } + ], + "text": "Foudre" + }, + { + "effects": [ + { + "id": "70o-RCTvnj1S2Rfy~zAvTCXW", + "category": "list", + "action": "add", + "list": "passive", + "item": "nT8HHMM53SgpocueRxua5qjl" + } + ], + "text": "Terre" + }, + { + "effects": [ + { + "id": "00l4LNM~kqVSePBlSq5smV4.", + "category": "list", + "action": "add", + "list": "passive", + "item": "_LAuZprDuEaWZ-TNPUX6GhfT" + } + ], + "text": "Arcane" + }, + { + "effects": [ + { + "id": "1ZL11dSB-vbVxBzfsV3N5Yr6", + "category": "list", + "action": "add", + "list": "passive", + "item": "x0AEtoYvMAk4UgP1AMLtMOag" + } + ], + "text": "Air" + }, + { + "effects": [ + { + "id": "Y5dFojcWrL9jQ3gpdPMAay4_", + "category": "list", + "action": "add", + "list": "passive", + "item": "zEODNKpyUAcsGsFKW6mlJPc4" + } + ], + "text": "Nature" + }, + { + "effects": [ + { + "id": "EeE_2.D38m-pCct7Mk-GWlps", + "category": "list", + "action": "add", + "list": "passive", + "item": "Cozzn1_fuKf8L.6O3gWMu8Bt" + } + ], + "text": "Lumière" + }, + { + "effects": [ + { + "id": "3Bm~sLQPpMqbyRlB.ZEBjKQy", + "category": "list", + "action": "add", + "list": "passive", + "item": "cw9HYWutoyiV5U1Am7HlwtvB" + } + ], + "text": "Psy" + } + ] + } + ] }, "GNDBexNnuFuzLMoLbV-RuG5g": { "id": "GNDBexNnuFuzLMoLbV-RuG5g", @@ -13088,12 +13997,13 @@ "power": 2, "restrictions": [ "weapon" - ] + ], + "cursed": false } }, "sickness": {}, - "poisons": {}, - "dedications": {}, + "poison": {}, + "dedication": {}, "trees": { "multiattack": { "name": "Attaques multiples", diff --git a/shared/character.ts b/shared/character.ts index 84cbb09..ea52752 100644 --- a/shared/character.ts +++ b/shared/character.ts @@ -2001,7 +2001,7 @@ export class CharacterSheet div('flex flex-col gap-2 h-full', [ div('flex flex-row justify-end items-center', [ div('flex flex-row gap-2 items-center', [ - dom('span', { class: () => ['italic text-sm', { 'text-light-red dark:text-dark-red': character.variables.spells.length + (character.lists.spells?.length ?? 0) !== character.spellslots }], text: () => `${character.variables.spells.length + (character.lists.spells?.length ?? 0)}/${character.spellslots} sort(s) maitrisé(s)`.replaceAll('(s)', character.variables.spells.length + (character.lists.spells?.length ?? 0) > 1 ? 's' : '') }), + dom('span', { class: () => ['italic text-sm', { 'text-light-red dark:text-dark-red': character.variables.spells.length !== character.spellslots }], text: () => `${character.variables.spells.length}/${character.spellslots} sort(s) maitrisé(s)`.replaceAll('(s)', character.variables.spells.length > 1 ? 's' : '') }), button(text('Modifier'), () => panel.show(), 'py-1 px-4'), tooltip(button(icon('ph:arrows-down-up', { width: 16, height: 16 }), sorter, 'p-1'), 'Trier par', 'right') ]) @@ -2042,7 +2042,7 @@ export class CharacterSheet const container = div("border-light-35 dark:border-dark-35 bg-light-10 dark:bg-dark-10 border-l absolute top-0 bottom-0 right-0 w-[10%] data-[state=active]:w-1/2 flex flex-col gap-4 text-light-100 dark:text-dark-100 p-8 transition-[width] transition-delay-[150ms]", [ div("flex flex-row justify-between items-center", [ dom("h2", { class: "text-xl font-bold", text: "Ajouter un sort" }), - div('flex flex-row gap-4 items-center', [ dom('span', { class: 'italic text-light-70 dark:text-dark-70 text-sm' }, [ text(() => `${spells.length + (character.lists.spells?.length ?? 0)}/${character.spellslots} sort(s) maitrisé(s)`.replaceAll('(s)', spells.length + (character.lists.spells?.length ?? 0) > 1 ? 's' : '')) ]), tooltip(button(icon("radix-icons:cross-1", { width: 20, height: 20 }), () => { + div('flex flex-row gap-4 items-center', [ dom('span', { class: 'italic text-light-70 dark:text-dark-70 text-sm' }, [ text(() => `${spells.length}/${character.spellslots} sort(s) maitrisé(s)`.replaceAll('(s)', spells.length > 1 ? 's' : '')) ]), tooltip(button(icon("radix-icons:cross-1", { width: 20, height: 20 }), () => { setTimeout(blocker.close, 150); container.setAttribute('data-state', 'inactive'); }, "p-1"), "Fermer", "left") ]) @@ -2149,7 +2149,7 @@ export class CharacterSheet const weight = div(() => ['flex flex-row min-w-16 gap-2 justify-between items-center px-2', { 'cursor-help': e.amount > 1 && !!item.weight }], [ icon('mdi:weight', { width: 16, height: 16, class: 'text-light-70 dark:text-dark-70' }), span(() => ({ 'underline decoration-1 decoration-dotted underline-offset-2': e.amount > 1 && !!item.weight }), () => item.weight ? `${item.weight * e.amount}` : '-') ]); return foldable(() => [ markdown(getText(item.description)), - div('flex flex-row gap-1', { list: () => e.enchantments!.map(e => config.enchantments[e]).filter(e => !!e), render: (e, _c) => _c ?? floater(div('flex flex-row gap-2 border border-accent-blue px-2 rounded-full py-px bg-accent-blue bg-opacity-20', [ span('text-sm font-semibold tracking-tight', e.name), div('flex flex-row gap-1 items-center', [icon('game-icons:bolt-drop', { width: 12, height: 12 }), span('text-sm font-light', e.power)]) ]), () => [markdown(getText(e.description), undefined, { tags: { a: preview } })], { class: 'max-w-96 max-h-48 p-2', position: "right" }) }), + div('flex flex-row gap-1', { list: () => e.enchantments!.map(e => config.enchantments[e]).filter(e => !!e), render: (e, _c) => _c ?? floater(div(() => ['flex flex-row gap-2 border px-2 rounded-full py-px !bg-opacity-20', { 'border-accent-blue bg-accent-blue': !e.cursed, 'border-light-purple bg-light-purple dark:border-dark-purple dark:bg-dark-purple': e.cursed }], [ span('text-sm font-semibold tracking-tight', e.name), div('flex flex-row gap-1 items-center', [icon('game-icons:bolt-drop', { width: 12, height: 12 }), span('text-sm font-light', e.power)]) ]), () => [markdown(getText(e.description), undefined, { tags: { a: preview } })], { class: 'max-w-96 max-h-48 p-2', position: "right" }) }), div('flex flex-row justify-center gap-1', [ this.character?.character.campaign ? button(text('Partager'), () => { @@ -2302,9 +2302,11 @@ export class CharacterSheet }, "p-1"), "Fermer", "left") ]) ]), - div('grid grid-cols-1 -my-2 overflow-y-auto gap-1', { list: () => Object.values(config.enchantments).filter(e => restrict(e, current.item?.id)), render: (enchant, _c) => _c ?? foldable(() => [ markdown(getText(enchant.description)) ], [div('flex flex-row justify-between', [ + div('grid grid-cols-1 -my-2 overflow-y-auto gap-1', { list: () => Object.values(config.enchantments).filter(e => restrict(e, current.item?.id)), render: (enchant, _c) => _c ?? foldable(() => [ markdown(getText(enchant.description)) ], [ + div('flex flex-row justify-between', [ div('flex flex-row items-center gap-4', [ span('text-lg', enchant.name) ]), div('flex flex-row items-center divide-x divide-light-50 dark:divide-dark-50 divide-dashed px-2 gap-4', [ + enchant.cursed ? span('italic text-sm text-light-purple dark:text-dark-purple', `Malédiction`) : undefined, span('italic text-sm', `Puissance magique: ${enchant.power}`), button(icon(() => current.item?.enchantments?.includes(enchant.id) ? 'radix-icons:minus' : 'radix-icons:plus', { width: 16, height: 16 }), () => { const idx = current.item!.enchantments?.findIndex(e => e === enchant.id) ?? -1; diff --git a/shared/feature.ts b/shared/feature.ts index 25f99a7..9b482e1 100644 --- a/shared/feature.ts +++ b/shared/feature.ts @@ -4,7 +4,7 @@ import { MarkdownEditor } from "#shared/editor"; import { preview } from "#shared/proses"; import { button, checkbox, combobox, foldable, input, multiselect, numberpicker, optionmenu, select, tabgroup, table, toggle, type Option } from "#shared/components"; import { confirm, contextmenu, fullblocker, tooltip } from "#shared/floating"; -import { ABILITIES, abilityTexts, ALIGNMENTS, alignmentTexts, categoryText, colorByRarity, damageTypeTexts, elementTexts, LEVELS, MAIN_STATS, mainStatShortTexts, mainStatTexts, masteryTexts, rarityText, RESISTANCES, resistanceTexts, SPELL_ELEMENTS, SPELL_TYPES, spellTypeTexts, subnameFactory, weaponTypeTexts } from "#shared/character"; +import { ABILITIES, abilityTexts, ALIGNMENTS, alignmentTexts, colorByRarity, damageTypeTexts, elementTexts, LEVELS, MAIN_STATS, mainStatShortTexts, mainStatTexts, masteryTexts, rarityText, RESISTANCES, resistanceTexts, SPELL_ELEMENTS, SPELL_TYPES, spellTypeTexts, subnameFactory, weaponTypeTexts } from "#shared/character"; import characterConfig from "#shared/character-config.json"; import { getID } from "#shared/general"; import markdown, { markdownReference, renderMDAsText } from "#shared/markdown"; @@ -306,44 +306,109 @@ export class HomebrewBuilder actions() { let editing: { type: 'action' | 'reaction' | 'freeaction' | 'passive', id: string } | undefined; - const render = (type: 'action' | 'reaction' | 'freeaction' | 'passive', feature: { id: string, name: string, description: string, cost?: number }) => { + const render = (type: 'action' | 'reaction' | 'freeaction' | 'passive', feature: { id: string, name: string, description: string, cost?: number, variants?: string[], parent?: string }, open?: boolean): { dom: HTMLDivElement; buttons: HTMLDivElement; md: { current: HTMLElement; }; type: "action" | "reaction" | "passive" | "freeaction"; id: string; variants?: any[] } => { const md = markdownReference(getText(feature.description), undefined, { tags: { a: preview }, class: 'ms-2 px-2 py-1 border-l-4 border-light-30 dark:border-dark-30' }); - const buttons = div('flex flex-row items-center gap-2', [ span('text-sm text-light-70 dark:text-dark-70', type), tooltip(button(icon('radix-icons:pencil-1'), () => edit(type, feature.id), 'p-1'), 'Modifier', 'left'), tooltip(button(icon('radix-icons:trash'), () => remove(type, feature.id), 'p-1'), 'Supprimer', 'right') ]); + const buttons = div('flex flex-row items-center gap-2', [ span('text-sm text-light-70 dark:text-dark-70', type), feature.parent ? undefined : tooltip(button(icon('radix-icons:symbol'), optionmenu([ + { title: "Classe élementaire", click: () => SPELL_ELEMENTS.forEach(e => add(type, { parent: feature.id, variation: elementTexts[e].text })) }, + { title: "Rangs de sort", click: () => ["Rang 1", "Rang 2", "Rang 3", "Sorts spéciaux"].forEach(e => add(type, { parent: feature.id, variation: e })) }, + { title: "Categories de sort", click: () => SPELL_TYPES.forEach(e => add(type, { parent: feature.id, variation: spellTypeTexts[e] })) }, + { title: "Statistique", click: () => MAIN_STATS.forEach(e => add(type, { parent: feature.id, variation: mainStatTexts[e] })) }, + { title: "Compétence", click: () => ABILITIES.forEach(e => add(type, { parent: feature.id, variation: abilityTexts[e] })) }, + { title: "Variante", click: () => add(type, { parent: feature.id, variation: "" }) }, + ]), 'p-1'), 'Variantes', 'left'), tooltip(button(icon('radix-icons:pencil-1'), () => edit(type, feature.id), 'p-1'), 'Modifier', 'left'), tooltip(button(icon('radix-icons:trash'), () => remove(type, feature.id), 'p-1'), 'Supprimer', 'right') ]); + const variants = feature.variants ? feature.variants.map(e => config[type][e] ? render(type, config[type][e]) : undefined).filter(e => !!e) : undefined; return { - dom: div('flex flex-col gap-2', [ + dom: feature.variants ? foldable(() => variants?.map(e => e.dom), [div('flex flex-col gap-2', [ div('flex flex-row justify-between', [ input('text', { defaultValue: feature.name, input: value => { feature.name = value }, placeholder: 'Nom', class: '!mx-0 w-80' }), div('flex flex-row gap-2 items-center', [ type === 'action' || type === 'reaction' ? div('flex flex-row items-center', [ numberpicker({ defaultValue: feature?.cost ?? 0, input: value => feature.cost = value, class: '!mx-1', max: type === 'action' ? 3 : 2, min: 0 }), text(`point${(feature?.cost ?? 0) > 1 ? 's' : ''}`)]) : undefined, buttons ])]), md.current, + ])], { open: open ?? false, class: { icon: 'self-start p-2', content: 'border-l-2 border-light-35 dark:border-dark-35 flex flex-col gap-4 ms-2 ps-2 py-2' } }) : div('flex flex-col gap-2', [ + div('flex flex-row justify-between', [ input('text', { defaultValue: feature.name, input: value => { feature.name = value }, placeholder: 'Nom', class: '!mx-0 w-80' }), div('flex flex-row gap-2 items-center', [ (type === 'action' || type === 'reaction') && feature.parent === undefined ? div('flex flex-row items-center', [ numberpicker({ defaultValue: feature?.cost ?? 0, input: value => feature.cost = value, class: '!mx-1', max: type === 'action' ? 3 : 2, min: 0 }), text(`point${(feature?.cost ?? 0) > 1 ? 's' : ''}`)]) : undefined, buttons ])]), + md.current, ]), + variants: variants, buttons, md, type, id: feature.id, }; } - const add = (type: 'action' | 'reaction' | 'freeaction' | 'passive') => { - const feature: { id: string, name: string, description: string, cost?: number } = { + const add = (type: 'action' | 'reaction' | 'freeaction' | 'passive', variant?: { parent: string, variation: string }) => { + const feature: { id: string, name: string, description: string, cost?: number, parent?: string } = { id: getID(), name: '', description: getID(), // i18nID - cost: type === 'action' || type === 'reaction' ? 1 : undefined, + cost: (type === 'action' || type === 'reaction') && variant === undefined ? 1 : undefined, + parent: variant?.parent, } - config.texts[feature.description] = { 'fr_FR': '' }; + setText(feature.description, ''); config[type][feature.id] = feature; - const option = render(type, feature); - options.push(option); - optionHolder.appendChild(option.dom); + if(variant === undefined) + { + const option = render(type, feature); + options.push(option); + optionHolder.appendChild(option.dom); + } + else if(config[type][variant.parent] !== undefined) + { + const parent = config[type][variant.parent]!; + parent.variants ??= []; + parent.variants.push(feature.id); + + feature.name = variant.variation; + setText(feature.description, getText(parent.description)); + + const option = render(type, parent, true) + const idx = options.findIndex(e => e.id === variant.parent && e.type === type); + if(idx !== -1) + { + options[idx]?.dom?.replaceWith(option.dom); + options[idx] = option; + } + } }; const remove = (type: 'action' | 'reaction' | 'freeaction' | 'passive', id: string) => { const feature = config[type][id]!; - confirm(`Voulez vous vraiment supprimer l'effet "${feature.name}" ?`).then(e => { + confirm(`Voulez vous vraiment supprimer l'effet "${feature.name}"${feature.variants !== undefined ? " et ses " + feature.variants.length + " variantes" : ''} ?`).then(e => { if(e) { + if(feature.parent) + { + const parent = config[type][feature.parent]; + + if(parent) + { + parent.variants = parent.variants!.filter(e => e !== id); + if(parent.variants.length === 0) + delete parent.variants; + + const option = render(type, parent, true) + const idx = options.findIndex(e => e.id === feature.parent && e.type === type); + if(idx !== -1) + { + options[idx]?.dom?.replaceWith(option.dom); + options[idx] = option; + } + } + } + else + { + if(feature.variants !== undefined) + { + feature.variants.forEach(e => { + const variant = config[type][e]; + if(variant) + delete config.texts[variant.description]; + delete config[type][e]; + }); + } + + const idx = options.findIndex(e => e.type === type && e.id === id); + options.splice(idx, 1)[0]?.dom.remove(); + } + delete config.texts[feature.description]; delete config[type][id]; - - const idx = options.findIndex(e => e.type === type && e.id === id); - options.splice(idx, 1)[0]?.dom.remove(); } }); }; @@ -394,8 +459,8 @@ export class HomebrewBuilder option!.md.current.replaceWith(editorDom); option!.md.current = editorDom; - } - const options = [...Object.values(config.action).map(e => render('action', e)), ...Object.values(config.reaction).map(e => render('reaction', e)), ...Object.values(config.freeaction).map(e => render('freeaction', e)), ...Object.values(config.passive).map(e => render('passive', e))]; + }; + const options = [...Object.values(config.action).filter(e => e.parent === undefined).map(e => render('action', e)), ...Object.values(config.reaction).filter(e => e.parent === undefined).map(e => render('reaction', e)), ...Object.values(config.freeaction).filter(e => e.parent === undefined).map(e => render('freeaction', e)), ...Object.values(config.passive).filter(e => e.parent === undefined).map(e => render('passive', e))]; const optionHolder = div('flex flex-col gap-4', options.map(e => e.dom)); return [ div('flex px-8 py-4 flex-col gap-4', [ div('flex flex-row-reverse', [ button(icon('radix-icons:plus'), optionmenu([{ title: 'Action', click: () => add('action') }, { title: 'Réaction', click: () => add('reaction') }, { title: 'Action libre', click: () => add('freeaction') }, { title: 'Passif', click: () => add('passive') }], { position: 'left-start' }), 'p-1') ]), optionHolder ] ) ]; } @@ -482,12 +547,13 @@ export class HomebrewBuilder const editing = reactive({ tree: undefined as string | undefined }); return [div('', [ () => editing.tree !== undefined ? undefined : div('flex flex-row gap-1 justify-start overflow-x-auto max-w-full', { list: Object.keys(config.trees), render: (e, _c) => _c ?? div('grid grid-cols-2 gap-2 items-baseline w-64 border border-light-35 dark:border-dark-35 p-2', [ span('text-lg font-semibold tracking-thigh', config.trees[e]!.name), div('flex flex-row justify-end', [ tooltip(button(icon('radix-icons:pencil-1', { width: 16, height: 16 }), () => editing.tree = e, 'p-1'), 'Modifier', 'left') ]), span('italic', `${Object.keys(config.trees[e]!.nodes).length} nodes`) ]) }), - () => editing.tree === undefined ? undefined : div('', [ + () => editing.tree === undefined ? undefined : div('flex flex-col', [ + , foldable([ div('flex flex-col gap-2', { list: Object.keys(config.trees[editing.tree]!.nodes), render: (e, _c) => _c ?? dom("div", { class: ["border border-light-40 dark:border-dark-40 cursor-pointer px-2 py-1 w-[400px] hover:border-light-50 dark:hover:border-dark-50"], listeners: { click: () => { FeaturePanel.edit(config.features[e]!).then(feature => { config.features[e] = feature; }).catch(e => {}); - }}}, [ markdown(getText(config.features[e]!.description), undefined, { tags: { a: preview } }) ]) }) ], [ span('text-lg font-bold px-2', 'Nodes'), button(text('Nouvelle node'), () => add(), 'py-1 px-2') ], { open: true, class: { title: 'flex flex-row justify-between' } }) + }}}, [ () => markdown(getText(config.features[e]!.description), undefined, { tags: { a: preview } }) ]) }) ], [ tooltip(button(icon('radix-icons:arrow-left', { width: 16, height: 16 }), () => editing.tree = undefined, 'p-1'), 'Retour', 'right'), span('text-lg font-bold px-2', 'Nodes'), button(text('Nouvelle node'), () => add(), 'py-1 px-2') ], { open: true, class: { title: 'flex flex-row justify-between' } }) ]), ])]; } @@ -641,9 +707,14 @@ class FeatureEditor case "mastery": list = Object.entries(masteryTexts).map(e => ({ text: e[1].text, value: e[0] })); break; - default: + case "sickness": + case "poison": + case "dedication": list = Object.values(config[buffer.list]).map(e => ({ text: e.name, render: () => div('flex flex-col', [ div('flex flex-row justify-between', [ dom('span', { text: e.name, class: 'font-bold' }) ]), div('text-sm text-light-70 dark:text-dark-70', [ text(renderMDAsText(getText(e.description))) ]) ]), value: e.id })); break; + default: + list = Object.values(config[buffer.list]).map(e => ({ text: e.name, render: () => e.parent ? dom('span', { text: e.name, class: 'font-bold' }) : div('flex flex-col', [ div('flex flex-row justify-between', [ dom('span', { text: e.name, class: 'font-bold' }) ]), div('text-sm text-light-70 dark:text-dark-70', [ text(renderMDAsText(getText(e.description))) ]) ]), value: e.variants !== undefined ? `variant_${e.id}` : e.id })); + break; } return { @@ -651,7 +722,25 @@ class FeatureEditor buffer.action = value as 'add' | 'remove'; this.edit(); }, class: { container: 'bg-light-25 dark:bg-dark-25 !-m-px hover:z-10 h-[36px] w-32' } }) ], - bottom: [ combobox(list, { defaultValue: buffer.item, change: (item) => buffer.item = item, class: { container: 'bg-light-25 dark:bg-dark-25 !-m-px hover:z-10 h-[36px] w-full overflow-hidden truncate', option: 'max-h-[90px] text-sm' }, fill: 'contain' }) ] + bottom: [ combobox(list, { defaultValue: buffer.item, change: (item) => { + if(item.startsWith('variant_')) + { + item = item.substring('variant_'.length); + const feature = config[buffer.list as "action" | "reaction" | "freeaction" | "passive"][item]; + if(feature) + { + this.option = { id: buffer.id, category: "choice", text: "", options: feature.variants?.map(e => ({ + effects: [{ id: getID(), category: 'list', action: buffer.action, list: buffer.list, item: e }], + text: config[buffer.list as "action" | "reaction" | "freeaction" | "passive"][e]?.name, + })) ?? [] } as FeatureChoice; + this.edit(); + } + } + else + { + buffer.item = item; + } + }, class: { container: 'bg-light-25 dark:bg-dark-25 !-m-px hover:z-10 h-[36px] w-full overflow-hidden truncate', option: 'max-h-[90px] text-sm' }, fill: 'contain' }) ] } } private editTree(buffer: Partial) @@ -950,7 +1039,7 @@ const featureChoices: Option>[] = [ { text: 'Résistance > Psyché', effects: [{ category: 'value', property: 'bonus/defense/psyche', operation: 'add', value: 1 }] } ]} as Partial} ] }, - { text: 'Bonus à l\'attaque', value: RESISTANCES.map(e => ({ text: `Bonus > ${resistanceTexts[e]}`, value: { category: 'value', property: `bonus/resistance/${e}`, operation: 'add', value: 1 } })) }, + { text: 'Difficulté des chocs', value: RESISTANCES.map(e => ({ text: `Difficulté > ${resistanceTexts[e]}`, value: { category: 'value', property: `bonus/resistance/${e}`, operation: 'add', value: 1 } })) }, { text: 'Magie', value: [ { text: 'Rang', value: [ { text: 'Rang > Sorts de précision', value: { category: 'value', property: 'spellranks/precision', operation: 'add', value: 1 } }, @@ -963,14 +1052,28 @@ const featureChoices: Option>[] = [ { text: 'Bonus > Savoir', value: { category: 'value', property: 'bonus/spells/type/knowledge', operation: 'add', value: 1 } }, { text: 'Bonus > Instinct', value: { category: 'value', property: 'bonus/spells/type/instinct', operation: 'add', value: 1 } }, { text: 'Bonus > Œuvres', value: { category: 'value', property: 'bonus/spells/type/arts', operation: 'add', value: 1 } }, - ] }, + { text: 'Bonus > Choix par type', value: { category: 'choice', options: [ + { text: 'Précision', effects: [{ category: 'value', property: 'bonus/spells/type/precision', operation: 'add', value: 1 }] }, + { text: 'Savoir', effects: [{ category: 'value', property: 'bonus/spells/type/knowledge', operation: 'add', value: 1 }] }, + { text: 'Instinct', effects: [{ category: 'value', property: 'bonus/spells/type/instinct', operation: 'add', value: 1 }] }, + { text: 'Œuvres', effects: [{ category: 'value', property: 'bonus/spells/type/arts', operation: 'add', value: 1 }] }, + ] } as Partial } + ]}, { text: 'Bonus par rang', value: [ { text: 'Bonus > Sorts de rang 1', value: { category: 'value', property: 'bonus/spells/rank/1', operation: 'add', value: 1 } }, { text: 'Bonus > Sorts de rang 2', value: { category: 'value', property: 'bonus/spells/rank/2', operation: 'add', value: 1 } }, { text: 'Bonus > Sorts de rang 3', value: { category: 'value', property: 'bonus/spells/rank/3', operation: 'add', value: 1 } }, { text: 'Bonus > Sorts uniques', value: { category: 'value', property: 'bonus/spells/rank/4', operation: 'add', value: 1 } }, + { text: 'Bonus > Choix par rang', value: { category: 'choice', options: [ + { text: 'Rang 1', effects: [{ category: 'value', property: 'bonus/spells/rank/1', operation: 'add', value: 1 }] }, + { text: 'Rang 2', effects: [{ category: 'value', property: 'bonus/spells/rank/2', operation: 'add', value: 1 }] }, + { text: 'Rang 3', effects: [{ category: 'value', property: 'bonus/spells/rank/3', operation: 'add', value: 1 }] }, + ] } } + ] as Partial }, + { text: 'Bonus par élément', value: [ + ...SPELL_ELEMENTS.map(e => ({ text: `Bonus > ${elementTexts[e].text}`, value: { category: 'value', property: `bonus/spells/elements/${e}`, operation: 'add', value: 1 } })) as Option>[], + { text: 'Bonus > Choix par élément', value: { category: 'choice', options: SPELL_ELEMENTS.map(e => ({ text: elementTexts[e].text, effects: [{ category: 'value', property: `bonus/spells/elements/${e}`, operation: 'add', value: 1 }] })) } as Partial } ] }, - { text: 'Bonus par element', value: SPELL_ELEMENTS.map(e => ({ text: `Bonus > ${elementTexts[e].text}`, value: { category: 'value', property: `bonus/spells/elements/${e}`, operation: 'add', value: 1 } })) }, ] }, { text: 'Aspect', value: [ { text: 'Aspect > Durée', value: { category: 'value', property: 'aspect/duration', operation: 'add', value: 15 } },