diff --git a/db.sqlite b/db.sqlite index 45c1e17..619ecd4 100644 Binary files a/db.sqlite and b/db.sqlite differ diff --git a/db.sqlite-shm b/db.sqlite-shm index d4b1a26..fe9ac28 100644 Binary files a/db.sqlite-shm and b/db.sqlite-shm differ diff --git a/db.sqlite-wal b/db.sqlite-wal index 8bcaf9c..e69de29 100644 Binary files a/db.sqlite-wal and b/db.sqlite-wal differ diff --git a/shared/character-config.json b/shared/character-config.json index 8c540ba..6b428a4 100644 --- a/shared/character-config.json +++ b/shared/character-config.json @@ -676,7 +676,7 @@ "psyche" ], "name": "Persuasion", - "description": "" + "description": "La capacité à convaincre et à argumenter avec un interlocuteur. Permet de négocier. " }, "animalhandling": { "max": [ @@ -684,7 +684,7 @@ "psyche" ], "name": "Dressage", - "description": "" + "description": "La capacité à dresser, à comprendre et à pacifier les animaux. Permet de pacifier et de convaincre les animaux." }, "deception": { "max": [ @@ -692,7 +692,7 @@ "psyche" ], "name": "Mensonge", - "description": "" + "description": "La capacité à dissimuler et à inviter de nouvelles vérités. Permet de mentir à un interlocuteur." } }, "resistances": { @@ -1345,790 +1345,1278 @@ }, "spells": [ { + "id": "gt4pgw3p5jgft5141m8joamthzvx9zbu", "name": "Trait de feu", "rank": 1, "type": "precision", - "cost": 3, - "speed": "action", "elements": [ "fire" ], - "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]]. Tire un faisceau de flamme, infligeant 2d8 dégâts de feu en touchant.", + "cost": 3, + "speed": "action", + "concentration": false, "tags": [ - "Dégats" + "damage" ], - "id": "0" + "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]]. Tire un faisceau de flamme, infligeant 2d8 dégâts de feu en touchant." }, { + "id": "thekhgi4lmux1sp6hlxqtyjo87e5uard", "name": "Echauffement", "rank": 1, "type": "knowledge", - "cost": 2, - "speed": "action", "elements": [ "fire" ], - "effect": "Chauffe à blanc une arme ou un projectile. Jusqu'au début de votre prochain tour, les coups portés avec l'objet infligent 1d6 dégâts supplémentaire. Les dégâts de l'arme deviennent des dégâts de feu.", + "cost": 2, + "speed": "action", + "concentration": false, "tags": [ - "Buff" + "buff" ], - "id": "1" + "effect": "Chauffe à blanc une arme ou un projectile. Jusqu'au début de votre prochain tour, les coups portés avec l'objet infligent 1d6 dégâts supplémentaire. Les dégâts de l'arme deviennent des dégâts de feu." }, { + "id": "65xcsetz9arfzlsoubb1hcl0pbhj4pdd", "name": "Projection bouillonnante", "rank": 1, "type": "precision", - "cost": 6, - "speed": "action", "elements": [ "fire" ], - "effect": "Lance un projectile de feu éclatant sur 3 cases de rayon. Chaque personne dans le rayon doit réussir un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]](d10/6 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) ou subit 2d8 dégâts de feu.", + "cost": 6, + "speed": "action", + "concentration": false, "tags": [ - "Dégats" + "damage" ], - "id": "2" + "effect": "Lance un projectile de feu éclatant sur 3 cases de rayon. Chaque personne dans le rayon doit réussir un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]](d10/6 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) ou subit 2d8 dégâts de feu." }, { + "id": "v496ms0t3ktw3vo8dgcjuxvig5tviy55", "name": "Corps ardent", "rank": 1, "type": "knowledge", - "cost": 6, - "speed": "action", "elements": [ "fire" ], - "effect": "Pendant 5 tours, toute personne terminant son tour à une case de vous subit 1d10 dégâts de feu.", + "cost": 6, + "speed": "action", + "concentration": true, "tags": [ - "Dégats" + "damage" ], - "id": "3" + "effect": "Pendant 5 tours, toute personne terminant son tour à une case de vous subit 1d10 dégâts de feu." }, { + "id": "g31vwaubzdisdra0xj1nlwpt6rpkypf5", "name": "Gravure marquante", "rank": 1, "type": "knowledge", - "cost": 3, - "speed": 10, "elements": [ "fire" ], - "effect": "Grave une marque discrète sur un objet, restant durant 3 jours ou jusqu'à ce que quelqu'un rentre en contact avec la marque, auquel cas cette dernière lui sera gravée avec une désagréable sensation de brulure. La brulure disparait après 3 jours.", + "cost": 3, + "speed": "10 ", + "concentration": false, "tags": [ - "Utilitaire" + "utilitary" ], - "id": "4" + "effect": "Grave une marque discrète sur un objet, restant durant 3 jours ou jusqu'à ce que quelqu'un rentre en contact avec la marque, auquel cas cette dernière lui sera gravée avec une désagréable sensation de brulure. La brulure disparait après 3 jours." }, { + "id": "0u3ycvkje1c4p0auake1sut4ek0wcojk", + "name": "Embrasement réflexe", + "rank": 1, + "type": "instinct", + "elements": [ + "fire" + ], + "cost": 3, + "speed": "reaction", + "concentration": false, + "tags": [ + "tank" + ], + "effect": "Lorsque vous êtes frapper par une arme au corps à corps (hors [[4. Équipement#Les armes naturelles|arme naturelle]]), le bref contact vous permet d'embrasser l'arme adverse. La cible doit réussir un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d8/5 + mod. de [[1. Entrainement#La psyché|psyché]]) de [[1. Entrainement#La constitution|constitution]] ou fait tomber son arme sur sa propre case." + }, + { + "id": "3ag85hj1bb4fjtubz040j475y7h0bs5w", "name": "Protection supérieure", "rank": 1, "type": "instinct", - "cost": 3, - "speed": "reaction", "elements": [ "ice" ], - "effect": "Votre armure subit l'intégralité des dégâts sur le prochain coup.", + "cost": 3, + "speed": "reaction", + "concentration": false, "tags": [ - "Tank" + "tank" ], - "id": "5" + "effect": "Lorsque vous êtes visé par une attaque, vous créez une couche de glace autour de votre armure, lui permettant de subir l'intégralité des dégâts sur le coup." }, { + "id": "9sp9zmh2c2yl3sqqi3nr7n1rioaetknj", "name": "Lames de glace", "rank": 1, "type": "precision", - "cost": 3, - "speed": "action", "elements": [ "ice" ], - "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]] en touchant. Tire 2 projectiles infligeant 1d8 dégâts de glace. *Augmenter les dés de dégâts offre un projectile supplémentaire à la place. Chaque projectile demande un jet d'attaque séparé et peut viser une cible différente.*", + "cost": 3, + "speed": "action", + "concentration": false, "tags": [ - "Dégats" + "damage" ], - "id": "6" + "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]] en touchant. Tire 2 projectiles infligeant 1d8 dégâts de glace. *Augmenter les dés de dégâts offre un projectile supplémentaire à la place. Chaque projectile demande un jet d'attaque séparé et peut viser une cible différente.*" }, { + "id": "t0uorr9gpk3n2325s4bgozwcjlk4g7af", + "name": "No name", + "rank": 1, + "type": "knowledge", + "elements": [ + "ice" + ], + "cost": 2, + "speed": "action", + "concentration": false, + "tags": [ + "movement" + ], + "effect": "Crée une fine couche de glace sous vos pieds vous permettant de glisser rapidement. Vous gagnez un bonus de +2 cases de courses et vous doublez le bonus de charge si vous parcourez au moins une fois votre vitesse de course. Vous pouvez gratuitement [[2. Actions en combat#Courir|courir]] ou [[2. Actions en combat#Charger|charger]] après avoir lancer ce sort." + }, + { + "id": "eo3lpk9xt605ygf2iup1b5gzppalot73", "name": "Chaine de foudre", "rank": 1, "type": "precision", - "cost": 3, - "speed": "action", "elements": [ "thunder" ], - "effect": "Faites un jet d'attaque avec la [[1. Entrainement#Dextérité|dextérité]]. Frappe une cible visible puis rebondit sur jusqu'à 2 autres cibles. Inflige 1d8[[2. Glossaire#Jet explosif|!]] dégâts de foudre.", + "cost": 3, + "speed": "action", + "concentration": false, "tags": [ - "Dégats" + "damage" ], - "id": "7" + "effect": "Faites un jet d'attaque avec la [[1. Entrainement#Dextérité|dextérité]]. Frappe une cible visible puis rebondit sur jusqu'à 2 autres cibles. Inflige 1d8[[2. Glossaire#Jet explosif|!]] dégâts de foudre." }, { + "id": "wpatq60qyv4nltxt621jasw6o6hp34sp", "name": "Vitesse lumière", "rank": 1, "type": "knowledge", - "cost": 2, - "speed": "action", "elements": [ "thunder" ], - "effect": "Se téléporte à 6 cases tant que vous pouvez voir et courir vers la destination.", + "cost": 2, + "speed": "action", + "concentration": false, "tags": [ - "Mouvement" + "movement" ], - "id": "8" + "effect": "Se téléporte à 6 cases tant que vous pouvez voir et courir vers la destination." }, { + "id": "qsrfqmoymoo729i8mqhghobk4gvhy2io", "name": "Décharge de foudre", "rank": 1, "type": "precision", - "cost": 3, - "speed": "action", "elements": [ "thunder" ], - "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]]. Tire une décharge foudroyante d'énergie, infligeant 4d4[[2. Glossaire#Jet explosif|!]] dégâts de foudre.", - "tags": [ - "Dégats" - ], - "id": "9" - }, - { - "name": "No name", - "rank": 1, - "type": "precision", - "cost": 2, - "speed": "action", - "elements": [ - "earth" - ], - "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]]. Un pilier de matière est extirpé du sol pour aller frapper la cible, qui est alors déplacée d'une case. Si la cible est propulsée contre un mur, elle subit alors 3d12 dégâts contondant.", - "tags": [ - "Dégats" - ], - "id": "10" - }, - { - "name": "No name", - "rank": 1, - "type": "precision", "cost": 3, "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]]. Tire une décharge foudroyante d'énergie, infligeant 4d4[[2. Glossaire#Jet explosif|!]] dégâts de foudre." + }, + { + "id": "p2o6hrfw5fgf22wpm7ocsxh6inhul3b1", + "name": "No name", + "rank": 1, + "type": "instinct", + "elements": [ + "thunder" + ], + "cost": 5, + "speed": "action", + "concentration": false, + "tags": [ + "debuff" + ], + "effect": "Place une zone de puissance electrisante de 2 cases de rayon pendant un tour. Toute personne qui se déplace dans cette zone prends 1d4! dégâts de foudre par case parcouru." + }, + { + "id": "31neb3hkr8o2pc6wq5juhkfywqpufi7c", + "name": "No name", + "rank": 1, + "type": "instinct", + "elements": [ + "thunder" + ], + "cost": 3, + "speed": "action", + "concentration": false, + "tags": [ + "debuff" + ], + "effect": "Désignez une zone de 2 cases de rayon. Toutes personne dans la zone doit réussir un jet de résistance (d6/4 + mod. de psyché) de constitution ou subit un malus de -3 en compréhension et en représentation." + }, + { + "id": "ci60uqd0xv6bvfpaugu5f1m9c0f4b2ta", + "name": "No name", + "rank": 1, + "type": "precision", "elements": [ "earth" ], - "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]]. Propulse un projectile de matière sur la cible, infligeant 1d12 dégâts contondant en touchant, ainsi qu'un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/5 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) à l'[[2. Liste des effets#L'hébètement|hébètement]].", + "cost": 2, + "speed": "action", + "concentration": false, "tags": [ - "Debuff" + "damage" ], - "id": "11" + "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]]. Un pilier de matière est extirpé du sol pour aller frapper la cible, qui est alors déplacée d'une case. Si la cible est propulsée contre un mur, elle subit alors 3d12 dégâts contondant." }, { + "id": "q8bn095qcyuqk10wru6oe0mdg6ilsqke", + "name": "No name", + "rank": 1, + "type": "precision", + "elements": [ + "earth" + ], + "cost": 3, + "speed": "action", + "concentration": false, + "tags": [ + "debuff" + ], + "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]]. Propulse un projectile de matière sur la cible, infligeant 1d12 dégâts contondant en touchant, ainsi qu'un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/5 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) à l'[[2. Liste des effets#L'hébètement|hébètement]]." + }, + { + "id": "t9eb90xzdtfwba8q11ko6fy6adezovo8", "name": "Bouclier tortue", "rank": 1, "type": "knowledge", - "cost": 3, - "speed": "action", "elements": [ "earth" ], - "effect": "Durant 1 minute, vous gagnez un bonus de 2 au blocage, mais subissez également un malus de 2 à l'esquive et perdez 2 cases de vitesse de course.", + "cost": 3, + "speed": "action", + "concentration": true, "tags": [ - "Tank" + "tank" ], - "id": "12" + "effect": "Durant 1 minute, vous gagnez un bonus de 2 au blocage, mais subissez également un malus de 2 à l'esquive et perdez 2 cases de vitesse de course." }, { + "id": "1yg0jfxt9tomjk8nfv6refiranzfcmqp", "name": "No name", "rank": 1, "type": "instinct", - "cost": 3, - "speed": "reaction", "elements": [ "earth" ], - "effect": "Vous gagnez une résistance aux dégâts physiques jusqu'au début de votre prochain tour.", + "cost": 3, + "speed": "reaction", + "concentration": false, "tags": [ - "Tank" + "tank" ], - "id": "13" + "effect": "Vous gagnez une résistance aux dégâts physiques jusqu'au début de votre prochain tour." }, { + "id": "y6adciztgkx37efe01btgjdmya44s4mv", + "name": "Rafistolage", + "rank": 1, + "type": "knowledge", + "elements": [ + "earth" + ], + "cost": null, + "speed": "10 ", + "concentration": false, + "tags": [ + "utilitary" + ], + "effect": "Vous rafistolez sommairement une armure abimée, lui faisant récupérer 2d10 point de vie pour 4 mana. Vous ne pouvez la réparer que 2 fois avec ce sort avant de devoir la réparer avec des procédés non magique. Cependant, certaines armures magiques ne peuvent être réparer qu'avec ce sort." + }, + { + "id": "c3unjy94da09kh7u5ul4tjbnvaohwbk1", "name": "Enchantement mineur", "rank": 1, "type": "knowledge", - "cost": 2, - "speed": "action", "elements": [ "arcana" ], - "effect": "Condense de l'énergie magique dans une arme ou un projectile sur vous. Vous faites une attaque immédiatement après avoir lancé ce sort sans dépenser d'action, infligeant 1d8 dégâts supplémentaire. Les dégâts de l'arme deviennent magique.", + "cost": 2, + "speed": "action", + "concentration": false, "tags": [ - "Buff" + "buff" ], - "id": "14" + "effect": "Condense de l'énergie magique dans une arme ou un projectile sur vous. Vous faites une attaque immédiatement après avoir lancé ce sort sans dépenser d'action, infligeant 1d8 dégâts supplémentaire. Les dégâts de l'arme deviennent magique." }, { + "id": "zhzdy298yj87cd8ql17eqbreln99ppii", "name": "Rupture de force", "rank": 1, "type": "knowledge", - "cost": 5, - "speed": "action", "elements": [ "arcana" ], - "effect": "Faites un jet d'attaque avec l'[[1. Entrainement#L'intelligence|intelligence]]. Vous condensez une puissante énergie magique qui est propulsée directement sur votre cible. Vous lancez 2d20 et prenez le plus haut résultat pour infliger des dégâts magique. *Avoir un [[2. Glossaire#Avantage et désavantage|avantage]] **aux dégâts** permet de lancer un autre d20.* *Augmenter les dégâts de ce sort permet d'infliger 5 dégâts magique supplémentaire.*", + "cost": 5, + "speed": "action", + "concentration": false, "tags": [ - "Dégats" + "damage" ], - "id": "15" + "effect": "Faites un jet d'attaque avec l'[[1. Entrainement#L'intelligence|intelligence]]. Vous condensez une puissante énergie magique qui est propulsée directement sur votre cible. Vous lancez 2d20 et prenez le plus haut résultat pour infliger des dégâts magique. *Avoir un [[2. Glossaire#Avantage et désavantage|avantage]] **aux dégâts** permet de lancer un autre d20.* *Augmenter les dégâts de ce sort permet d'infliger 5 dégâts magique supplémentaire.*" }, { + "id": "y7shn6cvb142lgnsy7xowmrnz73o53oa", + "name": "Essence magique", + "rank": 1, + "type": "knowledge", + "elements": [ + "arcana" + ], + "cost": 2, + "speed": "1 ", + "concentration": false, + "tags": [ + "utilitary" + ], + "effect": "Vous êtes capable d'identifier toutes les composantes d'un sort, d'un enchantement ou d'un objet magique. " + }, + { + "id": "4ad93il1edksm5qls12ok02896zj0yld", + "name": "Vision arcanique", + "rank": 1, + "type": "knowledge", + "elements": [ + "arcana" + ], + "cost": 3, + "speed": "1 ", + "concentration": true, + "tags": [ + "utilitary" + ], + "effect": "Pendant 10 minutes, vous pouvez percevoir toute trace de magie sous forme de tache bleutée laissant une faible persistance sur votre rétine. " + }, + { + "id": "lzw27vsj1lbu3unu161etqin3vxyyfbk", "name": "Foulée aérienne", "rank": 1, "type": "knowledge", - "cost": 3, - "speed": "action", "elements": [ "air" ], - "effect": "La vitesse de course de votre cible augmente de 2 cases pendant 1 minute. Elle gagne également un bonus de +1 à l'esquive.", + "cost": 3, + "speed": "action", + "concentration": false, "tags": [ - "Buff" + "buff" ], - "id": "16" + "effect": "La vitesse de course de votre cible augmente de 2 cases pendant 1 minute. Elle gagne également un bonus de +1 à l'esquive." }, { + "id": "uopb9o0tq279cuq4fteahxel4lifeiqe", "name": "Pression forcée", "rank": 1, "type": "precision", - "cost": 5, - "speed": "action", "elements": [ "air" ], - "effect": "Crée une imposante colonne d'air descendent de 3 cases de rayon sur 12 cases de haut à 18 cases de vous. Les créatures à l'intérieur ont un malus de 1 à l'esquive. Les créatures volantes chutent de 3 cases par tour. Dure 5 tours.", + "cost": 5, + "speed": "action", + "concentration": false, "tags": [ - "Mouvement" + "movement" ], - "id": "17" + "effect": "Crée une imposante colonne d'air descendent de 3 cases de rayon sur 12 cases de haut à 18 cases de vous. Les créatures à l'intérieur ont un malus de 1 à l'esquive. Les créatures volantes chutent de 3 cases par tour. Dure 5 tours." }, { + "id": "6w95y3psv5779hg0i3dmthuapngim3bl", "name": "Poids plume", "rank": 1, "type": "knowledge", - "cost": 2, - "speed": "action", "elements": [ "air" ], - "effect": "Réduit le poids d'un objet à un dixième de son poids d'origine pendant 1 minute. Fonctionne sur des objets inertes allant jusqu'à 500kg. ", + "cost": 2, + "speed": "action", + "concentration": true, "tags": [ - "Utilitaire" + "utilitary" ], - "id": "18" + "effect": "Réduit le poids d'un objet à un dixième de son poids d'origine pendant 1 minute. Fonctionne sur des objets inertes allant jusqu'à 500kg. " }, { + "id": "ufggg6m2fbrkb8hsmqmn5p57eow5z4du", + "name": "No name", + "rank": 1, + "type": "precision", + "elements": [ + "air" + ], + "cost": 2, + "speed": "action", + "concentration": false, + "tags": [ + "buff" + ], + "effect": "Jusqu'à la fin de votre prochain tour, vous imposez un [[2. Glossaire#Avantage et désavantage|désavantage]] à toute personne qui essaye de vous [[2. Actions en combat#Contraindre|contraindre]]." + }, + { + "id": "vxsbib5pvcugf1nbgz37xi0h83dhg7we", "name": "Conservation", "rank": 1, "type": "knowledge", - "cost": 2, - "speed": 1, "elements": [ "nature" ], - "effect": "Permet à jusqu'à 5 herbes ou préparations médicinales de se conserver 1 jour de plus. *Ne peux être utilisé qu'une seule fois par herbe/préparation.*", + "cost": 2, + "speed": "1 ", + "concentration": false, "tags": [ - "Utilitaire" + "utilitary" ], - "id": "19" + "effect": "Permet à jusqu'à 5 herbes ou préparations médicinales de se conserver 1 jour de plus. *Ne peux être utilisé qu'une seule fois par herbe/préparation.*" }, { + "id": "ia1l0huseavhkm1uhkea50d4j5isz98a", "name": "No name", "rank": 1, "type": "instinct", - "cost": 3, - "speed": "action", "elements": [ "nature" ], - "effect": "Vous récupérez un point de fatigue temporaire de la cible que vous touchez.", + "cost": 3, + "speed": "action", + "concentration": false, "tags": [ - "Support" + "support" ], - "id": "20" + "effect": "Vous récupérez un point de fatigue temporaire de la cible que vous touchez." }, { + "id": "67cka4v8izu8qdfo2mqulkq26fp99etg", "name": "No name", "rank": 1, "type": "precision", - "cost": 3, - "speed": "action", "elements": [ "nature" ], - "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]]. Inflige 2d8+2 dégâts magique à l'armure de la cible.", + "cost": 3, + "speed": "action", + "concentration": false, "tags": [ - "Dégats" + "damage" ], - "id": "21" + "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La dextérité|dextérité]]. Inflige 2d8+2 dégâts magique à l'armure de la cible." }, { + "id": "6mkmnwb4m28kx4n44yy4st9qut218pwc", + "name": "No name", + "rank": 1, + "type": "instinct", + "elements": [ + "nature" + ], + "cost": 2, + "speed": "action", + "concentration": false, + "tags": [ + "support" + ], + "effect": "Vous vous [[1. Aspect#Transformations|transformez]] immédiatement sans avoir à faire de jet. Après 5 tours, vous reprenez forme humaine et ne pouvez plus vous transformez pendant 5 tours." + }, + { + "id": "1gkskphodlrkzbbv9eno4l3m4qe2x981", "name": "Absorption radieuse", "rank": 1, "type": "knowledge", - "cost": 3, - "speed": "action", "elements": [ "light" ], - "effect": "Absorbe la lumière d'une zone de 4 cases de rayon, la faisant apparaitre comme plus sombre durant 1 minute. ", + "cost": 3, + "speed": "action", + "concentration": true, "tags": [ - "Support" + "support" ], - "id": "22" + "effect": "Absorbe la lumière d'une zone de 4 cases de rayon, la faisant apparaitre comme plus sombre durant 1 minute. " }, { + "id": "c6wvexqwolks7ke3deol6v26j3lls6el", "name": "Orbe de lumière", "rank": 1, "type": "knowledge", - "cost": 2, - "speed": "action", "elements": [ "light" ], - "effect": "Fait apparaitre une boule de lumière immatérielle illuminant d'une lumière visible à 12 cases. Peut être bougée de 6 cases avec une action libre.", + "cost": 2, + "speed": "action", + "concentration": false, "tags": [ - "Utilitaire" + "utilitary" ], - "id": "23" + "effect": "Fait apparaitre une boule de lumière immatérielle illuminant d'une lumière visible à 12 cases. Peut être bougée de 6 cases avec une action libre." }, { + "id": "4fr32awuxfzvg04magp64k3o5cr5omu7", "name": "Pas des ombres", "rank": 1, "type": "instinct", - "cost": 4, - "speed": "action", "elements": [ "light" ], - "effect": "Si vous êtes dans une zone de noir total, vous pouvez vous téléporter dans n'importe quelle autre zone de noir total à 9 cases.", + "cost": 4, + "speed": "action", + "concentration": false, "tags": [ - "Mouvement" + "movement" ], - "id": "24" + "effect": "Si vous êtes dans une zone de noir total, vous pouvez vous téléporter dans n'importe quelle autre zone de noir total à 9 cases." }, { + "id": "79l392k10xs5871a26rd5omm7djswuoz", "name": "No name", "rank": 1, "type": "instinct", - "cost": 6, - "speed": "action", "elements": [ "psyche" ], - "effect": "Envenime l'esprit de la cible, brouillant sa perception de la réalité et lui faisant voir des images subliminales de chaos. La cible fait un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d8/4 + mod. de psyché) à la [[2. Liste des effets#Apeuré|peur]].", + "cost": 6, + "speed": "action", + "concentration": false, "tags": [ - "Debuff" + "debuff" ], - "id": "25" + "effect": "Envenime l'esprit de la cible, brouillant sa perception de la réalité et lui faisant voir des images subliminales de chaos. La cible fait un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d8/4 + mod. de psyché) à la [[2. Liste des effets#Apeuré|peur]]." }, { + "id": "8764xnh1p2o0qtc8849s287a1sc5jwlt", "name": "Boule de feu", "rank": 2, "type": "precision", + "elements": [ + "fire" + ], "cost": 8, "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Lance une boule de feu éclatant sur 4 cases de rayon. Chaque personne dans le rayon doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/6 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) aux [[1. Magie#Les sorts de précision|sorts de précision]] ou subit 4d10 dégâts de [[4. Les types de dégâts#Feu|feu]]." + }, + { + "id": "ewyy5jeqa5zvffqpa2hxg9ehifg2nwj7", + "name": "No name", + "rank": 2, + "type": "knowledge", "elements": [ "fire" ], - "effect": "Lance une boule de feu éclatant sur 4 cases de rayon. Chaque personne dans le rayon doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/6 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) ou subit 3d10 dégâts de feu.", - "tags": [ - "Dégats" - ], - "id": "26" - }, - { - "name": "No name", - "rank": 2, - "type": "knowledge", - "cost": 5, - "speed": "action", - "elements": [ - "earth" - ], - "effect": "Fait apparaitre une myriade de petites pierres flottantes qui forment une ligne de 6 cases de long pour 3 lignes de haut. Tout le monde peut passer au travers mais les projectiles et sorts de précisions qui le traversent voit leur dé de dégâts réduit de 1 niveau. %% Important, pas de limite de durée %%", - "tags": [ - "Support" - ], - "id": "27" - }, - { - "name": "No name", - "rank": 2, - "type": "precision", - "cost": 4, - "speed": "action", - "elements": [ - "earth" - ], - "effect": "Durant 1 minute, vos [[4. Équipement#Les armes naturelles|armes naturelles]] se recouvrent de roches, infligeant des dégâts supplémentaires égal à votre mod. d'intelligence. A chaque coup porté (réussi comme raté), les dégâts décroient d'un point jusqu'à arrivée à 0.", - "tags": [ - "Buff" - ], - "id": "28" - }, - { - "name": "No name", - "rank": 2, - "type": "instinct", - "cost": 5, - "speed": "action", - "elements": [ - "arcana" - ], - "effect": "Votre cible doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d4/3 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) à l'[[2. Liste des effets#Influencé|influence]]. En cas d'échec, elle perds 2d4[[2. Glossaire#Jet explosif|!]] mana.", - "tags": [ - "Debuff" - ], - "id": "29" - }, - { - "name": "Enchantement dense", - "rank": 2, - "type": "knowledge", - "cost": 3, - "speed": "action", - "elements": [ - "arcana" - ], - "effect": "Condense de l'énergie magique dans toutes les arme ou projectiles sur vous. Vous faites une attaque immédiatement après avoir lancé ce sort sans dépenser d'action, avec chaque arme infligeant 1d8 dégâts supplémentaire. Les dégâts de l'arme deviennent magique.", - "tags": [ - "Buff" - ], - "id": "30" - }, - { - "name": "Enchantement tenace", - "rank": 2, - "type": "knowledge", - "cost": 4, - "speed": "action", - "elements": [ - "arcana" - ], - "effect": "Condense de l'énergie magique dans une arme sur vous *jusqu'à la fin de votre prochain tour*. Vous faites une attaque immédiatement après avoir lancé ce sort sans dépenser d'action, infligeant 1d8 dégâts supplémentaire. Les dégâts de l'arme deviennent magique.", - "tags": [ - "Buff" - ], - "id": "31" - }, - { - "name": "No name", - "rank": 2, - "type": "knowledge", - "cost": 7, - "speed": "action", - "elements": [ - "air" - ], - "effect": "Vous générez un vent chaotique dans un cylindre de 4 cases de rayon sur 6 cases de hauteur pendant 1 minute. Toute personne dans la zone doit se déplacer une fois par tour pour contrebalancer les puissantes rafales ou subira un malus de -2 à ces jets (hors [[1. Magie#Les sorts instinctif|sort d'instinct]]).", - "tags": [ - "Debuff" - ], - "id": "32" - }, - { - "name": "No name", - "rank": 2, - "type": "precision", - "cost": 4, - "speed": "action", - "elements": [ - "air" - ], - "effect": "Vous bénissez temporairement un arc avec la magie des vents pour les 3 prochaines attaques. Les flèches tirée par cet arc ont une vélocité accrue, les portée sont doublée et vous avez un bonus de +2 pour toucher à moyenne distance.", - "tags": [ - "Buff" - ], - "id": "33" - }, - { - "name": "No name", - "rank": 2, - "type": "precision", - "cost": 5, - "speed": "action", - "elements": [ - "air" - ], - "effect": "Choisissez une cible volante visible à portée. Votre cible doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/6 + mod. de [[1. Entrainement#La dextérité|dextérité]]) aux [[1. Magie#Les sorts de précision|sorts de précision]]. En cas d'échec, elle voit sa vitesse de vol réduite de 12 cases.", - "tags": [ - "Mouvement" - ], - "id": "34" - }, - { - "name": "No name", - "rank": 2, - "type": "instinct", - "cost": 4, - "speed": "reaction", - "elements": [ - "air" - ], - "effect": "Vous pouvez lancer ce sort lorsque vous êtes ciblé par une attaque au corps à corps. Faites un jet de [[1. Magie#Les sorts instinctif|sort instinctif]], si vous faites un meilleur score que l'attaque de votre attaquant, vous lui faites rater son attaque. Cependant, si vous ne parvenez pas à bloquer son attaque, il gagne un niveau de dé de dégâts sur son attaque. %% À vérifier %%", - "tags": [ - "Tank" - ], - "id": "35" - }, - { - "name": "No name", - "rank": 2, - "type": "knowledge", "cost": 6, "speed": "action", - "elements": [ - "nature" - ], - "effect": "Votre cible doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d8/5 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) aux [[1. Magie#Les sorts de savoir|sorts de savoir]]. En cas d'échec, elle subit un point de fatigue temporaire.", + "concentration": true, "tags": [ - "Debuff" + "damage" ], - "id": "36" + "effect": "Vous vous entourez d'un manteau de flamme pendant 1 minute. Tant que vous maintenez les flammes, vous subissez 1d4 dégâts de [[4. Les types de dégâts#Feu|feu]] et avez une [[1. Combat#Résistances et vulnérabilités|résistance]] aux dégâts de [[4. Les types de dégâts#Glace|glace]]. En un point d'action, vous pouvez mettre fin au sort en expulsant les flammes à 2 cases de vous, imposant un jet de résistance aux [[1. Magie#Les sorts de savoir|sorts de savoir]] (d4/3 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) à toute personne dans la zone qui subissent alors 2d10 de dégâts de [[4. Les types de dégâts#Feu|feu]] en cas d'échec." }, { - "name": "No name", - "rank": 2, - "type": "instinct", - "cost": 5, - "speed": "reaction", - "elements": [ - "nature" - ], - "effect": "Vous récupérez un point de fatigue persistante de votre cible.", - "tags": [ - "Support" - ], - "id": "37" - }, - { - "name": "No name", + "id": "9dped1xfz0ju8395m5kdhqv9uvt06lay", + "name": "Lance de givre", "rank": 2, "type": "knowledge", - "cost": 4, - "speed": "action", - "elements": [ - "light" - ], - "effect": "Vous gagnez pendant 1 minute une vision dans le noir à 12 cases.", - "tags": [ - "Utilitaire" - ], - "id": "38" - }, - { - "name": "Poussière incandescente", - "rank": 2, - "type": "knowledge", - "cost": 5, - "speed": "action", - "elements": [ - "light" - ], - "effect": "Crée une zone de poussière brulante de 6 cases de rayon émettant une lumière intense durant 1 minute. Finir son tour dans la poussière vous fait subir 1d12 dégâts de feu. #rework", - "tags": [ - "Dégats" - ], - "id": "39" - }, - { - "name": "Apaisement", - "rank": 2, - "type": "knowledge", - "cost": 3, - "speed": "action", - "elements": [ - "psyche" - ], - "effect": "En touchant la cible, guérit l'influence, le charme et la peur, mais inflige un malus de -1 aux jets de résistance de défense pour ces effets.", - "tags": [ - "Support" - ], - "id": "40" - }, - { - "name": "Painshock", - "rank": 2, - "type": "instinct", - "cost": 6, - "speed": "action", - "elements": [ - "psyche" - ], - "effect": "*Ne fonctionne que si la cible touchée à subit des dégâts depuis votre dernier tour.* Vous touchez une plaie et intensifiez la douleur à l'extrême. La cible doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/5 + mod. d'[[1. Entrainement#L'intelligence|intelligence]] + 1 par 10% de vie perdu au tour précédent) à l'[[2. Liste des effets#L'hébètement|hébètement]]. ", - "tags": [ - "Debuff" - ], - "id": "41" - }, - { - "name": "Perturbateur", - "rank": 2, - "type": "instinct", - "cost": 4, - "speed": "reaction", - "elements": [ - "psyche" - ], - "effect": "Vous pouvez perturber les flux magiques d'un lanceur de sort que vous voyez à 9 cases pour lui imposer un malus de 3 à son lancer de sort en cours.", - "tags": [ - "Debuff" - ], - "id": "42" - }, - { - "name": "Tourbillon de braise", - "rank": 3, - "type": "knowledge", - "cost": 6, - "speed": "action", - "elements": [ - "fire" - ], - "effect": "Fait apparaitre une tornade de braises ardente de 2 cases de rayon. Chaque tour, vous pouvez la faire bouger de 2 cases pour 1 point d'action. Toute personne commençant son tour dans la tornade subit 2d8 dégâts de feu.", - "tags": [ - "Dégats" - ], - "id": "43" - }, - { - "name": "Engourdissement", - "rank": 3, - "type": "instinct", - "cost": 5, - "speed": "action", "elements": [ "ice" ], - "effect": "La cible doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/6 + mod. de [[1. Entrainement#La psyché|psyché]]) aux [[1. Magie#Les sorts instinctif|sorts d'instinct]], divisant sa vitesse par 2 et lui imposant un malus de 3 pour attaquer avec des armes en cas d'échec.", + "cost": 3, + "speed": "action", + "concentration": false, "tags": [ - "Debuff" + "buff" ], - "id": "44" + "effect": "Une lame de glace vient grandir le long d'une arme que vous touchez. Augmente la portée de l'arme d'une case. L'extension inflige des dégâts tranchants. Dure 1 min, casse après 8 coups **réussis**." }, { - "name": "Orbe de chaos", - "rank": 3, + "id": "tbukopbrdr9cl8nc1wwnbecxd7teublg", + "name": "Cône de givre", + "rank": 2, "type": "precision", - "cost": 9, + "elements": [ + "ice" + ], + "cost": 8, "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Vous faites s'abattre un cône de givre sur vos cible. Chaque personne dans un cône de 6 cases (60°) doit réussir un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/6 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) aux [[1. Magie#Les sorts de précision|sorts de précision]] ou subit 5d8 dégâts de [[4. Les types de dégâts#Glace|glace]]." + }, + { + "id": "kxk0yq1qd0b4sl2yyfi9xje6vfkxh0aa", + "name": "No name", + "rank": 2, + "type": "instinct", + "elements": [ + "ice" + ], + "cost": 5, + "speed": "action", + "concentration": false, + "tags": [ + "debuff" + ], + "effect": "Vous tentez de geler les jambes de votre cible. La cible doit faire un jet de résistance (d8/5 + mod. de [[1. Entrainement#La psyché|psyché]]) aux [[1. Magie#Les sorts instinctif|sorts d'instinct]] ou est [[2. Liste des effets#Agrippé|agrippée]] durant 3 tours. Vous ne pouvez pas vous déplacer malgré la contrainte." + }, + { + "id": "r7eedcw9z9z4j37i87bcp6e77nwcw788", + "name": "Piège de cristal", + "rank": 2, + "type": "knowledge", + "elements": [ + "ice" + ], + "cost": 6, + "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Vous placez une mine de glace sur une case inoccupée. Lorsqu'elle subit le moindre dégât, elle explose sur 2 cases et inflige 3d6 de dégâts [[4. Les types de dégâts#Perçant|perçant]]. Si un personnage marche dessus, il subit 4d8 de dégâts [[4. Les types de dégâts#Perçant|perçant]] à la place." + }, + { + "id": "yvw719v7k1faxd5ykshd2ksqgzgt030l", + "name": "Téléportation", + "rank": 2, + "type": "instinct", "elements": [ "thunder" ], - "effect": "Fait apparaitre une orbe de foudre d'une case. Chaque tour pendant 1 minute, à l'initiative de l'environnement, l'orbe lance un d4 pour choisir un point cardinal. Chaque personne dans un cône de 6 cases (90°) dans cette direction doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d12/7 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) aux [[1. Magie#Les sorts de précision|sorts de précision]] ou subit 6d6[[2. Glossaire#Jet explosif|!]] dégâts de foudre.", - "tags": [ - "Dégats" - ], - "id": "45" - }, - { - "name": "Rejet pur", - "rank": 3, - "type": "knowledge", - "cost": null, + "cost": 4, "speed": "action", - "elements": [ - "arcana" - ], - "effect": "Faites un jet d'attaque avec l'[[1. Entrainement#L'intelligence|intelligence]]. Vous propulsez une énergie magique pure condensée sur votre adversaire avec une puissance absolue. Vous infligez 1d6[[2. Glossaire#Jet explosif|!]]+2 dégâts magique par tranche de 3 mana dépensé. Vous pouvez dépenser jusqu'à 30 mana. Vous subissez un malus de 4 au lancer de sort au tour suivant.", + "concentration": false, "tags": [ - "Dégats" + "movement" ], - "id": "46" + "effect": "Se téléporte à un point visible à 9 cases max." }, { - "name": "Disruption", - "rank": 3, + "id": "wc7wfbpoxpbpdgttspm33wp1r9l94p4x", + "name": "Foudroiement", + "rank": 2, + "type": "precision", + "elements": [ + "thunder" + ], + "cost": 8, + "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Tire un trait de foudre vrombissant sur 12 cases en partant de votre position. Chaque personne sur la ligne doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/6 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) aux [[1. Magie#Les sorts de précision|sorts de précision]] ou subit 10d4! dégâts de foudre." + }, + { + "id": "54z5hr40pfmsbbeyksgj1ybvdzy2lrg1", + "name": "No name", + "rank": 2, "type": "instinct", - "cost": 5, - "speed": "action", "elements": [ - "arcana" + "thunder" ], - "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La psyché|psyché]]. Vous imposez un jet de concentration à une cible que vous voyez. La difficulté est de 4d6+4.", + "cost": 4, + "speed": "action", + "concentration": false, "tags": [ - "Debuff" + "debuff" ], - "id": "47" + "effect": "Désignez une zone de 2 cases de rayon. Toutes personne dans la zone doit réussir un jet de résistance (d10/6 + mod. de psyché) de constitution ou devient sourd pendant 2 tours." }, { - "name": "Anomalie immaculée", - "rank": 3, + "id": "awt4tmkif5valsga4bcbezhjhckm7mxq", + "name": "No name", + "rank": 2, "type": "knowledge", + "elements": [ + "thunder" + ], "cost": 6, "speed": "action", + "concentration": true, + "tags": [ + "damage" + ], + "effect": "Génère un champ de foudre statique autour de vous pendant 1 minute. Toute personne qui cours à 2 cases de vous reçoit un choc électrique de 1d6[[2. Glossaire#Jet explosif|!]] dégâts de [[4. Les types de dégâts#Foudre|foudre]]." + }, + { + "id": "vubi6idvry4vim1oavd9xneakek6jnnq", + "name": "No name", + "rank": 2, + "type": "knowledge", + "elements": [ + "earth" + ], + "cost": 5, + "speed": "action", + "concentration": true, + "tags": [ + "support" + ], + "effect": "Fait apparaitre une myriade de petites pierres flottantes qui forment une ligne de 6 cases de long pour 3 lignes de haut. Tout le monde peut passer au travers mais les projectiles et sorts de précisions qui le traversent voit leur dé de dégâts réduit de 1 niveau. %% Important, pas de limite de durée %%" + }, + { + "id": "unqrb8i8erotcaqt9g7e2jn6g0go9kfu", + "name": "No name", + "rank": 2, + "type": "precision", + "elements": [ + "earth" + ], + "cost": 4, + "speed": "action", + "concentration": false, + "tags": [ + "buff" + ], + "effect": "Durant 1 minute, vos [[4. Équipement#Les armes naturelles|armes naturelles]] se recouvrent de roches, infligeant des dégâts supplémentaires égal à votre mod. d'intelligence. A chaque coup porté (réussi comme raté), les dégâts décroient d'un point jusqu'à arrivée à 0." + }, + { + "id": "1o219d03xifhmcf7v5tb6z1n2dfv9cfh", + "name": "No name", + "rank": 2, + "type": "instinct", + "elements": [ + "arcana" + ], + "cost": 5, + "speed": "action", + "concentration": false, + "tags": [ + "debuff" + ], + "effect": "Votre cible doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d4/3 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) à l'[[2. Liste des effets#Influencé|influence]]. En cas d'échec, elle perds 2d4[[2. Glossaire#Jet explosif|!]] mana." + }, + { + "id": "5nzk2g1wma883o4mjm0ptbauj8yc39hm", + "name": "Télékinésie", + "rank": 2, + "type": "knowledge", + "elements": [ + "arcana" + ], + "cost": 3, + "speed": "action", + "concentration": true, + "tags": [ + "utilitary" + ], + "effect": "Vous êtes capable de soulever des objets allant jusqu'à votre mod. d'[[1. Entrainement#L'intelligenc|intelligence]] en kilogrammes. Vous pouvez les déplacer de 2 cases par point d'action, jusqu'à une distance de 6 cases de vous. Vous n'avez cependant pas la délicatesse requise pour manier des armes." + }, + { + "id": "ofysscp5tf6vpzq1b5fg5wgilhkm43x8", + "name": "Enchantement dense", + "rank": 2, + "type": "knowledge", + "elements": [ + "arcana" + ], + "cost": 3, + "speed": "action", + "concentration": false, + "tags": [ + "buff" + ], + "effect": "Condense de l'énergie magique dans toutes les arme ou projectiles sur vous. Vous faites une attaque immédiatement après avoir lancé ce sort sans dépenser d'action, avec chaque arme infligeant 1d8 dégâts supplémentaire. Les dégâts de l'arme deviennent magique." + }, + { + "id": "g6fzcy0v7wbthwm0wgzntz7nakn83pnw", + "name": "Enchantement tenace", + "rank": 2, + "type": "knowledge", + "elements": [ + "arcana" + ], + "cost": 4, + "speed": "action", + "concentration": false, + "tags": [ + "buff" + ], + "effect": "Condense de l'énergie magique dans une arme sur vous *jusqu'à la fin de votre prochain tour*. Vous faites une attaque immédiatement après avoir lancé ce sort sans dépenser d'action, infligeant 1d8 dégâts supplémentaire. Les dégâts de l'arme deviennent magique." + }, + { + "id": "ewkikv0f2p1332ic8m8tlf52f6k4mn3u", + "name": "No name", + "rank": 2, + "type": "knowledge", + "elements": [ + "arcana" + ], + "cost": 5, + "speed": "action", + "concentration": true, + "tags": [ + "support" + ], + "effect": "Vous vous liez à un allié visible à 3 cases pendant 1 minute. Tant que vous vous concentrez sur le sort, vous et votre allié gagnez un bonus de +2 à la concentration et aux [[3. Résistance aux chocs#Le jet de résistance|jets de résistance]] d'[[1. Entrainement#L'intelligence|intelligence]] et de [[1. Entrainement#La psyché|psyché]], qu'importe la distance. Cependant, dès que l'un des deux subit des dégâts, les deux doivent **réussir** un [[1. Magie#La concentration|jet de concentration]] pour maintenir ce sort." + }, + { + "id": "xockmmr8iu687kpjw09fua3835gwfzog", + "name": "No name", + "rank": 2, + "type": "knowledge", + "elements": [ + "air" + ], + "cost": 7, + "speed": "action", + "concentration": true, + "tags": [ + "debuff" + ], + "effect": "Vous générez un vent chaotique dans un cylindre de 4 cases de rayon sur 6 cases de hauteur pendant 1 minute. Toute personne dans la zone doit se déplacer une fois par tour pour contrebalancer les puissantes rafales ou subira un malus de -2 à ces jets (hors [[1. Magie#Les sorts instinctif|sort d'instinct]])." + }, + { + "id": "c3f71icemysqn30kcts3sup4rsq3nx7e", + "name": "No name", + "rank": 2, + "type": "precision", + "elements": [ + "air" + ], + "cost": 4, + "speed": "action", + "concentration": false, + "tags": [ + "buff" + ], + "effect": "Vous bénissez temporairement un arc avec la magie des vents pour les 3 prochaines attaques. Les flèches tirée par cet arc ont une vélocité accrue, les portée sont doublée et vous avez un bonus de +2 pour toucher à moyenne distance." + }, + { + "id": "zno89j1hd5jkgafhhar3x5tt17we1rzl", + "name": "No name", + "rank": 2, + "type": "precision", + "elements": [ + "air" + ], + "cost": 5, + "speed": "action", + "concentration": false, + "tags": [ + "movement" + ], + "effect": "Choisissez une cible volante visible à portée. Votre cible doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/6 + mod. de [[1. Entrainement#La dextérité|dextérité]]) aux [[1. Magie#Les sorts de précision|sorts de précision]]. En cas d'échec, elle voit sa vitesse de vol réduite de 12 cases." + }, + { + "id": "bov1z1ieb4s7gbzbgps21e1pvouohdwk", + "name": "No name", + "rank": 2, + "type": "instinct", + "elements": [ + "air" + ], + "cost": 4, + "speed": "reaction", + "concentration": false, + "tags": [ + "tank" + ], + "effect": "Vous pouvez lancer ce sort lorsque vous êtes ciblé par une attaque au corps à corps. Faites un jet de [[1. Magie#Les sorts instinctif|sort instinctif]], si vous faites un meilleur score que l'attaque de votre attaquant, vous lui faites rater son attaque. Cependant, si vous ne parvenez pas à bloquer son attaque, il gagne un niveau de dé de dégâts sur son attaque. %% À vérifier %%" + }, + { + "id": "p6kpqeqrrhw8iopl9b9jmuxuabtquvps", + "name": "No name", + "rank": 2, + "type": "knowledge", + "elements": [ + "nature" + ], + "cost": 6, + "speed": "action", + "concentration": false, + "tags": [ + "debuff" + ], + "effect": "Votre cible doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d8/5 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) aux [[1. Magie#Les sorts de savoir|sorts de savoir]]. En cas d'échec, elle subit un point de [[3. Fatigue et repos#Fatigue temporaire|fatigue temporaire]]." + }, + { + "id": "kwy42uq39xk85us5ozf0fm9t79041127", + "name": "No name", + "rank": 2, + "type": "instinct", + "elements": [ + "nature" + ], + "cost": 5, + "speed": "reaction", + "concentration": false, + "tags": [ + "support" + ], + "effect": "Vous récupérez un point de [[3. Fatigue et repos#Fatigue persistante|fatigue persistante]] de votre cible." + }, + { + "id": "o5xy0qagub9x7hsityncleza1ysrglm2", + "name": "No name", + "rank": 2, + "type": "knowledge", "elements": [ "light" ], - "effect": "Place une anomalie visuelle à 3 cases émettant une [[6. Visibilité et lumière#Lumière intense|lumière vive]] à 9 cases. Lorsqu'un être vivant rentre en contact avec l'anomalie, il absorbe toute l'énergie magique et subit 4d8 points de dégâts magique", + "cost": 4, + "speed": "action", + "concentration": false, "tags": [ - "Dégats" + "utilitary" ], - "id": "48" + "effect": "Vous gagnez pendant 1 minute une vision dans le noir à 12 cases." }, { - "name": "Dévastation elementaire", - "rank": 4, - "type": "precision", - "cost": 8, - "speed": "action", + "id": "31jw1s4trszeia7durzngxgivrxdqudu", + "name": "Apaisement", + "rank": 2, + "type": "knowledge", + "elements": [ + "psyche" + ], + "cost": 3, + "speed": "action", + "concentration": false, + "tags": [ + "support" + ], + "effect": "En touchant la cible, guérit l'influence, le charme et la peur, mais inflige un malus de -1 aux jets de résistance de défense pour ces effets durant 3 tours." + }, + { + "id": "xmarzcettgakdz741ze0ga2yppnmr8x2", + "name": "Painshock", + "rank": 2, + "type": "instinct", + "elements": [ + "psyche" + ], + "cost": 6, + "speed": "action", + "concentration": false, + "tags": [ + "debuff" + ], + "effect": "*Ne fonctionne que si la cible touchée à subit des dégâts depuis votre dernier tour.* Vous touchez une plaie et intensifiez la douleur à l'extrême. La cible doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/5 + mod. d'[[1. Entrainement#L'intelligence|intelligence]] + 1 par 10% de vie perdu au tour précédent) à l'[[2. Liste des effets#L'hébètement|hébètement]]. " + }, + { + "id": "pervvrh6bg3p85350bbduyf27ypfqax2", + "name": "Perturbateur", + "rank": 2, + "type": "instinct", + "elements": [ + "psyche" + ], + "cost": 4, + "speed": "reaction", + "concentration": false, + "tags": [ + "debuff" + ], + "effect": "Vous pouvez perturber les flux magiques d'un lanceur de sort que vous voyez à 9 cases pour lui imposer un malus de 3 à son lancer de sort en cours." + }, + { + "id": "bomey4ybz2g5pecx37rmwqom8lm1hlpo", + "name": "Tourbillon de braise", + "rank": 3, + "type": "knowledge", + "elements": [ + "fire" + ], + "cost": 6, + "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Fait apparaitre une tornade de braises ardente de 2 cases de rayon. Chaque tour, vous pouvez la faire bouger de 2 cases pour 1 point d'action. Toute personne commençant son tour dans la tornade subit 2d8 dégâts de feu." + }, + { + "id": "7qh77clsa0rre1j86dpxu6p0m7vxy7sw", + "name": "Armure frigorifique", + "rank": 3, + "type": "precision", + "elements": [ + "ice" + ], + "cost": 5, + "speed": "action", + "concentration": false, + "tags": [ + "tank" + ], + "effect": "Vous offrez une [[4. Les types de dégâts#Résistances et vulnérabilités|résistance]] au [[4. Les types de dégâts#Feu|feu]] ainsi qu'une armure de 20 PV (-5 PV) à votre cible. Votre cible voit sa vitesse de course réduite de 2 cases." + }, + { + "id": "vd4vbjlbab037ijf86h82bcip6ywlx4u", + "name": "Tempête de givre", + "rank": 3, + "type": "knowledge", + "elements": [ + "ice" + ], + "cost": 6, + "speed": "action", + "concentration": true, + "tags": [ + "debuff" + ], + "effect": "Fait apparaitre une tempête de givre localisée de 6 cases de rayon. Chaque tour, vous pouvez la faire bouger de 2 cases pour 1 point d'action. Toute personne dans la tempête ne peut pas voir à l'extérieur, est [[2. Liste des effets#Sourd|assourdi]] par la bruit de la tempête et voit sa vitesse de course réduite de 2 cases." + }, + { + "id": "db2k9yg2iggjtx894n8x06eawv6vzyn0", + "name": "Engourdissement", + "rank": 3, + "type": "instinct", + "elements": [ + "ice" + ], + "cost": 5, + "speed": "action", + "concentration": false, + "tags": [ + "debuff" + ], + "effect": "La cible doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/6 + mod. de [[1. Entrainement#La psyché|psyché]]) aux [[1. Magie#Les sorts instinctif|sorts d'instinct]], divisant sa vitesse par 2 et lui imposant un malus de 3 pour attaquer avec des armes en cas d'échec." + }, + { + "id": "bm9ywuo2gdtnzrigr1hg7y4falkrgm10", + "name": "No name", + "rank": 3, + "type": "instinct", "elements": [ - "fire", - "ice", "thunder" ], - "effect": "Faites un jet d'attaque soit la [[1. Entrainement#Dextérité|dextérité]], soit l'[[1. Entrainement#L'intelligence|intelligence]], soit la [[1. Entrainement#La psyché|psyché]]. Inflige 10+3d10 dégâts. Si vous attaquez avec la dextérité, vous infligez des dégâts de feu. Si vous attaquez avec l'intelligence, vous infligez des dégâts de glace et si vous attaquez avec la psyché, vous faites des dégâts de foudre.", + "cost": 5, + "speed": "reaction", + "concentration": false, "tags": [ - "Dégats" + "movement" ], - "id": "special-1" + "effect": "Vous et votre cible permutez de place. Si votre cible n'est pas consentante, elle peut réussir un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d10/6 + mod. de [[1. Entrainement#La psyché|psyché]]) de [[1. Entrainement#La psyché|psyché]] pour ne pas être permuter." + }, + { + "id": "4dt6edbp8bpxiigzyawno68zub1o233h", + "name": "Foudroiement energetique", + "rank": 3, + "type": "knowledge", + "elements": [ + "thunder" + ], + "cost": 7, + "speed": "action", + "concentration": true, + "tags": [ + "buff" + ], + "effect": "Durant 1 minute, la cible touchée gagne un point d'action. Cependant, elle subit 2d4[[2. Glossaire#Jet explosif|!]] dégâts de [[4. Les types de dégâts#Foudre|foudre]] en le dépensant." + }, + { + "id": "znk9ygfbemryakpnfae5e1sb8y3ijwun", + "name": "Orbe de chaos", + "rank": 3, + "type": "precision", + "elements": [ + "thunder" + ], + "cost": 9, + "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Fait apparaitre une orbe de foudre d'une case. Chaque tour pendant 1 minute, à l'initiative de l'environnement, l'orbe lance un d4 pour choisir un point cardinal. Chaque personne dans un cône de 6 cases (90°) dans cette direction doit faire un [[3. Résistance aux chocs#Le jet de résistance|jet de résistance]] (d12/7 + mod. d'[[1. Entrainement#L'intelligence|intelligence]]) aux [[1. Magie#Les sorts de précision|sorts de précision]] ou subit 6d6[[2. Glossaire#Jet explosif|!]] dégâts de foudre." + }, + { + "id": "fchuvggmgrh89dyx06kk3433a1wf4u3m", + "name": "No name", + "rank": 3, + "type": "knowledge", + "elements": [ + "earth" + ], + "cost": 8, + "speed": "action", + "concentration": true, + "tags": [ + "damage" + ], + "effect": "Vous désignez une zone de 3 cases de rayon. Tout les tours, vous pouvez utiliser un point d'action pour faire sortir un pilier de terre dans une case libre de la zone désignée. Faites un jet de [[1. Entrainement#La dextérité|dextérité]]. Le pilier inflige 1d12 dégâts [[4. Les types de dégâts#Contondant|contondant]] et déplace la cible d'une case s'il touche. Il occupe cette case durant 3 tours avant de se désintégrer." + }, + { + "id": "kfz4nibuso2um6na7v5z2lc22ng1lgca", + "name": "No name", + "rank": 3, + "type": "precision", + "elements": [ + "earth" + ], + "cost": 8, + "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Vous érigez 6 piliers de roche tranchante dans une zone de 2 cases de rayon. Jusqu'à 4 peuvent être placé sur la même case. Vous faites un jet d'attaque de [[1. Entrainement#La dextérité|dextérité]] par **case**. Un pilier inflige 1d12 dégâts [[4. Les types de dégâts#Tranchant|tranchant]]." + }, + { + "id": "c3suj3xajdpi1xznd8uvtjk89rg3fn15", + "name": "Protection suprême", + "rank": 3, + "type": "knowledge", + "elements": [ + "earth" + ], + "cost": 6, + "speed": "action", + "concentration": false, + "tags": [ + "tank" + ], + "effect": "Vous vous entourez d'une imposante carapace de roche réactive qui absorbe les chocs. Vous gagnez une armure temporaire de 25PV (-5PV) pendant 2 tours. Subir un coup critique détruit l'armure mais annule l'effet critique." + }, + { + "id": "co8uafhopo5gvbac3yt06zude0ev7mof", + "name": "Mutisme", + "rank": 3, + "type": "knowledge", + "elements": [ + "arcana" + ], + "cost": 7, + "speed": "action", + "concentration": true, + "tags": [ + "support" + ], + "effect": "Crée une zone de 4 cases de rayon dans laquelle aucun son ne peut être émis ou perçu, rendant ainsi toute personne dans la zone [[2. Liste des effets#Sourd|sourd]] et [[2. Liste des effets#Muet|muet]]. Dure 1 min. Les limites de la zone sont finement perceptible sous forme d'ondulation de chaleur." + }, + { + "id": "z5so5kkc51yxzc8lx1cr4higistev1sw", + "name": "Magie volée", + "rank": 3, + "type": "knowledge", + "elements": [ + "arcana" + ], + "cost": 6, + "speed": "action", + "concentration": false, + "tags": [ + "buff" + ], + "effect": "Durant 3 tours, chaque fois que vous êtes explicitement cibler par un sort (hors effet de zone), vous gagnez un nombre de mana égal à la moitié du mana dépensé." + }, + { + "id": "h6cqablsa3vy5gn7iy4nbppgtebdckxo", + "name": "Rejet pur", + "rank": 3, + "type": "knowledge", + "elements": [ + "arcana" + ], + "cost": null, + "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Faites un jet d'attaque avec l'[[1. Entrainement#L'intelligence|intelligence]]. Vous propulsez une énergie magique pure condensée sur votre adversaire avec une puissance absolue. Vous infligez 1d6[[2. Glossaire#Jet explosif|!]]+2 dégâts magique par tranche de 3 mana dépensé. Vous pouvez dépenser jusqu'à 30 mana. Vous subissez un malus de 4 au lancer de sort au tour suivant." + }, + { + "id": "h22utvozahnrlxkyodnwweybv2uy8gx8", + "name": "Disruption", + "rank": 3, + "type": "instinct", + "elements": [ + "arcana" + ], + "cost": 5, + "speed": "action", + "concentration": false, + "tags": [ + "debuff" + ], + "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La psyché|psyché]]. Vous imposez un jet de concentration à une cible que vous voyez. La difficulté est de 4d6+4." + }, + { + "id": "6z02eebtw1p7wlfc4jned3iwo16bb772", + "name": "No name", + "rank": 3, + "type": "instinct", + "elements": [ + "air" + ], + "cost": 3, + "speed": "reaction", + "concentration": false, + "tags": [ + "support" + ], + "effect": "Vous repoussez un projectile physique ou magique de rang 1 qui passe à 3 cases de vous vers l'attaquant d'origine." + }, + { + "id": "5tbntzzv7h681luamy5dzuo507icwszs", + "name": "Epuisement répété", + "rank": 3, + "type": "instinct", + "elements": [ + "nature" + ], + "cost": 6, + "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Faites un jet d'attaque avec la [[1. Entrainement#La psyché|psyché]]. Vous infligez 1d6 point de dégâts [[4. Les types de dégâts#Neutre|magique]] par [[3. Fatigue et repos#La fatigue|point de fatigue]] de la cible." + }, + { + "id": "84m01hs91jz03qdtuukgnkk405a2503f", + "name": "Anomalie immaculée", + "rank": 3, + "type": "knowledge", + "elements": [ + "light" + ], + "cost": 6, + "speed": "action", + "concentration": false, + "tags": [ + "damage" + ], + "effect": "Place une anomalie visuelle à 3 cases émettant une [[6. Visibilité et lumière#Lumière intense|lumière vive]] à 9 cases. Lorsqu'un être vivant rentre en contact avec l'anomalie, il absorbe toute l'énergie magique et subit 4d8 points de dégâts magique" } ], "aspects": [ - { - "name": "Digride", - "description": "", - "stat": "dexterity", - "alignment": { - "loyalty": "loyal", - "kindness": "evil" - }, - "magic": true, - "difficulty": 10, - "physic": { - "min": 12, - "max": 22 - }, - "mental": { - "min": 8, - "max": 15 - }, - "personality": { - "min": 12, - "max": 20 - }, - "options": [] - }, { "name": "Akkatom", "description": "", "stat": "strength", "alignment": { - "loyalty": "loyal", - "kindness": "good" + "kindness": "good", + "loyalty": "neutral" }, "magic": true, "difficulty": 9, @@ -2147,12 +2635,132 @@ "options": [] }, { - "name": "Nolcalir", + "name": "Anseilid", "description": "", "stat": "intelligence", "alignment": { - "loyalty": "loyal", - "kindness": "neutral" + "kindness": "neutral", + "loyalty": "chaotic" + }, + "magic": true, + "difficulty": 13, + "physic": { + "min": 6, + "max": 18 + }, + "mental": { + "min": 15, + "max": 20 + }, + "personality": { + "min": 10, + "max": 20 + }, + "options": [] + }, + { + "name": "Arsinam", + "description": "", + "stat": "constitution", + "alignment": { + "kindness": "neutral", + "loyalty": "chaotic" + }, + "magic": false, + "difficulty": 8, + "physic": { + "min": 18, + "max": 25 + }, + "mental": { + "min": 5, + "max": 12 + }, + "personality": { + "min": 5, + "max": 15 + }, + "options": [] + }, + { + "name": "Asnol", + "description": "", + "stat": "intelligence", + "alignment": { + "kindness": "evil", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 9, + "physic": { + "min": 6, + "max": 15 + }, + "mental": { + "min": 8, + "max": 18 + }, + "personality": { + "min": 12, + "max": 20 + }, + "options": [] + }, + { + "name": "Beth'oit", + "description": "", + "stat": "charisma", + "alignment": { + "kindness": "good", + "loyalty": "loyal" + }, + "magic": true, + "difficulty": 9, + "physic": { + "min": 3, + "max": 13 + }, + "mental": { + "min": 10, + "max": 20 + }, + "personality": { + "min": 12, + "max": 20 + }, + "options": [] + }, + { + "name": "Brukaur", + "description": "", + "stat": "constitution", + "alignment": { + "kindness": "neutral", + "loyalty": "chaotic" + }, + "magic": false, + "difficulty": 9, + "physic": { + "min": 18, + "max": 25 + }, + "mental": { + "min": 3, + "max": 13 + }, + "personality": { + "min": 8, + "max": 15 + }, + "options": [] + }, + { + "name": "Calderan", + "description": "", + "stat": "intelligence", + "alignment": { + "kindness": "neutral", + "loyalty": "loyal" }, "magic": true, "difficulty": 9, @@ -2171,34 +2779,706 @@ "options": [] }, { - "name": "Brukaur", + "name": "Dao Tua", "description": "", - "stat": "constitution", + "stat": "charisma", "alignment": { - "loyalty": "chaotic", - "kindness": "neutral" + "kindness": "evil", + "loyalty": "neutral" }, "magic": false, "difficulty": 9, + "physic": { + "min": 10, + "max": 18 + }, + "mental": { + "min": 0, + "max": 10 + }, + "personality": { + "min": 15, + "max": 20 + }, + "options": [] + }, + { + "name": "Digride", + "description": "", + "stat": "dexterity", + "alignment": { + "kindness": "evil", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 12, + "max": 22 + }, + "mental": { + "min": 8, + "max": 15 + }, + "personality": { + "min": 12, + "max": 20 + }, + "options": [] + }, + { + "name": "Drinbuur", + "description": "", + "stat": "psyche", + "alignment": { + "kindness": "good", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 12, + "max": 20 + }, + "mental": { + "min": 8, + "max": 12 + }, + "personality": { + "min": 15, + "max": 20 + }, + "options": [] + }, + { + "name": "Franeline", + "description": "", + "stat": "dexterity", + "alignment": { + "kindness": "neutral", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 8, + "physic": { + "min": 12, + "max": 22 + }, + "mental": { + "min": 12, + "max": 20 + }, + "personality": { + "min": 3, + "max": 10 + }, + "options": [] + }, + { + "name": "Goldreg", + "description": "", + "stat": "psyche", + "alignment": { + "kindness": "evil", + "loyalty": "neutral" + }, + "magic": false, + "difficulty": 9, + "physic": { + "min": 8, + "max": 20 + }, + "mental": { + "min": 3, + "max": 15 + }, + "personality": { + "min": 10, + "max": 20 + }, + "options": [] + }, + { + "name": "Hashura", + "description": "", + "stat": "charisma", + "alignment": { + "kindness": "neutral", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 10, + "max": 18 + }, + "mental": { + "min": 10, + "max": 18 + }, + "personality": { + "min": 12, + "max": 20 + }, + "options": [] + }, + { + "name": "Incabat", + "description": "", + "stat": "constitution", + "alignment": { + "kindness": "evil", + "loyalty": "neutral" + }, + "magic": false, + "difficulty": 10, "physic": { "min": 18, - "max": 25 + "max": 28 + }, + "mental": { + "min": 3, + "max": 10 + }, + "personality": { + "min": 12, + "max": 20 + }, + "options": [] + }, + { + "name": "Kaha Bii", + "description": "", + "stat": "curiosity", + "alignment": { + "kindness": "good", + "loyalty": "loyal" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 3, + "max": 18 + }, + "mental": { + "min": 12, + "max": 20 + }, + "personality": { + "min": 10, + "max": 20 + }, + "options": [] + }, + { + "name": "Kronian", + "description": "", + "stat": "psyche", + "alignment": { + "kindness": "evil", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 6, + "max": 15 + }, + "mental": { + "min": 10, + "max": 18 + }, + "personality": { + "min": 15, + "max": 20 + }, + "options": [] + }, + { + "name": "Kuelid", + "description": "", + "stat": "intelligence", + "alignment": { + "kindness": "neutral", + "loyalty": "loyal" + }, + "magic": true, + "difficulty": 9, + "physic": { + "min": 0, + "max": 15 + }, + "mental": { + "min": 15, + "max": 20 + }, + "personality": { + "min": 5, + "max": 20 + }, + "options": [] + }, + { + "name": "Lonidae", + "description": "", + "stat": "intelligence", + "alignment": { + "kindness": "evil", + "loyalty": "chaotic" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 6, + "max": 13 + }, + "mental": { + "min": 15, + "max": 20 + }, + "personality": { + "min": 10, + "max": 20 + }, + "options": [] + }, + { + "name": "Miador", + "description": "", + "stat": "dexterity", + "alignment": { + "kindness": "neutral", + "loyalty": "loyal" + }, + "magic": true, + "difficulty": 8, + "physic": { + "min": 10, + "max": 22 + }, + "mental": { + "min": 10, + "max": 20 + }, + "personality": { + "min": 0, + "max": 12 + }, + "options": [] + }, + { + "name": "Mul'dekar", + "description": "", + "stat": "curiosity", + "alignment": { + "kindness": "evil", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 10, + "max": 18 + }, + "mental": { + "min": 12, + "max": 20 + }, + "personality": { + "min": 10, + "max": 18 + }, + "options": [] + }, + { + "name": "Nigiak", + "description": "", + "stat": "charisma", + "alignment": { + "kindness": "neutral", + "loyalty": "loyal" + }, + "magic": true, + "difficulty": 9, + "physic": { + "min": 6, + "max": 18 + }, + "mental": { + "min": 8, + "max": 20 + }, + "personality": { + "min": 8, + "max": 20 + }, + "options": [] + }, + { + "name": "Nyelis", + "description": "", + "stat": "curiosity", + "alignment": { + "kindness": "neutral", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 8, + "physic": { + "min": 8, + "max": 13 + }, + "mental": { + "min": 10, + "max": 20 + }, + "personality": { + "min": 5, + "max": 15 + }, + "options": [] + }, + { + "name": "Onimee", + "description": "", + "stat": "dexterity", + "alignment": { + "kindness": "neutral", + "loyalty": "chaotic" + }, + "magic": false, + "difficulty": 7, + "physic": { + "min": 18, + "max": 28 + }, + "mental": { + "min": 0, + "max": 1 + }, + "personality": { + "min": 3, + "max": 10 + }, + "options": [] + }, + { + "name": "Othompa", + "description": "", + "stat": "psyche", + "alignment": { + "kindness": "evil", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 10, + "max": 20 + }, + "mental": { + "min": 10, + "max": 18 + }, + "personality": { + "min": 12, + "max": 20 + }, + "options": [] + }, + { + "name": "Promolide", + "description": "", + "stat": "constitution", + "alignment": { + "kindness": "evil", + "loyalty": "chaotic" + }, + "magic": true, + "difficulty": 11, + "physic": { + "min": 15, + "max": 27 + }, + "mental": { + "min": 10, + "max": 15 + }, + "personality": { + "min": 10, + "max": 20 + }, + "options": [] + }, + { + "name": "Qua'faltar", + "description": "", + "stat": "psyche", + "alignment": { + "kindness": "evil", + "loyalty": "chaotic" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 12, + "max": 20 + }, + "mental": { + "min": 8, + "max": 18 + }, + "personality": { + "min": 12, + "max": 20 + }, + "options": [] + }, + { + "name": "Rudnar", + "description": "", + "stat": "dexterity", + "alignment": { + "kindness": "good", + "loyalty": "chaotic" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 15, + "max": 23 + }, + "mental": { + "min": 8, + "max": 15 + }, + "personality": { + "min": 10, + "max": 18 + }, + "options": [] + }, + { + "name": "Shelfine", + "description": "", + "stat": "intelligence", + "alignment": { + "kindness": "good", + "loyalty": "chaotic" + }, + "magic": true, + "difficulty": 8, + "physic": { + "min": 8, + "max": 18 + }, + "mental": { + "min": 12, + "max": 20 + }, + "personality": { + "min": 5, + "max": 12 + }, + "options": [] + }, + { + "name": "Shlahog", + "description": "", + "stat": "strength", + "alignment": { + "kindness": "evil", + "loyalty": "chaotic" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 17, + "max": 28 + }, + "mental": { + "min": 8, + "max": 15 + }, + "personality": { + "min": 10, + "max": 18 + }, + "options": [] + }, + { + "name": "Thymeïr", + "description": "", + "stat": "strength", + "alignment": { + "kindness": "evil", + "loyalty": "chaotic" + }, + "magic": false, + "difficulty": 10, + "physic": { + "min": 18, + "max": 22 }, "mental": { "min": 3, "max": 13 }, "personality": { + "min": 10, + "max": 20 + }, + "options": [] + }, + { + "name": "Urdi'rik", + "description": "", + "stat": "constitution", + "alignment": { + "kindness": "evil", + "loyalty": "loyal" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 12, + "max": 25 + }, + "mental": { + "min": 8, + "max": 20 + }, + "personality": { + "min": 5, + "max": 18 + }, + "options": [] + }, + { + "name": "Vadeaxil", + "description": "", + "stat": "strength", + "alignment": { + "kindness": "neutral", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 8, + "physic": { + "min": 18, + "max": 25 + }, + "mental": { + "min": 12, + "max": 20 + }, + "personality": { + "min": 0, + "max": 8 + }, + "options": [] + }, + { + "name": "Vernil", + "description": "", + "stat": "curiosity", + "alignment": { + "kindness": "neutral", + "loyalty": "neutral" + }, + "magic": false, + "difficulty": 8, + "physic": { + "min": 8, + "max": 18 + }, + "mental": { + "min": 8, + "max": 18 + }, + "personality": { + "min": 5, + "max": 12 + }, + "options": [] + }, + { + "name": "Yinkovn", + "description": "", + "stat": "psyche", + "alignment": { + "kindness": "neutral", + "loyalty": "neutral" + }, + "magic": true, + "difficulty": 9, + "physic": { + "min": 0, + "max": 13 + }, + "mental": { "min": 8, "max": 15 }, + "personality": { + "min": 15, + "max": 20 + }, + "options": [] + }, + { + "name": "Zaliax", + "description": "", + "stat": "strength", + "alignment": { + "kindness": "evil", + "loyalty": "loyal" + }, + "magic": false, + "difficulty": 9, + "physic": { + "min": 12, + "max": 28 + }, + "mental": { + "min": 0, + "max": 12 + }, + "personality": { + "min": 10, + "max": 20 + }, + "options": [] + }, + { + "name": "Zeniom", + "description": "", + "stat": "charisma", + "alignment": { + "kindness": "neutral", + "loyalty": "chaotic" + }, + "magic": true, + "difficulty": 10, + "physic": { + "min": 8, + "max": 18 + }, + "mental": { + "min": 10, + "max": 18 + }, + "personality": { + "min": 12, + "max": 20 + }, "options": [] } ], "features": { "d1lwlo7dgp5ii3e4sujo9fwt74hupk45": { "id": "d1lwlo7dgp5ii3e4sujo9fwt74hupk45", - "descriptipn": "", + "description": "Vous êtes capable de fabriquer des objets magiques d'une rareté accrue.", "effect": [ { "id": "z67m9t810ngz2yzi76adu4xyaoqycu8x", @@ -2207,12 +3487,11 @@ "action": "add", "item": "8r0sq7yiambfapkl4e82nmvc384jv7vw" } - ], - "description": "Vous êtes capable de fabriquer des objets magiques d'une rareté accrue." + ] }, "sshiooh8h4ufh1tqbb0vz09kgm4ll6fy": { "id": "sshiooh8h4ufh1tqbb0vz09kgm4ll6fy", - "descriptipn": "", + "description": "Vous êtes capable de fabriquer des [[Prototypes|prototypes]].", "effect": [ { "id": "oh4pp8rgb9gfm8tfv3bt2krzvp9lyrlr", @@ -2228,8 +3507,7 @@ "operation": "add", "value": 1 } - ], - "description": "Vous êtes capable de fabriquer des [[Prototypes|prototypes]]." + ] }, "zne1gy546fiflmaz2fw3o33pskonfplr": { "description": "Pas d'équipement.\nNe peut pas se déplacer par soi même.\nDef max à 3.", diff --git a/shared/character.util.ts b/shared/character.util.ts index 9ed8285..6d63d27 100644 --- a/shared/character.util.ts +++ b/shared/character.util.ts @@ -2,7 +2,7 @@ import type { Ability, Alignment, Character, CharacterConfig, CompiledCharacter, import { z } from "zod/v4"; import characterConfig from '#shared/character-config.json'; import { fakeA } from "#shared/proses"; -import { button, input, loading, numberpicker, select } from "#shared/components.util"; +import { button, input, loading, numberpicker, select, toggle } from "#shared/components.util"; import { div, dom, icon, mergeClasses, text, type Class } from "#shared/dom.util"; import { followermenu, popper } from "#shared/floating.util"; import { clamp } from "#shared/general.util"; @@ -17,6 +17,7 @@ export const TRAINING_LEVELS = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] as const; export const SPELL_TYPES = ["precision","knowledge","instinct","arts"] as const; export const CATEGORIES = ["action","reaction","freeaction","misc"] as const; export const SPELL_ELEMENTS = ["fire","ice","thunder","earth","arcana","air","nature","light","psyche"] as const; +export const ALIGNMENTS: Alignment[] = [{ kindness: 'good', loyalty: 'loyal' }, { kindness: 'good', loyalty: 'neutral' }, { kindness: 'good', loyalty: 'chaotic' }, { kindness: 'neutral', loyalty: 'loyal' }, { kindness: 'neutral', loyalty: 'neutral' }, { kindness: 'neutral', loyalty: 'chaotic' }, { kindness: 'evil', loyalty: 'loyal' }, { kindness: 'evil', loyalty: 'neutral' }, { kindness: 'evil', loyalty: 'chaotic' }]; export const defaultCharacter: Character = { id: -1, @@ -715,14 +716,7 @@ class PeoplePicker implements BuilderTab document.title = `d[any] - Edition de ${this._builder.character.name || 'nouveau personnage'}`; } }); - this._visibilityInput = dom("div", { class: `group mx-3 w-12 h-6 select-none transition-all border border-light-35 dark:border-dark-35 bg-light-20 dark:bg-dark-20 outline-none - data-[state=checked]:bg-light-35 dark:data-[state=checked]:bg-dark-35 hover:border-light-50 dark:hover:border-dark-50 focus:shadow-raw focus:shadow-light-40 dark:focus:shadow-dark-40 - data-[disabled]:bg-light-20 dark:data-[disabled]:bg-dark-20 data-[disabled]:border-light-20 dark:data-[disabled]:border-dark-20 relative py-[2px]`, attributes: { "data-state": "unckecked" }, listeners: { - click: (e: Event) => { - this._builder.character.visibility = this._builder.character.visibility === "private" ? "public" : "private"; - this._visibilityInput.setAttribute('data-state', this._builder.character.visibility === "private" ? "checked" : "unchecked"); - } - }}, [ div('block w-[18px] h-[18px] translate-x-[2px] will-change-transform transition-transform bg-light-50 dark:bg-dark-50 group-data-[state=checked]:translate-x-[26px] group-data-[disabled]:bg-light-30 dark:group-data-[disabled]:bg-dark-30 group-data-[disabled]:border-light-30 dark:group-data-[disabled]:border-dark-30') ]); + this._visibilityInput = toggle({ defaultValue: this._builder.character.visibility === "private", change: (value) => this._builder.character.visibility = value ? "private" : "public" }); this._options = config.peoples.map( (people, i) => dom("div", { class: "flex flex-col flex-nowrap gap-2 p-2 border border-light-35 dark:border-dark-35 cursor-pointer hover:border-light-70 dark:hover:border-dark-70 w-[320px]", listeners: { click: () => { diff --git a/shared/components.util.ts b/shared/components.util.ts index 149866f..0d3c011 100644 --- a/shared/components.util.ts +++ b/shared/components.util.ts @@ -50,7 +50,7 @@ export function select>(options: Array<{ text: string return dom('div', { listeners: { click: () => { textValue.textContent = e.text; settings?.change && settings?.change(e.value); - close && close(); + context && context.close && context.close(); }, mouseenter: (e) => focus(i) }, class: ['data-[focused]:bg-light-30 dark:data-[focused]:bg-dark-30 text-light-70 dark:text-dark-70 data-[focused]:text-light-100 dark:data-[focused]:text-dark-100 py-1 px-2 cursor-pointer', settings?.class?.option] }, [ text(e.text) ]); }); const select = dom('div', { listeners: { click: () => { @@ -96,6 +96,78 @@ export function select>(options: Array<{ text: string }) return select; } +export function multiselect>(options: Array<{ text: string, value: T } | undefined>, settings?: { defaultValue?: T[], change?: (value: T[]) => void, class?: { container?: Class, popup?: Class, option?: Class }, disabled?: boolean }): HTMLElement +{ + let context: { close: Function }; + let focused: number | undefined; + let selection: T[] = settings?.defaultValue ?? []; + + options = options.filter(e => !!e); + + const focus = (i?: number) => { + focused !== undefined && optionElements[focused]?.toggleAttribute('data-focused', false); + i !== undefined && optionElements[i]?.toggleAttribute('data-focused', true) && optionElements[i]?.scrollIntoView({ behavior: 'instant', block: 'nearest' }); + focused = i; + } + + let disabled = settings?.disabled ?? false; + const textValue = text(selection.length > 0 ? ((options.find(f => f?.value === selection[0])?.text ?? '') + (selection.length > 1 ? ` +${selection.length - 1}` : '')) : ''); + const optionElements = options.map((e, i) => { + if(e === undefined) + return; + + const element = dom('div', { listeners: { click: () => { + selection = selection.includes(e.value) ? selection.filter(f => f !== e.value) : [...selection, e.value]; + textValue.textContent = selection.length > 0 ? ((options.find(f => f?.value === selection[0])?.text ?? '') + (selection.length > 1 ? ` +${selection.length - 1}` : '')) : ''; + element.toggleAttribute('data-selected', selection.includes(e.value)); + settings?.change && settings?.change(selection); + context && context.close && context.close(); + }, mouseenter: (e) => focus(i) }, class: ['group flex flex-row justify-between items-center data-[focused]:bg-light-30 dark:data-[focused]:bg-dark-30 text-light-70 dark:text-dark-70 data-[focused]:text-light-100 dark:data-[focused]:text-dark-100 py-1 px-2 cursor-pointer', settings?.class?.option], attributes: { 'data-selected': selection.includes(e.value) } }, [ text(e.text), icon('radix-icons:check', { class: 'hidden group-data-[selected]:block', noobserver: true }) ]); + return element; + }); + const select = dom('div', { listeners: { click: () => { + if(disabled) + return; + + const handleKeys = (e: KeyboardEvent) => { + switch(e.key.toLocaleLowerCase()) + { + case 'arrowdown': + focus(clamp((focused ?? -1) + 1, 0, options.length - 1)); + return; + case 'arrowup': + focus(clamp((focused ?? 1) - 1, 0, options.length - 1)); + return; + case 'pageup': + focus(0); + return; + case 'pagedown': + focus(optionElements.length - 1); + return; + case 'enter': + focused && optionElements[focused]?.click(); + return; + case 'escape': + context?.close(); + return; + default: return; + } + } + window.addEventListener('keydown', handleKeys); + + const box = select.getBoundingClientRect(); + context = contextmenu(box.x, box.y + box.height, optionElements.filter(e => !!e).length > 0 ? optionElements : [ div('text-light-60 dark:text-dark-60 italic text-center px-2 py-1', [ text('Aucune option') ]) ], { placement: "bottom-start", class: ['flex flex-col max-h-[320px] overflow-auto', settings?.class?.popup], style: { "min-width": `${box.width}px` }, blur: () => window.removeEventListener('keydown', handleKeys) }); + } }, class: ['mx-4 inline-flex items-center justify-between px-3 text-sm font-semibold leading-none h-8 gap-1 bg-light-20 dark:bg-dark-20 border border-light-35 dark:border-dark-35 focus:shadow-raw transition-[box-shadow] focus:shadow-light-40 dark:focus:shadow-dark-40 hover:border-light-50 dark:hover:border-dark-50 data-[disabled]:border-light-25 dark: data-[disabled]:border-dark-25 data-[disabled]:bg-light-20 dark: data-[disabled]:bg-dark-20', settings?.class?.container] }, [ dom('span', {}, [ textValue ]), icon('radix-icons:caret-down') ]); + + Object.defineProperty(select, 'disabled', { + get: () => disabled, + set: (v) => { + disabled = !!v; + select.toggleAttribute('data-disabled', disabled); + }, + }) + return select; +} export function combobox>(options: Option[], settings?: { defaultValue?: T, change?: (value: T) => void, class?: { container?: Class, popup?: Class, option?: Class }, disabled?: boolean, fill?: 'contain' | 'cover' }): HTMLElement { let context: { container: HTMLElement, content: NodeChildren, close: () => void }; @@ -294,7 +366,7 @@ export function numberpicker(settings?: { defaultValue?: number, change?: (value focus: () => settings?.focus && settings.focus(), blur: () => settings?.blur && settings.blur(), }}); - if(settings?.defaultValue) field.value = storedValue.toString(10); + if(settings?.defaultValue !== undefined) field.value = storedValue.toString(10); return field; } @@ -309,8 +381,23 @@ export function foldable(content: NodeChildren, title: NodeChildren, settings?: return fold; } type TableRow = Record HTMLElement) | HTMLElement | string>; -export function table(content: TableRow[], headers: TableRow, properties?: { class?: { table?: Class, header?: Class, body?: Class, row?: Class } }) +export function table(content: TableRow[], headers: TableRow, properties?: { class?: { table?: Class, header?: Class, body?: Class, row?: Class, cell?: Class } }) { const render = (item: (() => HTMLElement) | HTMLElement | string) => typeof item === 'string' ? text(item) : typeof item === 'function' ? item() : item; - return dom('table', { class: ['', properties?.class?.table] }, [ dom('thead', { class: ['', properties?.class?.header] }, [ dom('tr', { class: '' }, Object.values(headers).map(e => dom('th', {}, [ render(e) ]))) ]), dom('tbody', { class: ['', properties?.class?.body] }, content.map(e => dom('tr', { class: ['', properties?.class?.row] }, Object.keys(headers).map(f => e.hasOwnProperty(f) ? dom('td', { class: '' }, [ render(e[f]!) ]) : undefined)))) ]); + return dom('table', { class: ['', properties?.class?.table] }, [ dom('thead', { class: ['', properties?.class?.header] }, [ dom('tr', { class: '' }, Object.values(headers).map(e => dom('th', {}, [ render(e) ]))) ]), dom('tbody', { class: ['', properties?.class?.body] }, content.map(e => dom('tr', { class: ['', properties?.class?.row] }, Object.keys(headers).map(f => e.hasOwnProperty(f) ? dom('td', { class: ['', properties?.class?.cell] }, [ render(e[f]!) ]) : undefined)))) ]); +} +export function toggle(settings?: { defaultValue?: boolean, change?: (value: boolean) => void, disabled?: boolean, class?: { container?: Class } }) +{ + let state = settings?.defaultValue ?? false; + const element = dom("div", { class: [`group mx-3 w-12 h-6 select-none transition-all border border-light-35 dark:border-dark-35 bg-light-20 dark:bg-dark-20 outline-none + data-[state=checked]:bg-light-35 dark:data-[state=checked]:bg-dark-35 hover:border-light-50 dark:hover:border-dark-50 focus:shadow-raw focus:shadow-light-40 dark:focus:shadow-dark-40 + data-[disabled]:bg-light-20 dark:data-[disabled]:bg-dark-20 data-[disabled]:border-light-20 dark:data-[disabled]:border-dark-20 relative py-[2px]`, settings?.class?.container], attributes: { "data-state": state ? "checked" : "unchecked" }, listeners: { + click: (e: Event) => { + state = !state; + element.setAttribute('data-state', state ? "checked" : "unchecked"); + settings?.change && settings.change(state); + } + } + }, [ div('block w-[18px] h-[18px] translate-x-[2px] will-change-transform transition-transform bg-light-50 dark:bg-dark-50 group-data-[state=checked]:translate-x-[26px] group-data-[disabled]:bg-light-30 dark:group-data-[disabled]:bg-dark-30 group-data-[disabled]:border-light-30 dark:group-data-[disabled]:border-dark-30') ]); + return element; } \ No newline at end of file diff --git a/shared/feature.util.ts b/shared/feature.util.ts index fe3296f..2098ee7 100644 --- a/shared/feature.util.ts +++ b/shared/feature.util.ts @@ -1,12 +1,12 @@ -import type { Ability, CharacterConfig, Feature, FeatureEffect, FeatureItem, MainStat, Resistance } from "~/types/character"; +import type { Ability, AspectConfig, CharacterConfig, Feature, FeatureEffect, FeatureItem, MainStat, Resistance, SpellConfig } from "~/types/character"; import { div, dom, icon, text, type NodeChildren } from "#shared/dom.util"; import { MarkdownEditor } from "#shared/editor.util"; import { fakeA } from "#shared/proses"; -import { button, combobox, foldable, input, numberpicker, select, table, type Option } from "#shared/components.util"; +import { button, combobox, foldable, input, multiselect, numberpicker, select, table, toggle, type Option } from "#shared/components.util"; import { fullblocker, tooltip } from "#shared/floating.util"; -import { elementTexts, MAIN_STATS, mainStatShortTexts, mainStatTexts, spellTypeTexts } from "#shared/character.util"; +import { ALIGNMENTS, alignmentToString, elementTexts, MAIN_STATS, mainStatShortTexts, mainStatTexts, SPELL_ELEMENTS, SPELL_TYPES, spellTypeTexts } from "#shared/character.util"; import characterConfig from "#shared/character-config.json"; -import { clamp, getID, ID_SIZE } from "#shared/general.util"; +import { getID, ID_SIZE } from "#shared/general.util"; import renderMarkdown, { renderText } from "#shared/markdown.util"; import { Tree } from "#shared/tree"; import markdownUtil from "#shared/markdown.util"; @@ -42,8 +42,8 @@ export class HomebrewBuilder new TrainingEditor(this, this._config), new AbilityEditor(this, this._config), new AspectEditor(this, this._config), - /* new SpellEditor(this), - new ListEditor(this), */ + new SpellEditor(this, this._config), + /* new ListEditor(this), */ ]; this._content = div('flex-1 outline-none max-w-full w-full overflow-y-auto'); this._container.appendChild(div('flex flex-1 flex-col justify-start items-center px-8 w-full h-full overflow-y-hidden', [ @@ -173,53 +173,115 @@ class AbilityEditor extends BuilderTab constructor(builder: HomebrewBuilder, config: CharacterConfig) { super(builder, config); - - Object.entries(config.abilities).map(e => div('flex flex-col gap-4 border border-light-25 dark:border-dark-25', [ ])) - this._content = [ table(Object.entries(config.abilities).map(e => ({ - max1: div('', [ text(mainStatTexts[e[1].max[0]]) ]), - max2: div('', [ text(mainStatTexts[e[1].max[1]]) ]), - name: div('', [ text(e[1].name) ]), - description: div('', [ text(e[1].description) ]), - id: div('', [ text(e[0]) ]), - })), { id: 'ID', name: 'Nom', description: 'Description', max1: 'Stat 1', max2: 'Stat 2' }) ]; + this._content = [ div('flex px-24 py-4', [table(Object.entries(config.abilities).map(e => ({ + max1: select(MAIN_STATS.map(e => ({ text: mainStatTexts[e], value: e })), { change: (value) => e[1].max[0] = value, defaultValue: e[1].max[0], class: { container: 'w-full !m-0' } }), + max2: select(MAIN_STATS.map(e => ({ text: mainStatTexts[e], value: e })), { change: (value) => e[1].max[1] = value, defaultValue: e[1].max[1], class: { container: 'w-full !m-0' } }), + name: input('text', { input: (value) => e[1].name = value, placeholder: 'Nom', defaultValue: e[1].name, class: 'w-full !m-0' }), + description: input('text', { input: (value) => e[1].description = value, placeholder: 'Description', defaultValue: e[1].description, class: 'w-full !m-0' }), + id: div('w-full !m-0', [ text(e[0]) ]), + })), { id: 'ID', name: 'Nom', description: 'Description', max1: 'Stat 1', max2: 'Stat 2' }, { class: { table: 'flex-1' } })] ) ]; } } class AspectEditor extends BuilderTab { - private _filter: boolean = true; - - private _options: HTMLDivElement[]; - constructor(builder: HomebrewBuilder, config: CharacterConfig) { super(builder, config); + + const render = (aspect: AspectConfig) => { + return { + name: input('text', { input: (value) => aspect.name = value, defaultValue: aspect.name, class: '!m-0 w-full' }), + description: input('text', { input: (value) => aspect.description = value, defaultValue: aspect.description, class: '!m-0 w-full' }), + stat: select(MAIN_STATS.map(f => ({ text: mainStatTexts[f], value: f })), { change: (value) => aspect.stat = value, defaultValue: aspect.stat, class: { container: '!m-0 w-full' } }), + alignment: select(ALIGNMENTS.map(f => ({ text: alignmentToString(f), value: f })), { change: (value) => aspect.alignment = value, defaultValue: aspect.alignment, class: { container: '!m-0 w-full' } }), + magic: toggle({ defaultValue: aspect.magic, change: (value) => aspect.magic = value, class: { container: '' } }), + difficulty: numberpicker({ min: 6, max: 13, input: (value) => aspect.difficulty = value, defaultValue: aspect.difficulty, class: '!m-0 w-full' }), + physic: div('flex flex-row justify-center gap-2', [ numberpicker({ defaultValue: aspect.physic.min, input: (value) => aspect.physic.min = value }), numberpicker({ defaultValue: aspect.physic.max, input: (value) => aspect.physic.max = value }) ]), + mental: div('flex flex-row justify-center gap-2', [ numberpicker({ defaultValue: aspect.mental.min, input: (value) => aspect.mental.min = value }), numberpicker({ defaultValue: aspect.mental.max, input: (value) => aspect.mental.max = value }) ]), + personality: div('flex flex-row justify-center gap-2', [ numberpicker({ defaultValue: aspect.personality.min, input: (value) => aspect.personality.min = value }), numberpicker({ defaultValue: aspect.personality.max, input: (value) => aspect.personality.max = value }) ]), + action: div('flex flex-row justify-center gap-2', [ button(icon('radix-icons:file-text'), () => {}, 'p-1'), button(icon('radix-icons:trash'), () => remove(aspect), 'p-1') ]) + }; + } + const add = () => { + config.aspects.push({ + name: '', + description: '', + stat: 'strength', + alignment: { kindness: 'good', loyalty: 'loyal' }, + magic: false, + difficulty: 6, + physic: { min: 0, max: 30 }, + mental: { min: 0, max: 20 }, + personality: { min: 0, max: 20 }, + options: [] + }); - /* this._options = config.aspects.map((e, i) => dom('div', { attributes: { "data-aspect": i.toString() }, listeners: { click: () => { - this._builder.character.aspect = i; - this._options.forEach(_e => _e.setAttribute('data-state', 'inactive')); - this._options[i]?.setAttribute('data-state', 'active'); - }}, class: 'group flex flex-col w-[360px] border border-light-35 dark:border-dark-35 hover:border-light-50 dark:hover:border-dark-50 cursor-pointer' }, [ - div('bg-light-10 dark:bg-dark-10 border-b border-light-35 dark:border-dark-35 p-2 flex flex-col gap-2 group-data-[state=active]:bg-accent-blue group-data-[state=active]:bg-opacity-10', [ - div('flex flex-row gap-8 ps-4 items-center', [ - div("flex flex-1 flex-col gap-2 justify-center", [ div('text-lg font-bold', [ text(e.name) ]), dom('span', { class: 'border-b w-full border-light-50 dark:border-dark-50 group-data-[state=active]:border-b-[4px] group-data-[state=active]:border-accent-blue' }) ]), - div('rounded-full w-[96px] h-[96px] border border-light-50 dark:border-dark-50 bg-light-100 dark:bg-dark-100 !bg-opacity-10') - ]) - ]), - div('flex justify-stretch items-stretch py-2 px-4 gap-4', [ - div('flex flex-col flex-1 items-stretch gap-4', [ - div('flex flex-1 justify-between', [ text('Difficulté'), div('text-sm font-bold', [ text(e.difficulty.toString()) ]) ]), - div('flex flex-1 justify-between', [ text('Bonus'), div('text-sm font-bold', [ text(e.stat === 'special' ? 'Special' : mainStatTexts[e.stat]) ]) ]) - ]), - div('w-px h-full bg-light-50 dark:bg-dark-50'), - div('flex flex-col items-center justify-between py-2', [ - div('text-sm italic', [ text(alignmentToString(e.alignment)) ]), - div(['text-sm font-bold', { "text-light-purple dark:text-dark-purple italic": e.magic, "text-light-orange dark:text-dark-orange": !e.magic }], [ text(e.magic ? 'Magie autorisée' : 'Magie interdite') ]), - ]), - ]) - ])); */ + const element = redraw(); + content.parentElement?.replaceChild(element, content); + content = element; + }; + const remove = (aspect: AspectConfig) => { + config.aspects = config.aspects.filter(e => e !== aspect); - this._content = [ div('flex flex-row flex-wrap justify-center items-center flex-1 gap-8 mx-8 my-4 px-8', /* this._options */)]; + const element = redraw(); + content.parentElement?.replaceChild(element, content); + content = element; + } + const redraw = () => table(config.aspects.map(render), { name: 'Nom', description: 'Description', stat: 'Buff de stat', alignment: 'Alignement', magic: 'Magie', difficulty: 'Difficulté', physic: 'Physique', mental: 'Mental', personality: 'Caractère', action: 'Actions' }, { class: { table: 'flex-1' } }); + let content = redraw(); + this._content = [ div('flex px-8 py-4 flex-col gap-4', [ div('flex flex-row-reverse', [ button(icon('radix-icons:plus'), add, 'p-1') ]), content ] ) ]; + } +} +class SpellEditor extends BuilderTab +{ + constructor(builder: HomebrewBuilder, config: CharacterConfig) + { + super(builder, config); + + const render = (spell: SpellConfig) => { + return { + id: spell.id, + name: input('text', { input: (value) => spell.name = value, defaultValue: spell.name, class: '!m-0 w-full' }), + rank: select([{ text: 'Rang 1', value: 1 }, { text: 'Rang 2', value: 2 }, { text: 'Rang 3', value: 3 }, { text: 'Spécial', value: 4 }], { change: (value: 1 | 2 | 3 | 4) => spell.rank = value, defaultValue: spell.rank, class: { container: '!m-0 w-full' } }), + type: select(SPELL_TYPES.map(f => ({ text: spellTypeTexts[f], value: f })), { change: (value) => spell.type = value, defaultValue: spell.type, class: { container: '!m-0 w-full' } }), + cost: numberpicker({ defaultValue: spell.cost, input: (value) => spell.cost = value, class: '!m-0 w-full' }), + speed: select<'action' | 'reaction' | number>([{ text: 'Action', value: 'action' }, { text: 'Reaction', value: 'reaction' }, { text: '1 minute', value: 1 }, { text: '10 minutes', value: 10 }], { change: (value) => spell.speed = value, defaultValue: spell.speed, class: { container: '!m-0 w-full' } }), + elements: multiselect(SPELL_ELEMENTS.map(f => ({ text: elementTexts[f].text, value: f })), { change: (value) => spell.elements = value, defaultValue: spell.elements, class: { container: '!m-0 w-full' } }), + effect: input('text', { input: (value) => spell.effect = value, defaultValue: spell.effect, class: '!m-0 w-full' }), + tags: multiselect([{ text: 'Dégâts', value: 'damage' }, { text: 'Buff', value: 'buff' }, { text: 'Debuff', value: 'debuff' }, { text: 'Support', value: 'support' }, { text: 'Tank', value: 'tank' }, { text: 'Mouvement', value: 'movement' }, { text: 'Utilitaire', value: 'utilitary' }], { change: (value) => spell.tags = value, defaultValue: spell.tags, class: { container: '!m-0 w-full' } }), + concentration: toggle({ change: (value) => spell.concentration = value, defaultValue: spell.concentration, class: { container: '!m-0' } }), + action: div('flex flex-row justify-center gap-2', [ button(icon('radix-icons:trash'), () => remove(spell), 'p-1') ]) + }; + } + const add = () => { + config.spells.push({ + id: getID(ID_SIZE), + name: '', + rank: 1, + type: 'precision', + cost: 1, + speed: 'action', + elements: [], + effect: '', + concentration: false, + tags: [], + }); + + const element = redraw(); + content.parentElement?.replaceChild(element, content); + content = element; + }; + const remove = (spell: SpellConfig) => { + config.spells = config.spells.filter(e => e !== spell); + + const element = redraw(); + content.parentElement?.replaceChild(element, content); + content = element; + } + const redraw = () => table(config.spells.map(render), { id: 'ID', name: 'Nom', rank: 'Rang', type: 'Type', cost: 'Coût', speed: 'Incantation', elements: 'Elements', effect: 'Effet', tags: 'Tag', concentration: 'Concentration', action: 'Actions' }, { class: { table: 'flex-1' } }); + let content = redraw(); + this._content = [ div('flex px-8 py-4 flex-col gap-4', [ div('flex flex-row-reverse', [ button(icon('radix-icons:plus'), add, 'p-1') ]), content ] ) ]; } } diff --git a/types/character.d.ts b/types/character.d.ts index d69a09d..f028aa5 100644 --- a/types/character.d.ts +++ b/types/character.d.ts @@ -63,6 +63,7 @@ export type SpellConfig = { speed: "action" | "reaction" | number; elements: Array; effect: string; + concentration: boolean; tags?: string[]; }; export type AbilityConfig = {