From 0b286ac994b37b282576c7682ac6d97a6887aac0 Mon Sep 17 00:00:00 2001
From: LeRatierBretonnien Adalia est devenue patrouilleuse fluviale pour deux raisons précises : avoir une chance de servir l’Empire et son peuple, et éviter d’être pendue pour avoir volé une chèvre. Concernant son service à l’Empire, Adalia n’est pas certaine d’avoir accompli quoi que ce soit d’utile jusqu’à présent, pour chaque équipage de naufrageurs qu’ils enferment, un autre fait son apparition dans la semaine, mais au moins, personne n’a encore posé de question à propos de la chèvre. Adalia est une patrouilleuse fluviale assez pragmatique ; ainsi, elle accepte de fermer les yeux sur quelques paquets d’herbe à pipe de contrebande, du moment que son équipage se tient à carreau. Même si cette philosophie lui a valu la réputation d’être une personne assez juste, à qui l’on veut bien confier des tuyaux et autres informations utiles, ses supérieurs voient d’un mauvais œil ce qu’ils considèrent comme une attitude laxiste vis-à-vis du maintien de l’ordre. L’espérance de vie d’un zélote n’est généralement guère bien longue, ce qui fait d’Agrin une sorte de curiosité. Approchant des 70 ans, mais aussi vigoureux qu’un homme ayant la moitié de son âge, Agrin aime raconter des anecdotes sur les pèlerinages de sa jeunesse. D’après lui, les jeunes d’aujourd’hui sont beaucoup moins dégourdis que ceux des années 2470(c’est à peine s’ils savent par quel bout il faut tenir un fléau !) Tandis que d’autres dans sa situation auraient sans doute pu s’élever à une position importante, Agrin s’est écarté de toutes ces tentations qu’il jugeait néfastes pour son humilité. Il ne connaît pas de plus grand bonheur que de s’accroupir devant un modeste feu de camp et de prier le grand Sigmar par le sacrifice de sa propre chair. Ce marchand sociable et quelque peu rustre vient de vendre sa cargaison à un bon prix et offre à boire à quiconque veut bien écouter les récits fastidieux et emplis d’autosatisfaction de ses relations commerciales. Après-demain, il prévoit de descendre le fleuve jusqu’à Altdorf, où il amarrera son bateau et se rendra au nord, à Middenheim, pour le carnaval de la ville. ‘Vous ne connaissez pas le carnaval ? Mes amis, qu’attendez-vous ! À côté, la Schaffenfest de Bögenhafen est un spectacle de foire, je vous assure ! Une semaine entière de spectacles, d’expositions, de boissons, de jeunes créatures et de tout ce qui vous fait envie. Oui, je sais ce que vous allez me dire : les habitants du Middenland n’ont aucun sens de l’humour, et en temps normal, j’aurais été d’accord avec vous. Mais pendant le carnaval... c’est une tout autre paire de manches, voyez-vous ! Ma foi, il faut bien qu’ils se détendent d’une manière ou d’une autre, et ils le font lors de cette semaine de folie. Ils relâchent toute la pression pour être à nouveau prêts à passer le reste de l’année aussi impassibles qu’une statue de nain. Sans vouloir les vexer, très chers camarades. Une autre tournée ? Aubergiste !’ Tous les clients de l’auberge connaissent le carnaval de Middenheim, et la plupart d’entre eux partageront l’entrain d’Alex. Les aventuriers avaient déjà plusieurs raisons de se rendre à Middenheim, ils en ont maintenant une de plus. Les amibes sont des créatures simples et unicellulaires qui ressemblent à une substance gluante ou à de la gelée informe. Elles rampent lentement ou, pour se déplacer plus rapidement, déploient des pseudopodes qui peuvent atteindre la moitié de leur longueur. Elles se nourissent de matière organiques, laissant de côté les métaux et minéraux. Elles sont inexorables, dépourvues d'esprit et existent simplement pour se déplacer et absorber de la nourriture, qu'il s'agisse de feuilles, d'animaux morts, de champignons, ou d'aventuriers endormis. Les amibes sont attirées par la chaleur, qu'elles associent à de la nourriture, mais fuient les températures extrêmes qui peuvent endommager leur membrane cellulaire. Elles sont par ailleurs dépourvues de sens. Les amibes sont des créatures simples et unicellulaires qui ressemblent à une substance gluante ou à de la gelée informe. Elles rampent lentement ou, pour se déplacer plus rapidement, déploient des pseudopodes qui peuvent atteindre la moitié de leur longueur. Elles se nourrissent de matière organiques, laissant de côté les métaux et minéraux. Elles sont inexorables, dépourvues d'esprit et existent simplement pour se déplacer et absorber de la nourriture, qu'il s'agisse de feuilles, d'animaux morts, de champignons, ou d'aventuriers endormis. Les amibes sont attirées par la chaleur, qu'elles associent à de la nourriture, mais fuient les températures extrêmes qui peuvent endommager leur membrane cellulaire. Elles sont par ailleurs dépourvues de sens. Cela fait plus d’une décennie qu’Hauser a dédié sa vie à la rivière, et il a toujours fait en sorte de naviguer sur des eaux où peu de gens le reconnaîtraient. Aimable, rigoureux dans son travail, et doté d’un penchant pour les paris aux enjeux excentriques, ce patrouilleur fluvial à la carrure robuste prend cependant une mine sombre lorsqu’on lui pose trop de questions sur son passé. C’était il y a quelques mois qu’il fit la rencontre, à sa grande surprise, d’une jeune femme portant une amulette de Bögenhauer en argent, l’ultime cadeau qu’il avait fait à sa femme avant de les quitter, elle et leur petite fille tout juste née. Hauser usa alors de son don pour les jeux d’argent, ainsi que d’un crochet du gauche, pour faire monter @UUID[Actor.kMZg1EbDjxYSQrWu]{Gertrud} à bord de son bateau de patrouille. Même s’il est bien trop tard pour réparer ses erreurs, Hauser nourrit quand même l’espoir de transmettre un peu de savoir utile à la jeune femme. Fille d’un prince marchand ruiné et devenu chef cuisinier assassiné, Avaloi s’est retrouvée seule et abandonnée de tous dans le Vieux Monde. Elle s’est mise à la seule chose qu’elle connaissait : l’art de son père, qu’elle a expérimenté dès son plus jeune âge. Aujourd’hui, surtout par curiosité, Avaloi vit dans les souvenirs de mets fins d’une époque révolue, tout en s’étouffant avec les ‘produits frais’ putrides de l’Empire et en priant pour le moment où elle s’habituera aux innombrables puanteurs qui infestent son nouveau ‘foyer’. La plupart du temps, Aynjulls porte une veste de cuir maculée de taches d’huile, des hauts-de-chausses écarlates et de grosses bottes de sécurité à clous. Elle est réputée pour son travail rapide et de qualité, ce dont elle tire une grande fierté. De caractère bourru et renfrogné, elle est tellement démunie face à la disparition de ses ouvriers qu’elle est prête à essayer n’importe quoi — même si elle doit faire appel à un elfe ! A tort ou à raison, la population de mutants de l'Empire est msie au ban de la société. Si certains cherchent simplement à se cacher, beaucoup se tournent vers la violence, soit pour survivre, soit pour punir la société qui les a abandonnées. Dès son plus jeune âge, Bathilda a fait preuve d’une grande cruauté. Renvoyée emploi après emploi, les gens se lassant ou ayant peur de la jeune Reiklander, il était inévitable qu’elle finisse par rejoindre une organisation criminelle d’une manière ou d’une autre. Bathilda s’attendait à trouver des âmes sœurs parmi les naufrageurs, mais fut consternée d’apprendre qu’ils préféraient laisser leurs victimes en vie tant que celles-ci coopéraient. Depuis, elle observe attentivement le capitaine, certaine que si elle parvient à prendre sa place, elle montrera au Reik ce qu’est vraiment un naufrageur...… Comme sa mère le lui avait prédit, Bella commence déjà à regretter d’avoir quitté le Mootland. Depuis que l’expédition a pris le chemin du retour, la jeune étudiante a remarqué qu’une sorte de miasme infâme semble les avoir suivis. En tant que halfling, elle est elle-même dotée d’une résistance naturelle aux forces corruptrices du Chaos ; malheureusement, tous ses compagnons n’ont pas cette chance. Bella est certaine qu’au moins un de ses compagnons leur cache quelque chose, mais elle ne sait pas encore exactement qui. Elle a désespérément besoin d’aide, de quitter ce bateau, et d’une demi-douzaine des fameuses tourtes à l’anguille et aux épices de sa maman. Tous les hommes-oiseaux possèdent un bec crochu, des serres, et des ailes. Même si leur corps et leur tête conservent une forme humaine, ils sont recouverts de plumes colorées. Certains ressemblent à des grives, d'autres à des canaris, à des perroquets, ou d'autres espèces encore. Leur taille varie d'un individu à l'autre : quelques-uns sont de taille humaine, mais la plupart ne sont pas plus grands que des halflings. Les hommes-oiseaux sont capables de parler une version simplifiée du reikspiel, et sont assez heureux, malgré leur cage pas si dorée. En temps normal, Bernhardt est un homme chaleureux et jovial, mais ces derniers temps, il est ravagé par l’inquiétude et la fatigue : il est clair qu’il tient beaucoup au bateau et à son équipage. Il s’inquiète particulièrement pour son fils, @UUID[Actor.5EI89gq14N3aYdg3]{Karl Dampfer}. Bernhardt pense qu’il a déjà affronté tout ce que le fleuve peut lui réserver, mais il n’a jamais eu affaire à un vampire avant ça. Il croit d’ailleurs que les histoires à leur sujet, du moins à notre époque, ne sont que des contes. Il refusera de prendre des mesures drastiques envers sa cargaison tant qu’il n’aura pas de preuve irréfutable de la nature vampirique du @UUID[Actor.NSfa2kFiXH3Wwtwe]{Graf Orlock}. Boris a nettoyé des porcheries pendant douze ans. Un jour, alors qu’il transportait des porcs au marché avec sa barge, des pirates ont abordé, ont emmené les porcs, le peu d’argent qu’il possédait et Boris lui-même. Ils n’étaient pas méchants et avaient juste besoin de lui comme otage pendant qu’ils s’enfuyaient à quelques kilomètres en aval. Ils lui ont proposé de le déposer à Dunkelberg : il aurait pu rentrer à pied en quelques heures. Retrouver les porcs. Retrouver la soue. Il leur a dit de poursuivre la navigation. Dorénavant, Boris ne nettoie plus les porcheries. Il y a cent vingt ans, Brunhilde servit d'éclaireur à l'expédition organisée par Dagmar von Wittgenstein pour trouver la malepierre. Après avoir découvert ce qu'il cherchait, Dagmar tua tous les membres de l'expédition : il poignarda Brunhilde à plusieurs reprises pendant qu'elle dormait et enterra les autres vivants dans une caverne non loin de là. Depuis ce jour, Brunhilde hante la région autour de @UUID[Scene.yP2ara84Sj86X6ZE]{The Devil's Bowl}, yearning for a proper burial for herself and her companions. She will tell the tale of Dagmar’s betrayal — of how he led them into the lush hills to find a meteorite that he calculated had landed here, and of how he changed when he found it, becoming first secretive and then murderous. Il y a cent vingt ans, Brunhilde servit d'éclaireur à l'expédition organisée par Dagmar von Wittgenstein pour trouver la malepierre. Après avoir découvert ce qu'il cherchait, Dagmar tua tous les membres de l'expédition : il poignarda Brunhilde à plusieurs reprises pendant qu'elle dormait et enterra les autres vivants dans une caverne non loin de là. Depuis ce jour, Brunhilde hante la région autour de @UUID[Scene.yP2ara84Sj86X6ZE]{La Cuvette du diable}, animée par la seule volonté que sa dépouille et celles de ses compagnons soient enfin convenablement enterrées . Elle racontera l’histoire de la trahison de Dagmar , comment il les mena dans ces collines verdoyantes pour trouver une météorite dont il avait calculé le point d’impact, et comment il changea une 63 fois celle -ci trouvée , adoptant d’abord un comportement mystérieux, puis meurtrier. Brutagh was once a woodcutter, but thanks to prolonged exposure to warpstone, little of his humanity remains. He is now completely insane, apart from rare moments of lucidity when he becomes melancholic, his eyes fill with tears, and he rambles about his life in the forest. Most of the time, though, he prowls the caves, venturing out only to find food. Until he attacks, Brutagh should never be fully visible: he should remain a shadowy, indistinct figure, only ever glimpsed briefly. Brutagh’s body, arms and head are covered in a hard, green carapace that confers 2 AP to these areas. He has an extremely long neck that he can snake around corners. Suckers on his hands and feet allow him to cling to passage roofs and walls. Brutagh était jadis bûcheron. Mais à cause de son exposition prolongée à la malepierre, il a perdu beaucoup de son humanité. Désormais, il est complètement fou, même s’il a de brefs moments de lucidité quand il se laisse aller à la mélancolie : ses yeux s’emplissent de larmes, et il divague sur son ancienne vie dans les bois. La plupart du temps, il rôde dans la grotte et ne sort que pour chercher de la nourriture. Brutagh ne doit pas être vu avant d’attaquer : il doit être une présence furtive, mystérieuse et insaisissable. Le tronc, les bras et la tête de Brutagh sont couverts d’une carapace verte et dure, qui lui confère 2 PA dans ces zones. Son cou extrêmement long peut serpenter au tournant d’un couloir. Des ventouses sur ses mains et ses pieds lui permettent de grimper sur les murs et au plafond. These unfortunates have suffered terribly under the experiments arranged by @UUID[Actor.fmUd7AtbJckbiWo6]{Lady Margritte} and administered by @UUID[Actor.vgazeY44kVGP4tmW]{Jean Rousseaux}. Each Beggar already has 4 Corruption points, and you should make one or two rolls on the @Table[mutatephys]{table} to determine what mutations they bear. Even brief physical contact counts as a @Corruption[minor]{Minor Exposure to Corruption}. Ces malheureux ont terriblement souffert des expériences menées par @UUID[Actor.fmUd7AtbJckbiWo6]{dame Margritte} et administrées par @UUID[Actor.vgazeY44kVGP4tmW]{Jean Rousseaux}. Chaque mendiant possède déjà 4 points de Corruption, et vous êtes invité à leur attribuer une ou deux mutations à déterminer en effectuant un ou deux lancers en vous basant sur le @Table[mutatephys]{tableau de corruption physique}. Même un bref contact physique compte comme une @Corruption[minor]{Exposition Mineure à la Corruption}. @UUID[Actor.HoRIcFyhgSPLyrd0]{Luigi} ne va nulle part sans ses deux « petits » cousins, Carlo et @UUID[Actor.LskCuTumSjA0zyDs]{Furio}. Ces deux Tiléens colossaux au regard vide le suivent de près en permanence, prêts à pousser tout ce qui se trouve sur son chemin, vivant ou non. Même s’il ne s’agit pas des gardes du corps les plus malins, leur loyauté n’est plus à prouver, si l’on considère ce qui attend ceux qui déçoivent Il Signor Belladonna. Carlo fait d’ailleurs parfois des cauchemars au sujet de cloaques. Des cloaques, et des rats. Comme tous les autres occupants du château, les domestiques n’ont pas échappé aux effets de la malepierre. Ils portent chacun une Mutation mineure. Les domestiques ont envie de partir, mais ne veulent pas prendre de risques inutiles. Pour les convaincre de se battre, l’un des aventuriers doit faire un Test de Difficult (-10) Leadership. Un autre Test est requis chaque fois qu’un domestique est touché. Si le Test échoue, ils fuiront tous. Le visage de Corrobreth porte de profondes marques verticales sur chaque joue, qui se remarquent surtout quand il sourit. Il n’aime pas trop se joindre aux conversations banales ; lorsqu’il prend la parole, c’est souvent pour donner des conseils ou fournir des informations précieuses. Comme tous les adeptes de @UUID[Compendium.wfrp4e-core.journals.NcH9OhleJFfaUdon.JournalEntryPage.dY6NZyY5pujNM5h8]{Rhya}, il évite autant que possible d’ôter la vie, sauf en cas de légitime défense ou pour sa subsistance. Par conséquent, il préfère éviter les conflits en usant de discrétion et de diplomatie plutôt qu’affronter le danger. Corrobreth est conscient des transformations causées par la météorite de malepierre. Il connaît la position de son cratère d’impact et sait qu’il est entouré de monolithes. Il n’a jamais eu de raison de s’y rendre lui-même, mais acceptera malgré tout de servir de guide aux aventuriers. Crot and his followers have been drawn to this area by the traces of warpstone that remain here. Their instincts tell them that a large piece of warpstone was here, but has been removed. They have been watching the adventurers since they arrived, and when they enter the caves, the Skaven see a chance to capture and question them. Crot stands 6 ft tall — huge for a Skaven — and is covered in dirty grey fur. He has a prehensile tail that he can use to attack in any direction. He is cunning and utterly ruthless. Crot speaks Reikspiel in a very clipped, squeaky fashion, repeating some words in pairs and running others together. Crap et ses compagnons sont venus dans cette région car ils ont été attirés par les résidus d’énergie de la malepierre. Leur instinct leur dit qu’un gros morceau de malepierre se trouvait là, mais qu’il n’y est plus. Ils observent les aventuriers depuis leur arrivée, et quand ceux-ci sont entrés dans les grottes, les skavens y ont vu une opportunité de les capturer et de les interroger. Crap mesure 1,80 m (ce qui est très grand pour un skaven) et son corps est recouvert d’une fourrure grise sale. Il possède une queue préhensile qu’il peut utiliser pour attaquer dans toutes les directions. Il est rusé et absolument sans pitié. Crap parle le Reikspiel avec maints couinements et de manière saccadée, répétant certains mots ou les joignant ensemble. Peu d’entre eux ont opté volontairement pour la vie de naufrageur. Dederick n’a pas vraiment eu le choix après que la barge qu’il pilotait s’est accrochée à un récif, coulant avec les 3 000 Couronnes de la meilleure eau-de-vie de Kemperbad qu’il transportait pour l’entreprise commerciale Kliendorfer. Ce qui aurait dû être une simple affaire pour ses assureurs s’est transformé en une fuite nocturne jusqu’à Weissbruck, une auberge en flammes et trois corps laissés dans le sillage de Dederick. Aujourd’hui, il gagne sa vie comme il le doit, son ancien équipage et quelques nouvelles recrues, certaines plus désespérées que d’autres, tirant le meilleur parti de la situation en transmettant leur malheur aux autres. Boulette sera très impressionnée par tout halfling qui n’est pas cuisinier, puisqu’elle n’en a jamais croisé un en dehors du Mootland qui ait choisi un autre métier. Elle sera soulagée de voir les aventuriers et leur demandera de l’escorter jusqu’à Grissenwald, « ou tout autre endroit où je pourrai prendre une diligence ou un bateau vers de meilleurs horizons. Ma Maîtresse se débrouillera. Je n’ai pas de scrupule à partir sans prévenir, étant donné la situation déplorable dans laquelle elle m’a laissée. » Boulette est très heureuse de répondre aux questions des aventuriers, car selon elle, elle n’a plus à faire preuve de loyauté envers Etelka. Si quelqu’un l’insulte ou la menace, elle mettra les aventuriers dans le même panier que sa maîtresse et refusera de les aider. Un homme au visage fin de fouine est venu déposer une lettre pour sa maîtresse quelques jours plus tôt (voir @UUID[JournalEntry.RHzfHNhGeRie4mg9.JournalEntryPage.fXyDc5vrtm7tzDhx]{La Chronologie}). Etelka et lui sont partis tous les deux : ‘Ils se rendaient à la Norn pour se procurer de la colle hystérique.’ (Boulette n’a pas très bien tendu l’oreille et n’a pas entendu correctement « le long de la Narn, jusqu’aux Collines Stériles ».) Ils prévoyaient de passer d’abord par Kemperbad. Note : certaines de ces informations doivent être modifiées si, par exemple, Etelka a rencontré Heidlemann à Kemperbad au lieu de l’attendre ici. Durak est un personnage austère et obstiné qui est resté fidèle à son clan contre vents et marées, malgré l’envie de partir une fois la mine vendue. Il a été pris en embuscade par une patrouille de gobelins alors qu’il était sorti chasser. Si les joueurs le sauvent, Durak se montre très reconnaissant, et une fois complètement guéri, il serait prêt à rejoindre les aventuriers et quitter Khazid Slumbol. Cependant, si le groupe comprend ne serait-ce qu’un elfe, tous les joueurs doivent faire un Test de Hard (-20) Charm, sinon Durak refusera de les suivre. Il reste six ingénieurs la première fois que les aventuriers rencontrent @UUID[Actor.aGPAXAzBh5AnTWFl]{Aynjulls}: Thingrim, Belegol, Kardak, Gundrun, Guzul and Minak. Ils sont tous désarçonnés et terrifiés par la mort mystérieuse de leurs collègues, mais ils tentent de ne rien laisser paraître. Apparence: Impeccable, bien habillé. Personnalité: Charmant, amusant. Motivations: Profit, amusement, sécurité personnelle. Exemple de dialogue: « Quelqu’un veut jouer honnêtement à un jeu de hasard ? » et « Souhaitez-vous votre revanche sur la partie d’hier ? » Le rôle du commissaire de bord est d’être à la disposition des passagers lorsque le capitaine est occupé à autre chose. Il est responsable de la tenue des comptes du bateau, de la supervision de toutes les transactions en espèces et de la surveillance du contenu du coffre. Apparence: taille : 1,75 m, mince, cheveux gris ramenés en arrière, yeux bleus. Personnalité: correct, digne, amical. Motivations: rendre les passagers heureux et garder l’argent en sécurité, superviser l’équipe de régisseurs. Exemples de dialogue: « Merci d ’avoir porté cela à mon attention. Je m’en occupe immédiatement ». Lorsqu’un répurgateur a commencé à donner des coups de botte pour enfoncer la porte qu’Edgar était chargé de garder, il a compris que sa chance avait finalement tourné. Edgar savait que le groupe qu’il servait était douteux, mais il avait choisi d’ignorer ce qui se tramait derrière ces portes fermées qu’il était payé pour surveiller. C’est cette ignorance qui l’a sauvé du bûcher, mais pas des chaînes de la servitude. Cependant, « La Pique » est un meilleur gladiateur qu’il n’était portier, et avec quelques victoires supplémentaires et une bonne dose de sa graisse de porc préférée — une astuce qu’il a apprise d’un nain plutôt étrange— il peut encore espérer regagner sa liberté. Apparence: âgée, impeccable, légèrement frêle. Personnalité: impérieux, exigeant, snob. Motivations: inspirer le respect, terrifier les serviteurs, effrayer les roturiers. Etemple de dialogue: « Je déteste voyager. C’est si inconfortable. Une telle agitation ! » et « Certaines personnes n’ont aucune idée de la façon correcte de se comporter ». Le bateau d’Elias, Je décline à regret, est autant une maison qu’un navire de commerce. Avec ses voiles rouge sang et son intérieur de cuivre rutilant, cette péniche de 12 m de long reflète toute l’excentricité de son capitaine. Elle se transmet de génération en génération aux membres de la famille Answell et a été réaménagée tellement de fois qu’elle ressemble de plus en plus à ce qui pourrait être la mise en pratique physique d’une expérience de pensée tiléenne au sujet de la nature de l’identité. Quant à Elias, c’est un homme calme et réfléchi ; son implacable honnêteté a fait de lui un négociant respecté de tous, malgré son goût immodéré pour le poisson mariné, à l’odeur particulièrement nauséabonde. Ella est chargée de la navigation quotidienne de l'Empereur Luitpold. Ayant grandi sur les rives de l’Aver dans le Mootland, Ella est fascinée par les rivières depuis son plus jeune âge. Elle a construit son premier bateau à l’âge de douze ans, et à vingt ans, ce qui est encore considéré comme l’enfance par la plupart des halflings, elle dirigeait déjà sa propre entreprise de transport fluvial local. Bien que le capitaine soit aux commandes, Ella considère l'Empereur Luitpold comme son propre navire et sa priorité est de veiller à sa sécurité. Apparence: taille : 1,20 m, forte carrure, cheveux bruns bouclés, yeux marrons. Personnalité: agréable, agitée, efficace. Motivations: éviter les dangers de la rivière, avancer dans la vie. Exemple de dialogue: « Les cartes c’est très bien, mais il faut connaître la rivière comme sa poche. Ce n’est pas le moment de se pencher sur une carte lorsqu’une rivière gonflée par la pluie te pousse sur un banc de sable et t’expédie des arbres tombés dans la foulée ». La trentaine passée, les cheveux châtain clair et les yeux bleu foncé, Elvyra affiche une personnalité attachante et extravertie. Sous son apparente désinvolture se cachent un esprit affuté et un grand enthousiasme pour les médicaments, herbes et autres préparations médicales. Elle peut parler boutique toute la journée ainsi qu’une grande partie de la nuit, toujours ravie de faire la connaissance de personnes partageant ses passions. Cependant, elle a tendance à considérer les médecins comme des rats de bibliothèque coincés avec peu de connaissances pratiques, et les partisans de Verena comme des idiots pleurnichards dont la foi supplante l’intelligence. Ainsi, les personnages qui en font partie doivent montrer qu’ils sont réellement intéressés, et de préférence bien informés, avant qu’elle ne s’ouvre à eux. Elvyra habite à @UUID[JournalEntry.49qp95QA3aWDRmWS.JournalEntryPage.sDCpxwZ4AINph6av]{Weissbruck} depuis deux ans. Originaire d’Altdorf, elle a déménagé peu de temps après avoir décidé qu’il était plus rentable d’escroquer les gens que de fabriquer et de vendre de véritables médicaments, bien qu’elle fournisse toujours de vrais produits à ses voisins et à ceux qu’elle apprécie. Les Personnages l’auront probablement rencontrée à Bögenhafen. L’altgräfin Luneburg est une femme au cœur juste, mais elle juge parfois utile de rappeler aux classes inférieures qui tient les rênes de l’Empire. Elle se plaît à formuler des requêtes fantaisistes, exigeant de ses serviteurs qu’ils lui apportent toutes sortes de choses, d’une simple pomme rouge véreuse à un recueil de cantiques bretonniens. Elle se soucie peu des détails et, la plupart du temps, elle n’inspecte même pas ce qu’on lui apporte : elle souhaite seulement constater qu’un effort a été fait, et que les égards dus à son rang ont été observés en tout point. Si tel est le cas, elle accorde une belle récompense aux personnes impliquées, d’au moins deux fois la valeur des biens qui lui ont été présentés. Dans le cas contraire, eh bien... Disons que l’Altgräfin cache sous ses jupons volumineux un tromblon chargé, et qu’elle est reconnue comme étant une tireuse hors pair. Ernst est un homme sec et dégingandé au visage de fouine, aux cheveux châtains et au teint blafard. Il se fait passer pour un médecin récemment diplômé au service de @UUID[Actor.wXB3Bam0z0kp45Ht]{dame Etelka}, et entretient la supercherie en refusant de soigner qui que ce soit d’autre. Ernst est discret et réservé, il ne parle pas beaucoup, mais peut se montrer cinglant avec ceux qui lui déplaisent. Il est cruel et calculateur, et pendant la campagne, il n’hésitera pas à recruter des voyous pour effectuer ses basses besognes, afin de réserver ses pouvoirs jusqu’au moment le plus opportun. Maladie débilitante: Ernst souffre d’une maladie débilitante qui le tue à petit feu. Ses maîtres lui ont fourni des potions pour en combattre les effets et il en conserve toujours sur lui. S’il n’en consomme pas, il perd 1 point d’Endurance toutes les 12 heures, et meurt quand il arrive à zéro. Au premier abord, Etelka est une noble amicale, mais timide. Elle est de taille moyenne, ses cheveux blonds lui arrivent aux épaules, et ses yeux sont bleus. Derrière cette façade se cache une femme impitoyable et déterminée, qui ne laisse rien ni personne s’interposer entre elle et ses objectifs. Afin de maintenir son identité secrète, elle n’emploie la magie que lorsqu’elle est sûre qu’il n’y a aucun témoin (ou qu’il n’y aura aucun survivant). Quand on l’attaque, elle attend en général un ou deux Rounds avant de commencer à lancer des sorts. La présence d’Etelka est reconnaissable entre mille : la corruption qui émane d’elle est évidente. Sa peau émet une forte odeur âcre qu’elle recouvre avec de puissants parfums. Son odeur s’attarde parfois derrière elle jusqu’à 15 minutes après son départ. Toute personne entrant dans un lieu qu’elle a récemment quitté ne pourra que le remarquer. La grâce et la sophistication de l’aristocratie estalienne associées à la présence et la stature de la noblesse de l’Empire font de Balacañon un membre respecté de la haute société. Et le fait qu’elle soit un sorcier la fait craindre à juste titre. Véritable machine de guerre, Balacañon combine son éducation avec les énergies primitives de Ghur pour se démarquer. Apparance : âgé, aristocrate, bien habillé. Personnalité : exige le respect. Sympathique à moins d’être offensé. Motivations : profit, statut social. Exemple de dialogue : « Je ne voudrais pas voyager autrement » et « Vous ne vous souvenez probablement pas de la crise de 85 ». Le père Marcus, tant par son air que par sa manière de s’exprimer (avec un léger accent middenlander), a tout du stéréotype de l’érudit distrait. Il est vif et perspicace, mais après n’avoir côtoyé que des prêtres et érudits pendant si longtemps, il a tendance à penser que tout le monde en sait autant que lui, et sa conversation peut rapidement devenir incompréhensible pour le profane. Il se montre parfois vague ou distant, mais il n’est pas malveillant, et il est difficile de ne pas l’apprécier. Martin et @UUID[Actor.8xYAPlRLgbNOq519]{Rolf} sont tous deux solidement bâtis et ont l’air de savoir se servir d’une épée. Ils parlent peu, surtout en présence du @UUID[Actor.bUxA8zyayMarTXP7]{Père Marcus}, et il est clair qu’ils éprouvent une immense admiration pour lui, qui s’apparente presque à de la vénération. Lorsque leur supérieur n’est pas présent, ils sont assez conviviaux ; ils ne sont jamais allés à Altdorf et laissent transparaître un enthousiasme discret à l’idée de se rendre en ville, interrogeant les Personnages au sujet de la capitale lorsque le père Marcus n’est pas là. Ils peuvent également mentionner qu’en plus d’être un érudit, le père Marcus est à la tête de leur monastère, et qu’il est par conséquent très haut placé. @UUID[Actor.tCDLCDRYyPyNkFzB]{Martin} et Rolf sont tous deux solidement bâtis et ont l’air de savoir se servir d’une épée. Ils parlent peu, surtout en présence du @UUID[Actor.bUxA8zyayMarTXP7]{Père Marcus}, et il est clair qu’ils éprouvent une immense admiration pour lui, qui s’apparente presque à de la vénération. Lorsque leur supérieur n’est pas présent, ils sont assez conviviaux ; ils ne sont jamais allés à Altdorf et laissent transparaître un enthousiasme discret à l’idée de se rendre en ville, interrogeant les Personnages au sujet de la capitale lorsque le père Marcus n’est pas là. Ils peuvent également mentionner qu’en plus d’être un érudit, le père Marcus est à la tête de leur monastère, et qu’il est par conséquent très haut placé. Cette commerçante à la petite semaine revient de Marienburg et sera intéressée par toute nouvelle en provenance de l’amont du fleuve. Selon elle, Marienburg est en pleine guerre des prix. Les factions marchandes s’affaiblissent mutuellement et peu de marchandises entrent dans la ville, car les commerçants fluviaux savent qu’ils n’obtiendront pas un prix correct tant que la guerre ne sera pas terminée. Si les aventuriers disent à Frida qu’ils transportent une cargaison à Marienburg pour le compte des Blucher, elle sera curieuse, car elle a demandé le matin même à un employé des Blucher s’ils avaient besoin d’un transporteur pour Marienburg, question à laquelle ils ont répondu par la négative. Les autres marchands considèrent Frida comme du menu fretin. Transporteuse indépendante et très intelligente, elle possède une barge de 7 mètres de long. Elle n’est pas du genre à créer des problèmes. La partie inférieure du corps de Fritz a considérablement maigri après des années d’inactivité, et ses jambes ont l’air de deux bâtonnets. Le haut de son corps est émacié et sa grande barbe blanche est crasseuse. Son regard est perdu dans le vague, mais sa bouche esquisse un sourire amical. Fritz est « l’invité » de @UUID[Actor.fmUd7AtbJckbiWo6]{dame Margritte} depuis son échec face à la maladie qui rongeait @UUID[Actor.ihG2gFIFF6Ai5Gik]{Ludwig}, il y a de cela cinq ans. Il a vu @UUID[Actor.tslFtQFPcFWc7XQ5]{Slagdarg} écarteler, découper, brûler et briser de nombreuses victimes, ce qui lui a fait perdre l’esprit. ‘Bien le bonjour, ’ dira-t-il. ‘Comment allez-vous ? Vous venez prendre le thé ? Je suis l’invité de dame Ingrid. C’est elle qui m’a offert cette belle chambre.’ Fritz caresse les barreaux de sa cage, ‘t Slagdarg veille sur moi depuis mon arrivée. Il va bientôt venir s’occuper de vous, ne vous en faites pas. Apparence: d’âge moyen, coriace, mal à l’aise dans des habits de cour. Personnalité: grincheux, asocial, terrifiant si on le croise. Motivations: en finir avec cette foutue affaire et retourner sur le terrain. Exemple de dialogue: ‘Je n’y connais pas grand-chose à ce sujet. J’ai été soldat toute ma vie » et « Celui-là ne tiendrait pas cinq minutes dans les collines.’ @UUID[Actor.HoRIcFyhgSPLyrd0]{Luigi} ne va nulle part sans ses deux « petits » cousins, @UUID[Actor.2IwkTzKIsxtjA4AG]{Carlo} et Furio. Ces deux Tiléens colossaux au regard vide le suivent de près en permanence, prêts à pousser tout ce qui se trouve sur son chemin, vivant ou non. Même s’il ne s’agit pas des gardes du corps les plus malins, leur loyauté n’est plus à prouver, si l’on considère ce qui attend ceux qui déçoivent Il Signor Belladonna. Carlo fait d’ailleurs parfois des cauchemars au sujet de cloaques. Des cloaques, et des rats. Rightly or wrongly, the Empire’s population of mutants are shunned from society. While some simply seek to hide themselves away, many turn to violence — either to survive, or to punish the society that abandoned them. À tort ou à raison, la population de mutants de l’Empire est mise au ban de la société. Si certains cherchent simplement à se cacher, beaucoup se tournent vers la violence, soit pour survivre, soit pour punir la société qui les a abandonnés. Apparence: impeccable, d’âge moyen ou âgé. Personnalité: courtois, charmant, snob. Motivations: fréquenter des gens, raconter des histoires sans fin. Exemple de Dialogue: ‘La dernière fois que j’étais au palais... et e vous ai parlé de la bataille de Rogenburg ? J’étais sur le flanc gauche... Hegel was Captain of the Guard before his unfortunate death three months ago. He has not been allowed to rest in peace, however, for @UUID[Actor.fmUd7AtbJckbiWo6]{Lady Margritte} (who does not entirely trust @UUID[Actor.OF35NiRpF5Nmbl2z]{Lieutenant Doppler}) reanimated Hegel using magic and a sprinkling of warpstone dust. Now Hegel is little more than a skeleton rattling around inside his armour, but he is absolutely loyal to Lady Margritte, knowing that his continued existence relies on her powers. Hegel était capitaine de la garde avant son fâcheux trépas, il y a trois mois. Malheureusement, même sa mort ne l’a pas libéré de son travail : @UUID[Actor.fmUd7AtbJckbiWo6]{dame Margritte} (qui ne fait pas totalement confiance à @UUID[Actor.OF35NiRpF5Nmbl2z]{Doppler}) l’a réanimé grâce à sa magie et une pincée de poudre de malepierre. Désormais, Hegel n’est rien de plus qu’un squelette coincé dans son armure, mais sa loyauté envers dame Margritte reste absolue. Il sait qu’il doit son existence actuelle à ses pouvoirs. armi ceux qui ont connu Gertrud dans sa jeunesse, très peu auraient pu imaginer qu’elle rejoindrait la Patrouille fluviale un jour ; et pourtant, sa rencontre fortuite avec le patrouilleur fluvial @UUID[Actor.WwacZBjM7X2WLkp2]{August Hauser}, dans une auberge près de Kemperbad, résulta en un pari stupide, un nez cassé et une place sur le pont d’un bateau de patrouille. Depuis, la jeune femme a montré qu’elle avait un don pour flairer les ennuis, et ce malgré son nez cassé : son instinct a permis plus d’une fois d’arrêter des contrebandiers, des pirates, ou pire encore. Gertrud n’est pas encore sûre de vouloir consacrer sa vie à la Patrouille fluviale, mais pour le moment, son salaire lui permet de vivre, et Hauser s’est révélé être un mentor attentif. One of the Wizard Dagmar's final experiments, this unfortunate creature has guarded its long dead creator’s home for centuries. Preserved by foul sorcery and the occasional foolhardy rat, the Ghoul is ravenous for a more substantial meal. Cette funeste créature est l’une des dernières expériences de Dagmar. Elle garde la demeure vide de son créateur depuis sa mort, il y a des siècles. Elle survit grâce à sa sorcellerie ignoble et aux rats qu’elle trouve de temps en temps. Mais il lui en faut plus. Elle a faim. Giant Leeches hunt in marshes and near rivers, and typically grow to between one and three feet in length. They can detect vibrations, heat, and light with sensory organs on their heads. They are aggressively predatory when not satiated. The Analgesic Saliva of a Giant Leech may be harvested (carefully) from a living specimen. Turned into a @UUID[JournalEntry.JhZ4qkEf569rEcsY.JournalEntryPage.uxIVUGe1gSkqbo8m#poultices]{Poultice} it grants +1 SL to any Heal Test made to treat a critical wound. Chameleoleeches have glands near their heads that secrete a powerful @UUID[Compendium.wfrp4e-dotr.items.rYgOZSGFwF3a7GBu]{Hallucinogen}. This only affects sentient mammals, who are plagued by hallucinations of their greatest desires. Some find these delusions addictive. These creatures have the @UUID[Compendium.wfrp4e-core.items.sJ3yX1kvzu2hgNq5]{Amphibious} and @UUID[Compendium.wfrp4e-core.items.rOV2s6PQBBrhpMOv]{Arboreal} Traits rather than Aquatic. They conceal themselves among the hanging vines and foliage of wetlands areas, waiting to drop onto a passing source of body heat. Les sangsues géantes chassent dans les marais et près des rivières. Elles atteignent généralement une longueur de 30 à 90 cm. Elles peuvent détecter les vibrations, la chaleur et la lumière grâce à des organes sensoriels situés sur leur tête. Ce sont des prédateurs agressifs lorsqu’elles ne sont pas rassasiées. La salive analgésique d’une sangsue géante peut être récoltée (avec précaution) sur un spécimen vivant. Transformée en @UUID[JournalEntry.JhZ4qkEf569rEcsY.JournalEntryPage.uxIVUGe1gSkqbo8m#poultices]{Cataplasme} elle accorde +1 DR à tout Test de Guérison effectué pour traiter une blessure critique. Les sangsues-caméléons possèdent des glandes près de leur tête qui sécrètent un puissant @UUID[Compendium.wfrp4e-dotr.items.rYgOZSGFwF3a7GBu]{hallucinogène}. Il n’affecte que les mammifères sensibles, qui sont en proie à des hallucinations de leurs plus grands désirs. Certains trouvent ces illusions addictives. Ces créatures possèdent le trait @UUID[Compendium.wfrp4e-core.items.sJ3yX1kvzu2hgNq5]{Amphibie} et @UUID[Compendium.wfrp4e-core.items.rOV2s6PQBBrhpMOv]{Arboricole} plutôt qu’Aquatique. Elles se dissimulent parmi les vignes et les feuillages suspendus des zones humides, attendant de tomber sur une source de chaleur corporelle qui passe par là. The Goblins of the Twisted Maw are originally from @UUID[Compendium.wfrp4e-core.journals.ozE2DMCMK64eE5pD.JournalEntryPage.w0YfGxsBuLoODCgc]{The Grey Mountains}, but this group left the tribe a few years ago rather than submit to a dominant tribe of orcs. Ever since, they have been hiding in the forest, competing with mutants and Beastmen for food and territory. They regard @UUID[Actor.wXB3Bam0z0kp45Ht]{Etelka Herzen} with mixed feelings: contempt because she is a Human, fear because of her magical powers, and jealousy because of her house and possessions, and her freedom to do as she pleases. In her absence, they have been exploring her house and enjoying themselves in the surrounds. Les gobelins de la Gueule Tordue sont originaires des @UUID[Compendium.wfrp4e-core.journals.ozE2DMCMK64eE5pD.JournalEntryPage.w0YfGxsBuLoODCgc]{Mountagnes Grises}. Ils se sont séparés de leur tribu il y a quelques années de cela pour échapper au joug d’un puissant clan d’orcs. Ils se cachent depuis dans la forêt et se disputent les territoires et la nourriture avec les mutants et les hommes-bêtes. Leurs sentiments à l'égard d' @UUID[Actor.wXB3Bam0z0kp45Ht]{Etelka Herzen} sont mitigés : ils la méprisent parce qu’elle est humaine, craignent ses pouvoirs magiques et sont jaloux de sa maison, de ses possessions, et du fait qu’elle soit libre de faire ce qu’elle veut. En son absence, ils ont inspecté sa demeure et profité de ce nouvel environnement. Gorim est bien bâti avec une longue chevelure et d’une barbe assortie, chef des quelques nains restés à Khazid Slumbol. Pour empêcher son peuple de mourir de faim, il a vendu son marteau de guerre magique pour partager les gains au sein du clan. Comme les autres nains, Gorim est persuadé qu’@UUID[Actor.wXB3Bam0z0kp45Ht]{Etelka Herzen} leur a dérobé une mine riche en or en les arnaquant sur le prix. Though not himself a relic of the Time of Three Emperors, ‘Graf ’ Orlok, as he styles himself, claims a noble lineage dating far beyond his own 257 years and to that time of strife and war in the Empire. Orlok has left behind the trappings of his unlife in the mountains - a crumbling castle, a handful of bumbling servants, and the quotidian fears of rural peasants - in hope of finding new stimulation to relieve the boredom of his long, long years. Should the Character’s happen to disturb Orlok by night he will prove a fearsome foe indeed, though promises of a suitably entertaining distraction or willing service might stay his fangs for a little while. Still, the graf is a creature of animal need, and before long he will seek blood from any suitable source. Bien qu’il n’ait pas connu l’Âge des Trois Empereurs, « Graf » Orlok, comme il aime être appelé, affirme que sa lignée remonte à cette période de guerre et de conflits dans l’Empire, et non à sa naissance il y a 257 ans. Orlok a abandonné son ancienne vie dans les montagnes (un château en ruines, une poignée de domestiques empotés, et les peurs quotidiennes des paysans du coin) dans l’espoir de trouver un nouvel environnement plus stimulant, qui lui fera oublier l’ennui de ses longues, longues années. Si les aventuriers le dérangent pendant la nuit, il s’avérera être un adversaire redoutable, mais des promesses de distractions assez amusantes ou de services utiles pourraient le pousser à couvrir ses crocs (du moins pendant un temps). Évidemment, il reste un prédateur aux besoins sanguinaires, et il ne lui faudra pas longtemps avant de devoir repartir à la chasse. La vie d’un escroc professionnel n’est pas chose aisée, mais Grugor a porté l’art de l’escroquerie à des niveaux encore jamais vus. Il s’investit corps et âme dans les produits douteux qu’il essaie de vendre à une clientèle peu méfiante. Une série de peintures qu’il a créées à Nuln est en fait devenue une sorte de mode lorsque l’on a découvert qu’il s’agissait de faux. Une poignée de critiques ont même admis en privé qu’ils préféraient les œuvres de Lustig aux originaux. Sa brève carrière de brasseur a donné lieu à plusieurs fûts de Bugman XXXXXX qui ont failli tromper un certain nombre de nains à moitié ivres, et en effet, à l’insu de Lustig, au moins un d’entre eux a prêté le Serment du Tueur à cause de cet incident. À présent, Lustig s’est mis en tête de créer les « potions magiques les plus authentiques ». Cependant, fidèle à lui-même, une poignée de ses « fausses » potions présentent des propriétés magiques, même si elles ne produisent pas l’effet escompté... Comme tous les autres occupants du château, les domestiques n’ont pas échappé aux effets de la malepierre. Ils portent chacun une Mutation mineure. Les domestiques ont envie de partir, mais ne veulent pas prendre de risques inutiles. Pour les convaincre de se battre, l’un des aventuriers doit faire un Test de Difficult (-10) Leadership. Un autre Test est requis chaque fois qu’un domestique est touché. Si le Test échoue, ils fuiront tous. Les gardes du château étaient autrefois humains, mais le fait d’avoir vécu si près de la malepierre les a quelque peu transformés. Sous leur cotte de mailles et leur casque intégral se cache un corps en putréfaction. Quiconque aperçoit le visage ou le corps d’un garde devra faire un Test de Peur 2 ou rester pétrifié. En plus de ça, l’odeur de pourriture et de saleté est telle que quiconque se trouve dans un rayon de 2 mètres doit réussir un Test de Challenging (+0) Endurance, sous peine d’un malus de -10 à la CC. Voir la mutation @UUID[.Item.5TYShpZL7umAIBns]{Chair en putréfaction} pour appliquer le malus de CC et de Peur. A little (very little) brighter than the average Goblin, Gutbag has been inspired by his acquaintance with @UUID[Actor.wXB3Bam0z0kp45Ht]{Etelka Herzen}, and has decided to become a wizard himself. He has no idea how to achieve this, but until he has a better idea he is copying her in as many ways as he can, even wearing her clothes, jewellery, and perfume. One of these strange habits must surely be the source of her power, after all. Gutbag presents a comical sight. He wears a red ball gown of Etelka’s that is at least two feet too long for him, and it drags on the ground and constantly threatens to trip him. His head is adorned with a glittering tiara. When confronting the adventurers, he waves his arms theatrically, chanting gibberish at the top of his voice. When nothing happens after a Round of chanting, he shrugs fatalistically, draws his sword, and charges. If things go badly he will try to flee, begging for mercy if caught and blaming his actions on the society that raised him. ‘We wus forced inta this ya know! We wus a nice ‘n’ peaceful tribe, nevva did any ’arm, didn’t caws no trubble. But we wus picked on and forced outta da mountains by erm... trolls. Yeah! Big trolls it wus... Hey, if ya let us go, I wun’ caws no more trubble.’ Gutbag, un gobelin un peu (à peine) plus intelligent que la moyenne, a pris @UUID[Actor.wXB3Bam0z0kp45Ht]{Etelka Herzen} pour modèle et a décidé de devenir sorcier à son tour. Il ne sait absolument pas comment s’y prendre, mais en attendant d’y voir plus clair, il la copie sous tous les aspects : il porte ses vêtements, ses bijoux, et même son parfum. L’une de ces étranges habitudes doit bien être la source de son pouvoir, non ? GGutbag a un côté comique. La robe de bal rouge d’Etelka est trop longue d’au moins 60 cm pour lui, et elle traîne au sol, menaçant à chaque pas de le faire trébucher. Une tiare scintille sur sa tête. Face aux aventuriers, il fait de grands mouvements de bras théâtraux et scande des inepties d’une voix puissante. Lorsque rien ne se passe après 1 Round d’incantations, il hausse les épaules d’un air fataliste et dégaine son épée avant de charger. Si les choses tournent au vinaigre, il essaiera de s’enfuir, et en cas de capture, il suppliera d’être épargné, en rejetant la faute sur la société qui l’a façonné.On nous a forcés, d’abord ! On était une gentille tribu, nous, on a jamais nui à personne, on a rien fait de mal. On s’en est pris à nous, on nous a fait quitter les montagnes, c’est la faute des... des trolls. Ouais ! Des grands trolls. Si vous nous laissez partir, on arrêtera les bêtises. Le pillage de tombes n’est pas une vocation pour la plupart des gens, mais @UUID[Actor.2fsU3gUUNfv86mhk]{Hans} et Hannes se sont découvert une passion commune pour cette activité. Leur première incursion s’est faite tout à fait par hasard : ils sont tombés sur un cimetière isolé où un prêtre de Morr négligent s’était endormi à mi-chemin des derniers préparatifs, et ils se sont servis dans les affaires du cadavre. Depuis lors, ils ont découvert que le cadavre lui-même a souvent plus de valeur que les bagues que l’on peut enlever à des doigts froids et les plombages en or arrachés à des crânes pourris. À leur manière, ils font progresser les connaissances médicales, ou du moins, c’est ce qu’ils pensent. Le pillage de tombes n’est pas une vocation pour la plupart des gens, mais Hans et @UUID[Actor.DRlS1CNBxnVL4aim]{Hannes} se sont découvert une passion commune pour cette activité. Leur première incursion s’est faite tout à fait par hasard : ils sont tombés sur un cimetière isolé où un prêtre de Morr négligent s’était endormi à mi-chemin des derniers préparatifs, et ils se sont servis dans les affaires du cadavre. Depuis lors, ils ont découvert que le cadavre lui-même a souvent plus de valeur que les bagues que l’on peut enlever à des doigts froids et les plombages en or arrachés à des crânes pourris. À leur manière, ils font progresser les connaissances médicales, ou du moins, c’est ce qu’ils pensent. Si le @UUID[Actor.qmyTFgfbGqPl1cT9]{capitaine Willendorf} est le gant de velours, bien qu’elle soit tout sauf tendre, alors Sauber est la main de fer. Ses fonctions consistent à superviser l’équipage de bagnards rameurs et à maintenir l’ordre à bord. Bien qu’il soit aussi poli que les normes sociales l’exigent, il ne faut pas prendre sa courtoisie pour de la servilité. Même les jeunes nobles les plus obtus se rendent bien compte qu’il n’est pas le genre d’homme qu’il faut traiter à la légère, bien que de temps en temps quelqu’un essaye de tester ses limites. Ces vauriens finissent toujours par être débarqués du navire, soit au port suivant, soit directement dans la rivière. Apparence: taille : 1,85 m, forte carrure, cheveux blond foncé, yeux bleus, visage marqué de cicatrices. Personnalité: agressif, professionnel, bourru. Motivations: empêcher l’équipage de se relâcher et les passagers de devenir ingérables. Exemple de dialogue: « METTEZ-Y DU VÔTRE ! » Les canotiers de la Maria Borger sont des hommes amicaux et affables avec la plupart des gens qu’ils croisent sur le fleuve, mais ils gardent toujours une arbalète à portée de main. @UUID[Actor.aXFzRsefQ7YCXxOj]{Reiner} et @UUID[Actor.5EI89gq14N3aYdg3]{Karl} ont une vingtaine d’années, et se préparent à reprendre l’entreprise familiale. @UUID[Actor.ohx4btGNaWPnb59A]{Hans} est plus âgé et expérimenté que les deux fils Dampfer : ça fait presque dix ans qu’il travaille avec leur père. À cause du travail nécessaire à l’entretien et au bon fonctionnement de la barge, sans parler de son inquiétude pour ses camarades malades, Reiner n’a pas une minute à lui. Il fera de son mieux pour assister les aventuriers, mais ses corvées sur le bateau occuperont le plus clair de son temps. Hans Peter est un homme mince de taille moyenne aux cheveux noirs et bouclés et aux yeux marron. Il a l’air plutôt détendu, bien que sous cette façade se cache une grande soif de connaissance... et donc de pouvoir. Il se forme aux côtés d’@UUID[Actor.j3XNhduYwpEeBcOk]{Heironymous} depuis environ deux ans, et a l’air plutôt satisfait de sa vie d’apprenti. En vérité, ce n’est pas le cas, et il passe le plus clair de son temps libre à espionner Hieronymus pour apprendre ses secrets, mais sans grand succès. Sa soif de pouvoir se manifeste par des accès de jalousie contre les autres apprentis, qu’il considère comme des rivaux, et avec lesquels il serait incapable de se lier d’amitié. Selon lui, une vie d’aventurier n’est pas aussi précieuse qu’une vie studieuse passée à travailler dur et à nourrir de grandes ambitions. Les autres apprentis se rendront peut-être compte que Hans Peter ne prend pas en considération, voire sabote leur travail. Après tout, c’est lui l’apprenti préféré d’Hieronymus. Hieronymus est conscient des défauts de caractère et de l’ambition de son élève, et le surveille donc de près. Harold et @UUID[Actor.0fjPbArcl7uXDEnT]{Stefan}, quand ils ne sont pas occupés à récurer les casseroles dans les cuisines du @UUID[JournalEntry.w5rvSKCXvivjnTVU.JournalEntryPage.PTqp6A7lC9v8x7uu]{Col du Cygne}, prennent un malin plaisir à botter les fesses des ivrognes, des profiteurs, des fauteurs de troubles, des troubadours et des mimes. Leur taille et leur réputation leur permettent d’éviter la plupart des problèmes, mais on peut toujours compter sur eux pour se jeter corps et âme dans n’importe quelle situation impliquant la boisson. Hieronymus est un personnage à l’air particulièrement excentrique. Ses cheveux gris sont souvent en pagaille et ses yeux bleus pétillent en permanence d’une lueur de folie. Il est richement vêtu, dans un style évoquant la noblesse de campagne, et prend suffisamment soin de lui pour que tout cela lui aille bien. Mais il y aura toujours quelque chose qui cloche. Porter des chaussures dépareillées ne le gêne aucunement, par exemple, ni le fait de porter des couleurs qui ne vont vraiment pas ensemble. Les trivialités du monde ne l’intéressent pas toujours, et il sait bien que les gens seraient déçus de rencontrer un sorcier qui ne soit pas un minimum étrange. Il a souvent l’air perplexe et ses mouvements sont saccadés, voire maladroits, mais contrôlés. Il fait exprès d’avoir l’air distrait et légèrement irritable, mais en général, il écoute attentivement tout ce qu’on lui dit. Il a tendance à opter pour des réponses courtes qui vont droit au but, ce qui révèle son côté organisé derrière cette façade chaotique. Il garde en général sur lui environ 10 CO, mais peut avoir accès à bien plus. Herbert est aubergiste à @UUID[JournalEntry.WKhLoiUL9sdUE2Gs.JournalEntryPage.kAXCwOUU0oL8j10u]{L’Étoile Filante} depuis deux décennies. Ayant perdu sa famille dans un incident survenu deux ans plus tôt, il est normal qu’il paraisse un peu renfrogné. Hilda est l’agent secret des hors-la-loi à Wittgendorf. Elle vit avec son grand-père vieillissant, Hans, et ils gagnent péniblement leur vie en tant que meuniers du village. Elle a réussi à cacher ses liens avec les hors-la-loi aux gardes du château, mais elle est prête à risquer sa couverture pour emmener les aventuriers au campement des hors-la-loi. Elle est courageuse, mais reste prudente. Après avoir mené les Personnages au camp,elle les accompagnera dans leur reconnaissance du château, mais seulement si on le lui demande. Hilma Bootschlecht sait que certaines personnes se retirent plus tôt que d’autres lorsqu’une bagarre se prépare dans un bar, mais que Sigmar l’emporte si elle comprend un jour pourquoi. Le craquement d’un nez qui se casse, le choc d’un bon coup de pied dans un ventre rempli de bière, ou encore le fracas agréable d’un tabouret de bar qui se brise sur le dos de quelqu’un sont autant de choses qui font que la vie vaut la peine d’être vécue. Elle ne comprend vraiment pas pourquoi certaines personnes essaient d’éviter cela. Alors, oui, la gueule de bois peut être un problème, et la majeure partie de son salaire sert à payer la bière et les amendes, mais à quoi peut bien servir l’argent si ce n’est à être dépensé ? Et si jamais elle est vraiment ric-rac, les Kliendorfer sont toujours prêts à payer un petit supplément pour que quelqu’un débarque une petite cargaison d’une barge à l’abri des regards des inspecteurs fiscaux... La peau pâle et les cheveux blancs de dame Ingrid la font paraître moribonde. Ses beaux vêtements sont recouverts de poils de chat et tachés d’empreintes de pattes, surtout au niveau de ses cuisses. Elle dirige cette famille depuis la métamorphose de son mari Ludwig (voir @UUID[Actor.ihG2gFIFF6Ai5Gik]{Ludwig von Wittgenstein}). Bien qu’elle ne montre aucun signe extérieur de mutation, la souillure du Chaos a atteint les tréfonds de son âme. Ces dernières années, sa folie a empiré, et elle passe désormais ses journées à dorloter ses chats mutants. Les meubles de dame Ingrid ont été dégradés et lacérés par d’innombrables griffes. Les rideaux sont en lambeaux et toutes les surfaces en bois sont profondément marquées par des griffures. Rousseaux est en surpoids, ses vêtements sont légèrement trop petits et recouverts du tabac en poudre dont il est excessivement friand. Il n’a pas échappé aux effets de la malepierre : le contact quotidien a provoqué une desquamation de sa peau et il a pris l’habitude de se plâtrer le visage avec de la poudre blanche pour la cacher. S’il est vu la nuit sans son maquillage, Rousseaux offre un spectacle hideux. Voir son vrai visage compte comme une @Corruption[minor]{Exposition Mineure à la Corruption}. Jean Rousseaux est né en Bretonnie. Après avoir commencé une carrière d’étudiant en médecine, il a décidé qu’il pourrait gagner plus d’argent en tant que charlatan et s’est mis à voyager à travers l’Empire avant de s’établir à Wittgendorf, il y a dix ans. Il s’est établi comme médecin, vendant aux villageois des « médicaments » inefficaces, mais créant une dépendance. En utilisant ses compétences médicales limitées, il a pu guérir des affections mineures et détourner tout soupçon de charlatanisme. La poudre de malepierre ayant eu des effets néfastes sur le village, Rousseaux a cessé d’utiliser ses compétences de guérison. Au lieu de cela, il demande simplement à @UUID[Actor.gjlMsoOEcSH8lNQs]{Kurt} de distribuer son @UUID[Compendium.wfrp4e-dotr.items.zQBh7HQBBaTL9rRb]{tord-boyaux} aux paysans. Il est épris de @UUID[Actor.fmUd7AtbJckbiWo6]{dame Margritte} réalise tous ses souhaits. C’est elle qui lui fournit la malepierre qu’il ajoute ensuite au tord-boyaux. Rousseaux en surveille les effets et en rend compte à dame Margritte, mais il ne sait pas que la poudre est en réalité de la malepierre et serait très choqué de l’apprendre. En raison de la pénurie de nourriture qui a suivi la maletempête, Rousseaux s’est mis à manger des cadavres. L’un d’eux se trouve dans sa cave, mais s’il est découvert, il prétendra qu’il est là uniquement à des fins scientifiques de dissection. Un regard plus attentif révélera des couverts de qualité à proximité du cadavre. Rousseaux s’intéresse de près aux aventuriers, les interroge sous couvert de conversation polie et rapporte chaque détail à dame Margritte au château. Selon lui, les malformations observées chez les villageois seraient le résultat inévitable de la consanguinité au sein d’une communauté isolée : ‘J’aide du mieux que je peux ’, explique-t-il, ‘mais il n’y a pas grand- chose à faire’. Il parle en bien de la famille Wittgenstein et est impatient que les aventuriers rencontrent dame Margritte lors du dîner organisé chez lui. Il ne mentionne pas la source du tord-boyaux que boivent les mendiants, mais ne démentira pas ses activités si on lui présente des preuves. Selon lui : ‘C’est seulement pour aider ces pauvres malheureux. Quels que soient les effets secondaires, cet alcool dilue leur souffrance’. Si les aventuriers contestent, il se vexe. ‘Bien évidemment,’ dit-il avec sarcasme, ‘vous autres, voyageurs bien éduqués, en savez plus sur la médecine que les médecins et les professeurs de la meilleure académie de toute la Bretonnie. Suis-je bête d’avoir pensé le contraire.’ Doktor Schnee vient d’entrer dans l’âge mûr et était auparavant titulaire à Hugeldal. Schnee est un médecin itinérant qui tente de rassembler des informations pour une grande thèse qu’elle espère présenter à l’Université d’Altdorf. Fascinée par la propagation des maladies et déterminée à combattre leur pestilence partout où elle se rend, elle a connu à la fois un grand succès et une profonde frustration. Nombreux sont ceux qui, dans son domaine, la considèrent comme un génie, alors que beaucoup d’autres la voient comme une arriviste arrogante, aux théories farfelues sur les ‘poisons invisibles’, les ‘germes’, et autres balivernes de ce genre. Plutôt grand, Josef mesure 1 m 77, et est doté d’une bonne musculature sous une couche généreuse de gras. Il fait remarquer avec amusement, à voix basse et avec un fort accent de classe ouvrière d’Altdorf, que sa forte corpulence le protège du froid, le soir sur la rivière. Sa longue barbe hirsute épouse la courbe de son énorme ventre. Josef affiche un tempérament jovial qui se lit dans ses yeux marron, et il aime être en bonne compagnie, surtout si cette compagnie lui offre à boire. Les canotiers de la Maria Borger sont des hommes amicaux et affables avec la plupart des gens qu’ils croisent sur le fleuve, mais ils gardent toujours une arbalète à portée de main. @UUID[Actor.aXFzRsefQ7YCXxOj]{Reiner} et @UUID[Actor.5EI89gq14N3aYdg3]{Karl} ont une vingtaine d’années, et se préparent à reprendre l’entreprise familiale. @UUID[Actor.ohx4btGNaWPnb59A]{Hans} est plus âgé et expérimenté que les deux fils Dampfer : ça fait presque dix ans qu’il travaille avec leur père. À cause du travail nécessaire à l’entretien et au bon fonctionnement de la barge, sans parler de son inquiétude pour ses camarades malades, Reiner n’a pas une minute à lui. Il fera de son mieux pour assister les aventuriers, mais ses corvées sur le bateau occuperont le plus clair de son temps. Le fait que chaque repas soit servi à l’heure et selon les normes de qualité les plus élevées témoigne des compétences et du niveau de commandement de @UUID[Actor.JgMiudqnXlYViAOG]{Max}. De nombreux passagers ont même exprimé leur incrédulité lorsqu’ils ont appris que tout ceci était réalisé par le seul chef et un personnel de cuisine composé de deux personnes. Cela demande un travail acharné du matin au soir, une planification magistrale et une préparation minutieuse, mais Max n’a jamais failli à la tâche. Les cuisiniers qu’il a formés ont par la suite travaillé dans certains des hôtels et restaurants les plus prestigieux de l’Empire, et plus d’une fois il a dû faire preuve de beaucoup de tact pour empêcher un riche passager de les emmener avec lui. Selon certaines rumeurs, Klaus, qui mesure près de 2 mètres, serait à moitié ogre, mais il les déteste car il craint qu’elles ne soient fondées. Il parle doucement, mais n’a pas besoin de jouer les gros bras : quand il parle, les gens l’écoutent. Klaus est à la tête du groupe de débardeurs des @UUID[Actor.FTT9hoFswIqAW9do]{Blucher} ; il supervise le chargement et le déchargement des bateaux et s’assure que les gens obéissent aux Blucher. Les débardeurs le craignent tout autant qu’ils le respectent, mais ils ont surtout peur de lui. Klaus est loyal envers les Blucher et l’idée de les trahir ne lui a jamais traversé l’esprit. Comme tant de chasseurs avant lui, Klaus a commencé sa vie en tant que braconnier, chassant le gibier partout où il pouvait en trouver, y compris dans la réserve privée des von Bildhofen. Il a finalement été capturé après une longue poursuite à travers les landes, mais le Graf fut si impressionné par les rapports de son garde-chasse sur ce chasseur rusé qu’il fit une proposition très simple à Klaus : un travail ou un nœud coulant. Inutile de préciser que Klaus a choisi la première option et a gagné la confiance de la famille. Le sergent Kratz est un homme grand et musclé à l’air menaçant. Il porte une armure noire et ne retire jamais son casque (son visage est si putréfié qu’il en arrive à apprécier lui- même l’effet que son apparence produit sur les autres résidents du château). Kratz adore persécuter les villageois, et il verra dans un premier temps les aventuriers comme de potentielles nouvelles victimes de son sens de l’humour particulier. Kratz ne se limite pas à de l’intimidation, il n’hésitera pas à mettre ses menaces à exécution et à attaquer quiconque s’oppose à lui. Il frappera ceux qui l’agacent avec son coup-de-poing, mais face à quelqu’un de déterminé à lui résister, il sortira son fléau. Kratz n’est toutefois pas stupide et battra en retraite s’il se rend compte qu’il n’a aucune chance de vaincre. UArborant une attitude étrangement décontractée pour une naine, Kraz, comme elle préfère qu’on l’appelle, est devenue nautonière après que sa propre barge s’est échouée sur un banc de sable. Kraz habite encore aujourd’hui à côté de cette barge échouée, dont la vue n’inspire que peu de confiance à ceux qui souhaiteraient potentiellement l’engager pour guider leurs bateaux. Cependant, Kraz connaît bien son banc, et l’accident avec son propre bateau fut le dernier qu’elle ait jamais eu. Elle a dit à sa famille, qui habite Grissenwald, qu’elle économisait pour faire tirer son bateau hors de la rivière et le faire réparer ; mais Kraz n’a entendu que des mauvaises choses à propos des conditions de vie à Grissenwald, et n’a donc aucune intention d’y retourner pour le moment. Kurt passe la plupart de ses journées à s’occuper de l’alambic et à distribuer du tord-boyaux aux paysans. Ses mains sont couvertes d’une tache brune et ses doigts épais et boudinés commencent à ressembler à des gourdin. Kurt boit lui-même du tord-boyaux et est presque complètement dérangé. Ses paroles ont peu de sens et on l’entend souvent se chanter des absurdités en travaillant. La nuit, il verrouille la salle de distillation et va dormir dans sa chambre. C’est un fidèle fanatique de @UUID[Actor.vgazeY44kVGP4tmW]{Rousseaux}, à qui il obéit sans discuter. Kurt est complètement fou et passe son temps à préparer et empailler des cadavres de tous types. Il adore ses « amis » naturalisés et leur parle comme s’ils étaient encore en vie. Il avoue sans problème qu’il aimerait que tous les habitants du château (non, du monde entier !) deviennent ses « amis », et l’idée provoque en lui une excitation perturbante. Les domestiques refusent depuis peu d’entrer dans son atelier, puisque la dernière à avoir osé se trouve désormais accrochée au dos de la porte. Elle n’apporte plus ses repas, mais Kurt juge que leurs conversations sont désormais bien plus intéressantes. Dame Margritte est jeune et jolie, mais ses recherches en nécromancie ont eu de lourdes conséquences sur son apparence. Son obsession pour la mort et les cadavres a fini par déteindre sur elle : sa peau d’une extrême pâleur commence à se tendre sur ses os. Elle masque ce problème avec du maquillage et elle a réussi jusque-là à maintenir une apparence quasi normale. Dame Margritte est la fille d'@UUID[Actor.ySbdLyidudlMwGhU]{Ingrid} et @UUID[Actor.ihG2gFIFF6Ai5Gik]{Ludwig}, mais c’est aussi et surtout l’arrière-arrière-petite-fille de Dagmar von Wittgenstein. Elle a pris la suite des expériences de son aïeul et son nouveau projet consiste à se servir de la malepierre pour créer le mort-vivant idéal, une créature qui ne soit pas @UUID[Compendium.wfrp4e-core.items.D0ImWEIMSDgElsnl]{Instable} et qui soit capable de se passer de supervision, ainsi que de mener et contrôler d’autres morts-vivants. Elle se sert également de @UUID[Actor.vgazeY44kVGP4tmW]{Rousseaux} (see @UUID[JournalEntry.WKhLoiUL9sdUE2Gs.JournalEntryPage.W7qHxIXBRPthzGHY]{La Maison du Médecin}) pour étudier les effets de la poudre de malepierre sur les êtres vivants. Dame Margritte a utilisé des cadavres de villageois et de mendiants imprégnés de malepierre pour se fabriquer un être composite dont elle espère faire le chef d’une armée de morts-vivants. Son projet a mis du temps à arriver à terme, mais son monstre est désormais prêt. Il ne lui manque plus que la touche finale : l’étincelle de vie, une impulsion électrique tirée d’un éclair, qu’elle lui insuffle au moment où les aventuriers entrent dans son laboratoire. Gorgée de vie, la créature obéira à tous ses ordres, tant que dame Margritte sera à même de lui donner des instructions lorsqu’elle se « réveillera ». Lashworms are small, carnivorous creatures that live in fissures, which they disguise with debris, leaving only a hair-like ‘trigger’ outside. A Hard (-20) Perception Test is required to see the Lashworm’s lair, and a Difficult (-10) Lore (Beasts) Test is required to identify it as the lair of a Lashworm. This test may be modified at your discretion if the Character has encountered Lashworms before. When the ‘trigger’ senses any movement within 5 yd, a thin, saw-toothed organ whips out, grasping a shred of its victim’s flesh, then retracting into the crevice almost instantly. Characters must make a Difficult (-10) Cool Test or gain a @Condition[Surprised] condition. The Lashworm will spend the next 4 hours digesting this meal, and will not attack again in that time. Lashworms are incredibly fast, and always attack first, even if their target is aware of their presence. Les vers fouetteurs sont de petites créatures carnivores qui vivent dans des fissures qu’ils camouflent avec des décombres. Ils ne laissent qu’un « déclencheur » fin comme un cheveu à l’extérieur. Un Test de Hard (-20) Perception est nécessaire pour détecter leur présence, en plus d’un Test de Difficult (-10) Lore (Beasts) pour savoir qu’elle appartient à un ver fouetteur. Ce test peut être ajusté si l’aventurier qui le réalise a déjà été confronté à des vers fouetteurs par le passé. Quand le déclencheur détecte du mouvement dans un rayon de 5 mètres, un organe fin, couvert de dents aiguisées comme des lames de rasoir, jaillit de son trou, arrache un morceau de chair à sa victime, et se rétracte presque instantanément. Les Personnages doivent réussir un Test de Difficult (-10) Cool ou subir l'état @Condition[Surpris]. Le ver fouetteur passera les quatre prochaines heures à digérer son repas, et n’attaquera plus pendant ce temps. Les vers fouetteurs sont incroyablement rapides, et attaquent toujours en premier, même quand leur cible a conscience de leur présence.. The Daemonette is 5 ft tall, and has white skin with deep-green, saucer-like eyes. Its face and figure resemble those of a Human woman, except that its arms end in powerful, crab-like claws. It will try to distract the adventurers with conversation as it edges close enough to cast @UUID[Compendium.wfrp4e-core.items.2fBaYkBsPZzxNSNj]{Acquiescence}. It asks why the adventurers are not dancing, or pleasuring themselves in some other way. Why do they look so unhappy? If attacked, the Daemonette will fight, taking great pleasure in the battle so long as it appears to be winning. The Daemonette has no wish to have its soul thrown back to the Realm of Chaos in shame, and will vanish in a puff of pink smoke if reduced to 5 Wounds or less. La démonette mesure un mètre cinquante, possède une peau crémeuse et de très grands yeux ronds vert foncé. Son visage et sa silhouette sont similaires à ceux d’une humaine, à l’exception de ses bras qui se terminent par des griffes puissantes aux allures de pinces de crabe. Elle essayera de distraire les aventuriers en leur parlant afin de pouvoir s’approcher suffisamment d’eux et lancer le sort @UUID[Compendium.wfrp4e-core.items.2fBaYkBsPZzxNSNj]{Consentement}. Elle leur demandera pourquoi ils ne dansent pas ou ne s’adonnent pas à d’autres plaisirs. Pourquoi ont-ils l’air si malheureux ? Lorsqu’on l’attaque, la démonette frappe en retour et a l’air ravie de se battre tant qu’elle semble en position de force. Puisqu’elle n’a aucune envie que son âme soit renvoyée dans son Royaume du Chaos et couverte de honte, elle disparaîtra dans un nuage de fumée rose s’il ne lui reste plus que 5 Points de Blessure ou moins. Liza porte une simple blouse et se déplace pieds nus. Elle aime beaucoup @UUID[Actor.kyAFKxInnAxoqJfL]{Elvyra} et fera tout ce qu’elle peut pour l’aider. Ludwig est un individu raffiné et cultivé, qui apprécie la littérature, l’art et la sculpture. Contrairement aux autres membres de sa famille, il est chaleureux et accueillant. Depuis sa transformation en cafard il y a une dizaine d’années, il quitte rarement sa chambre. Il se console par la musique et la lecture, et apprécie de plus en plus la compagnie de ses millions d’« amis » cafards. On ne peut pas dire qu’il soit satisfait de son sort, mais il s’en contente du mieux qu’il peut. Ludwig déplore le comportement de sa famille, qu’il attribue à ‘la malédiction des Wittgenstein’. ‘Tout a commencé avec Dagmar von Wittgenstein,’  explique-t-il. ‘C’était mon arrière- grand-père, celui qui a construit l’observatoire près de Grünburg. Il est devenu obnubilé par une étoile filante. Il n’avait qu’une seule idée en tête : la retrouver. C’est ce qu’il a fini par faire. Alors il l’a ramenée ici. Depuis, tout va de mal en pis pour nous.’ Luigi est de taille moyenne et a les cheveux gris. Il affiche également un léger embonpoint, mais personne n’a jamais pu le lui faire remarquer deux fois. Ses bajoues semblent toujours garder un peu de nourriture en réserve, voire une paire de chaussettes, et ses yeux bruns lui donnent un regard sévère et impitoyable. Son discours n’est qu’un murmure rauque, ce qui force ses interlocuteurs à se pencher vers lui pour entendre ce qu’il leur raconte. Luigi ne se répète jamais, et n’élève jamais la voix. Il n’en a pas besoin : c’est à son audience de prêter l’oreille. Il choisit bien ses mots et parle de manière formelle, signe d’une éducation et de pensées complexes qu’on ne s’imagine pas forcément retrouver chez un criminel. Ses vêtements sont composés des plus belles soies et laines, et ses cheveux sont élégamment gominés. Ses petits doigts potelés sont ornés de bagues en or et en diamant. Il a l’air en tous points d’un marchand prospère, jouissant d’une fortune gagnée et non héritée. Cela fait des années que Luigi n’est plus un voyou. Avec le temps, il a appris à persuader les autres de faire le sale boulot à sa place, et s’attend à être obéi sans discussion. Le fait que son commerce soit du mauvais côté de la loi laisse Luigi de marbre : à ses yeux, seuls l’argent, l’autorité et l’influence comptent. Malgré les apparences, la personne importante dans cette interaction n’est pas @UUID[Actor.q7DYHbjxedEeX2WN]{Max} mais son patron, Matthias Blucher. Malgré son jeune âge, Matthias a l’instinct d’un marchand et le sang des Blucher. Il est déjà à la tête des activités commerciales de la famille sur cette partie du Reik. The maw gapes wide, revealing bright-green teeth and an interior filled with a sickly green ichor. Characters who have been dragged 6 yd will be within biting range: roll to hit as normal. Any Character reduced to 0 Wounds is swallowed in the following Round. La gueule est grande ouverte, révélant des rangées de dents couvertes d’un pus sanguinolent et verdâtre. Les Personnages qui se sont fait tirer sur 6 m sont à portée de morsure : faites un jet d’attaque normal. Tout Personnage réduit à 0 Point de Blessure est avalé au Round suivant. Max Wagner est au moins deux fois plus âgé que @UUID[Actor.FTT9hoFswIqAW9do]{Matthias Blucher}, mais il sait qu’il ne sera jamais un aussi bon marchand que son jeune maître. Les compétences de Max résident dans les détails de la logistique, la manipulation des chiffres sur le papier et la structuration des transactions pour tirer le maximum de profit. Il a un énorme respect pour Matthias et l’ensemble de la famille Blucher et ne fera rien pour les trahir, même s’il est mal à l’aise avec la façon dont Matthias fait parfois affaire. Aucun cadre de luxe, qu’il s’agisse d’un château, d’un hôtel ou d’un bateau, n’est totalement complet sans un cuisinier halfling pour offrir une cuisine de classe mondiale aux clients les plus exigeants. Max est à bord de l'Emperor Luitpold depuis plus longtemps que n’importe quel autre membre de l’équipage, à l’exception du commissaire de bord @UUID[Actor.JxoG6n49gRjNg6kR]{Purser Kleingeld}, et certains reviennent sur le bateau de croisière simplement pour déguster sa cuisine. Apparence: Taille : 1,15 m, corpulence forte, cheveux roux bouclés, yeux marrons. Personnalité: bavard, sociable, perfectionniste. Motivations: fournir aux passagers la meilleure nourriture du Vieux Monde. Exemple de dialogue: ‘BARBARES ! Vous ne pouvez pas servir ça tiède !’ et ‘Je suis tout à fait d’accord, monsieur. Trop d’origan gâcherait normalement le goût, mais...’ Max est un grand homme dégingandé aux yeux gris pâle et dont les cheveux gris arrivent aux épaules. Il a des bras relativement longs et porte presque toujours un ciré crasseux qui lui descend aux mollets, ainsi qu’un chapeau à calotte haute qui se balance dangereusement sur sa tête. Max parle d’une voix fluette et nasillarde, et bute constamment sur ses mots. Tout ceci, complété par un nez busqué et une carrure toute en angles, lui donne souvent l’air d’un étourneau nerveux quelque peu dépenaillé. Ses manches sont souvent tachées de sang, mais mis à part ce détail, il s’agit, à sa manière, de quelqu’un de très méticuleux. Il donne l’impression d’être impatient, incisif et méprisant, mais cerne très bien les gens qu’il rencontre, et est loin d’être aussi dur qu’il aime le prétendre. Vif d’esprit et intelligent, il est bien conscient qu’il pourrait faire fortune en se mettant au service de riches hypocondriaques, mais il préfère venir en aide à ceux qui ont réellement besoin de lui, sans se soucier de leur potentiel manque d’argent. Aux yeux de certains, il est donc devenu un dangereux dissident. Mia Answell a deux buts précis dans la vie : obtenir une situation confortable en faisant le moins d’efforts possible, et hériter du bateau de son père, le Je décline à regret. Parce que son @UUID[Actor.USyqhyNdCSObjPB4]{père} est une bonne pâte, Mia est parvenue à accomplir le premier de ses deux objectifs avec brio. Malheureusement pour lui, cette victoire douteuse a rendu Mia encore plus impatiente de réaliser le second. Si un groupe de parfaits bons à rien venait à croiser sa route, Mia inventerait toutes sortes d’histoires au sujet de son père pour les convaincre de l’aider à faire d’elle le nouveau capitaine du Je décline à regret Qu’un tel groupe soit tout aussi bien capable de s’emparer du bateau est une idée qui risque de ne pas lui venir à l’esprit avant qu’il ne soit trop tard. The cats vary greatly, but each has at least one visible mutation. Some have long ears or long tails, some are strangely coloured (bright blue, red and yellow stripes), others have human-like hands, or long fangs, or multiple limbs or eyes. You should feel free to describe any kind of mutation that comes to mind. These cats have been thoroughly spoilt by Lady Ingrid. The other residents of the castle try to avoid them, as they can be quite vicious. The creatures are dreaded by the servants of the castle, whom they have been known to attack, and more than one of the beasts has developed a taste for blood that goes beyond mice and small birds. Les chats sont très différents les uns des autres, mais ils ont au moins tous une mutation visible. Certains arborent de grandes oreilles ou une grande queue, d’autres ont un pelage aux couleurs étranges (tigré bleu, rouge et jaune vifs), d’autres encore possèdent des mains humaines, ou de longs crocs, voire même plusieurs yeux ou pattes. N’hésitez pas à décrire tous les types de mutations qui vous viennent à l’esprit. Ces chats ont été terriblement gâtés par dame Ingrid. Les autres résidents du château essayent de les éviter parce qu’ils peuvent se montrer vicieux. Les domestiques du château redoutent ces créatures qui les attaquent fréquemment, et qui sont nombreuses à avoir développé un penchant pour le sang de victimes plus grosses que des souris et de petits oiseaux. A tort ou à raison, la population de mutants de l'Empire est msie au ban de la société. Si certains cherchent simplement à se cacher, beaucoup se tournent vers la violence, soit pour survivre, soit pour punir la société qui les a abandonnées. Naiads are beautiful and elusive nature spirits that inhabit some rivers of the Old World. They usually appear as slender, elfin-looking women with pale, blue-tinged flesh and white or blue hair and eyes — but they are natural shapeshifters and can assume a terrifying war-form. Naiads prefer seclusion and defend their territory ferociously from perceived threats. They are inscrutable creatures, with deep passions that are quick to rise without warning. Les naïades sont des esprits de la nature, belles et insaisissables, qui habitent certaines rivières du Vieux Monde. Elles se présentent généralement sous la forme de femmes élancées, à l’allure elfique, au teint pâle et bleuté, aux cheveux et aux yeux blancs ou bleus, mais elles sont naturellement métamorphes et peuvent prendre la forme de guerrières terrifiantes. Les naïades préfèrent l’isolement et défendent férocement leur territoire contre les menaces perçues. Ce sont des créatures impénétrables aux passions profondes qui se déchaînent sans prévenir. Les rameurs font avancer l'Emperor Luitpold lorsque le vent est insuffisant pour les voiles. La majorité d’entre eux sont d’anciens détenus de la prison pour débiteurs, le Donjon Mundsen d’Altdorf, qui a conclu un accord avec les Lignes Hindelin selon lequel les condamnés les plus forts et les mieux éduqués peuvent travailler à la rame sur les bateaux de la compagnie pour rembourser leurs dettes. Bien que ce travail ne soit pas de tout repos, les rameurs dorment sur leurs rames et doivent être prêts à ramer à toute heure du jour et de la nuit, leur sort est bien meilleur que celui de simples galériens : ils sont nourris régulièrement, encouragés à rester propres et traités correctement par le maître d’équipage. A tentacle can only be severed by damage of 6 Wounds or more, delivered in a single blow by an edged weapon. All other damage is instantly regenerated. Il est possible de sectionner un tentacule si l’attaque fait au moins 4 Points de Blessure, qu’elle a été infligée par une arme tranchante et en un seul coup. Tous les autres dégâts sont absorbés par sa capacité de régénération. Le comte Otto est un homme d’âge mûr, plutôt replet, avec des cheveux gris et clairsemés toujours coupés avec soin. Au premier abord, il n’est qu’un petit noble guindé et mesquin, qui se croit au-dessus du commun des mortels et insiste pour être traité avec le plus de courbettes possible. Sous cette façade, c’est un homme politique compétent et un excellent juge de caractère ; bien sûr, son snobisme n’est pas feint, mais il est exagéré. Otto a compris qu’il y a bien des avantages à être sous-estimé. Cet austère marchand du Nord remontait le fleuve lorsque son bateau et sa cargaison lui ont été volés par des pirates fluviaux. Il essaie maintenant d’accomplir les missions qui s’offrent à lui afin de rentrer à bon port. Il proposera ses services en tant que « consultant commercial », présentant différentes personnes les unes aux autres en échange d’un pourcentage pour tout accord conclu. Il est à l’affût de la possibilité de se rendre en aval du fleuve à un bon prix (ou gratuitement). Il parlera aux aventuriers de la famille Blucher en échange de quelques pistoles, mais insistera pour échanger dans l’un des boxes à rideaux, où personne ne pourra les entendre ni profiter gratuitement de son expérience. Otto a fait affaire avec les Blucher à plusieurs reprises et pense que ce sont des hommes d’affaires fiables.. @UUID[Actor.FTT9hoFswIqAW9do]{Matthias} est peut- être jeune, mais il dirige brillamment l’exploitation locale (il n’a même pas fait de pause après son mariage). Les Blucher donnent également dans le commerce d’armes, en particulier d’armes fabriquées par des nains qu’ils transportent des Montagnes Noires à Marienburg, bien qu’ils ne le crient pas sur tous les toits. Otto pense que si cela venait à se savoir, aucun elfe ne traiterait plus avec les Blucher. @UUID[Actor.J2gcD0wui2vjEoLB]{Sigrid} est à la tête d’un groupe d’anciens villageois qui ont préféré devenir hors-la-loi plutôt que de continuer à subir le règne sévère et insensé de la famille Wittgenstein. Il y a dix- huit mois, son mari a été emmené au château et personne n’a plus jamais entendu parler de lui. Pour se venger, Sigrid a tué un garde et s’est enfuie dans la forêt, refusant de se soumettre à la justice des Wittgenstein. D’autres hommes et femmes ont fui le village pour la rejoindre ; sa bande compte actuellement trente hors-la-loi. Tous les hommes-oiseaux possèdent un bec crochu, des serres, et des ailes. Même si leur corps et leur tête conservent une forme humaine, ils sont recouverts de plumes colorées. Certains ressemblent à des grives, d'autres à des canaris, à des perroquets, ou d'autres espèces encore. Leur taille varie d'un individu à l'autre : quelques-uns sont de taille humaine, mais la plupart ne sont pas plus grands que des halflings. Les hommes-oiseaux sont capables de parler une version simplifiée du reikspiel, et sont assez heureux, malgré leur cage pas si dorée. All the Purple Hand cultists have some item of clothing that is purple: a tunic, cloak, belt, or something else. After three or four cultist encounters, begin making secret Challenging (+0) Intelligence Tests for the adventurers to spot this purple theme. Also, every cultist has a small purple tattoo of an open hand, somewhere on their bodies. Although the cultists have a variety of occupations which provide them with suitable cover stories, they all have a number of Skills in common, that are listed below. In addition, they have whatever non-combat Skills are consistent with their cover and the situation in which they are encountered. Tous les adeptes de la Main Pourpre portent un vêtement de cette couleur : tunique, cape, ceinture ou autre. Après trois ou quatre rencontres avec des adeptes, commencez à effectuer des Tests Challenging (+0) Intelligence secrets pour que les aventuriers repèrent ces éléments de couleur pourpre. De plus, tous les adeptes ont un petit tatouage violet représentant une main ouverte quelque part sur le corps. Bien qu’ils disposent d’une variété de professions leur fournissant une couverture plausible, ils ont tous un certain nombre de Compétences en commun énumérées ci-dessous. Ils disposent également de toutes les Compétences hors combat cohérentes avec leur couverture et la situation dans laquelle ils se trouvent. Apparence: tout âge et toute carrure. Bien habillé sans trop en faire. Personnalité: observateur, diplomate, aimable. Motivations:profiter, s’amuser, établir des contacts utiles. Exemple de dialogue: ‘Restons en contact. Nous pourrions faire affaire un jour’. En plus d’être aux commandes de l'@UUID[JournalEntry.0VspKmtULhucmZCl]{Empereur Luitpold}, avec une autorité qui n’a d’égal que celle de l’Empereur lui-même, le capitaine Willendorf est le visage public de la compagnie des Lignes Hindelin et doit être une hôte aimable aussi bien qu’un chef inflexible. Son principal devoir social est de dîner tous les soirs à la table du capitaine et de faire la conversation avec les passagers les plus distingués du bateau de croisière, mais il peut également arriver qu’elle doive arbitrer des différends entre les passagers sans offenser aucune des parties. Il s’agit d’un rôle exigeant, mais elle possède à la fois les compétences en matière de navigation et de relations sociales pour le mener à bien et occupe l’un des postes les plus convoités de la vie fluviale. Apparence: taille : 1,75 m, athlétique, cheveux châtain clair, yeux bleus. Personnalité: formelle, polie, ponctuelle, efficace. Motivations: un voyage sans problème et des passagers satisfaits. Exemple de dialogue: ‘Vous profitez bien du voyage ?’ Reginhard Vieth a fait enfermer plus de @UUID[JournalEntry.tYjAPDY7d9Hu5lt1.JournalEntryPage.NA0PooQSdYnBPi6K]{pirates} que la plupart des gens n’en verront jamais, les traînant dans les cellules sous le château Reikguard ou laissant la rivière emporter leurs corps. Pourquoi n’aurait-il pas été autorisé à garder un peu de leur butin pour lui ? Le salaire d’un patrouilleur fluvial était une somme dérisoire comparée à l’argent et aux marchandises qu’il pouvait dérober à ses proies. De telles pensées rongeaient Reginhard, jusqu’à ce qu’un marchand ingrat de trop soit témoin de la nouvelle vie de Vieth et de ses plus loyaux officiers : ils étaient bien déterminés à commencer une nouvelle vie de l’autre côté de la loi. Aujourd’hui, Vieth est la terreur de son tronçon des voies navigables de l’Empire et la honte de ses camarades patrouilleurs fluviaux. Vieth ne se sépare jamais de son chapeau, fabriqué avec la peau d’un requin qui a failli lui arracher la jambe. Cependant, ce couvre-chef a un autre but qu’afficher fièrement son exploit, car il cache ses mutations : un aileron de requin et des branchies qui ont poussé dans son cou et son dos. Grâce à elles, Vieth est capable de respirer sous l’eau et de nager avec une habileté surnaturelle. The Reik Eel is found in river Reik and its many tributaries. It commonly grows up to 12–15 feet in length and has a ridge down the length of its green-grey back. Some can grow to truly terrifying sizes, and there are tales — only a little exhaggerated, of Reik Eels swallowing entire row boats. Reik Eels of size Enormous will typically @UUID[Compendium.wfrp4e-core.items.KynNUYYKzTMeHrKl]{Constrict} their victims before attempting to drag them beneath the water to drown. L’anguille du Reik se trouve dans le Reik et ses nombreux affluents. Elle atteint généralement une longueur de 3 à 5 mètres et possède une crête sur toute la longueur de son dos vert-gris. Certaines peuvent atteindre des tailles vraiment terrifiantes, et il existe des récits, à peine exagérés, d’anguilles du Reik avalant des barques entières. Les Anguilles du Reik de Taille Énorme étoufferont généralement leurs victimes @UUID[Compendium.wfrp4e-core.items.KynNUYYKzTMeHrKl]{Empêtré} avant de tenter de les entraîner sous l’eau pour les noyer. Les canotiers de la Maria Borger sont des hommes amicaux et affables avec la plupart des gens qu’ils croisent sur le fleuve, mais ils gardent toujours une arbalète à portée de main. @UUID[Actor.aXFzRsefQ7YCXxOj]{Reiner} et @UUID[Actor.5EI89gq14N3aYdg3]{Karl} ont une vingtaine d’années, et se préparent à reprendre l’entreprise familiale. @UUID[Actor.ohx4btGNaWPnb59A]{Hans} est plus âgé et expérimenté que les deux fils Dampfer : ça fait presque dix ans qu’il travaille avec leur père. À cause du travail nécessaire à l’entretien et au bon fonctionnement de la barge, sans parler de son inquiétude pour ses camarades malades, Reiner n’a pas une minute à lui. Il fera de son mieux pour assister les aventuriers, mais ses corvées sur le bateau occuperont le plus clair de son temps. Reiner prend le relais lorsqu’Ella se repose ou sert de paire d’yeux supplémentaire sur les tronçons traîtres de la rivière. Il apprend encore le métier de nautonier. Mais un second pilote sur un bateau de croisière de classe impériale équivaut à un pilote en chef presque partout ailleurs. Apparence : taille : 1,70 m, mince, cheveux bruns flottants, yeux noisette. Personnalité : calme, studieux, sérieux. Motivations : éviter les dangers de la rivière, apprendre le métier. Exemple de dialogue : ‘ Étrange... Vous voyez cette forme à la surface ? Deux cents mètres, à l’avant bâbord. Il y a quelque chose là-bas qui ne se trouve pas sur les cartes, un morceau de bois, probablement. Pourrez-vous jeter un coup d’œil d’en haut quand nous passerons à côté ? J’aimerais savoir si j’ai vu juste’. Jeune femme très indépendante et autonome, Renate est souvent prise pour une Strigany. Elle préfère les vêtements aux couleurs vives aux motifs complexes, et porte généralement un foulard rouge sur ses cheveux noir corbeau, ainsi que deux grands anneaux en or aux oreilles. Renate est d’un naturel prudent (les joueurs auront peut-être un autre mot pour la définir) et entretient une aversion plutôt saine pour le danger. Elle essaiera toujours de trouver un moyen non violent d’échapper au danger, par exemple, en bluffant, en se cachant ou en fuyant. Elle aime voyager et voir des endroits différents. Plutôt qu’un amour particulier pour l’aventure, c’est cette raison qui l’a motivée à embrasser la vie itinérante de colporteuse. Si les aventuriers l’invitent à les rejoindre, elle le fera volontiers, car elle sait qu’elle est plus en sécurité avec eux que seule. Le bateau de patrouille fluviale a un équipage de [[/r 2+D10]] @UUID[Actor.Az8G5vd6t6lQk1hU]{patrouilleurs fluviaux}, dont un capitaine. Ce sont généralement des individus sérieux qui prennent leurs devoirs à cœur, et qui ont tendance à traiter les autres Riverains avec impartialité. Le bateau de patrouille fluviale a un équipage de [[/r 2+D10]] @UUID[Actor.Az8G5vd6t6lQk1hU]{patrouilleurs fluviaux}, dont un capitaine. Ce sont généralement des individus sérieux qui prennent leurs devoirs à cœur, et qui ont tendance à traiter les autres Riverains avec impartialité. Trolls are described in general terms @UUID[Compendium.wfrp4e-core.actors.7qslmdLa7so3BmFk]{here}. The following description and rules can be used for River Trolls. River Trolls are rare in the Empire, but not unknown. They are most common in the remote headwaters of the Empire’s great rivers, and a few are known to dwell in mountains lakes, but from time to time a River Troll will appear unexpectedly in a more populous area, lying in wait for passers-by under a bridge or in a bankside cave. A River Troll somewhat resembles the bottom of the river, if that riverbed is particularly coated in sediment, slime, rotting vegetation, fish carcasses, and other detritus. Its smell has been compared (unfavourably) to that of a rubbish-strewn mud-flat at low tide. Les Trolls sont décrits de manière générale @UUID[Compendium.wfrp4e-core.actors.7qslmdLa7so3BmFk]{ici}. TLa description et les règles suivantes peuvent être utilisées pour les trolls des rivières. Les trolls des rivières sont rares dans l’Empire, mais pas inconnus. On les trouve le plus souvent dans les sources reculées des grandes rivières de l’Empire, et quelques-uns sont connus pour habiter les lacs des montagnes. De temps en temps, un troll des rivières apparaît inopinément dans une zone plus peuplée, attendant les passants sous un pont ou dans une grotte en bord de rivière. Un Troll des rivières ressemble un peu au fond d’une rivière, surtout si ce lit est particulièrement recouvert de sédiments, de vase, de végétation en décomposition, de carcasses de poissons et d’autres détritus. Son odeur a été comparée (assez défavorablement) à celle d’une vasière couverte de détritus à marée basse. Bruckesel n’est sûr que de deux choses : la quantité minimale d’impact nécessaire pour fendre un crâne humain, et que le @UUID[Actor.3K8n0EmzIvvO8CaK]{Baron Sigismund} n’a jamais tort. Ces deux certitudes lui ont bien servi dans la vie. Ruairi est un homme robuste qui a fait fortune dans le commerce du crin de cheval. Connaisseur de tous les sujets, mais expert dans peu de domaines, il aime régaler quiconque veut bien l’écouter. ‘Vous voulez savoir qui a fait ça aux Wittgenstein ? Je vais vous le dire, moi. C’est les nains. Non. Enfin... Tout ce que je dis, c’est que j’y étais, moi, il y a cinq ans, et j’ai vu ce petit gars incroyable, vous voyez, et il portait une pelle. Vous me suivez ? Et les nains, ils construisent des tunnels, n’est-ce pas ? Et je pense, je dis ça comme ça, qu’ils ont peut-être creusé un très gros trou. Un gros trou, vous voyez ? Ils ont creusé en dessous du château, alors il est tombé. C’est logique. Vous me suivez ?’ Si les aventuriers ne ‘le suivent pas’, Ruairi partira dédaigneusement à la recherche d’un meilleur faire-valoir avec qui partager sa sagesse, pour revenir plus tard, encore plus ivre. ‘Alors, donc, ce château ? J’ai bien réfléchi. Et je sais qui a fait ça, vous voyez ? Les hommes-bêtes, vous me suivez ? Tout ce que je veux dire, c’est qu’on entend beaucoup parler des hommes-bêtes, mais jamais des hommes-poissons. C’est pas vrai ? C’est sûr qu’il y a des hommes-poissons. Enfin, je veux dire, c’est logique. C’est les hommes-poissons. Ils ont grignoté la rive. C’est logique...’ Sous l’œil attentif du @UUID[Actor.6455iMweyeMpYj9T]{maître d’équipage}, un équipage réduit, mais compétent, s’occupe des voiles du bateau de croisière et le fait avancer, tant que le vent est favorable. Apparence: d’âge moyen, en surpoids. Vêtement ostentatoire, peu d’allure. Personnalité: flatteur envers les personnes socialement supérieures, insultant envers les personnes inférieures. Vain, arrogant, lâche, avare. Bruyant, sans tact, souvent vulgaire. Motivations: avidité, besoin d’impressionner. Exemple de dialogue: ‘e n’avais rien quand j’ai commencé .’ et ‘ls n’ont jamais travaillé de leur vie, eux’. Les gardes du château étaient autrefois humains, mais le fait d’avoir vécu si près de la malepierre les a quelque peu transformés. Sous leur cotte de mailles et leur casque intégral se cache un corps en putréfaction. Quiconque aperçoit le visage ou le corps d’un garde devra faire un Test de Peur 2 ou rester pétrifié. En plus de ça, l’odeur de pourriture et de saleté est telle que quiconque se trouve dans un rayon de 2 mètres doit réussir un Test de Challenging (+0) Endurance, sous peine d’un malus de -10 à la CC. Voir la mutation @UUID[.Item.5TYShpZL7umAIBns]{Chair en putréfaction} pour appliquer le malus de CC et de Peur. @UUID[Actor.wXB3Bam0z0kp45Ht]{Etelka’s} black cat, Shadow, accompanies her wherever she goes. Although Shadow appears intelligent, with a disconcertingly knowing look in her eyes, she is an ordinary black cat. Le chat noir d'@UUID[Actor.wXB3Bam0z0kp45Ht]{Etelka}, Ombre, l’accompagne partout où elle va. Même si Ombre a l’air doué d’intelligence, et que ses yeux pétillent comme ceux d’un humain, c’est un chat noir tout ce qu’il y a de plus ordinaire. Doppler est cruel, vaniteux, et la torture lui procure un immense plaisir. Pour cacher son visage en putréfaction, il porte un masque lui donnant l’apparence d’un beau jeune homme. L’effet de ce masque très réaliste est gâché par les plaies qui lui couvrent le cou. Le courage de Doppler repose sur la présence de ses gardes. Si on le surprend seul, il se rendra immédiatement, mais tentera de faire tomber les aventuriers dans un piège. Il pourrait très bien leur offrir des informations précieuses, mais il mentira toujours si on lui demande où se trouve le reste des gardes, sauf s’il craint réellement pour sa vie. Une vie d’idylle et d’excès aurait pu être le lot de Sigfrida, si elle l’avait souhaité. Malheureusement, cette possibilité a été écartée lorsqu’elle a assisté à un duel à la poudre noire dans les rues de Nuln. Les mots du noble, le bruit de la poudre, le sang qui gicle... Elle a trouvé toute cette situation extrêmement excitante. Depuis, elle a décidé de se tourner vers une vie d’aventure et d’excès. Elle a quitté Nuln la saison suivante et, jusqu’à présent, la chance de Sigfrida et son objectif sont restés stables. Le bon baron a vécu une tout autre vie autrefois, mais peu de choses durent éternellement, comme von der Bahr le sait si bien. Aujourd’hui, il se distrait en parcourant les auberges et les tavernes de l’Empire, à la recherche d’une conversation exaltante ou d’un partenaire d’entraînement pour @UUID[Actor.7a5vHhRxCI7ZsI09]{Roland}, ce qui pourrait produire un combat intéressant. ‘Of course I'll go in first. Can't be any worse than Castle Wittgenstein...’ Sigrid has long, dark hair, and a perpetually serious expression. In those moments when she forgets her worries, however, something of the starry-eyed initiate of Rhya returns. She is wary of most people these days, and of the Empire's nobility in particular, whom she now suspects all harbour some secret corruption. Her loyalty, though rarely given, is almost unshakeable, and Rhya will go to great lengths to protect those who are important to her. Sigrid is a determined woman who protects the outlaws under her command. While the outlaws often attack guard patrols, she is against a direct assault on the castle, knowing that it will only end in defeat. She will help the adventurers reach the castle, but will not allow her followers to risk a direct assault unless the adventurers clear the way — for example, by infiltrating the castle through the secret cave and lowering ropes from the walls, or opening the main gates. Sigrid made her home in Wittgendorf, and would have been happy to live out her life there were it not for the Wittgenstein's kidnapping of her husband. She was devoted to Brandt, having left the priesthood to marry him, and swore to rescue him. She opposed the castle and its wardens long before the Characters arrived, and quite likely played an instrumental part in overthrowing the Wittgensteins for good. Castle Wittgenstein was a dangerous place, and it is quite possible that one of the existing Characters met their end their. If this is the case, Sigrid would make an excellent player character, especially if her allegiance was gained before the assault on the castle. Her husband will pass away from the effects of exposure to warpstone after a brief reunion, and Sigrid's surviving bandits will return to what is left of their lives in Wittgendorf. This leaves Sigrid with little tying her to the sullen village, and good reason to join the Characters as they depart. Especially so, in fact, if they reveal to Sigrid that this is not the first time they have opposed the terrible machinations of the Ruinous Powers. Begin with an additional [[/r 1d10]] silver shillings per secret chosen. ‘Bien sûr, j’entre la première. Ça ne peut pas être pire que le château Wittgenstein...’ Sigrid a de longs cheveux sombres, et une expression sérieuse constamment ancrée sur le visage. Mais quand elle parvient à oublier ses soucis, on devine sous ce masque l’ancienne initiée de Rhya, rêveuse et idéaliste. Ces derniers temps, elle se méfie de la plupart des gens, surtout des nobles de l’Empire, qu’elle soupçonne de prendre part à quelque complot maléfique. Elle n’accorde sa loyauté que rarement, mais une fois gagnée, elle est quasiment inébranlable. Elle est prête à tout pour protéger ceux qui comptent pour elle. Sigrid est une femme déterminée qui protège les hors-la- loi sous son commandement. Alors qu’ils attaquent souvent les patrouilles de garde, elle est contre un assaut direct sur le château, sachant pertinemment que la seule issue possible est la défaite. Elle aidera les aventuriers à atteindre le château, mais ne permettra pas à ses partisans de se risquer à une attaque, à moins que les aventuriers ne leur ouvrent la voie, par exemple, en s’infiltrant dans le château par la grotte secrète et en lançant des cordes depuis le haut des murs, ou en ouvrant les portes principales. Sigrid s’est installée à Wittgendorf, et aurait été heureuse d’y finir sa vie si les Wit- tgenstein n’avaient pas capturé son mari. Elle est très dévouée envers Brandt, pour qui elle a même quitté son ordre religieux. Elle s’est juré de lui venir en aide. Elle s’est élevée contre le château et ses habitants bien avant l’arrivée des aventuriers, et il est certain qu’elle a joué un rôle majeur dans le renversement final des Wittgenstein. Le château Wittgenstein était un endroit dangereux, et il est tout à fait possible qu’un des personnages y ait trouvé la mort. Si c’est le cas, Sigrid peut faire un excellent personnage joueur, surtout si son allégeance a été acquise avant l’attaque du château. Après de brèves retrouvailles avec son mari, celui-ci décédera à la suite de son exposition à la malepierre. Les bandits de Sigrid reprendront leur vie (ou ce qu’il en reste) à Wittgendorf. Sigrid n’a donc plus grand-chose pour la retenir dans ce village maussade, et peut tout à fait se joindre aux personnages avant leur départ. D’ailleurs, s’ils ont mentionné qu’ils s’opposent régulièrement aux terribles machinations des Puissances de la Ruine, Sigrid aura particulièrement envie de leur prêter ses forces. Commencez avec 1d10 pistoles d’argent en plus par secret choisi. Il fut un temps où Sigrund savait très bien que ses remèdes miracles ne guérissaient personne, mais ce temps est désormais révolu. Il a suffi de quelques guérisons heureuses, d’un peu de bidouillage avec ses propres concoctions et de l’éternelle crédulité d’un public désespéré de trouver du secours pour qu’il adopte le surnom de ‘Sigrund Dopplewasser, Médecin d’illustre renommée’, et qu’il ne réfère plus à sa personne d’une autre manière. Sigrund est convaincu que ses potions, baumes et autres remèdes sont vraiment efficaces, et même lorsqu’il apparaît évident que ce n’est pas du tout le cas, il trouve toujours une excuse. Peut-être que les plumes de coquelet n’ont pas été obtenues en plumant l’oiseau tout en étant tourné vers le sud, ou peut-être que les crottes de souris en poudre étaient en fait des crottes de rat ? Toujours à la recherche de nouveaux remèdes fantastiques, Sigrund a récemment fait l’acquisition d’une bouteille de la célèbre panacée du village de Wittgendorf, et il a terriblement hâte de l’essayer. Il peut être difficile de vivre en Bretonnie quand on est une jeune libre-penseuse cherchant à se faire une place dans le monde, et Simone trouve que les mœurs relativement libérales de l’Empire, en particulier celles des riverains, sont une véritable bouffée d’air frais. Certes, la plupart des habitants de l’Empire se contentent encore d’élever des porcs, mais même cela ne la répugne pas. La jeune troubadour serait presque entièrement insouciante. Mais, il y a quelques mois de cela, Simone a ‘fait l’acquisition’ d’une harpe, un magnifique instrument de bois aux cordes d’argent auprès d’un elfe distrait. Depuis elle n’a eu de cesse d’avoir l’impression qu’on l’observe depuis la rive. @UUID[Actor.VdK2FAqQTqT0Y19Q]{Crot} and his followers have been drawn to this area by the traces of warpstone that remain here. Their instincts tell them that a large piece of warpstone was here, but has been removed. They have been watching the adventurers since they arrived, and when they enter the caves, the Skaven see a chance to capture and question them. @UUID[Actor.VdK2FAqQTqT0Y19Q]{Crap} et ses compagnons sont venus dans cette région car ils ont été attirés par les résidus d’énergie de la malepierre. Leur instinct leur dit qu’un gros morceau de malepierre se trouvait là, mais qu’il n’y est plus. Ils observent les aventuriers depuis leur arrivée, et quand ceux-ci sont entrés dans les grottes, les skavens y ont vu une opportunité de les capturer et de les interroger. Because of the way they died, these skeletons are not Unstable, and can move around freely. If the Characters flee, the skeletons will follow them until they are destroyed or the Characters are dead. en raison des circonstances de leur mort, ces squelettes ne sont pas Instables, et peuvent se déplacer librement. Si les Personnages fuient, les squelettes les poursuivront jusqu’à être détruits ou jusqu’à ce que les Personnages meurent. @UUID[Actor.dEVeJ9SMkWL55IHn]{Corrobreth} has trained Skysoarer to act as a scout, flying in an indicated direction and swooping to mark the positions of any people or creatures that he sees larger than the raven himself. When not acting as a scout for Corrobreth, Skysoarer usually sits on his shoulder. @UUID[Actor.dEVeJ9SMkWL55IHn]{Corrobreth} a entraîné Graulich pour qu’il lui serve d’éclaireur : il peut voler dans une direction donnée et descendre en piqué pour indiquer la position de personnes ou de créatures plus grandes que lui. Quand il ne sert pas d’éclaireur à Corrobreth, Graulich reste généralement perché sur son épaule. All 10’ 5” of Slagdarg is bright green, with orange hairs growing out of his muscular arms. The heads of some of his previous victims hang from a large belt around his waist. He likes to keep his victims alive as long as possible but always asks the same two questions: ‘Where did you hide the money?’ and ‘Who are your accomplices?’ Regardless of what his victim may or may not have done — evading taxes or accidentally walking in front of @UUID[Actor.fmUd7AtbJckbiWo6]{Lady Margritte’s} coach — he always asks these same questions, and failing to answer is a good reason for turning the rack another notch. Slagdarg is not very bright, even for an ogre, and will think nothing of adventurers wandering around his dungeon. However, he will be alert to any ‘funny business,’ such as releasing prisoners, and will attempt to prevent it. He only got this job because the previous torturer accidentally flayed a visiting cousin of @UUID[Actor.fmUd7AtbJckbiWo6]{Lady Margritte}, so until he knows who the adventurers are, he will use violence as a last resort. Du haut de ses 3 m 20,Slagdarg est d’un vert vif parsemé de poils orange au niveau de ses bras musclés. Les têtes de quelques- unes de ses dernières victimes pendent à la grande ceinture qui lui enserre la taille. Il aime les maintenir en vie aussi longtemps que possible et leur pose toujours les deux mêmes questions : ‘Où est l’argent ? ’ et ‘ Qui sont tes complices ?’ Peu importe le crime de sa victime, que ce soit de l’évasion fiscale ou avoir marché sans faire exprès devant la calèche de @UUID[Actor.fmUd7AtbJckbiWo6]{dame Margritte}, il pose toujours ces deux questions, et ne pas y répondre justifie de faire tourner le levier du chevalet d’un cran supplémentaire. Slagdarg n’est pas très malin, même pour un ogre, et ne se posera pas de question sur la présence des aventuriers dans ses cachots. Cependant, il sentira les potentielles ‘entourloupes’, comme la libération des prisonniers, et tentera de les empêcher. Il a obtenu ce poste suite à une erreur du tortionnaire précédent, qui avait écorché un des cousins de dame Margritte, venu lui rendre visite. Tant qu’il ne saura pas qui sont les aventuriers, il n’usera de la violence qu’en dernier recours. Slurd a au moins 90 ans, mais personne ne connaît son âge exact, et lui non plus. Il a toujours été là, d’aussi loin qu’on se souvienne, et il a toujours été vieux. Slurd marche le dos voûté, si bien que son chef ridé et grisâtre pointe toujours vers le sol. Sa voix est rocailleuse et il penche toujours la tête sur le côté quand il parle. Sa main gauche a muté en serre d’oiseau, ce qui explique pourquoi il la cache dès que possible. En cas d’attaque, il tentera de griffer le visage de son adversaire. Slurd est sénile et se contente de répéter quelques actions simples. Il n’est pas une source sûre puisqu’il ne fait que répéter les paroles et les gestes imposés par son poste de majordome, encore et encore, sans réellement en comprendre le sens. Le petit bateau de pêche de Sofia, le Six pieds sous l’onde, est à la fois un rêve d’enfant devenu réalité, l’opportunité de gagner sa vie grâce à la rivière, et un témoignage de sa méconnaissance du fonctionnement des prêts à intérêts. Même si la vie de pêcheuse qu’elle mène sur les eaux du Reik s’est avérée aussi passionnante qu’elle l’avait imaginée, il n’y a tout simplement pas assez de truites dans le Reik pour rembourser sa dette grandissante. Si Sofia ne ferre pas rapidement une prise de valeur, une bonne prise de rougets barbus, par exemple, elle peut être certaine de perdre son bateau, ou même sa tête. Sorte de vilain petit canard de sa famille, Sophie est issue de l’illustre (et excessivement riche) famille van Haagen, l’une des dix maisons décisionnaires de Marienburg et l’une des principales puissances de Bögenhafen. Cependant, Sophie considère que l’accent mis par sa famille sur les produits de luxe standard est contraire à son propre esprit d’entreprise, c’est pourquoi elle s’est lancée sur les routes de l’Empire à la recherche de produits réellement exotiques. Bien sûr, ils ont tendance à être fournis par les pires personnes, mais cela ne semble pas déranger Sophie. @UUID[Actor.J2cgcgVT1mCOPKaQ]{Harold} et Stefan, quand ils ne sont pas occupés à récurer les casseroles dans les cuisines du @UUID[JournalEntry.w5rvSKCXvivjnTVU.JournalEntryPage.PTqp6A7lC9v8x7uu]{Col du Cygne}, prennent un malin plaisir à botter les fesses des ivrognes, des profiteurs, des fauteurs de troubles, des troubadours et des mimes. Leur taille et leur réputation leur permettent d’éviter la plupart des problèmes, mais on peut toujours compter sur eux pour se jeter corps et âme dans n’importe quelle situation impliquant la boisson. Une équipe d’une douzaine de serveurs fait la navette entre les cuisines, prend les commandes et veille au confort et à la satisfaction des passagers. Although the mottled, grey-green Stirpike has almost been wiped out in Stirland, it is still found in some lakes and rivers elsewhere in the Empire. It is one of the largest freshwater predators in the Old World, capable of reaching lengths of some 20 feet and weights in excess of 4,000 pounds. It eats anything foolish enough to cross its path, but its primary diet is a mixture of fish, eels, and leeches. Immature Stirpikes, called Pickerels, are believed to have various medicinal qualities, and are much sought after. Bien que le ‘brochet du Stir’ tacheté de gris et de vert, ait presque disparu du Stirland, on le trouve encore dans certains lacs et rivières ailleurs dans l’Empire. C’est l’un des plus grands prédateurs d’eau douce du Vieux Monde, capable d’atteindre une longueur de 6 mètres et un poids de plus de 1,8 tonne. Il dévore tous les êtres assez inconscients pour croiser son chemin, mais se nourrit principalement d’un mélange de poissons, d’anguilles et de sangsues. Les jeunes brochets du Stir, appelés brochetons, sont réputés pour leurs qualités médicinales et sont donc très recherchés. ‘Faites une autre arme à feu’, qu'ils disent. ‘C’est toujours utile, les armes à feu.’ La Guilde des ingénieurs de Middenheim, n’ayant accès à aucune étendue d’eau, ne s’est jamais montrée très enthousiasmée par les plans de bateaux de Sven. Qu’importe si le mécanisme de propulsion était astucieux, ou qu’il avait réalisé des calculs de flottabilité très précis, qu’importe la vitesse maximale supposée du bateau, la Cité a toujours refusé de lui accorder les fonds nécessaires. Sven est donc parti pour le Reikland où, au moins, on sait apprécier un bon bateau. Si seulement son prototype d’hydrofreins avait survécu au voyage... Rightly or wrongly, the Empire’s population of mutants are shunned from society. While some simply seek to hide themselves away, many turn to violence — either to survive, or to punish the society that abandoned them. À tort ou à raison, la population de mutants de l’Empire est mise au ban de la société. Si certains cherchent simplement à se cacher, beaucoup se tournent vers la violence, soit pour survivre, soit pour punir la société qui les a abandonnés. These unfortunates have suffered terribly under the experiments arranged by @UUID[Actor.fmUd7AtbJckbiWo6]{Lady Margritte} and administered by @UUID[Actor.vgazeY44kVGP4tmW]{Jean Rousseaux}. Each Beggar already has 4 Corruption points, and you should make one or two rolls on the @Table[mutatephys]{table} to determine what mutations they bear. Even brief physical contact counts as a @Corruption[minor]{Minor Exposure to Corruption}. Ces malheureux ont terriblement souffert des expériences menées par @UUID[Actor.fmUd7AtbJckbiWo6]{dame Margritte} et administrés par @UUID[Actor.vgazeY44kVGP4tmW]{Jean Rousseaux}. Chaque mendiant possède déjà 4 points de Corruption, et vous êtes invité à leur attribuer une ou deux mutations à déterminer en effectuant un ou deux lancers en vous basant sur le tableau @Table[mutatephys]{de Corruption physique}. Même un bref contact physique compte comme une @Corruption[minor]{Exposition Mineure à la Corruption}. Carrion are seldom seen in the Old World, although some accompanied the armies of Nekehara in their ancient campaigns of conquest and a few can be found in the remoter parts of the Worlds Edge Mountains. These great undead birds are powerful fighters, even though they are too small to carry a human-sized rider. Les charognards sont rares dans le Vieux Monde, bien qu’il y en ait eu quelques-uns qui accompagnèrent les armées de Néhékhara dans leurs campagnes de conquête, il y a fort longtemps, et qu’on peut parfois en apercevoir dans les régions les plus reculées des Montagnes du Bord du Monde. Ces grands oiseaux morts-vivants sont de redoutables combattants, mais ils sont trop petits pour être chevauchés par une créature de la taille d’un humain. The monster stands 8 ft tall, and its body is a patchwork of scars. It has dead-white skin with green discolouration on the cheeks and lower jaw. Le monstre, quant à lui, mesure près de deux mètres cinquante et son corps est un patchwork de cicatrices. Sa peau, d’un blanc cadavérique, est décolorée en taches vertes sur les joues ainsi que sur la partie inférieure de sa mâchoire. Ce Wastelander rusé vit pour se quereller, et il est très doué pour cela. Il n’y a rien de mieux pour terminer sa soirée qu’aborder avec un étranger la question de la législation sur l’arbalète à Altdorf ou les implications de la déclaration de l’Empereur selon laquelle les mutants ne doivent pas être mis au bûcher. Ce qui est véritablement agaçant, c’est qu’il peut débattre avec n’importe quel point de vue. Il lui arrive même de changer de camp en plein milieu de la discussion, sans jamais admettre que ses propos ont alterné et en argumentant de façon si experte que personne ne pourra le prouver. Pour faire simple, il est insupportable. Ostend est l’un des affréteurs locaux des Blucher. @UUID[Actor.q7DYHbjxedEeX2WN]{Max} lui a demandé de garder un œil sur les aventuriers et de lui rapporter à qui ils parlent et ce qu’ils demandent. Il se présentera à Max sur les quais tôt le lendemain matin. Les autres marchands de l’auberge savent qu’il est proche des Blucher, alors ils lui parlent, même si peu d’entre eux l’apprécient. Plus tard, il sera aperçu en train de se disputer violemment avec @UUID[Actor.AUpwf9ZR5IMVgyHm]{Ruairi Roddy}. Ulfhednar leads a band of mutants and Beastmen in the Great Forest. Having heard of the family’s reputation, he has journeyed to @UUID[JournalEntry.musGjY0nSDY6gPY4.JournalEntryPage.idS4ciy1UHxTFFfU]{Castle Wittgenstein} to gain @UUID[Actor.ySbdLyidudlMwGhU]{Lady Ingrid’s} support. Ulfhednar hopes to use the castle as a training ground for Chaos troops, and as a base from which his forces could strike at the Empire’s heartlands. So far, Lady Ingrid has not shown much interest in his scheme, but if she were removed, Ulfhednar thinks @UUID[Actor.fmUd7AtbJckbiWo6]{Lady Margritte} may be more amenable. A follower of Tzeentch, Ulfhednar does not understand why a castle full of mutants would not willingly join his cause. Ulfhednar est à la tête d’une bande de mutants et d’hommes- bêtes dans la Grande Forêt. Ayant eu vent de la réputation de la famille Wittgenstein, il a voyagé jusqu’au @UUID[JournalEntry.musGjY0nSDY6gPY4.JournalEntryPage.idS4ciy1UHxTFFfU]{château Wittgenstein} pour obtenir le soutien de @UUID[Actor.ySbdLyidudlMwGhU]{dame Ingrid}. Ulfhednar espère faire de ce lieu un terrain d’entraînement pour des armées du Chaos et de s’en servir comme une base pour permettre à ses forces de frapper le cœur de l’Empire. Pour l’instant, dame Ingrid n’a pas montré de signe d’intérêt pour ce plan, mais si elle venait à passer le flambeau, Ulfhednar pense que @UUID[Actor.fmUd7AtbJckbiWo6]{dame Margritte} serait davantage disposée à l’écouter. En tant que fidèle de Tzeentch, Ulfhednar ne comprend pas pourquoi un château rempli de mutants refuserait de rejoindre sa cause. UeUwe et ses amis ne se lassent jamais de ‘cabrioler’, selon leur expression, sur les voies fluviales de l’Empire. Cette pratique consiste à piloter un bateau de course, rapide et onéreux, de manière à frôler les embarcations plus petites pour les faire dangereusement vaciller sur l’eau, faisant ainsi basculer par- dessus bord les passagers peu méfiants. À la fin de la nuit, celui qui a fait tomber le plus de victimes à l’eau est déclaré vainqueur. Uwe ne se rend vraiment pas compte des désagréments que ces ‘cabrioles’ causent aux riverains, il pense honnêtement que ‘’est juste pour rire, mon vieux !’. Malgré son attitude bravache, Uwe s’est récemment trouvé ébranlé par sa rencontre avec une certaine @UUID[Actor.wXB3Bam0z0kp45Ht]{Etelka Herzen}; cette femme avait quelque chose de perturbant, et depuis ce jour, les jeux que ses camarades nobles affectionnent tant ne lui ont plus paru aussi insouciants... Vorster est doyen depuis 12 ans, il est aimé et respecté de tout le @UUID[JournalEntry.VbIsVjYK2ttpvkG2.JournalEntryPage.YMz2qRfYwqkfavWD]{village}. C’est un homme gentil et sympathique qui adore recevoir des invités. Il fait beaucoup d’efforts pour garantir leur confort, mais toujours de telle manière que son attitude paraisse naturelle et non forcée. Wilgryn a vécu toute sa vie sur la rivière ; ce n’est pas une exagération de dire que ses semelles ont plus souvent connu le bois d’un pont de bateau que la terre ferme. Il fit une brève pause dans sa carrière de patrouilleur fluvial pour poursuivre son rêve de devenir marchand, mais quand une entreprise de commerce rivale brûla sa péniche dans le but d’évincer la concurrence, Wilgryn se trouva ramené de force à la vie qu’il avait presque laissée derrière lui. Ce qu’il fit cette nuit-là à Kemperbad donna naissance à une véritable légende, dont l’histoire ne fait que gagner en extravagance avec chaque nouvelle génération de recrues. Aujourd’hui, Wilgryn est un maître abordeur chevronné et respecté de tous, avec sous son commandement une petite flotte de bateaux de patrouille. Il voit d’un très mauvais œil les pratiques commerciales douteuses, et on raconte que plus d’un extorqueur serait « tombé » par- dessus bord pour être jugé directement par Grand-père Reik. Rightly or wrongly, the Empire’s population of mutants are shunned from society. While some simply seek to hide themselves away, many turn to violence — either to survive, or to punish the society that abandoned them. À tort ou à raison, la population de mutants de l’Empire est mise au ban de la société. Si certains cherchent simplement à se cacher, beaucoup se tournent vers la violence, soit pour survivre, soit pour punir la société qui les a abandonnés. Apparence: jeune, athlétique, magnifiquement habillé. Personnalité:fougueux, irresponsable, bruyant. Motivations:: s’amuser, faire des blagues, embarrasser les autres. Exemple de dialogue: ‘Je vous le dis, mes amis ! C’est tout à fait splendide ! Quel amusement !’ et ‘Certaines personnes n’ont vraiment aucun sens de l’humour. Quel ennui’. ${this.actor.prototypeToken.name} has
+ Le sang du flagellant est celui de Sigmar
\nLes attaquants du bateau
\nThe Skaven
\nCrot Scaback – Skaven Champion
\nThe Skaven
\nCrap Raüdig – Champion Skaven
\nCuisinière d'Etelka
Prospecteur Nain Blessé
\nPremier pilote Ella Vertvallon
\nThe Boat Attackers
\nLes attaquants du Bateau
\nChameleoleeches
Tree Leeches
Sangsues-Caméléons
Sangsues Des arbres
"
},
"Gurda": {
"name": "Gurda",
- "description": ""
+ "description": "",
+ "gmNotes": ""
},
"Gutbag Stoat Throttler": {
- "name": "Gutbag Stoat Throttler",
- "description": "Goblin Leader
\nChef des Gobelins
\nMaître d’équipage Hans Sauber
\n
"
},
"Large Barge": {
- "name": "Large Barge"
+ "name": "Grande Barge"
},
"Lashworm": {
- "name": "Lashworm",
- "description": "La Grande Expérience
Chef cuisinier Maximillian
\nLes attaquants du Bateau
\nCapitaine Regina Willendorf
Second pilote Reiner Petersen
\n
"
},
"Shadow The Cat": {
- "name": "Shadow The Cat",
- "description": "Personality and Appearance
\nBackground
\nSecrets
\n\n
"
+ "description": "Apparence et personnalité
\nHistorique
\nSecrets
\n\n
",
+ "gmNotes": ""
},
"Sigrund Dopplewasser": {
"name": "Sigrund Dopplewasser",
- "description": ""
+ "description": "",
+ "gmNotes": "The Skaven
\nLes skavens
\nThe Boat Attackers
\nLes attaquants du Bateau
\nThe Boat Attackers
\nLes attaquants du Bateau
\n
+
+ It’s up to Ranald if their regenerating can outpace their poisoning.
When all Poisoned Conditions are lost, so too is Regenerate.
`, + { whisper: ChatMessage.getWhisperRecipients("GM"), blind: true }) diff --git a/scripts/04bAiHISSW53w94Y.js b/scripts/04bAiHISSW53w94Y.js new file mode 100644 index 0000000..2909e9f --- /dev/null +++ b/scripts/04bAiHISSW53w94Y.js @@ -0,0 +1 @@ +this.actor.addCondition("blinded", 3) \ No newline at end of file diff --git a/scripts/06IaVCOC0RCJbxEf.js b/scripts/06IaVCOC0RCJbxEf.js new file mode 100644 index 0000000..b2f49cb --- /dev/null +++ b/scripts/06IaVCOC0RCJbxEf.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.8piWcBKFlQ2J1E3A") +let data = item.toObject(); +data.system.location.key= this.item.system.location.key +this.actor.createEmbeddedDocuments("Item", [data]) \ No newline at end of file diff --git a/scripts/09sSpnW8z2zcVEdf.js b/scripts/09sSpnW8z2zcVEdf.js new file mode 100644 index 0000000..7079a3c --- /dev/null +++ b/scripts/09sSpnW8z2zcVEdf.js @@ -0,0 +1,5 @@ +if (!args.flags.quietenedApplied) +{ + args.fields.modifier += 10; + args.flags.quietenedApplied = true +} \ No newline at end of file diff --git a/scripts/0BP5l7bIkf744G1k.js b/scripts/0BP5l7bIkf744G1k.js new file mode 100644 index 0000000..22f117a --- /dev/null +++ b/scripts/0BP5l7bIkf744G1k.js @@ -0,0 +1 @@ +return !args.options.terror && !args.extendedTest?.flags.wfrp4e?.fear \ No newline at end of file diff --git a/scripts/0FNOq4J1AdPd2A0q.js b/scripts/0FNOq4J1AdPd2A0q.js new file mode 100644 index 0000000..ed69d87 --- /dev/null +++ b/scripts/0FNOq4J1AdPd2A0q.js @@ -0,0 +1 @@ +return !args.skill?.name.includes(game.i18n.localize("NAME.Row")) && !args.skill?.name.includes(game.i18n.localize("NAME.Sail")); \ No newline at end of file diff --git a/scripts/0FWto1oEr3jbWggw.js b/scripts/0FWto1oEr3jbWggw.js new file mode 100644 index 0000000..725afc8 --- /dev/null +++ b/scripts/0FWto1oEr3jbWggw.js @@ -0,0 +1,22 @@ +let spells = await game.wfrp4e.utility.findAll("spell", "Chargement des sorts") + +let text = (await game.wfrp4e.tables.rollTable("random-caster", {hideDSN: true})).result + +lore = Array.from(text.matchAll(/{(.+?)}/gm))[0][1] + +if (text == "GM's Choice") +{ + return this.script.scriptNotification(text) +} + +if (spellsWithLore.length > 0) +{ + let spellsWithLore = spells.filter(i => game.wfrp4e.config.magicLores[i.system.lore.value] == lore) + let selectedSpell = spellsWithLore[Math.floor(CONFIG.Dice.randomUniform() * spellsWithLore.length)] + this.script.scriptNotification(selectedSpell.name); + this.actor.createEmbeddedDocuments("Item", [selectedSpell]) +} +else +{ + ui.notifications.notify(`Impossible de trouver le sort ${lore}. Essayez à nouveau`) +} \ No newline at end of file diff --git a/scripts/0KG3HoTNoZhaINIj.js b/scripts/0KG3HoTNoZhaINIj.js new file mode 100644 index 0000000..195442f --- /dev/null +++ b/scripts/0KG3HoTNoZhaINIj.js @@ -0,0 +1,6 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.4CMKeDTDrRQZbPIJ") +let fixation = (await game.wfrp4e.tables.rollTable("fixations")) +let data = item.toObject(); +data.system.specification.value = fixation.result; +this.item.updateSource({name : this.item.name += ` (${fixation.result})`}); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/0LCQtsiK2aUfYRmD.js b/scripts/0LCQtsiK2aUfYRmD.js new file mode 100644 index 0000000..8bdb4ef --- /dev/null +++ b/scripts/0LCQtsiK2aUfYRmD.js @@ -0,0 +1 @@ +return !["t", "wp"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/0R0QAr3D024kWPfo.js b/scripts/0R0QAr3D024kWPfo.js new file mode 100644 index 0000000..ee3ed07 --- /dev/null +++ b/scripts/0R0QAr3D024kWPfo.js @@ -0,0 +1,18 @@ +let table = game.wfrp4e.tables.findTable("mutatephys"); +if (!table) +{ + return ui.notifications.error("La table des Mutations n'a pas été trouvée. Assurez vous que la table avec la clé `mutatephys` est bien importée dans le monde.") +} +let result = (await table.roll()).results[0]; +let uuid = `Compendium.${result.documentCollection}.${result.documentId}` +let item = await fromUuid(uuid); + +if (item) +{ + this.script.scriptNotification(`${item.name} added`) + this.actor.createEmbeddedDocuments("Item", [item]) +} +else +{ + ui.notifications.error("L'item ne peut être trouvé: " + uuid) +} \ No newline at end of file diff --git a/scripts/0Uly7OmkH0zqYbxQ.js b/scripts/0Uly7OmkH0zqYbxQ.js new file mode 100644 index 0000000..70ed1ac --- /dev/null +++ b/scripts/0Uly7OmkH0zqYbxQ.js @@ -0,0 +1,21 @@ +let location = this.item.system.location.key; + +if (location) +{ + let dropped = this.item.system.weaponsAtLocation; + + if (dropped.length) + { + this.script.scriptNotification(`Lache ${dropped.map(i => i.name).join(", ")}!`) + for(let weapon of dropped) + { + await weapon.system.toggleEquip(); + } + } +} + +let roll = await new Roll("max(1, 1d10 - @system.characteristics.t.bonus)", this.actor).roll() + +roll.toMessage(this.script.getChatData({flavor : `${this.effect.name} (Durée)`})); + +this.effect.updateSource({"duration.rounds" : roll.total}) \ No newline at end of file diff --git a/scripts/0YKQGbsKdHSmYGE7.js b/scripts/0YKQGbsKdHSmYGE7.js new file mode 100644 index 0000000..bb5ad3c --- /dev/null +++ b/scripts/0YKQGbsKdHSmYGE7.js @@ -0,0 +1,9 @@ +if (args.skill?.name != game.i18n.localize("NAME.Gossip")) +{ + return true; +} +else +{ + args.data.canReverse = true; // Kind of a kludge here, the talent Tests has a specific condition, but the description simply says "any gossip test can be reversed" so check it here instead of submission +} + \ No newline at end of file diff --git a/scripts/0abwNjpzo3SbEOeO.js b/scripts/0abwNjpzo3SbEOeO.js new file mode 100644 index 0000000..3e7463b --- /dev/null +++ b/scripts/0abwNjpzo3SbEOeO.js @@ -0,0 +1,6 @@ +if (args.applyAP && args.modifiers.ap.metal) +{ + args.modifiers.ap.ignored += args.modifiers.ap.metal + args.modifiers.ap.details.push("" + this.effect.name + ": Ignore le Métal (" + args.modifiers.ap.metal + ")"); + args.modifiers.ap.metal = 0 +} \ No newline at end of file diff --git a/scripts/0e0UZT2FodOJDdgW.js b/scripts/0e0UZT2FodOJDdgW.js new file mode 100644 index 0000000..b4db0a3 --- /dev/null +++ b/scripts/0e0UZT2FodOJDdgW.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.GbDyBCu8ZjDp6dkj") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/0e7OkamNAaAk4Oit.js b/scripts/0e7OkamNAaAk4Oit.js new file mode 100644 index 0000000..60cb5c0 --- /dev/null +++ b/scripts/0e7OkamNAaAk4Oit.js @@ -0,0 +1,10 @@ +let item1 = await fromUuid("Compendium.wfrp4e-core.items.3S4OYOZLauXctmev") +let item2 = await fromUuid("Compendium.wfrp4e-core.items.7mCcI3q7hgWcmbBU") + +let data1 = item1.toObject(); +data1.system.location.key = this.item.system.location.key + +let data2 = item2.toObject(); +data2.system.location.key = this.item.system.location.key + +this.actor.createEmbeddedDocuments("Item", [data1, data2], {fromEffect: this.effect.id}) diff --git a/scripts/0iTLDgFHO9Rgc010.js b/scripts/0iTLDgFHO9Rgc010.js new file mode 100644 index 0000000..5d34264 --- /dev/null +++ b/scripts/0iTLDgFHO9Rgc010.js @@ -0,0 +1 @@ +args.fields.modifier -= 20; \ No newline at end of file diff --git a/scripts/0mrUnxzufYgsR0Ph.js b/scripts/0mrUnxzufYgsR0Ph.js new file mode 100644 index 0000000..2c22c29 --- /dev/null +++ b/scripts/0mrUnxzufYgsR0Ph.js @@ -0,0 +1,7 @@ +this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}).then(async test => { + await test.roll() + if (test.failed) + { + this.actor.addCondition("stunned") + } +}) diff --git a/scripts/0vaYwAlMWTmOBl8k.js b/scripts/0vaYwAlMWTmOBl8k.js new file mode 100644 index 0000000..002e76f --- /dev/null +++ b/scripts/0vaYwAlMWTmOBl8k.js @@ -0,0 +1,7 @@ +if (!args.flags.strikeToStun) +{ + args.flags.strikeToStun = true + args.fields.modifier += 20; + args.fields.hitLocation = "head"; +} +args.fields.successBonus++; \ No newline at end of file diff --git a/scripts/0yyofYHeDRQlFliO.js b/scripts/0yyofYHeDRQlFliO.js new file mode 100644 index 0000000..dda0e0e --- /dev/null +++ b/scripts/0yyofYHeDRQlFliO.js @@ -0,0 +1 @@ +return args.options.terror || args.extendedTest?.flags.wfrp4e?.fear \ No newline at end of file diff --git a/scripts/11uCC0mK2uL783al.js b/scripts/11uCC0mK2uL783al.js new file mode 100644 index 0000000..100b843 --- /dev/null +++ b/scripts/11uCC0mK2uL783al.js @@ -0,0 +1,6 @@ +let type = this.item.getFlag("wfrp4e", "breath"); + +if (["fire", "electricity", "poison"].includes(type)) +{ + args.applyAP = false; +} \ No newline at end of file diff --git a/scripts/16nCOByUaSFDym1V.js b/scripts/16nCOByUaSFDym1V.js new file mode 100644 index 0000000..7d16a24 --- /dev/null +++ b/scripts/16nCOByUaSFDym1V.js @@ -0,0 +1 @@ +args.fields.modifier -= 20 diff --git a/scripts/190PHSHKGaJ74wsR.js b/scripts/190PHSHKGaJ74wsR.js new file mode 100644 index 0000000..dd52e55 --- /dev/null +++ b/scripts/190PHSHKGaJ74wsR.js @@ -0,0 +1,31 @@ +if (!this.item.name.includes("(") || this.item.system.tests.value.includes("Terrain")) +{ + let tests = this.item.system.tests.value + let name = this.item.name + + // If name already specifies, make sure tests value reflects that + if (name.includes("(")) + { + let terrain = name.split("(")[1].split(")")[0] + tests = tests.replace("the Terrain", terrain) + } + else // If no sense specified, provide dialog choice + { + let choice = await ItemDialog.create(ItemDialog.objectToArray({ + coastal : "Coastal", + deserts : "Deserts", + marshes : "Marshes", + rocky : "Rocky", + tundra : "Tundra", + woodlands : "Woodlands" + }, this.item.img), 1, "Choose Terrain"); + if (choice[0]) + { + name = `${name.split("(")[0].trim()} (${choice[0].name})` + tests = tests.replace("the Terrain", choice[0].name + " Terrain") + } + } + + this.effect.updateSource({name}) + this.item.updateSource({name, "system.tests.value" : tests}) +} \ No newline at end of file diff --git a/scripts/1A87vGLh2PXH0rG0.js b/scripts/1A87vGLh2PXH0rG0.js new file mode 100644 index 0000000..8a4090c --- /dev/null +++ b/scripts/1A87vGLh2PXH0rG0.js @@ -0,0 +1 @@ +return !args.skill?.name.includes(game.i18n.localize("NAME.Language")); \ No newline at end of file diff --git a/scripts/1BT0MWM2cbhlEnrn.js b/scripts/1BT0MWM2cbhlEnrn.js new file mode 100644 index 0000000..46f9433 --- /dev/null +++ b/scripts/1BT0MWM2cbhlEnrn.js @@ -0,0 +1,40 @@ + let characteristics = { + "ws" : 5, + "bs" : 5, + "s" : 5, + "t" : 0, + "i" : 5, + "ag" : 5, + "dex" : 5, + "int" : 0, + "wp" : 5, + "fel" : 5 + } + let items = [] + + let updateObj = this.actor.toObject(); + + let talents = (await Promise.all([game.wfrp4e.tables.rollTable("talents"), game.wfrp4e.tables.rollTable("talents"), game.wfrp4e.tables.rollTable("talents")])).map(i => i.text) + + for (let ch in characteristics) + { + updateObj.system.characteristics[ch].modifier += characteristics[ch]; + } + + for (let talent of talents) + { + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } + } + + + await this.actor.update(updateObj) + this.actor.createEmbeddedDocuments("Item", items); + diff --git a/scripts/1E47r2ba6IGe8uFK.js b/scripts/1E47r2ba6IGe8uFK.js new file mode 100644 index 0000000..f6a8c61 --- /dev/null +++ b/scripts/1E47r2ba6IGe8uFK.js @@ -0,0 +1 @@ +return args.characteristic != "t" \ No newline at end of file diff --git a/scripts/1IodsW9ImamYoEYz.js b/scripts/1IodsW9ImamYoEYz.js new file mode 100644 index 0000000..b72334a --- /dev/null +++ b/scripts/1IodsW9ImamYoEYz.js @@ -0,0 +1 @@ +args.actor.details.move.run += 4 \ No newline at end of file diff --git a/scripts/1JwxZujbDcueLWBL.js b/scripts/1JwxZujbDcueLWBL.js new file mode 100644 index 0000000..133c071 --- /dev/null +++ b/scripts/1JwxZujbDcueLWBL.js @@ -0,0 +1,2 @@ +await this.actor.addCondition("ablaze", 2) +await this.script.scriptMessage(await this.actor.applyBasicDamage(this.effect.sourceTest.result.damage, {suppressMsg: true})) \ No newline at end of file diff --git a/scripts/1LDm3OB32skZe6Xv.js b/scripts/1LDm3OB32skZe6Xv.js new file mode 100644 index 0000000..f504f6b --- /dev/null +++ b/scripts/1LDm3OB32skZe6Xv.js @@ -0,0 +1 @@ +return args.characteristic != "wp" \ No newline at end of file diff --git a/scripts/1MDOKny7IirJPoI6.js b/scripts/1MDOKny7IirJPoI6.js new file mode 100644 index 0000000..0826c2c --- /dev/null +++ b/scripts/1MDOKny7IirJPoI6.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` ${this.effect.name}`}) +await test.roll() +if (test.succeeded) +{ + this.effect.delete(); +} diff --git a/scripts/1OpT3CXs07XFWWCT.js b/scripts/1OpT3CXs07XFWWCT.js new file mode 100644 index 0000000..4e10bbf --- /dev/null +++ b/scripts/1OpT3CXs07XFWWCT.js @@ -0,0 +1 @@ +args.options.cardsharp = true; \ No newline at end of file diff --git a/scripts/1PQPxFjmRlulHHzo.js b/scripts/1PQPxFjmRlulHHzo.js new file mode 100644 index 0000000..b3f0001 --- /dev/null +++ b/scripts/1PQPxFjmRlulHHzo.js @@ -0,0 +1,5 @@ +if (args.opposedTest.result.hitloc.value == this.item.system.location.key && args.totalWoundLoss > 0) +{ + args.actor.addCondition("bleeding", 2); +} + \ No newline at end of file diff --git a/scripts/1UalUmNzjB4rp3SZ.js b/scripts/1UalUmNzjB4rp3SZ.js new file mode 100644 index 0000000..c76dee9 --- /dev/null +++ b/scripts/1UalUmNzjB4rp3SZ.js @@ -0,0 +1 @@ +return ["ws", "bs", "s", "ag", "t", "dex"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/1ZArMNUI8qqH6zkX.js b/scripts/1ZArMNUI8qqH6zkX.js new file mode 100644 index 0000000..8bee756 --- /dev/null +++ b/scripts/1ZArMNUI8qqH6zkX.js @@ -0,0 +1,7 @@ +let test = await args.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : " - " + this.effect.name, context : {failure: "Gain d'un état Assomé"}}) +await test.roll(); +if (test.failed) +{ + args.actor.addCondition("stunned") +} + diff --git a/scripts/1ZrzpfVwPJHdwp23.js b/scripts/1ZrzpfVwPJHdwp23.js new file mode 100644 index 0000000..31f227d --- /dev/null +++ b/scripts/1ZrzpfVwPJHdwp23.js @@ -0,0 +1 @@ +this.actor.status.addArmour(1, {source: this.effect, magical : true}) \ No newline at end of file diff --git a/scripts/1exiWlVUHsXDLLAH.js b/scripts/1exiWlVUHsXDLLAH.js new file mode 100644 index 0000000..5a275f6 --- /dev/null +++ b/scripts/1exiWlVUHsXDLLAH.js @@ -0,0 +1 @@ +this.script.scriptNotification(`Ne peut saisir ${this.effect.name}!`); \ No newline at end of file diff --git a/scripts/1fQr1Dg7DX0vfz3r.js b/scripts/1fQr1Dg7DX0vfz3r.js new file mode 100644 index 0000000..206a4f6 --- /dev/null +++ b/scripts/1fQr1Dg7DX0vfz3r.js @@ -0,0 +1,3 @@ +let healed = parseInt(this.effect.sourceTest.result.SL) +this.actor.modifyWounds(healed) +this.script.scriptMessage(`Soins de ${healed} Blessures`) \ No newline at end of file diff --git a/scripts/1kB2su7hLRYDhZ2H.js b/scripts/1kB2su7hLRYDhZ2H.js new file mode 100644 index 0000000..61a4ede --- /dev/null +++ b/scripts/1kB2su7hLRYDhZ2H.js @@ -0,0 +1,19 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : " - " + this.effect.name}) +await test.roll(); +if (!test.succeeded) +{ + let item = await fromUuid("Compendium.wfrp4e-core.items.ZhMADOqoo0y8Q9bx") + let data = item.toObject(); + if (this.item.system.location.key == "rLeg") + { + data.system.location.value = "Pied droit" + data.system.location.key = "rToe"; + } + else if (this.item.system.location.key == "lLeg") + { + data.system.location.value = "Pied gauche" + data.system.location.key = "lToe"; + } + this.actor.createEmbeddedDocuments("Item", [data]) +} +this.effect.delete(); \ No newline at end of file diff --git a/scripts/1l7Jz2ZHbAWko7Vm.js b/scripts/1l7Jz2ZHbAWko7Vm.js new file mode 100644 index 0000000..ac7048c --- /dev/null +++ b/scripts/1l7Jz2ZHbAWko7Vm.js @@ -0,0 +1 @@ +args.options.ballockKnife = true; \ No newline at end of file diff --git a/scripts/1mNkLj9JYNr3ofC6.js b/scripts/1mNkLj9JYNr3ofC6.js new file mode 100644 index 0000000..d64facd --- /dev/null +++ b/scripts/1mNkLj9JYNr3ofC6.js @@ -0,0 +1,7 @@ +this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}).then(async test => { + await test.roll(); + if (test.failed) + { + this.actor.addCondition("stunned", 3) + } +}) \ No newline at end of file diff --git a/scripts/1wEjrgff7ASxKVmy.js b/scripts/1wEjrgff7ASxKVmy.js new file mode 100644 index 0000000..ab9e51b --- /dev/null +++ b/scripts/1wEjrgff7ASxKVmy.js @@ -0,0 +1,2 @@ +if (args.effect.conditionId == "bleeding") + args.data.damage -= 1 \ No newline at end of file diff --git a/scripts/1wKVvxRTHOyV4Qdv.js b/scripts/1wKVvxRTHOyV4Qdv.js new file mode 100644 index 0000000..2ea9f2a --- /dev/null +++ b/scripts/1wKVvxRTHOyV4Qdv.js @@ -0,0 +1 @@ +return !args.skill?.name?.includes(game.i18n.localize("NAME.Sail")) \ No newline at end of file diff --git a/scripts/1wrPvP6lJwIAfmsl.js b/scripts/1wrPvP6lJwIAfmsl.js new file mode 100644 index 0000000..9e40d5a --- /dev/null +++ b/scripts/1wrPvP6lJwIAfmsl.js @@ -0,0 +1,10 @@ +let choice = await ItemDialog.create(ItemDialog.objectToArray(game.wfrp4e.config.locations), 1, "Choisir une localisation"); + +let location = choice[0].id; + +let itemTargeted = this.actor.items.get(this.effect.getFlag("wfrp4e", "itemTargets")[0]) + +if (itemTargeted) +{ + itemTargeted.update({[`system.APdamage.${location}`] : itemTargeted.system.APdamage[location] + 1}) +} \ No newline at end of file diff --git a/scripts/1yOvw74jzFfaI87b.js b/scripts/1yOvw74jzFfaI87b.js new file mode 100644 index 0000000..73649e3 --- /dev/null +++ b/scripts/1yOvw74jzFfaI87b.js @@ -0,0 +1 @@ +return args.options.reload diff --git a/scripts/22bW97lkvCqisfHX.js b/scripts/22bW97lkvCqisfHX.js new file mode 100644 index 0000000..5ab83db --- /dev/null +++ b/scripts/22bW97lkvCqisfHX.js @@ -0,0 +1 @@ +return args.type != "channelling" && !args.skill?.name.includes(game.i18n.localize("NAME.Channelling")) \ No newline at end of file diff --git a/scripts/23HgjCB1oecxANvA.js b/scripts/23HgjCB1oecxANvA.js new file mode 100644 index 0000000..275f379 --- /dev/null +++ b/scripts/23HgjCB1oecxANvA.js @@ -0,0 +1,5 @@ +if (args.item.range && args.item.range.bands) +{ +args.item.range.bands[game.i18n.localize("Long Range")].modifier = 0 +args.item.range.bands[game.i18n.localize("Extreme")].modifier /= 2 +} \ No newline at end of file diff --git a/scripts/23vWiHUjxtRQ3Efz.js b/scripts/23vWiHUjxtRQ3Efz.js new file mode 100644 index 0000000..5fdc693 --- /dev/null +++ b/scripts/23vWiHUjxtRQ3Efz.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.eWPN3CV2Eddwz8aM") +let data = item.toObject(); +data.system.location.value = "Back" +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/2AOo7KUyzMrgIlgM.js b/scripts/2AOo7KUyzMrgIlgM.js new file mode 100644 index 0000000..2982f22 --- /dev/null +++ b/scripts/2AOo7KUyzMrgIlgM.js @@ -0,0 +1 @@ +game.wfrp4e.utility.postCorruptionTest(this.item.system.specification.value, {speaker : {alias: this.actor.prototypeToken.name}}) \ No newline at end of file diff --git a/scripts/2AdSBXw7IwCiqawQ.js b/scripts/2AdSBXw7IwCiqawQ.js new file mode 100644 index 0000000..00a7def --- /dev/null +++ b/scripts/2AdSBXw7IwCiqawQ.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.Bribery") || args.skill?.name.includes(game.i18n.localize("NAME.Stealth")); \ No newline at end of file diff --git a/scripts/2Cw5j0iGAnFNegWr.js b/scripts/2Cw5j0iGAnFNegWr.js new file mode 100644 index 0000000..4712207 --- /dev/null +++ b/scripts/2Cw5j0iGAnFNegWr.js @@ -0,0 +1 @@ +return args.item?.system.attackType diff --git a/scripts/2GYAd4OC888oQFBp.js b/scripts/2GYAd4OC888oQFBp.js new file mode 100644 index 0000000..5150b7b --- /dev/null +++ b/scripts/2GYAd4OC888oQFBp.js @@ -0,0 +1 @@ +return !["fel"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/2NLINicPQWbuvp2n.js b/scripts/2NLINicPQWbuvp2n.js new file mode 100644 index 0000000..f98dd93 --- /dev/null +++ b/scripts/2NLINicPQWbuvp2n.js @@ -0,0 +1 @@ +return args.item?.name != game.i18n.localize("NAME.Navigation") \ No newline at end of file diff --git a/scripts/2OqLHRqEBEjBm2LW.js b/scripts/2OqLHRqEBEjBm2LW.js new file mode 100644 index 0000000..1a3189b --- /dev/null +++ b/scripts/2OqLHRqEBEjBm2LW.js @@ -0,0 +1 @@ +args.fields.slBonus += this.actor.system.characteristics.wp.bonus \ No newline at end of file diff --git a/scripts/2Qi1hwLYhdE6v6Hs.js b/scripts/2Qi1hwLYhdE6v6Hs.js new file mode 100644 index 0000000..2782756 --- /dev/null +++ b/scripts/2Qi1hwLYhdE6v6Hs.js @@ -0,0 +1,9 @@ +if (!["rLeg", "lLeg"].includes(this.effect.getFlag("wfrp4e", "location"))) + return true; + +if (args.options.dodge) +{ + args.abort = true; + this.script.scriptNotification("Impossible d'Esquiver!") +} +return ["t", "int", "wp", "fel"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/2VNnVrtktdGUqXEV.js b/scripts/2VNnVrtktdGUqXEV.js new file mode 100644 index 0000000..38a1edd --- /dev/null +++ b/scripts/2VNnVrtktdGUqXEV.js @@ -0,0 +1,9 @@ +if (args.totalWoundLoss > 0) +{ + let test = await args.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) + await test.roll(); + if (test.failed && parseInt(args.opposedTest.attackerTest.result.SL) > 0) + { + args.actor.addCondition("stunned", parseInt(args.opposedTest.attackerTest.result.SL)) + } +} \ No newline at end of file diff --git a/scripts/2W9uMTT6iJhfQ044.js b/scripts/2W9uMTT6iJhfQ044.js new file mode 100644 index 0000000..fb037b9 --- /dev/null +++ b/scripts/2W9uMTT6iJhfQ044.js @@ -0,0 +1,18 @@ +let skill = `Trade (${this.item.parenthesesText})` +let currentCareer = this.actor.system.currentCareer; +let existingSkill = this.actor.itemTypes.skill.find(i => i.name == skill); + +if (!currentCareer) return + + +let inCurrentCareer = currentCareer.system.skills.includes(skill); +if (existingSkill && inCurrentCareer) +{ + existingSkill.system.advances.costModifier = -5; +} +else +{ + currentCareer.system.skills.push(skill); +} + + diff --git a/scripts/2WBq5gW780C6zfCp.js b/scripts/2WBq5gW780C6zfCp.js new file mode 100644 index 0000000..90b4c35 --- /dev/null +++ b/scripts/2WBq5gW780C6zfCp.js @@ -0,0 +1,9 @@ +if (args.weapon && this.item.system.usesLocation(args.weapon)) +{ + args.bleedingHand = true; + let success = await this.effect.manualScripts[0].execute({actor: this.actor}) + if (!success) + { + args.abort = true; + } +} \ No newline at end of file diff --git a/scripts/2WSN306tL4apjRtD.js b/scripts/2WSN306tL4apjRtD.js new file mode 100644 index 0000000..6931737 --- /dev/null +++ b/scripts/2WSN306tL4apjRtD.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.9h82z72XGo9tfgQS") +let data = item.toObject(); +data.name = data.name += " (Hearing)" +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/2cKarG9ToyW2ptCd.js b/scripts/2cKarG9ToyW2ptCd.js new file mode 100644 index 0000000..bdeca2b --- /dev/null +++ b/scripts/2cKarG9ToyW2ptCd.js @@ -0,0 +1,10 @@ +if (this.item.system.quantity.value) +{ + this.item.update({"system.quantity.value" : this.item.system.quantity.value - 0.25}) + let actor = Array.from(game.user.targets)[0]?.actor || this.actor; + actor.applyEffect({effectData : [this.item.effects.contents[1].convertToApplied()]}) +} +else +{ + this.script.scriptNotification("Vide !", "error") +} \ No newline at end of file diff --git a/scripts/2hzDv8ROulOe1elK.js b/scripts/2hzDv8ROulOe1elK.js new file mode 100644 index 0000000..1a9e5bd --- /dev/null +++ b/scripts/2hzDv8ROulOe1elK.js @@ -0,0 +1 @@ +return args.skill?.name.includes(game.i18n.localize("NAME.Lore")); \ No newline at end of file diff --git a/scripts/2mFNelLOAQ6iJsZl.js b/scripts/2mFNelLOAQ6iJsZl.js new file mode 100644 index 0000000..76ff0b6 --- /dev/null +++ b/scripts/2mFNelLOAQ6iJsZl.js @@ -0,0 +1,4 @@ +if (args.test.isFumble) +{ + args.test.result.other.push("@Table[doomrocket-fumble]") +} \ No newline at end of file diff --git a/scripts/2miWWeRrEpq1beG4.js b/scripts/2miWWeRrEpq1beG4.js new file mode 100644 index 0000000..579cd50 --- /dev/null +++ b/scripts/2miWWeRrEpq1beG4.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.qn4ZpvTQIX4rcJDl"); +let data = item.toObject(); +data.system.location.key = this.item.system.location.key +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) diff --git a/scripts/2p9IK6Y5Z4NQD6FY.js b/scripts/2p9IK6Y5Z4NQD6FY.js new file mode 100644 index 0000000..2facb9d --- /dev/null +++ b/scripts/2p9IK6Y5Z4NQD6FY.js @@ -0,0 +1 @@ +args.prefillModifiers.difficulty = "hard" \ No newline at end of file diff --git a/scripts/2rzxQlL7A9ujZ9uK.js b/scripts/2rzxQlL7A9ujZ9uK.js new file mode 100644 index 0000000..4c9c7f1 --- /dev/null +++ b/scripts/2rzxQlL7A9ujZ9uK.js @@ -0,0 +1,6 @@ +if (args.opposedTest.result.winner == "attacker") { + if (args.opposedTest.defenderTest.weapon && args.opposedTest.defenderTest.item.properties.qualities.shield) { + ui.notifications.notify(`${this.effect.name}: Gain de ${this.item.Advances} Avantages`) + this.actor.setAdvantage(this.item.Advances) + } +} \ No newline at end of file diff --git a/scripts/2sDH6RvoOAR40oqH.js b/scripts/2sDH6RvoOAR40oqH.js new file mode 100644 index 0000000..6efdf20 --- /dev/null +++ b/scripts/2sDH6RvoOAR40oqH.js @@ -0,0 +1,20 @@ + + +if (!["Goblin", "Orc"].includes(this.actor.system.details.species.value)) { + let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), { appendTitle: ` - ${this.effect.name}` }) + await test.roll(); + if (test.failed) { + let infection = await fromUuid("Compendium.wfrp4e-core.items.Item.1hQuVFZt9QnnbWzg") + this.actor.createEmbeddedDocuments("Item", [infection]) + } +} + +// Since wounds change when the effect is deleted, need to wait until after +// the max wounds have been recalculated to apply damage +game.wfrp4e.utility.sleep(1000).then(async () => { + let roll = await new Roll("1d10").roll(); + + roll.toMessage(this.script.getChatData()); + this.script.scriptMessage(await this.actor.applyBasicDamage(roll.total, { damageType: game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL, suppressMsg: true })) + +}) \ No newline at end of file diff --git a/scripts/2vTVR0quRZQtjNfQ.js b/scripts/2vTVR0quRZQtjNfQ.js new file mode 100644 index 0000000..512f2c3 --- /dev/null +++ b/scripts/2vTVR0quRZQtjNfQ.js @@ -0,0 +1,18 @@ +let currentCareer = this.actor.system.currentCareer; +if (!currentCareer) +{ + return; +} + +let talents = ["Aethyric Attunement", +"Arcane Magic (Any)", +"Chaos Magic (Tzeentch)", +"Fast Hands", +"Instinctive Diction", +"Magical Sense", +"Petty Magic", +"Second Sight", +"War Wizard", +"Witch!"].filter(t => !currentCareer.system.talents.includes(t)) + +currentCareer.system.talents = currentCareer.system.talents.concat(talents) \ No newline at end of file diff --git a/scripts/2wk0yrRPlPsdqr3L.js b/scripts/2wk0yrRPlPsdqr3L.js new file mode 100644 index 0000000..20b7014 --- /dev/null +++ b/scripts/2wk0yrRPlPsdqr3L.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.9GNpAqgsKzxZKJpp") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/2yctEihGmdCfTTVx.js b/scripts/2yctEihGmdCfTTVx.js new file mode 100644 index 0000000..a6d16a1 --- /dev/null +++ b/scripts/2yctEihGmdCfTTVx.js @@ -0,0 +1,2 @@ +args.data.canReverse = true; +args.options.fieldDressing = true; \ No newline at end of file diff --git a/scripts/2zeP2nMSURjxrqYz.js b/scripts/2zeP2nMSURjxrqYz.js new file mode 100644 index 0000000..a0ac1e4 --- /dev/null +++ b/scripts/2zeP2nMSURjxrqYz.js @@ -0,0 +1,6 @@ +let wounds = this.actor.system.status.wounds +if (wounds.value == 0) + return this.script.scriptNotification("No effect at 0 Wounds", "error") + +this.script.scriptNotification(`Healed ${this.actor.characteristics.t.bonus} Wounds`) +await this.actor.modifyWounds(this.actor.characteristics.t.bonus) \ No newline at end of file diff --git a/scripts/33PWizq5F7pkKnQT.js b/scripts/33PWizq5F7pkKnQT.js new file mode 100644 index 0000000..127ff99 --- /dev/null +++ b/scripts/33PWizq5F7pkKnQT.js @@ -0,0 +1,4 @@ +if (args.item.type == "spell") +{ + args.item.cn.value = Math.floor(args.item.cn.value / 2) +} \ No newline at end of file diff --git a/scripts/33US8YRgaMqYu2We.js b/scripts/33US8YRgaMqYu2We.js new file mode 100644 index 0000000..6569e71 --- /dev/null +++ b/scripts/33US8YRgaMqYu2We.js @@ -0,0 +1 @@ +return !args.options.handling \ No newline at end of file diff --git a/scripts/37UN17gb8suFeZIW.js b/scripts/37UN17gb8suFeZIW.js new file mode 100644 index 0000000..145ebc8 --- /dev/null +++ b/scripts/37UN17gb8suFeZIW.js @@ -0,0 +1 @@ +this.script.scriptMessage(await this.actor.applyBasicDamage(8, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_AP, suppressMsg: true})) \ No newline at end of file diff --git a/scripts/3Cn2TlRahlm5LkSj.js b/scripts/3Cn2TlRahlm5LkSj.js new file mode 100644 index 0000000..c1ee085 --- /dev/null +++ b/scripts/3Cn2TlRahlm5LkSj.js @@ -0,0 +1 @@ +args.fields.successBonus += 1; \ No newline at end of file diff --git a/scripts/3D5ImpMgpOTPucvv.js b/scripts/3D5ImpMgpOTPucvv.js new file mode 100644 index 0000000..d69e334 --- /dev/null +++ b/scripts/3D5ImpMgpOTPucvv.js @@ -0,0 +1,9 @@ +if (args.test.options.cardsharp && args.test.succeeded) +{ + +let SL = Math.floor(args.test.target / 10) - Math.floor(args.test.result.roll / 10) +let ones = Number(args.test.result.roll.toString().split("").pop()) + +if (ones > SL) + args.test.result.other.push(` `) +} \ No newline at end of file diff --git a/scripts/3IGO7xEjRjat937X.js b/scripts/3IGO7xEjRjat937X.js new file mode 100644 index 0000000..f45a41d --- /dev/null +++ b/scripts/3IGO7xEjRjat937X.js @@ -0,0 +1,7 @@ +let fatigue = this.actor.hasCondition("fatigued") +if (fatigue) +{ + this.script.scriptNotification("Removing Fatigued Condition, disabled effect") + this.effect.update({disabled : true}) + await this.actor.removeCondition("fatigued") +} \ No newline at end of file diff --git a/scripts/3JEzEzF1SeYA9lsV.js b/scripts/3JEzEzF1SeYA9lsV.js new file mode 100644 index 0000000..1b8b828 --- /dev/null +++ b/scripts/3JEzEzF1SeYA9lsV.js @@ -0,0 +1,44 @@ +let choice = await ItemDialog.create(ItemDialog.objectToArray(game.wfrp4e.config.locations, this.effect.img), 1, "Choose Location"); +if (choice[0]) +{ + this.effect.updateSource({name : `${this.effect.name} (${choice[0].name})`}) +this.effect.updateSource({"flags.wfrp4e.location" : choice[0].id}) +} + +let location = choice[0].id; + +if (["lArm", "rArm"].includes(location)) +{ + let dropped = this.actor.itemTypes.weapon.filter(i => i.isEquipped & i.system.usesHands.includes(location)); + + if (dropped.length) + { + this.script.scriptNotification(`Dropped ${dropped.map(i => i.name).join(", ")}!`) + for(let weapon of dropped) + { + await weapon.system.toggleEquip(); + } + } +} + +if (location == "body") +{ + await this.actor.addCondition("fatigued"); + test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields : {difficulty : "hard"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`}) + await test.roll(); + if (test.failed) + { + this.actor.addCondition("prone"); + } +} + +if (location == "head") +{ + await this.actor.addCondition("stunned"); + test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields : {difficulty : "average"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`}) + await test.roll(); + if (test.failed) + { + this.actor.addCondition("unconscious"); + } +} \ No newline at end of file diff --git a/scripts/3LLiSgj6KGtgqcmo.js b/scripts/3LLiSgj6KGtgqcmo.js new file mode 100644 index 0000000..8a4090c --- /dev/null +++ b/scripts/3LLiSgj6KGtgqcmo.js @@ -0,0 +1 @@ +return !args.skill?.name.includes(game.i18n.localize("NAME.Language")); \ No newline at end of file diff --git a/scripts/3R6Y4NpNTqPc83wh.js b/scripts/3R6Y4NpNTqPc83wh.js new file mode 100644 index 0000000..c0857ab --- /dev/null +++ b/scripts/3R6Y4NpNTqPc83wh.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.IPKRMGry6WotuS1G") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/3TesBGh8HnlGuafu.js b/scripts/3TesBGh8HnlGuafu.js new file mode 100644 index 0000000..05ab756 --- /dev/null +++ b/scripts/3TesBGh8HnlGuafu.js @@ -0,0 +1,5 @@ +let modifier = this.effect.sourceTest?.result.overcast.usage.other.current || 0 + +let test = await this.actor.setupCharacteristic("dex", {fields: {modifier}, skipTargets: true, appendTitle : " - " + this.script.label}); + +test.roll(); \ No newline at end of file diff --git a/scripts/3Vbe6gdW8N0bIvXJ.js b/scripts/3Vbe6gdW8N0bIvXJ.js new file mode 100644 index 0000000..5bf968e --- /dev/null +++ b/scripts/3Vbe6gdW8N0bIvXJ.js @@ -0,0 +1,5 @@ +if (args.item.type == "weapon" || args.item.type == "trait") +{ + args.item.qualities.value.push({name : "penetrating"}) + args.item.qualities.value.push({name : "impale"}) +} \ No newline at end of file diff --git a/scripts/3aEzK0DehSHtVykd.js b/scripts/3aEzK0DehSHtVykd.js new file mode 100644 index 0000000..9b294f4 --- /dev/null +++ b/scripts/3aEzK0DehSHtVykd.js @@ -0,0 +1 @@ +this.effect.manualScripts[0].execute({actor : this.actor}); \ No newline at end of file diff --git a/scripts/3eSaX0BeaUalNkEP.js b/scripts/3eSaX0BeaUalNkEP.js new file mode 100644 index 0000000..077517d --- /dev/null +++ b/scripts/3eSaX0BeaUalNkEP.js @@ -0,0 +1 @@ +return args.options.mutate \ No newline at end of file diff --git a/scripts/3fdCQ3h3iVuhdDs9.js b/scripts/3fdCQ3h3iVuhdDs9.js new file mode 100644 index 0000000..f3281db --- /dev/null +++ b/scripts/3fdCQ3h3iVuhdDs9.js @@ -0,0 +1 @@ +args.fields.slBonus += this.actor.characteristics.ag.bonus; \ No newline at end of file diff --git a/scripts/3hfMQkUKYI4rCuBy.js b/scripts/3hfMQkUKYI4rCuBy.js new file mode 100644 index 0000000..7cf8f33 --- /dev/null +++ b/scripts/3hfMQkUKYI4rCuBy.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.CharmAnimal") && !args.skill?.name.includes(game.i18n.localize("NAME.AnimalTraining")); \ No newline at end of file diff --git a/scripts/3jm0NoYpgB6ZuUSl.js b/scripts/3jm0NoYpgB6ZuUSl.js new file mode 100644 index 0000000..a7b132e --- /dev/null +++ b/scripts/3jm0NoYpgB6ZuUSl.js @@ -0,0 +1 @@ +args.options.useOnesAttractive = true; \ No newline at end of file diff --git a/scripts/3l7MQSa10Kve2K3P.js b/scripts/3l7MQSa10Kve2K3P.js new file mode 100644 index 0000000..0d12a2b --- /dev/null +++ b/scripts/3l7MQSa10Kve2K3P.js @@ -0,0 +1,2 @@ +this.script.scriptMessage(await this.actor.applyBasicDamage(Math.ceil(CONFIG.Dice.randomUniform() * 10) + 6, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_AP, suppressMsg : true})) +this.actor.addCondition("ablaze"); \ No newline at end of file diff --git a/scripts/3plV9WFqs2prfAdp.js b/scripts/3plV9WFqs2prfAdp.js new file mode 100644 index 0000000..9ec91ac --- /dev/null +++ b/scripts/3plV9WFqs2prfAdp.js @@ -0,0 +1 @@ +return !["NAME.Evaluate", "NAME.Gamble"].map(i => game.i18n.localize(i)).includes(args.skill?.name) \ No newline at end of file diff --git a/scripts/3sfD1nedXLzuYoXJ.js b/scripts/3sfD1nedXLzuYoXJ.js new file mode 100644 index 0000000..674133f --- /dev/null +++ b/scripts/3sfD1nedXLzuYoXJ.js @@ -0,0 +1,4 @@ +if (this.actor.hasCondition("surprised")) +{ + this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {fields : {difficulty : "average"}, skipTargets: true, appendTitle : " - " + this.effect.name}).then(test => test.roll()) +} diff --git a/scripts/3tE8gFSl28EhCmo5.js b/scripts/3tE8gFSl28EhCmo5.js new file mode 100644 index 0000000..9e28dce --- /dev/null +++ b/scripts/3tE8gFSl28EhCmo5.js @@ -0,0 +1,2 @@ +await args.actor.addCondition("ablaze") +await args.actor.addCondition("prone") \ No newline at end of file diff --git a/scripts/454x3Q95pLvZm0Kx.js b/scripts/454x3Q95pLvZm0Kx.js new file mode 100644 index 0000000..0072c5f --- /dev/null +++ b/scripts/454x3Q95pLvZm0Kx.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.ConsumeAlcohol"); \ No newline at end of file diff --git a/scripts/4FGKZk2f0xrmIDnp.js b/scripts/4FGKZk2f0xrmIDnp.js new file mode 100644 index 0000000..59535fd --- /dev/null +++ b/scripts/4FGKZk2f0xrmIDnp.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Research") && !args.skill?.name?.includes(game.i18n.localize("NAME.Language")); \ No newline at end of file diff --git a/scripts/4HN98hMdQJxM35pA.js b/scripts/4HN98hMdQJxM35pA.js new file mode 100644 index 0000000..23c0294 --- /dev/null +++ b/scripts/4HN98hMdQJxM35pA.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.gz2xy41OSVZ8YBgI"); +let data = item.toObject(); +data.system.location.key = this.item.system.location.key +this.actor.createEmbeddedDocuments("Item", [data]) diff --git a/scripts/4JVIy5xtVwvadoqv.js b/scripts/4JVIy5xtVwvadoqv.js new file mode 100644 index 0000000..bb85425 --- /dev/null +++ b/scripts/4JVIy5xtVwvadoqv.js @@ -0,0 +1 @@ +this.actor.details.move.run *= 2 \ No newline at end of file diff --git a/scripts/4MQ7u4INxp51oyyR.js b/scripts/4MQ7u4INxp51oyyR.js new file mode 100644 index 0000000..95200bd --- /dev/null +++ b/scripts/4MQ7u4INxp51oyyR.js @@ -0,0 +1,85 @@ +let characteristics = { + "ws" : 25, + "bs" : 10, + "s" : 15, + "t" : 15, + "i" : 25, + "ag" : 20, + "dex" : 0, + "int" : 10, + "wp" : 25, + "fel" : 10 +} +let skills = ["Cool", "Dodge", "Intimidate", "Intuition", "Leadership", "Lore (Warfare)", "Perception"] +let skillAdvancements = [15, 15, 15, 15, 15, 10, 10] +let talents = ["Combat Aware", "Combat Reflexes", "Feint", "Inspiring", "Resolute", "War Leader"] +let trappings = ["Hand Weapon", "Shield"] +let items = []; + +let updateObj = this.actor.toObject(); + +for (let ch in characteristics) +{ + updateObj.system.characteristics[ch].modifier += characteristics[ch]; +} + +for (let index = 0; index < skills.length; index++) +{ + let skill = skills[index] + let skillItem; + skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill") + if (skillItem) + skillItem.system.advances.value += skillAdvancements[index] + else + { + skillItem = await game.wfrp4e.utility.findSkill(skill) + skillItem = skillItem.toObject(); + skillItem.system.advances.value = skillAdvancements[index]; + items.push(skillItem); + } +} + +for (let talent of talents) +{ + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } +} + +for (let trapping of trappings) +{ + let trappingItem = await game.wfrp4e.utility.findItem(trapping) + if (trappingItem) + { + trappingItem = trappingItem.toObject() + + equip(trappingItem) + + items.push(trappingItem); + } + else + { + ui.notifications.warn(`Could not find ${trapping}`, {permanent : true}) + } +} + +updateObj.name = updateObj.name += " " + this.effect.name + +await this.actor.update(updateObj) +this.actor.createEmbeddedDocuments("Item", items); + +function equip(item) +{ + if (item.type == "armour") + item.system.worn.value = true + else if (item.type == "weapon") + item.system.equipped = true + else if (item.type == "trapping" && item.system.trappingType.value == "clothingAccessories") + item.system.worn = true +} \ No newline at end of file diff --git a/scripts/4QoxhoekgVeZcQA7.js b/scripts/4QoxhoekgVeZcQA7.js new file mode 100644 index 0000000..4ebe285 --- /dev/null +++ b/scripts/4QoxhoekgVeZcQA7.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.M5QSWOYt2Rbv2yxW") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/4XrAeL2DitxE8OaK.js b/scripts/4XrAeL2DitxE8OaK.js new file mode 100644 index 0000000..93877a2 --- /dev/null +++ b/scripts/4XrAeL2DitxE8OaK.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.0hn6UaKq8CoZP2zD") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}); \ No newline at end of file diff --git a/scripts/4cOZzUvu1nytcqNn.js b/scripts/4cOZzUvu1nytcqNn.js new file mode 100644 index 0000000..b5902b0 --- /dev/null +++ b/scripts/4cOZzUvu1nytcqNn.js @@ -0,0 +1 @@ +args.initiative = "-10" \ No newline at end of file diff --git a/scripts/4fnTKgl0HW9ZrWyJ.js b/scripts/4fnTKgl0HW9ZrWyJ.js new file mode 100644 index 0000000..e818ce4 --- /dev/null +++ b/scripts/4fnTKgl0HW9ZrWyJ.js @@ -0,0 +1,10 @@ +this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty : "average"}}).then(async test => +{ + await test.roll() + if (test.failed) + { + let char = Math.ceil(CONFIG.Dice.randomUniform() * 2) == 2 ? "s" : "t"; + this.script.scriptMessage(`${this.actor.name} lost 1 point of ${game.wfrp4e.config.characteristics[char]}`) + this.actor.update({[`system.characteristics.${char}.initial`] : this.actor.system.characteristics[char].initial - 1}) + } +}) \ No newline at end of file diff --git a/scripts/4gkz3LR7CK1b8ulK.js b/scripts/4gkz3LR7CK1b8ulK.js new file mode 100644 index 0000000..b6432a4 --- /dev/null +++ b/scripts/4gkz3LR7CK1b8ulK.js @@ -0,0 +1 @@ +return args.item?.system.attackType != "ranged" || this.actor.uuid != this.effect.sourceActor.uuid \ No newline at end of file diff --git a/scripts/4iuTz0uInAfMaoGl.js b/scripts/4iuTz0uInAfMaoGl.js new file mode 100644 index 0000000..d3f97d5 --- /dev/null +++ b/scripts/4iuTz0uInAfMaoGl.js @@ -0,0 +1 @@ +return args.skill?.name?.includes(game.i18n.localize("NAME.Language")) || args.type == "cast" \ No newline at end of file diff --git a/scripts/4pQW4WLyhjbZR85k.js b/scripts/4pQW4WLyhjbZR85k.js new file mode 100644 index 0000000..8a2680f --- /dev/null +++ b/scripts/4pQW4WLyhjbZR85k.js @@ -0,0 +1,7 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "average"}, context : {failure: "1 Corruption Point Gained"}}) +await test.roll(); +if (test.failed && this.actor.type == "character") +{ + this.actor.update({"system.status.corruption.value" : parseInt(this.actor.status.corruption.value) + 1}) + this.script.scriptMessage("Gained a Corruption point", {whisper : ChatMessage.getWhisperRecipients("GM")}) +} \ No newline at end of file diff --git a/scripts/4rTmV3TNxctUe0ly.js b/scripts/4rTmV3TNxctUe0ly.js new file mode 100644 index 0000000..30a0737 --- /dev/null +++ b/scripts/4rTmV3TNxctUe0ly.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupCharacteristic("ag", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}); +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("bleeding"); +} diff --git a/scripts/4rb7LfMq9CTnlrpn.js b/scripts/4rb7LfMq9CTnlrpn.js new file mode 100644 index 0000000..214bdc9 --- /dev/null +++ b/scripts/4rb7LfMq9CTnlrpn.js @@ -0,0 +1,10 @@ +if (args.totalWoundLoss > 0) +{ + let test = await args.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : " - " + this.effect.name}) + await test.roll(); + if (test.failed) + { + args.totalWoundLoss += 5; + args.modifiers.other.push({label : this.effect.name, value : 5}) + } +} \ No newline at end of file diff --git a/scripts/4rhxLzau7jZ4SDxg.js b/scripts/4rhxLzau7jZ4SDxg.js new file mode 100644 index 0000000..19f3d85 --- /dev/null +++ b/scripts/4rhxLzau7jZ4SDxg.js @@ -0,0 +1,2 @@ +await args.actor.addCondition("grappling") +await args.actor.addCondition("entangled") \ No newline at end of file diff --git a/scripts/52kbfuWrOh6dsTtd.js b/scripts/52kbfuWrOh6dsTtd.js new file mode 100644 index 0000000..d5df29a --- /dev/null +++ b/scripts/52kbfuWrOh6dsTtd.js @@ -0,0 +1,2 @@ +if (!this.actor.hasCondition("blinded")) + this.actor.addCondition("blinded", 1, {"flags.wfrp4e.flockOfDoom" : true}) \ No newline at end of file diff --git a/scripts/52mwb33mGrQjq89B.js b/scripts/52mwb33mGrQjq89B.js new file mode 100644 index 0000000..33c3e75 --- /dev/null +++ b/scripts/52mwb33mGrQjq89B.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Research"); \ No newline at end of file diff --git a/scripts/53HFDNuMnX1Aw1a4.js b/scripts/53HFDNuMnX1Aw1a4.js new file mode 100644 index 0000000..d6198c0 --- /dev/null +++ b/scripts/53HFDNuMnX1Aw1a4.js @@ -0,0 +1 @@ +return ["ws", "bs", "s", "ag", "dex", "int", "wp", "fel"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/58rFc9HiBoX66J6p.js b/scripts/58rFc9HiBoX66J6p.js new file mode 100644 index 0000000..1e3c7a2 --- /dev/null +++ b/scripts/58rFc9HiBoX66J6p.js @@ -0,0 +1,9 @@ +let sourceActor = this.effect.sourceActor; +let damage = args.totalWoundLoss; +let tb = sourceActor.system.characteristics.t.bonus +args.abort = `${this.effect.name}: Damage applied to ${sourceActor.name}`; + +let message = await sourceActor.applyBasicDamage(damage - tb, {damageType: game.wfrp4e.config.DAMAGE_TYPE.IGNORE_AP, suppressMsg : true}) + +this.script.scriptMessage(message.replace(`${tb} TB`, `${tb} × 2 TB`)) +args.abort = true; \ No newline at end of file diff --git a/scripts/5DI6cHAg1LHo54Yv.js b/scripts/5DI6cHAg1LHo54Yv.js new file mode 100644 index 0000000..6929228 --- /dev/null +++ b/scripts/5DI6cHAg1LHo54Yv.js @@ -0,0 +1,6 @@ +if (args.opposedTest.result.differenceSL >= 0 && args.opposedTest.result.differenceSL <= 2 && args.opposedTest.result.winner == "attacker") +{ + this.actor.update({"system.status.fortune.value" : Math.max(0, (this.actor.system.status.fortune?.value - 1) || 0)}) + this.script.scriptMessage(`Fortune point stolen from ${this.actor.name}`, {blind : true, whisper : ChatMessage.getWhisperRecipients("GM")}) + +} \ No newline at end of file diff --git a/scripts/5Fe1ELaS6Gnvy0Cj.js b/scripts/5Fe1ELaS6Gnvy0Cj.js new file mode 100644 index 0000000..ad46ad3 --- /dev/null +++ b/scripts/5Fe1ELaS6Gnvy0Cj.js @@ -0,0 +1 @@ +return args.skill?.name.includes("Channelling") || args.type == "channelling" || args.skill?.name == game.i18n.localize("NAME.Charm") || args.skill?.name.includes("Language (Magick)") || args.type == "cast" \ No newline at end of file diff --git a/scripts/5IoYTyedCMYwt3ys.js b/scripts/5IoYTyedCMYwt3ys.js new file mode 100644 index 0000000..cedf74b --- /dev/null +++ b/scripts/5IoYTyedCMYwt3ys.js @@ -0,0 +1 @@ +args.fields.slBonus += 2; \ No newline at end of file diff --git a/scripts/5JWC0l3JEpOsqbR9.js b/scripts/5JWC0l3JEpOsqbR9.js new file mode 100644 index 0000000..d2eb0b6 --- /dev/null +++ b/scripts/5JWC0l3JEpOsqbR9.js @@ -0,0 +1,85 @@ +let characteristics = { + "ws" : 0, + "bs" : 5, + "s" : 0, + "t" : 0, + "i" : 10, + "ag" : 10, + "dex" : 0, + "int" : 0, + "wp" : 5, + "fel" : 0 +} +let skills = ["Dodge", "Perception"] +let skillAdvancements = [10, 10] +let talents = ["Flee!", "Marksman"] +let trappings = ["Hand Weapon"] +let items = []; + +let updateObj = this.actor.toObject(); + +for (let ch in characteristics) +{ + updateObj.system.characteristics[ch].modifier += characteristics[ch]; +} + +for (let index = 0; index < skills.length; index++) +{ + let skill = skills[index] + let skillItem; + skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill") + if (skillItem) + skillItem.system.advances.value += skillAdvancements[index] + else + { + skillItem = await game.wfrp4e.utility.findSkill(skill) + skillItem = skillItem.toObject(); + skillItem.system.advances.value = skillAdvancements[index]; + items.push(skillItem); + } +} + +for (let talent of talents) +{ + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } +} + +for (let trapping of trappings) +{ + let trappingItem = await game.wfrp4e.utility.findItem(trapping) + if (trappingItem) + { + trappingItem = trappingItem.toObject() + + equip(trappingItem) + + items.push(trappingItem); + } + else + { + ui.notifications.warn(`Could not find ${trapping}`, {permanent : true}) + } +} + +updateObj.name = updateObj.name += " " + this.effect.name + +await this.actor.update(updateObj) +this.actor.createEmbeddedDocuments("Item", items); + +function equip(item) +{ + if (item.type == "armour") + item.system.worn.value = true + else if (item.type == "weapon") + item.system.equipped = true + else if (item.type == "trapping" && item.system.trappingType.value == "clothingAccessories") + item.system.worn = true +} \ No newline at end of file diff --git a/scripts/5JvKJZPcd6Hz5zvn.js b/scripts/5JvKJZPcd6Hz5zvn.js new file mode 100644 index 0000000..be61706 --- /dev/null +++ b/scripts/5JvKJZPcd6Hz5zvn.js @@ -0,0 +1,85 @@ +let characteristics = { + "ws" : 10, + "bs" : 0, + "s" : 10, + "t" : 10, + "i" : 20, + "ag" : 10, + "dex" : 0, + "int" : 0, + "wp" : 15, + "fel" : 0 +} +let skills = ["Cool", "Dodge", "Intimidate", "Leadership"] +let skillAdvancements = [15, 15, 10, 5] +let talents = ["Combat Aware", "Combat Reflexes", "Feint", "Resolute"] +let trappings = ["Mail Coat", "Mail Chausses", "Mail Coif", "Hand Weapon", "Shield"] +let items = []; + +let updateObj = this.actor.toObject(); + +for (let ch in characteristics) +{ + updateObj.system.characteristics[ch].modifier += characteristics[ch]; +} + +for (let index = 0; index < skills.length; index++) +{ + let skill = skills[index] + let skillItem; + skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill") + if (skillItem) + skillItem.system.advances.value += skillAdvancements[index] + else + { + skillItem = await game.wfrp4e.utility.findSkill(skill) + skillItem = skillItem.toObject(); + skillItem.system.advances.value = skillAdvancements[index]; + items.push(skillItem); + } +} + +for (let talent of talents) +{ + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } +} + +for (let trapping of trappings) +{ + let trappingItem = await game.wfrp4e.utility.findItem(trapping) + if (trappingItem) + { + trappingItem = trappingItem.toObject() + + equip(trappingItem) + + items.push(trappingItem); + } + else + { + ui.notifications.warn(`Could not find ${trapping}`, {permanent : true}) + } +} + +updateObj.name = this.effect.name + " " + updateObj.name + +await this.actor.update(updateObj) +this.actor.createEmbeddedDocuments("Item", items); + +function equip(item) +{ + if (item.type == "armour") + item.system.worn.value = true + else if (item.type == "weapon") + item.system.equipped = true + else if (item.type == "trapping" && item.system.trappingType.value == "clothingAccessories") + item.system.worn = true +} \ No newline at end of file diff --git a/scripts/5LdJCKfQem1AQK24.js b/scripts/5LdJCKfQem1AQK24.js new file mode 100644 index 0000000..7ec5f13 --- /dev/null +++ b/scripts/5LdJCKfQem1AQK24.js @@ -0,0 +1,6 @@ + +if (!args.flags.howlingWarpGale) +{ + args.fields.modifier -= 10; + args.flags.howlingWarpGale = true; // prevent double application +} \ No newline at end of file diff --git a/scripts/5M6IgCUncCwyxHok.js b/scripts/5M6IgCUncCwyxHok.js new file mode 100644 index 0000000..ceef2c0 --- /dev/null +++ b/scripts/5M6IgCUncCwyxHok.js @@ -0,0 +1,35 @@ +let etiquette = (await fromUuid("Compendium.wfrp4e-core.items.Item.sYbgpSnRqSZWgwFP")).toObject(); +etiquette.name += ` (Followers of Tzeentch)`; + +let animosity = (await fromUuid("Compendium.wfrp4e-core.items.Item.0VpT5yubw4UL7j6f")).toObject(); +animosity.system.specification.value = "Followers of Nurgle"; + +let roll = await new Roll("ceil(1d10 / 3)").roll(); + +roll.toMessage(this.script.getChatData()); + +let mutations = []; +let msg = `Mutations Gained
` +for(let i = 0; i < roll.total; i++) +{ + let item; + let uuid; + let result; + if (i % 2 == 0) + { + result = await game.wfrp4e.tables.rollTable("mutatemental", {hideDSN: true}, "Tzeentch") + } + else + { + result = await game.wfrp4e.tables.rollTable("mutatephys", {hideDSN: true}, "Tzeentch") + } + uuid = `Compendium.${result.object.documentCollection}.${result.object.documentId}`; + item = await fromUuid(uuid); + if (item) + { + msg += `@UUID[${uuid}]{${item.name}}
` + mutations.push(item.toObject()); + } +} +this.actor.createEmbeddedDocuments("Item", mutations.concat([etiquette, animosity]), {fromEffect : this.effect.id}) +this.script.scriptMessage(msg); \ No newline at end of file diff --git a/scripts/5MxRDXzUBPfp2KKD.js b/scripts/5MxRDXzUBPfp2KKD.js new file mode 100644 index 0000000..578674f --- /dev/null +++ b/scripts/5MxRDXzUBPfp2KKD.js @@ -0,0 +1 @@ +args.options.useOnesSupportive = true; \ No newline at end of file diff --git a/scripts/5dR7Erj3nwsxLAV7.js b/scripts/5dR7Erj3nwsxLAV7.js new file mode 100644 index 0000000..443c65a --- /dev/null +++ b/scripts/5dR7Erj3nwsxLAV7.js @@ -0,0 +1,85 @@ +let characteristics = { + "ws" : 35, + "bs" : 10, + "s" : 25, + "t" : 30, + "i" : 30, + "ag" : 25, + "dex" : 0, + "int" : 15, + "wp" : 35, + "fel" : 15 +} +let skills = ["Cool", "Dodge", "Intimidate", "Intuition", "Leadership", "Lore (Warfare)", "Perception"] +let skillAdvancements = [25, 15, 25, 25, 30, 20, 20] +let talents = ["Combat Aware", "Combat Reflexes", "Feint", "Inspiring", "Luck", "Resolute", "Unshakable", "War Leader"] +let trappings = ["Hand Weapon", "Shield"] +let items = []; + +let updateObj = this.actor.toObject(); + +for (let ch in characteristics) +{ + updateObj.system.characteristics[ch].modifier += characteristics[ch]; +} + +for (let index = 0; index < skills.length; index++) +{ + let skill = skills[index] + let skillItem; + skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill") + if (skillItem) + skillItem.system.advances.value += skillAdvancements[index] + else + { + skillItem = await game.wfrp4e.utility.findSkill(skill) + skillItem = skillItem.toObject(); + skillItem.system.advances.value = skillAdvancements[index]; + items.push(skillItem); + } +} + +for (let talent of talents) +{ + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } +} + +for (let trapping of trappings) +{ + let trappingItem = await game.wfrp4e.utility.findItem(trapping) + if (trappingItem) + { + trappingItem = trappingItem.toObject() + + equip(trappingItem) + + items.push(trappingItem); + } + else + { + ui.notifications.warn(`Could not find ${trapping}`, {permanent : true}) + } +} + +updateObj.name = updateObj.name += " " + this.effect.name + +await this.actor.update(updateObj) +this.actor.createEmbeddedDocuments("Item", items); + +function equip(item) +{ + if (item.type == "armour") + item.system.worn.value = true + else if (item.type == "weapon") + item.system.equipped = true + else if (item.type == "trapping" && item.system.trappingType.value == "clothingAccessories") + item.system.worn = true +} \ No newline at end of file diff --git a/scripts/5lc1eHIYQNpSRWip.js b/scripts/5lc1eHIYQNpSRWip.js new file mode 100644 index 0000000..39f6f8b --- /dev/null +++ b/scripts/5lc1eHIYQNpSRWip.js @@ -0,0 +1,8 @@ +if (["death", "necromancy"].includes(args.spell?.system.lore.value)) +{ + args.fields.successBonus += 1 +} +else if(["life", "light", "heavens"].includes(args.spell?.system.lore.value)) +{ + args.fields.modifier -= 10; +} \ No newline at end of file diff --git a/scripts/5o1XiceC4rutjMms.js b/scripts/5o1XiceC4rutjMms.js new file mode 100644 index 0000000..2646b2f --- /dev/null +++ b/scripts/5o1XiceC4rutjMms.js @@ -0,0 +1 @@ +return !args.item?.name.includes(game.i18n.localize("NAME.Stealth")) \ No newline at end of file diff --git a/scripts/5sI9iYh5j2nx2XyT.js b/scripts/5sI9iYh5j2nx2XyT.js new file mode 100644 index 0000000..4a9e7b3 --- /dev/null +++ b/scripts/5sI9iYh5j2nx2XyT.js @@ -0,0 +1 @@ +return !(["Animal Care", "Charm Animal"].includes(args.item?.name) || args.item?.name.includes("Ride") || args.item?.name.includes("Animal Training")) \ No newline at end of file diff --git a/scripts/62Ky6bC1EnTllSJA.js b/scripts/62Ky6bC1EnTllSJA.js new file mode 100644 index 0000000..8d0a535 --- /dev/null +++ b/scripts/62Ky6bC1EnTllSJA.js @@ -0,0 +1,4 @@ +if (this.effect.sourceActor.uuid != args.actor.uuid) +{ + this.script.scriptMessage(await this.actor.applyBasicDamage(this.effect.sourceTest.result.overcast.usage.other.current, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL, suppressMsg: true})); +} \ No newline at end of file diff --git a/scripts/65o8pQj6oGNnXce6.js b/scripts/65o8pQj6oGNnXce6.js new file mode 100644 index 0000000..6737896 --- /dev/null +++ b/scripts/65o8pQj6oGNnXce6.js @@ -0,0 +1,2 @@ +let ch = this.effect.getFlag("wfrp4e", "characteristic") +this.actor.system.characteristics[ch].modifier += 10; \ No newline at end of file diff --git a/scripts/65xE9OV5sA1ZWT7j.js b/scripts/65xE9OV5sA1ZWT7j.js new file mode 100644 index 0000000..2e9318c --- /dev/null +++ b/scripts/65xE9OV5sA1ZWT7j.js @@ -0,0 +1,9 @@ +if (args.test.options.diceman && args.test.succeeded) +{ + +let SL = Math.floor(args.test.target / 10) - Math.floor(args.test.result.roll / 10) +let ones = Number(args.test.result.roll.toString().split("").pop()) + +if (ones > SL) + args.test.result.other.push(` `) +} \ No newline at end of file diff --git a/scripts/6Aqq4F4Xui923sc6.js b/scripts/6Aqq4F4Xui923sc6.js new file mode 100644 index 0000000..0a9ebf3 --- /dev/null +++ b/scripts/6Aqq4F4Xui923sc6.js @@ -0,0 +1,12 @@ +// Imbibing this substance grants the user the Painless Creature Trait. +const hasColdBlooded = this.actor.has("Cold Blooded") +if (hasColdBlooded === undefined) +{ + let item = await fromUuid("Compendium.wfrp4e-core.items.mCh1KK9jomwFZcLB") + let data = item.toObject() + this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) + + this.script.scriptMessage(`${this.actor.prototypeToken.name} has gained the Cold Blooded Creature Trait and may reverse any failed Willpower based Tests.
+If they gain a Surprised Condition, this Condition is not lost the first time it should be (which is typically at the end of the Round or if they victim is attacked).
`, + {whisper: ChatMessage.getWhisperRecipients("GM"), blind: true }) +} \ No newline at end of file diff --git a/scripts/6BmvV9c03FkfisnE.js b/scripts/6BmvV9c03FkfisnE.js new file mode 100644 index 0000000..3d03be7 --- /dev/null +++ b/scripts/6BmvV9c03FkfisnE.js @@ -0,0 +1,20 @@ +// Apply changes when the mask is worn + +if (args.equipped) { + this.actor.createEmbeddedDocuments("ActiveEffect", [this.item.effects.contents[1]?.convertToApplied()]) + this.script.scriptMessage(`${this.actor.name} dons the ${this.item.name}.Use Ward provided by ${this.effect.name}?`,
+ buttons : {
+ yes : {
+ label : "Yes",
+ callback: () => {
+ return true;
+ }
+ },
+ no : {
+ label: "No",
+ callback: () => {
+ return false;
+ }
+ }
+ }
+})
+
+if (useWard)
+ args.ward = 9;
\ No newline at end of file
diff --git a/scripts/6mpw9cGseG4W4eyd.js b/scripts/6mpw9cGseG4W4eyd.js
new file mode 100644
index 0000000..1a3b985
--- /dev/null
+++ b/scripts/6mpw9cGseG4W4eyd.js
@@ -0,0 +1,12 @@
+if (this.actor.system.status.advantage.value >= 2)
+{
+ await this.actor.modifyAdvantage(-2);
+ this.script.scriptNotification("Advantage Subtracted")
+}
+else
+{
+ return this.script.scriptNotification("Not enough Advantage!", "error")
+}
+
+let test = await this.actor.setupTrait(this.item)
+await test.roll();
\ No newline at end of file
diff --git a/scripts/6qUKKep5vhFYmo1J.js b/scripts/6qUKKep5vhFYmo1J.js
new file mode 100644
index 0000000..0fc2aa5
--- /dev/null
+++ b/scripts/6qUKKep5vhFYmo1J.js
@@ -0,0 +1 @@
+return args.type == "channelling" || args.skill?.name.includes(game.i18n.localize("NAME.Channelling"))
\ No newline at end of file
diff --git a/scripts/6tjn0RH4VyOPFneS.js b/scripts/6tjn0RH4VyOPFneS.js
new file mode 100644
index 0000000..0001110
--- /dev/null
+++ b/scripts/6tjn0RH4VyOPFneS.js
@@ -0,0 +1 @@
+return ["NAME.Row", "NAME.Swim"].map(i => game.i18n.localize(i)).includes(args.skill?.name);
\ No newline at end of file
diff --git a/scripts/6uldpFvKOCoW92cC.js b/scripts/6uldpFvKOCoW92cC.js
new file mode 100644
index 0000000..9f67eea
--- /dev/null
+++ b/scripts/6uldpFvKOCoW92cC.js
@@ -0,0 +1,8 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.uqGxFOEqeurwkAO3")
+item = item.toObject()
+
+item.system.specification.value = 10;
+item.name += " (Fire)"
+setProperty(item, "flags.wfrp4e.breath", "fire")
+
+Item.create(item, {parent : this.actor, fromEffect: this.effect.id})
\ No newline at end of file
diff --git a/scripts/6xTtJEhRc4OjcDTf.js b/scripts/6xTtJEhRc4OjcDTf.js
new file mode 100644
index 0000000..5a8b642
--- /dev/null
+++ b/scripts/6xTtJEhRc4OjcDTf.js
@@ -0,0 +1,5 @@
+if (getProperty(args.data, "system.status.fortune.value"))
+{
+ this.script.scriptNotification("Cannot update Fortune");
+ delete args.data.system.status.wounds.value;
+}
\ No newline at end of file
diff --git a/scripts/715G1Bf0haOHvmYQ.js b/scripts/715G1Bf0haOHvmYQ.js
new file mode 100644
index 0000000..56674c9
--- /dev/null
+++ b/scripts/715G1Bf0haOHvmYQ.js
@@ -0,0 +1 @@
+return !(args.skill?.name == game.i18n.localize("NAME.Bribery") || args.skill?.name.includes(game.i18n.localize("NAME.Stealth")))
\ No newline at end of file
diff --git a/scripts/71DmrxCTKGYL4Z7X.js b/scripts/71DmrxCTKGYL4Z7X.js
new file mode 100644
index 0000000..159a835
--- /dev/null
+++ b/scripts/71DmrxCTKGYL4Z7X.js
@@ -0,0 +1 @@
+return ["fel"].includes(args.characteristic)
\ No newline at end of file
diff --git a/scripts/7Ck0fkzE4WQ62qVe.js b/scripts/7Ck0fkzE4WQ62qVe.js
new file mode 100644
index 0000000..6850a0b
--- /dev/null
+++ b/scripts/7Ck0fkzE4WQ62qVe.js
@@ -0,0 +1,4 @@
+if (args.item.type == "skill" && args.item.name == "Melee (Basic)")
+{
+ args.item.system.modifier.value += 20;
+}
\ No newline at end of file
diff --git a/scripts/7F3miqRA0ceMUBIu.js b/scripts/7F3miqRA0ceMUBIu.js
new file mode 100644
index 0000000..1088080
--- /dev/null
+++ b/scripts/7F3miqRA0ceMUBIu.js
@@ -0,0 +1 @@
+return args.characteristic != "int" || args.skill
\ No newline at end of file
diff --git a/scripts/7F6aGxZJjwxm5e5P.js b/scripts/7F6aGxZJjwxm5e5P.js
new file mode 100644
index 0000000..18e9f56
--- /dev/null
+++ b/scripts/7F6aGxZJjwxm5e5P.js
@@ -0,0 +1,18 @@
+if (args.test.result.castOutcome == "failure")
+{
+ ValueDialog.create("Enter Wounds Lost to gain SL", this.effect.name, "0").then(async value => {
+ value = Math.clamped(value, 0, 3)
+ if (value == 0)
+ {
+ return;
+ }
+ else if (Number.isNumeric(value))
+ {
+ this.script.scriptNotification(`Lost ${value} Wounds`)
+ this.actor.modifyWounds(-1 * value)
+ await this.item.system.toggleEquip();
+ args.test.addSL(value);
+ args.test.preData.other.push(`${this.effect.name}: +${value} SL`)
+ }
+ })
+}
\ No newline at end of file
diff --git a/scripts/7H6wYyJ6cpaoc2QQ.js b/scripts/7H6wYyJ6cpaoc2QQ.js
new file mode 100644
index 0000000..05cbeea
--- /dev/null
+++ b/scripts/7H6wYyJ6cpaoc2QQ.js
@@ -0,0 +1 @@
+return args.skill?.name == game.i18n.localize("NAME.Cool");
\ No newline at end of file
diff --git a/scripts/7JW9t8AYSDkkzG2V.js b/scripts/7JW9t8AYSDkkzG2V.js
new file mode 100644
index 0000000..5e3d751
--- /dev/null
+++ b/scripts/7JW9t8AYSDkkzG2V.js
@@ -0,0 +1,21 @@
+// Apply changes when the mask is worn
+
+if (args.equipped)
+{
+ this.actor.createEmbeddedDocuments("ActiveEffect", [this.item.effects.contents[1]?.convertToApplied()])
+ this.script.scriptMessage(`${this.actor.name} dons the ${this.item.name}.
+ If they wear the mask for more than an hour or benefit from any of its effects, they are exposed to @Corruption[moderate]{Moderate Corruption}.
+ `,
+ {whisper: ChatMessage.getWhisperRecipients("GM")})
+}
+
+// Notify of lingering effects when mask is removed
+else if (!args.equipped)
+{
+ await this.item.effects.contents[0].delete();
+ await this.item.update({name : this.item.name += " (Used)"})
+ this.script.scriptMessage(`${this.item.name} on ${this.actor.name} has been taken off and loses its properties. However, the effects last for [[1d10+4]] days, after which they should be manually removed.`,
+ {whisper: ChatMessage.getWhisperRecipients("GM")}
+ )
+
+}
\ No newline at end of file
diff --git a/scripts/7OmrMjaU48o2FEZi.js b/scripts/7OmrMjaU48o2FEZi.js
new file mode 100644
index 0000000..4ca0181
--- /dev/null
+++ b/scripts/7OmrMjaU48o2FEZi.js
@@ -0,0 +1,6 @@
+
+this.actor.characteristics.t.bonus = 10
+
+this.actor.details.move.value = 0;
+this.actor.details.move.walk= 0;
+this.actor.details.move.run = 0;
\ No newline at end of file
diff --git a/scripts/7ScfB4o1QhXnNUfq.js b/scripts/7ScfB4o1QhXnNUfq.js
new file mode 100644
index 0000000..a8f5e60
--- /dev/null
+++ b/scripts/7ScfB4o1QhXnNUfq.js
@@ -0,0 +1 @@
+return !["int", "wp"].includes(args.characteristic)
\ No newline at end of file
diff --git a/scripts/7VAhXHov6pR1SkgD.js b/scripts/7VAhXHov6pR1SkgD.js
new file mode 100644
index 0000000..67dfce8
--- /dev/null
+++ b/scripts/7VAhXHov6pR1SkgD.js
@@ -0,0 +1 @@
+return args.item?.name == game.i18n.localize("NAME.Endurance");
\ No newline at end of file
diff --git a/scripts/7WR2hJjHPhHhHxAq.js b/scripts/7WR2hJjHPhHhHxAq.js
new file mode 100644
index 0000000..45d5ca2
--- /dev/null
+++ b/scripts/7WR2hJjHPhHhHxAq.js
@@ -0,0 +1,8 @@
+let poisoned = args.actor.hasCondition("poisoned")
+if (poisoned)
+{
+ this.script.scriptNotification(`Removed ${poisoned.conditionValue} Poisoned Conditions`)
+ poisoned.delete();
+}
+else
+ this.script.scriptNotification(`No Poisoned Conditions`)
\ No newline at end of file
diff --git a/scripts/7ZoFUMDG2WJd8RMg.js b/scripts/7ZoFUMDG2WJd8RMg.js
new file mode 100644
index 0000000..0ff8299
--- /dev/null
+++ b/scripts/7ZoFUMDG2WJd8RMg.js
@@ -0,0 +1 @@
+this.script.scriptMessage(`Claimed ${this.effect.name} Bonus`);
\ No newline at end of file
diff --git a/scripts/7e8FgQUF2oANANmx.js b/scripts/7e8FgQUF2oANANmx.js
new file mode 100644
index 0000000..b195380
--- /dev/null
+++ b/scripts/7e8FgQUF2oANANmx.js
@@ -0,0 +1 @@
+return args.skill?.name == "Melee (Brawling)" || args.item?.weaponGroup?.value == "brawling"
\ No newline at end of file
diff --git a/scripts/7f6OsttTzE7Hvzfk.js b/scripts/7f6OsttTzE7Hvzfk.js
new file mode 100644
index 0000000..aff4c37
--- /dev/null
+++ b/scripts/7f6OsttTzE7Hvzfk.js
@@ -0,0 +1,5 @@
+if (this.actor.statuses.has("infighting")) // Only add +10 if already infighting
+ args.prefillModifiers.modifier += 10;
+
+
+args.prefillModifiers.successBonus += 1;
diff --git a/scripts/7n3SEAGRA5ESK8gV.js b/scripts/7n3SEAGRA5ESK8gV.js
new file mode 100644
index 0000000..f577178
--- /dev/null
+++ b/scripts/7n3SEAGRA5ESK8gV.js
@@ -0,0 +1 @@
+args.options.disarm = true;
\ No newline at end of file
diff --git a/scripts/7szLG4VALuuy1cPm.js b/scripts/7szLG4VALuuy1cPm.js
new file mode 100644
index 0000000..1fbcead
--- /dev/null
+++ b/scripts/7szLG4VALuuy1cPm.js
@@ -0,0 +1,6 @@
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "easy"}})
+await test.roll();
+if (test.failed)
+{
+ await this.actor.addCondition("fatigued")
+}
\ No newline at end of file
diff --git a/scripts/7wBWUw05q0igh508.js b/scripts/7wBWUw05q0igh508.js
new file mode 100644
index 0000000..95e3da1
--- /dev/null
+++ b/scripts/7wBWUw05q0igh508.js
@@ -0,0 +1,17 @@
+// Imbibing this substance grants the user the Painless Creature Trait.
+const hasPainless = this.actor.has("Painless");
+if (hasPainless === undefined)
+{
+ let item = await fromUuid("Compendium.wfrp4e-core.items.wMwSRDmgiF2IdCJr");
+ let data = item.toObject()
+ this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id})
+
+ this.script.scriptMessage(
+ `
${this.actor.prototypeToken.name} has gained the Painless Creature Trait. This + effect lasts for one hour, after which it dissipates and the full effect + of all the imbiber's wounds come crashing down at once.
+Note that this does not prevent the user from acquiring a Critical + Wound or dying from one. It merely allows them to ignore most + of their effects.
`, + { whisper: ChatMessage.getWhisperRecipients("GM"), blind: true}) +} \ No newline at end of file diff --git a/scripts/84IB8CWa55XzoAkv.js b/scripts/84IB8CWa55XzoAkv.js new file mode 100644 index 0000000..3cdc615 --- /dev/null +++ b/scripts/84IB8CWa55XzoAkv.js @@ -0,0 +1 @@ +return (["Animal Care", "Charm Animal"].includes(args.item?.name) || args.item?.name.includes("Ride") || args.item?.name.includes("Animal Training")) \ No newline at end of file diff --git a/scripts/87rrZ3ojHrXa3lCn.js b/scripts/87rrZ3ojHrXa3lCn.js new file mode 100644 index 0000000..75193a6 --- /dev/null +++ b/scripts/87rrZ3ojHrXa3lCn.js @@ -0,0 +1 @@ +this.actor.modifyWounds(1) \ No newline at end of file diff --git a/scripts/8AoA4bnstBtglRGZ.js b/scripts/8AoA4bnstBtglRGZ.js new file mode 100644 index 0000000..ff38d2d --- /dev/null +++ b/scripts/8AoA4bnstBtglRGZ.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.wMwSRDmgiF2IdCJr") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/8ByuHnUZ4RNTdGVv.js b/scripts/8ByuHnUZ4RNTdGVv.js new file mode 100644 index 0000000..37290b2 --- /dev/null +++ b/scripts/8ByuHnUZ4RNTdGVv.js @@ -0,0 +1,16 @@ +let strLoss = Math.ceil(CONFIG.Dice.randomUniform() * 10) +let tghLoss = Math.ceil(CONFIG.Dice.randomUniform() * 10) + +if (!this.actor.has("Undead") && !this.actor.has("Daemonic")) +{ + this.actor.setupSkill(game.i18n.localize("NAME.Cool"), { appendTitle: " - " + this.effect.name, fields: { difficulty: "average" }, context: { failure: `Lost ${strLoss} Strength and ${tghLoss} Toughness` } }).then(async test => { + await test.roll(); + if (test.failed) { + this.actor.update({ "system.characteristics.s.initial": this.actor.system.characteristics.s.initial - strLoss, "system.characteristics.t.initial": this.actor.system.characteristics.t.initial - tghLoss }) + } + }) + +} +else { + this.script.scriptNotification(`${this.actor.name} is immune to ${this.effect.name}`) +} diff --git a/scripts/8GyJgdHVBaLrHCY8.js b/scripts/8GyJgdHVBaLrHCY8.js new file mode 100644 index 0000000..2ee98a7 --- /dev/null +++ b/scripts/8GyJgdHVBaLrHCY8.js @@ -0,0 +1,21 @@ +let type = this.item.getFlag("wfrp4e", "breath") +let types = { + none : "None", + cold : "Cold", + corrosion : "Corrosion", + fire : "Fire", + electricity : "Electricity", + poison : "Poison", + smoke : "Smoke", + various : "Various" +} +if (!type) +{ + type = (await ItemDialog.create(ItemDialog.objectToArray(types, this.item.img), 1, "Choose Breath"))[0]?.id; + this.item.updateSource({"flags.wfrp4e.breath" : type}) +} + +if (!this.item.name.includes("(") && types[type] && type != "none") +{ + this.item.updateSource({name : this.item.name += ` (${types[type]})`, "system.specification.value" : this.item.system.specification.value.replace("(Type)", "").trim()}) +} \ No newline at end of file diff --git a/scripts/8K9tpCwvFC9INk5V.js b/scripts/8K9tpCwvFC9INk5V.js new file mode 100644 index 0000000..757ac38 --- /dev/null +++ b/scripts/8K9tpCwvFC9INk5V.js @@ -0,0 +1,8 @@ +if (["t", "wp"].includes(args.characteristic)) +{ + args.fields.modifier += 10; +} +else if (["ag", "i", "int"].includes(args.characteristic)) +{ + args.fields.modifier -= 10; +} \ No newline at end of file diff --git a/scripts/8LmUVQxOwTLSeabg.js b/scripts/8LmUVQxOwTLSeabg.js new file mode 100644 index 0000000..32cd5df --- /dev/null +++ b/scripts/8LmUVQxOwTLSeabg.js @@ -0,0 +1 @@ +return args.data.targets.length > 0 || !args.weapon?.system.qualities.value.find(i => i.name == "shield") // Should count even if they don't have the skill \ No newline at end of file diff --git a/scripts/8N3Uqjq1ZxPxo4pk.js b/scripts/8N3Uqjq1ZxPxo4pk.js new file mode 100644 index 0000000..43dddd4 --- /dev/null +++ b/scripts/8N3Uqjq1ZxPxo4pk.js @@ -0,0 +1 @@ +return !args.skill?.name?.includes(game.i18n.localize("NAME.Lore")) \ No newline at end of file diff --git a/scripts/8RNziYGGb4sp3BGQ.js b/scripts/8RNziYGGb4sp3BGQ.js new file mode 100644 index 0000000..b853c6b --- /dev/null +++ b/scripts/8RNziYGGb4sp3BGQ.js @@ -0,0 +1,5 @@ +if (!args.test.weapon?.name.includes("Drakefire")) +{ + args.test.result.misfire = game.i18n.localize("Misfire"); + args.test.result.misfireDamage = (0, eval)(parseInt(args.test.result.roll.toString().split('').pop()) + args.test.weapon.system.Damage); +} \ No newline at end of file diff --git a/scripts/8ShLVT0bK1eQpinj.js b/scripts/8ShLVT0bK1eQpinj.js new file mode 100644 index 0000000..9783813 --- /dev/null +++ b/scripts/8ShLVT0bK1eQpinj.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.k00PimCWkff11IA0") +let data = item.toObject(); +data.system.location.key = this.item.system.location.key +this.actor.createEmbeddedDocuments("Item", [data]) \ No newline at end of file diff --git a/scripts/8TRiAJ8thIKE4IoL.js b/scripts/8TRiAJ8thIKE4IoL.js new file mode 100644 index 0000000..3814c2c --- /dev/null +++ b/scripts/8TRiAJ8thIKE4IoL.js @@ -0,0 +1,5 @@ + +let SL = Number(getProperty(this.item, "flags.wfrp4e.sourceTest.result.SL") || 1) + +args.actor.characteristics.i.modifier += 10 * SL +args.actor.characteristics.ag.modifier += 10 * SL \ No newline at end of file diff --git a/scripts/8ThudCYRqkjQIwJH.js b/scripts/8ThudCYRqkjQIwJH.js new file mode 100644 index 0000000..0395373 --- /dev/null +++ b/scripts/8ThudCYRqkjQIwJH.js @@ -0,0 +1,4 @@ +if (args.opposedTest.attackerTest.result.critical) +{ + args.actor.addCondition("ablaze") +} \ No newline at end of file diff --git a/scripts/8WJsecxdndaHRxxS.js b/scripts/8WJsecxdndaHRxxS.js new file mode 100644 index 0000000..5bd3474 --- /dev/null +++ b/scripts/8WJsecxdndaHRxxS.js @@ -0,0 +1 @@ +this.actor.status.addArmour(this.actor.characteristics.wp.bonus, {source: this.effect, magical : true}) \ No newline at end of file diff --git a/scripts/8WeYU5e5LN9UeWFs.js b/scripts/8WeYU5e5LN9UeWFs.js new file mode 100644 index 0000000..7ede669 --- /dev/null +++ b/scripts/8WeYU5e5LN9UeWFs.js @@ -0,0 +1,8 @@ +if (args.item.type == "spell") +{ + let range = parseInt(args.item.Range) + if (Number.isNumeric(range)) + { + args.item.system.range.value = "2 * " + args.item.system.range.value + } +} \ No newline at end of file diff --git a/scripts/8ZAUBSH9CM9OTpTL.js b/scripts/8ZAUBSH9CM9OTpTL.js new file mode 100644 index 0000000..eb0439d --- /dev/null +++ b/scripts/8ZAUBSH9CM9OTpTL.js @@ -0,0 +1,11 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Perception"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "easy"}}); +await test.roll(); + +if (test.succeeded) +{ + this.actor.addCondition("stunned") +} +else if (test.failed) +{ + this.actor.addCondition("poisoned", 2); +} \ No newline at end of file diff --git a/scripts/8araLuwmBq8GKEw3.js b/scripts/8araLuwmBq8GKEw3.js new file mode 100644 index 0000000..66a5c92 --- /dev/null +++ b/scripts/8araLuwmBq8GKEw3.js @@ -0,0 +1,7 @@ +let APIgnored = args.AP.layers.reduce((prev, current) => prev + ((current.weakpoints && !current.ignored) ? current.value : 0), 0) + +if (APIgnored) +{ + args.modifiers.ap.ignored += APIgnored + args.modifiers.ap.details.push(`${this.effect.name}: Ignore AP with Weakpoints (${APIgnored})`) +} \ No newline at end of file diff --git a/scripts/8fefDfiYKFOWdPER.js b/scripts/8fefDfiYKFOWdPER.js new file mode 100644 index 0000000..dc649cd --- /dev/null +++ b/scripts/8fefDfiYKFOWdPER.js @@ -0,0 +1 @@ +args.update({texture : {scaleX : 2, scaleY: 2, src: "modules/wfrp4e-core/tokens/popout/gor.webp"}}); \ No newline at end of file diff --git a/scripts/8g2iitsgaJarKQpr.js b/scripts/8g2iitsgaJarKQpr.js new file mode 100644 index 0000000..4ce1574 --- /dev/null +++ b/scripts/8g2iitsgaJarKQpr.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.V0c3qBU1CMm8bmsW") +let data = item.toObject() +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) diff --git a/scripts/8gCja0mfKt4nYVZc.js b/scripts/8gCja0mfKt4nYVZc.js new file mode 100644 index 0000000..d05c4f3 --- /dev/null +++ b/scripts/8gCja0mfKt4nYVZc.js @@ -0,0 +1 @@ +args.fields.slBonus += 2 \ No newline at end of file diff --git a/scripts/8hIyWDyfbgGAig65.js b/scripts/8hIyWDyfbgGAig65.js new file mode 100644 index 0000000..bdf054c --- /dev/null +++ b/scripts/8hIyWDyfbgGAig65.js @@ -0,0 +1 @@ +return ["ws", "bs", "s", "t", "ag", "dex"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/8jvEVPUCg3rKG48Y.js b/scripts/8jvEVPUCg3rKG48Y.js new file mode 100644 index 0000000..38cef06 --- /dev/null +++ b/scripts/8jvEVPUCg3rKG48Y.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.9fq6p9Q6H02LjaSi") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/8noxHUQKR55Kx1YN.js b/scripts/8noxHUQKR55Kx1YN.js new file mode 100644 index 0000000..d164bff --- /dev/null +++ b/scripts/8noxHUQKR55Kx1YN.js @@ -0,0 +1 @@ +this.actor.system.status.corruption.max += 1 \ No newline at end of file diff --git a/scripts/8oE0DTzz0krOfFlV.js b/scripts/8oE0DTzz0krOfFlV.js new file mode 100644 index 0000000..e4d4736 --- /dev/null +++ b/scripts/8oE0DTzz0krOfFlV.js @@ -0,0 +1,2 @@ +args.item.system.qualities.value.push({name : "magical"}) +args.item.system.qualities.value.push({name : "impact"}) diff --git a/scripts/8rq4GL5d5nCn4kO7.js b/scripts/8rq4GL5d5nCn4kO7.js new file mode 100644 index 0000000..79c9046 --- /dev/null +++ b/scripts/8rq4GL5d5nCn4kO7.js @@ -0,0 +1,7 @@ +let caster = this.effect.sourceActor +if (caster) +{ + let healed= caster.characteristics.wp.bonus + this.actor.modifyWounds(healed); + this.script.scriptMessage(`${this.actor.prototypeToken.name} regains ${healed} Wounds`) +} \ No newline at end of file diff --git a/scripts/8tyMXDfHR8AJBdDu.js b/scripts/8tyMXDfHR8AJBdDu.js new file mode 100644 index 0000000..9e0a473 --- /dev/null +++ b/scripts/8tyMXDfHR8AJBdDu.js @@ -0,0 +1,7 @@ +let weakpointsAP = args.AP.layers.filter(i => !i.ignored && i.weakpoints).reduce((ap, layer) => ap + layer.value, 0); + +if (weakpointsAP > 0) +{ + args.modifiers.ap.ignored += weakpointsAP; + args.modifiers.ap.details.push(`${this.effect.name} - Ignore Weakpoints (${weakpointsAP})`); +} \ No newline at end of file diff --git a/scripts/8vpAtJ93GIeye1qj.js b/scripts/8vpAtJ93GIeye1qj.js new file mode 100644 index 0000000..aefec45 --- /dev/null +++ b/scripts/8vpAtJ93GIeye1qj.js @@ -0,0 +1 @@ +return args.type == "cast" \ No newline at end of file diff --git a/scripts/8wG9l4T9fc1bM0TN.js b/scripts/8wG9l4T9fc1bM0TN.js new file mode 100644 index 0000000..a043287 --- /dev/null +++ b/scripts/8wG9l4T9fc1bM0TN.js @@ -0,0 +1,3 @@ +let item = (await fromUuid("Compendium.wfrp4e-core.items.Item.kJNAY1YRaCy9IgmT")).toObject(); +item.system.specification.value = 1; +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/8yBr6VbdKcrWUuqw.js b/scripts/8yBr6VbdKcrWUuqw.js new file mode 100644 index 0000000..ce24a5f --- /dev/null +++ b/scripts/8yBr6VbdKcrWUuqw.js @@ -0,0 +1,4 @@ +this.actor.characteristics.i.value= "-" +this.actor.characteristics.int.value= "-" +this.actor.characteristics.wp.value= "-" +this.actor.characteristics.fel.value = "-" \ No newline at end of file diff --git a/scripts/8zTkDVziBPaNbMQX.js b/scripts/8zTkDVziBPaNbMQX.js new file mode 100644 index 0000000..c032cba --- /dev/null +++ b/scripts/8zTkDVziBPaNbMQX.js @@ -0,0 +1,30 @@ +let filters = [ + { + property : "type", + value : "spell" + }, + { + property : "system.lore.value", + value : "petty" + } +] + +let petty = await game.wfrp4e.apps.ItemDialog.createFromFilters(filters, 6, "Choose 6 Petty Spells") + + +filters = [ + { + property : "type", + value : "spell" + }, + { + property : "system.lore.value", + value : "" + } +] + +let arcane = await game.wfrp4e.apps.ItemDialog.createFromFilters(filters, 9, "Choose 9 Arcane Spells") + +let items = petty.concat(arcane).map(i => i.toObject()) + +this.actor.createEmbeddedDocuments("Item", items); \ No newline at end of file diff --git a/scripts/91S2GnBFYFbxmOCK.js b/scripts/91S2GnBFYFbxmOCK.js new file mode 100644 index 0000000..3e28299 --- /dev/null +++ b/scripts/91S2GnBFYFbxmOCK.js @@ -0,0 +1,2 @@ +this.actor.characteristics.s.bonus += 1 +this.actor.characteristics.s.calculationBonusModifier -= 1 \ No newline at end of file diff --git a/scripts/93K85NnVwjVNXlZq.js b/scripts/93K85NnVwjVNXlZq.js new file mode 100644 index 0000000..3b0ffe3 --- /dev/null +++ b/scripts/93K85NnVwjVNXlZq.js @@ -0,0 +1 @@ +return !args.skill?.name.includes(game.i18n.localize("NAME.Trade")); \ No newline at end of file diff --git a/scripts/956dUb5sd6OtbWZR.js b/scripts/956dUb5sd6OtbWZR.js new file mode 100644 index 0000000..3f6bdb7 --- /dev/null +++ b/scripts/956dUb5sd6OtbWZR.js @@ -0,0 +1 @@ +args.fields.successBonus++; \ No newline at end of file diff --git a/scripts/96Y1yIH1lRjTs5hL.js b/scripts/96Y1yIH1lRjTs5hL.js new file mode 100644 index 0000000..1fab3ce --- /dev/null +++ b/scripts/96Y1yIH1lRjTs5hL.js @@ -0,0 +1,5 @@ +if (args.test.succeeded) + return + +if (args.test.characteristicKey == "wp") + this.actor.addCondition("broken") \ No newline at end of file diff --git a/scripts/98nKfcimlaPeM9h5.js b/scripts/98nKfcimlaPeM9h5.js new file mode 100644 index 0000000..dde67fd --- /dev/null +++ b/scripts/98nKfcimlaPeM9h5.js @@ -0,0 +1,2 @@ +await this.actor.addCondition("bleeding") +await this.script.scriptMessage(await this.actor.applyBasicDamage(10, {suppressMsg : true})); \ No newline at end of file diff --git a/scripts/9A7rYY3FKi5XLihG.js b/scripts/9A7rYY3FKi5XLihG.js new file mode 100644 index 0000000..e8ade7a --- /dev/null +++ b/scripts/9A7rYY3FKi5XLihG.js @@ -0,0 +1,6 @@ +fromUuid("Compendium.wfrp4e-core.items.5QcrpLQWWrsbKR79").then(item => { + let data = item.toObject(); + data.system.tests.value = data.system.tests.value.replace("coins", "metal objects"); + data.system.description.value += "This Talent also extends to any metal object because of Metallic Affinity
" + this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) +}) \ No newline at end of file diff --git a/scripts/9EVj4bmZJex45Mt7.js b/scripts/9EVj4bmZJex45Mt7.js new file mode 100644 index 0000000..a17d972 --- /dev/null +++ b/scripts/9EVj4bmZJex45Mt7.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Athletics"); \ No newline at end of file diff --git a/scripts/9JnPK1jNUEso7Pv8.js b/scripts/9JnPK1jNUEso7Pv8.js new file mode 100644 index 0000000..8c33cb3 --- /dev/null +++ b/scripts/9JnPK1jNUEso7Pv8.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.9h82z72XGo9tfgQS") +let data = item.toObject(); +data.name += ` (Smell)` +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/9MDi3ok9gPwtbALf.js b/scripts/9MDi3ok9gPwtbALf.js new file mode 100644 index 0000000..d6892bc --- /dev/null +++ b/scripts/9MDi3ok9gPwtbALf.js @@ -0,0 +1 @@ +args.actor.details.move.value /= 2 \ No newline at end of file diff --git a/scripts/9MwRUzRinhq1IjhG.js b/scripts/9MwRUzRinhq1IjhG.js new file mode 100644 index 0000000..280ccc9 --- /dev/null +++ b/scripts/9MwRUzRinhq1IjhG.js @@ -0,0 +1 @@ +args.actor.addCondition("grappling"); \ No newline at end of file diff --git a/scripts/9RFoasDcFnYZ1txR.js b/scripts/9RFoasDcFnYZ1txR.js new file mode 100644 index 0000000..8a60a20 --- /dev/null +++ b/scripts/9RFoasDcFnYZ1txR.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.Perception"); \ No newline at end of file diff --git a/scripts/9VfeubiCV83LN9iY.js b/scripts/9VfeubiCV83LN9iY.js new file mode 100644 index 0000000..83f9f95 --- /dev/null +++ b/scripts/9VfeubiCV83LN9iY.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.AtpAudHA4ybXVlWM") +let data = item.toObject(); +data.name += ` (When Charging)` +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/9WZa63lr0K3SsP4G.js b/scripts/9WZa63lr0K3SsP4G.js new file mode 100644 index 0000000..bac4c09 --- /dev/null +++ b/scripts/9WZa63lr0K3SsP4G.js @@ -0,0 +1,7 @@ +let sourceItem = this.effect.sourceItem; + +if (sourceItem) +{ + this.actor.applyEffect({effectUuids : [sourceItem.effects.contents[2].uuid]}) + this.script.scriptNotification("Applied after effects"); +} \ No newline at end of file diff --git a/scripts/9Yn9uViEjcuaESJ2.js b/scripts/9Yn9uViEjcuaESJ2.js new file mode 100644 index 0000000..f964391 --- /dev/null +++ b/scripts/9Yn9uViEjcuaESJ2.js @@ -0,0 +1,12 @@ +if (this.item.getFlag("wfrp4e", "failedCool")) +{ + this.item.name += " (No AP)" + this.item.system.AP = { + "head": 0, + "lArm": 0, + "rArm": 0, + "lLeg": 0, + "rLeg": 0, + "body": 0 + } +} \ No newline at end of file diff --git a/scripts/9ZFPDCk8M2TQxh7x.js b/scripts/9ZFPDCk8M2TQxh7x.js new file mode 100644 index 0000000..3529480 --- /dev/null +++ b/scripts/9ZFPDCk8M2TQxh7x.js @@ -0,0 +1 @@ +args.fields.modifier += 20 diff --git a/scripts/9bJGJrLqslV5lBya.js b/scripts/9bJGJrLqslV5lBya.js new file mode 100644 index 0000000..9023650 --- /dev/null +++ b/scripts/9bJGJrLqslV5lBya.js @@ -0,0 +1 @@ + return args.characteristic == "bs" \ No newline at end of file diff --git a/scripts/9eWR4mdaoCSQawDT.js b/scripts/9eWR4mdaoCSQawDT.js new file mode 100644 index 0000000..82e0ef9 --- /dev/null +++ b/scripts/9eWR4mdaoCSQawDT.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.GlShFJF2TpsNh1FX"); +let data = item.toObject(); +data.system.location.key = this.item.system.location.key +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) diff --git a/scripts/9fK07tqqZyPg7dpx.js b/scripts/9fK07tqqZyPg7dpx.js new file mode 100644 index 0000000..baccb76 --- /dev/null +++ b/scripts/9fK07tqqZyPg7dpx.js @@ -0,0 +1,12 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty: "veasy"}}) +await test.roll(); +if (test.failed) +{ + this.script.scriptNotification("Gained a Festering Wound") + let item = await fromUuid("Compendium.wfrp4e-core.items.kKccDTGzWzSXCBOb") + this.actor.createEmbeddedDocuments("Item", [item.toObject()]) +} +else +{ + this.script.scriptNotification("Avoided a Festering Wound") +} diff --git a/scripts/9nroaZDkW3WXNkB7.js b/scripts/9nroaZDkW3WXNkB7.js new file mode 100644 index 0000000..64deeef --- /dev/null +++ b/scripts/9nroaZDkW3WXNkB7.js @@ -0,0 +1,2 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.Item.4MJJCiOKPkBByYwW"); +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/9ob2lPnk3PDot9Tx.js b/scripts/9ob2lPnk3PDot9Tx.js new file mode 100644 index 0000000..1edbafd --- /dev/null +++ b/scripts/9ob2lPnk3PDot9Tx.js @@ -0,0 +1 @@ +this.actor.addCondition("blinded", this.effect.sourceTest.result.SL) \ No newline at end of file diff --git a/scripts/9qWUuEF8F5nehF1y.js b/scripts/9qWUuEF8F5nehF1y.js new file mode 100644 index 0000000..442e3d1 --- /dev/null +++ b/scripts/9qWUuEF8F5nehF1y.js @@ -0,0 +1,2 @@ +args.item.system.qualities.value = args.item.system.qualities.value.concat([{name : "magical"}, {name : "unbreakable"}]) +args.item.system.damage.value += ` + ${this.effect.sourceActor.system.characteristics.wp.bonus}` \ No newline at end of file diff --git a/scripts/A0OK0qAMmnf8iNJf.js b/scripts/A0OK0qAMmnf8iNJf.js new file mode 100644 index 0000000..b3df7c5 --- /dev/null +++ b/scripts/A0OK0qAMmnf8iNJf.js @@ -0,0 +1,8 @@ +if (args.test.result.SL < 0) +{ + this.script.scriptMessage(`Gained ${Math.abs(args.test.result.SL)} Corruption points`, {whisper : ChatMessage.getWhisperRecipients("GM")}) + if (args.test.failed && this.actor.type == "character") + { + this.actor.update({"system.status.corruption.value" : parseInt(this.actor.status.corruption.value) + Math.abs(args.test.result.SL)}) + } +} \ No newline at end of file diff --git a/scripts/A1odAcuRbq9797ZB.js b/scripts/A1odAcuRbq9797ZB.js new file mode 100644 index 0000000..04c6e12 --- /dev/null +++ b/scripts/A1odAcuRbq9797ZB.js @@ -0,0 +1,94 @@ +let choice1 = [ + { + type : "skill", + name : "Melee (Basic)", + diff : { + system : { + advances : { + value : 10 + } + } + } + } +] +let choice2 = [ + { + type : "skill", + name : "Melee (Polearm)", + diff : { + system : { + advances : { + value : 10 + } + } + } + } +] + +let choice = await Dialog.wait({ + title : "Choice", + content : + `+ Select your choice +
+Apply damage with ${this.effect.name} to attacker?`,
+ buttons: {
+ yes: {
+ label: "Yes",
+ callback: () => {
+ return true;
+ }
+ },
+ no: {
+ label: "No",
+ callback: () => {
+ return false;
+ }
+ }
+ }
+ })
+
+ if (choice)
+ {
+ this.script.scriptMessage(await args.attacker.applyBasicDamage(this.actor.system.characteristics.wp.bonus, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_AP, suppressMsg : true}));
+ }
+}
\ No newline at end of file
diff --git a/scripts/CkE8NZOhzPkuRrKJ.js b/scripts/CkE8NZOhzPkuRrKJ.js
new file mode 100644
index 0000000..d4e519f
--- /dev/null
+++ b/scripts/CkE8NZOhzPkuRrKJ.js
@@ -0,0 +1,14 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.MnMZv7ZXoRqoH9dS")
+let data = item.toObject();
+data.system.location.key = this.item.system.location.key
+this.actor.createEmbeddedDocuments("Item", [data])
+
+
+
+
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields: {difficulty: "hard"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`})
+await test.roll();
+if (test.failed)
+{
+ this.actor.addCondition("unconscious")
+}
\ No newline at end of file
diff --git a/scripts/CoImIH9OCMx9DfQZ.js b/scripts/CoImIH9OCMx9DfQZ.js
new file mode 100644
index 0000000..d5f9737
--- /dev/null
+++ b/scripts/CoImIH9OCMx9DfQZ.js
@@ -0,0 +1,4 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.nbhn2wX35b7Jrcbg")
+let data = item.toObject();
+data.system.location.value = "Jaw"
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id})
\ No newline at end of file
diff --git a/scripts/D5XmzrUGFa1JN0cl.js b/scripts/D5XmzrUGFa1JN0cl.js
new file mode 100644
index 0000000..fe0c170
--- /dev/null
+++ b/scripts/D5XmzrUGFa1JN0cl.js
@@ -0,0 +1,2 @@
+args.prefillModifiers.modifier += 10
+
diff --git a/scripts/DANLE5HxrkTNelhl.js b/scripts/DANLE5HxrkTNelhl.js
new file mode 100644
index 0000000..e8601ac
--- /dev/null
+++ b/scripts/DANLE5HxrkTNelhl.js
@@ -0,0 +1 @@
+args.wounds += 4;
\ No newline at end of file
diff --git a/scripts/DBafsY1HrclJRTtA.js b/scripts/DBafsY1HrclJRTtA.js
new file mode 100644
index 0000000..b3311bb
--- /dev/null
+++ b/scripts/DBafsY1HrclJRTtA.js
@@ -0,0 +1 @@
+return args.type != "cast"
\ No newline at end of file
diff --git a/scripts/DHxUKY9LMyifFgCi.js b/scripts/DHxUKY9LMyifFgCi.js
new file mode 100644
index 0000000..a9beef0
--- /dev/null
+++ b/scripts/DHxUKY9LMyifFgCi.js
@@ -0,0 +1 @@
+return args.skill?.name == "Trade (Apothecary)" || args.skill?.name == "Trade (Alchemist)"
\ No newline at end of file
diff --git a/scripts/DL9vYNft9aXdV2aW.js b/scripts/DL9vYNft9aXdV2aW.js
new file mode 100644
index 0000000..ef975b7
--- /dev/null
+++ b/scripts/DL9vYNft9aXdV2aW.js
@@ -0,0 +1,12 @@
+let tooth = await fromUuid("Compendium.wfrp4e-core.items.pLW9SVX0TVTYPiPv")
+tooth = tooth.toObject()
+tooth.system.specification.value = 3
+tooth.system.qualities.value = [{name : "magical"}]
+
+let claw = await fromUuid("Compendium.wfrp4e-core.items.AtpAudHA4ybXVlWM")
+claw = claw.toObject()
+claw.system.specification.value = 4
+claw.system.qualities.value = [{name : "magical"}]
+claw.name = "Claw"
+
+this.actor.createEmbeddedDocuments("Item", [tooth, claw], {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/DMQ0taEpBUJU5njV.js b/scripts/DMQ0taEpBUJU5njV.js
new file mode 100644
index 0000000..8fb1dd8
--- /dev/null
+++ b/scripts/DMQ0taEpBUJU5njV.js
@@ -0,0 +1 @@
+args.actor.status.fortune.value = 0
\ No newline at end of file
diff --git a/scripts/DTiHS6RfwhF4THbf.js b/scripts/DTiHS6RfwhF4THbf.js
new file mode 100644
index 0000000..1a7339b
--- /dev/null
+++ b/scripts/DTiHS6RfwhF4THbf.js
@@ -0,0 +1 @@
+return args.skill?.name != game.i18n.localize("NAME.Drive") && !args.skill?.name.includes(game.i18n.localize("NAME.Ride"));
\ No newline at end of file
diff --git a/scripts/DVlZGbiuMIHEQOnM.js b/scripts/DVlZGbiuMIHEQOnM.js
new file mode 100644
index 0000000..4395d41
--- /dev/null
+++ b/scripts/DVlZGbiuMIHEQOnM.js
@@ -0,0 +1,10 @@
+if (this.actor.getFlag("wfrp4e", "isAttached"))
+{
+ let roll = await new Roll("1d10").roll()
+ await roll.toMessage(this.script.getChatData());
+ if (roll.total == 9 || roll.total == 10)
+ {
+ this.script.scriptMessage(`${this.actor.name} attached to ${this.actor.getFlag("wfrp4e", "isAttached")} gorges and falls off.`)
+ await this.actor.unsetFlag("wfrp4e", "isAttached")
+ }
+ }
\ No newline at end of file
diff --git a/scripts/DWBxvzfWGcG7PVNP.js b/scripts/DWBxvzfWGcG7PVNP.js
new file mode 100644
index 0000000..789e83f
--- /dev/null
+++ b/scripts/DWBxvzfWGcG7PVNP.js
@@ -0,0 +1,5 @@
+let letter = this.item.system.location.key[0]; // "l" or "r";
+
+this.item.updateSource({"system.location.key" : letter + "Finger"})
+
+// We want the location to be Right or Left Hand, but the key to be rFinger or lFinger
\ No newline at end of file
diff --git a/scripts/DcSJNRBXE9ZBBY7T.js b/scripts/DcSJNRBXE9ZBBY7T.js
new file mode 100644
index 0000000..22c294b
--- /dev/null
+++ b/scripts/DcSJNRBXE9ZBBY7T.js
@@ -0,0 +1 @@
+this.actor.addCondition("blinded", Math.max(0, this.effect.sourceTest.result.SL))
\ No newline at end of file
diff --git a/scripts/DhZqJso1JWYtGrKk.js b/scripts/DhZqJso1JWYtGrKk.js
new file mode 100644
index 0000000..5808036
--- /dev/null
+++ b/scripts/DhZqJso1JWYtGrKk.js
@@ -0,0 +1,3 @@
+this.actor.addCondition("ablaze")
+let damage = this.effect.sourceTest.result.damage + this.effect.sourceTest.result.additionalDamage
+this.script.scriptMessage(await this.actor.applyBasicDamage(damage, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL, suppressMsg : true}))
\ No newline at end of file
diff --git a/scripts/DmbWR9s5I8LHBwxB.js b/scripts/DmbWR9s5I8LHBwxB.js
new file mode 100644
index 0000000..0875467
--- /dev/null
+++ b/scripts/DmbWR9s5I8LHBwxB.js
@@ -0,0 +1,14 @@
+let column = await ValueDialog.create("Select the column to roll on to determine Beast Head", "Select Column", "", ["Undivided", "Khorne", "Nurgle", "Slaanesh", "Tzeentch"]);
+
+if (column)
+{
+ let result = await game.wfrp4e.tables.rollTable("beasthead", {}, column);
+ this.script.scriptMessage(`${result.title}
${result.result}`);
+ let uuid = `Compendium.${result.object.documentCollection}.${result.object.documentId}`;
+ let item = await fromUuid(uuid);
+ if (item)
+ {
+ this.actor.createEmbeddedDocuments("Item", [item])
+ this.item.delete();
+ }
+}
\ No newline at end of file
diff --git a/scripts/DpdSEHM6NMN1ey6h.js b/scripts/DpdSEHM6NMN1ey6h.js
new file mode 100644
index 0000000..aa9268a
--- /dev/null
+++ b/scripts/DpdSEHM6NMN1ey6h.js
@@ -0,0 +1,4 @@
+if (parseInt(this.item.system.specification.value) > 0)
+{
+ this.actor.system.status.ward.value = parseInt(this.item.system.specification.value);
+}
\ No newline at end of file
diff --git a/scripts/DqJFo74trI916qXN.js b/scripts/DqJFo74trI916qXN.js
new file mode 100644
index 0000000..a2791f0
--- /dev/null
+++ b/scripts/DqJFo74trI916qXN.js
@@ -0,0 +1,3 @@
+let fatigued = args.actor.hasCondition("fatigued")
+if (fatigued)
+ setProperty(fatigued, "flags.wfrp4e.scriptData", getProperty(fatigued, "flags.wfrp4e.scriptData").filter(s => s.trigger != "dialog"))
\ No newline at end of file
diff --git a/scripts/DsE6rTSzxEn6uWMz.js b/scripts/DsE6rTSzxEn6uWMz.js
new file mode 100644
index 0000000..63b87e9
--- /dev/null
+++ b/scripts/DsE6rTSzxEn6uWMz.js
@@ -0,0 +1,7 @@
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "average"}})
+await test.roll();
+if (test.failed)
+{
+ await this.actor.addCondition("blinded");
+ await this.actor.addCondition("fatigued")
+}
\ No newline at end of file
diff --git a/scripts/DuM5l2Yb4bdvDeaG.js b/scripts/DuM5l2Yb4bdvDeaG.js
new file mode 100644
index 0000000..ddbd4db
--- /dev/null
+++ b/scripts/DuM5l2Yb4bdvDeaG.js
@@ -0,0 +1 @@
+return args.skill?.name != "Athletics"
\ No newline at end of file
diff --git a/scripts/DxQnamsb2AuW0p2e.js b/scripts/DxQnamsb2AuW0p2e.js
new file mode 100644
index 0000000..fbdcd2f
--- /dev/null
+++ b/scripts/DxQnamsb2AuW0p2e.js
@@ -0,0 +1 @@
+return !args.skill?.name.includes(game.i18n.localize("NAME.Lore"));
\ No newline at end of file
diff --git a/scripts/DyZ1jH88EAp1ueOK.js b/scripts/DyZ1jH88EAp1ueOK.js
new file mode 100644
index 0000000..3b86fbc
--- /dev/null
+++ b/scripts/DyZ1jH88EAp1ueOK.js
@@ -0,0 +1,5 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.GlShFJF2TpsNh1FX")
+let data = item.toObject();
+data.system.location.key = this.item.system.location.key
+data.system.location.value = data.system.location.value.replace("Arm", "Wrist")
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id})
diff --git a/scripts/E1Xo4RVuN1YRRxg7.js b/scripts/E1Xo4RVuN1YRRxg7.js
new file mode 100644
index 0000000..d6efa41
--- /dev/null
+++ b/scripts/E1Xo4RVuN1YRRxg7.js
@@ -0,0 +1 @@
+return args.item?.attackType != "ranged"
\ No newline at end of file
diff --git a/scripts/E1vUepgop09FF5wy.js b/scripts/E1vUepgop09FF5wy.js
new file mode 100644
index 0000000..3da19b7
--- /dev/null
+++ b/scripts/E1vUepgop09FF5wy.js
@@ -0,0 +1,22 @@
+if (this.actor.system.status.advantage.value == 0)
+{
+ return this.script.scriptNotification("Not enough Advantage!", "error")
+}
+
+let hatred = await fromUuid("Compendium.wfrp4e-core.items.Item.aE3pyW20Orvdjzj0")
+let frenzy = await fromUuid("Compendium.wfrp4e-core.items.Item.yRhhOlt18COq4e1q");
+
+if (this.actor.system.status.advantage.value >= 3)
+{
+ this.script.scriptNotification(`Adding ${frenzy.name}`)
+ this.actor.setAdvantage(0)
+ this.actor.createEmbeddedDocuments("Item", [frenzy])
+}
+else if (this.actor.system.status.advantage.value >= 1)
+{
+ let data = hatred.toObject();
+ data.system.specification.value = "Close Combat opponents"
+ this.script.scriptNotification(`Adding ${hatred.name}`)
+ this.actor.setAdvantage(0)
+ this.actor.createEmbeddedDocuments("Item", [data])
+}
\ No newline at end of file
diff --git a/scripts/E2VfOVuju67qO3VL.js b/scripts/E2VfOVuju67qO3VL.js
new file mode 100644
index 0000000..200ae8f
--- /dev/null
+++ b/scripts/E2VfOVuju67qO3VL.js
@@ -0,0 +1,5 @@
+let blinded = this.actor.hasCondition("blinded");
+if (blinded.getFlag("wfrp4e", "nightshroud"))
+{
+ blinded.delete()
+}
\ No newline at end of file
diff --git a/scripts/E4CHDe1xfmcV3oGv.js b/scripts/E4CHDe1xfmcV3oGv.js
new file mode 100644
index 0000000..c1e0400
--- /dev/null
+++ b/scripts/E4CHDe1xfmcV3oGv.js
@@ -0,0 +1 @@
+return args.skill?.name == game.i18n.localize("NAME.Navigation");
\ No newline at end of file
diff --git a/scripts/E6DMqfDeczqmVMFV.js b/scripts/E6DMqfDeczqmVMFV.js
new file mode 100644
index 0000000..2a0bc28
--- /dev/null
+++ b/scripts/E6DMqfDeczqmVMFV.js
@@ -0,0 +1,3 @@
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "average"}})
+
+await test.roll();
\ No newline at end of file
diff --git a/scripts/E7D4bxz8gy4e1wL7.js b/scripts/E7D4bxz8gy4e1wL7.js
new file mode 100644
index 0000000..ec82dce
--- /dev/null
+++ b/scripts/E7D4bxz8gy4e1wL7.js
@@ -0,0 +1 @@
+if (["Stealth (Rural)", "Track", "Outdoor Survival", "Swim", "Perception", "Intuition"].includes(args.item?.name))
\ No newline at end of file
diff --git a/scripts/EGWF3LHav3e2zFL4.js b/scripts/EGWF3LHav3e2zFL4.js
new file mode 100644
index 0000000..cb217a7
--- /dev/null
+++ b/scripts/EGWF3LHav3e2zFL4.js
@@ -0,0 +1 @@
+return args.skill?.name.includes(game.i18n.localize("NAME.Ranged")) || args.item?.isRanged || args.item?.name == game.i18n.localize("NAME.Charm");
\ No newline at end of file
diff --git a/scripts/EJObiSth3WdcJOXN.js b/scripts/EJObiSth3WdcJOXN.js
new file mode 100644
index 0000000..a98ecba
--- /dev/null
+++ b/scripts/EJObiSth3WdcJOXN.js
@@ -0,0 +1,5 @@
+if (args.test.characteristicKey == "wp" && args.test.failed && args.test.result.SL <= -3)
+{
+ this.script.scriptNotification("Adding Prone");
+ this.actor.addCondition("prone")
+}
\ No newline at end of file
diff --git a/scripts/EJaBfqADqlo92Fx6.js b/scripts/EJaBfqADqlo92Fx6.js
new file mode 100644
index 0000000..9fd2959
--- /dev/null
+++ b/scripts/EJaBfqADqlo92Fx6.js
@@ -0,0 +1,4 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.oGbDwnLOn3isPJpO")
+let data = item.toObject();
+data.name += " (To Be Determined)"
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/EKkdyp51Wf4csw2B.js b/scripts/EKkdyp51Wf4csw2B.js
new file mode 100644
index 0000000..e3d745d
--- /dev/null
+++ b/scripts/EKkdyp51Wf4csw2B.js
@@ -0,0 +1 @@
+return this.actor.statuses.has("frenzy");
\ No newline at end of file
diff --git a/scripts/ENGmwaItRXO5s0XY.js b/scripts/ENGmwaItRXO5s0XY.js
new file mode 100644
index 0000000..0a79fa7
--- /dev/null
+++ b/scripts/ENGmwaItRXO5s0XY.js
@@ -0,0 +1,5 @@
+await this.actor.modifyWounds(this.actor.system.characteristics.t.bonus * 3)
+this.script.scriptMessage(`Heals ${this.actor.system.characteristics.t.bonus * 3} Wounds`)
+
+this.actor.hasCondition("bleeding")?.delete()
+this.actor.hasCondition("fatigued")?.delete()
diff --git a/scripts/EQ5dtGW5kQhtAb87.js b/scripts/EQ5dtGW5kQhtAb87.js
new file mode 100644
index 0000000..767e730
--- /dev/null
+++ b/scripts/EQ5dtGW5kQhtAb87.js
@@ -0,0 +1,7 @@
+await this.actor.addCondition("prone")
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields: {difficulty : "hard"}, skipTargets: true, appendTitle : " - " + this.effect.name})
+await test.roll();
+if (test.failed)
+{
+ await this.actor.addCondition("stunned")
+}
\ No newline at end of file
diff --git a/scripts/ERxrWzSpw8qwxFVi.js b/scripts/ERxrWzSpw8qwxFVi.js
new file mode 100644
index 0000000..e0eaff5
--- /dev/null
+++ b/scripts/ERxrWzSpw8qwxFVi.js
@@ -0,0 +1 @@
+this.script.scriptNotification(`Cannot enter ${this.effect.name}!`); this.actor.addCondition("broken");
\ No newline at end of file
diff --git a/scripts/EU5j0hnDTG9Z6d1e.js b/scripts/EU5j0hnDTG9Z6d1e.js
new file mode 100644
index 0000000..82d6a1d
--- /dev/null
+++ b/scripts/EU5j0hnDTG9Z6d1e.js
@@ -0,0 +1,6 @@
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty: "hard"}})
+await test.roll();
+if(test.failed)
+{
+ this.actor.addCondition("stunned", 2)
+}
\ No newline at end of file
diff --git a/scripts/EVBSHEC5nmmj2X41.js b/scripts/EVBSHEC5nmmj2X41.js
new file mode 100644
index 0000000..c08a5ea
--- /dev/null
+++ b/scripts/EVBSHEC5nmmj2X41.js
@@ -0,0 +1 @@
+return args.skill?.name != game.i18n.localize("NAME.Climb") && !args.skill?.name?.includes(game.i18n.localize("NAME.Stealth"));
\ No newline at end of file
diff --git a/scripts/EYny6z5oTOhxGDfb.js b/scripts/EYny6z5oTOhxGDfb.js
new file mode 100644
index 0000000..087904f
--- /dev/null
+++ b/scripts/EYny6z5oTOhxGDfb.js
@@ -0,0 +1 @@
+args.fields.modifier -= 10;
diff --git a/scripts/EaSNOmXUxAkUHnm5.js b/scripts/EaSNOmXUxAkUHnm5.js
new file mode 100644
index 0000000..89a428d
--- /dev/null
+++ b/scripts/EaSNOmXUxAkUHnm5.js
@@ -0,0 +1,2 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.kKccDTGzWzSXCBOb")
+this.actor.createEmbeddedDocuments("Item", [item], {fromEffect: this.effect.id})
\ No newline at end of file
diff --git a/scripts/Eay7GpDyfsEE40jT.js b/scripts/Eay7GpDyfsEE40jT.js
new file mode 100644
index 0000000..14f4feb
--- /dev/null
+++ b/scripts/Eay7GpDyfsEE40jT.js
@@ -0,0 +1,4 @@
+if (args.totalWoundLoss > 0)
+{
+ args.actor.addCondition("ablaze")
+}
\ No newline at end of file
diff --git a/scripts/EdTChmSouS0MSmk5.js b/scripts/EdTChmSouS0MSmk5.js
new file mode 100644
index 0000000..b5c9aed
--- /dev/null
+++ b/scripts/EdTChmSouS0MSmk5.js
@@ -0,0 +1,10 @@
+let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`})
+await test.roll();
+if (test.succeeded)
+{
+ this.script.scriptMessage("Can perform an Action or Move (choose one)")
+}
+else
+{
+ this.script.scriptMessage("Cannot perform an Action or Move this round")
+}
\ No newline at end of file
diff --git a/scripts/EiLaZW4b4ypw5sLV.js b/scripts/EiLaZW4b4ypw5sLV.js
new file mode 100644
index 0000000..7761e61
--- /dev/null
+++ b/scripts/EiLaZW4b4ypw5sLV.js
@@ -0,0 +1,2 @@
+// can't use Damage application type because that checks if wounds were dealt
+args.actor.applyEffect({effectUuids : this.item.effects.contents[0].uuid})
\ No newline at end of file
diff --git a/scripts/EmXwcuycEH8slEn5.js b/scripts/EmXwcuycEH8slEn5.js
new file mode 100644
index 0000000..4bd0b62
--- /dev/null
+++ b/scripts/EmXwcuycEH8slEn5.js
@@ -0,0 +1,6 @@
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty: "hard"}})
+await test.roll();
+if(test.failed)
+{
+ this.actor.addCondition("unconscious")
+}
\ No newline at end of file
diff --git a/scripts/EmmG49pMOPHRwDzR.js b/scripts/EmmG49pMOPHRwDzR.js
new file mode 100644
index 0000000..8c92354
--- /dev/null
+++ b/scripts/EmmG49pMOPHRwDzR.js
@@ -0,0 +1,8 @@
+ let roll = Math.ceil(CONFIG.Dice.randomUniform() * 10)
+ if (args.test.isFumble && roll == 1 && !args.test.result.misfire)
+ {
+ args.test.result.misfire = game.i18n.localize("Misfire") + " (Rolled 1)"
+ args.test.result.misfireDamage = eval(parseInt(args.test.result.roll.toString().split('').pop()) + args.test.item.Damage)
+ }
+ else if (args.test.isFumble && roll != 1)
+ args.test.result.other.push("Misfire Roll: " + roll)
diff --git a/scripts/EpdMj9d9SYPeP44q.js b/scripts/EpdMj9d9SYPeP44q.js
new file mode 100644
index 0000000..ebf9773
--- /dev/null
+++ b/scripts/EpdMj9d9SYPeP44q.js
@@ -0,0 +1 @@
+return args.characteristic != "ag" && args.item?.id != this.item?.id
\ No newline at end of file
diff --git a/scripts/ErgOwSiVnm9VLVHN.js b/scripts/ErgOwSiVnm9VLVHN.js
new file mode 100644
index 0000000..f81a403
--- /dev/null
+++ b/scripts/ErgOwSiVnm9VLVHN.js
@@ -0,0 +1,2 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.Item.DrNUTPeodEgpWTnT")
+this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/Et4tPHlrkueLqP3T.js b/scripts/Et4tPHlrkueLqP3T.js
new file mode 100644
index 0000000..46d8efd
--- /dev/null
+++ b/scripts/Et4tPHlrkueLqP3T.js
@@ -0,0 +1 @@
+if (args.item.type == "skill") args.item.system.modifier.value -= 10
\ No newline at end of file
diff --git a/scripts/Ew3C2WmLCtc1KT46.js b/scripts/Ew3C2WmLCtc1KT46.js
new file mode 100644
index 0000000..9e8991b
--- /dev/null
+++ b/scripts/Ew3C2WmLCtc1KT46.js
@@ -0,0 +1 @@
+return args.skill?.name.includes(game.i18n.localize("NAME.Stealth")) || args.item?.id == this.item?.id
\ No newline at end of file
diff --git a/scripts/EwD053Fyy46b59ZI.js b/scripts/EwD053Fyy46b59ZI.js
new file mode 100644
index 0000000..4512a9a
--- /dev/null
+++ b/scripts/EwD053Fyy46b59ZI.js
@@ -0,0 +1,2 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.Item.6l3jvIAvrKxt0lA9");
+this.actor.createEmbeddedDocuments("Item", [item], {fromEffect: this.effect.id})
\ No newline at end of file
diff --git a/scripts/Eye6dranWpNsILjm.js b/scripts/Eye6dranWpNsILjm.js
new file mode 100644
index 0000000..917fad5
--- /dev/null
+++ b/scripts/Eye6dranWpNsILjm.js
@@ -0,0 +1,4 @@
+if (this.actor.system.status.wounds.value <= 1)
+{
+ this.effect.delete();
+}
\ No newline at end of file
diff --git a/scripts/F4aGsdzJ9SYcX57F.js b/scripts/F4aGsdzJ9SYcX57F.js
new file mode 100644
index 0000000..57eb47b
--- /dev/null
+++ b/scripts/F4aGsdzJ9SYcX57F.js
@@ -0,0 +1,10 @@
+if (args.equipped)
+{
+ let item = await fromUuid("Compendium.wfrp4e-core.items.HpFkVJ2lYPAWumUL")
+ let data = item.toObject();
+ this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
+}
+else
+{
+ this.effect.deleteCreatedItems();
+}
\ No newline at end of file
diff --git a/scripts/FAB12eLcSCAOOQwk.js b/scripts/FAB12eLcSCAOOQwk.js
new file mode 100644
index 0000000..4e92511
--- /dev/null
+++ b/scripts/FAB12eLcSCAOOQwk.js
@@ -0,0 +1 @@
+this.script.scirptMessage(await this.actor.applyBasicDamage(20, {suppressMsg: true});
\ No newline at end of file
diff --git a/scripts/FAf4iXj5LkdvukS2.js b/scripts/FAf4iXj5LkdvukS2.js
new file mode 100644
index 0000000..a39a05c
--- /dev/null
+++ b/scripts/FAf4iXj5LkdvukS2.js
@@ -0,0 +1 @@
+fromUuid("Compendium.wfrp4e-wom.items.0Xdm4r7l2EwC4fcg").then(item => Item.create(item.toObject(), {fromEffect : this.effect.id, parent : this.actor}))
\ No newline at end of file
diff --git a/scripts/FMA16PvoObBV8vDl.js b/scripts/FMA16PvoObBV8vDl.js
new file mode 100644
index 0000000..873a4f2
--- /dev/null
+++ b/scripts/FMA16PvoObBV8vDl.js
@@ -0,0 +1,5 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.EO05HX7jql0g605A")
+item = item.toObject()
+item.system.specification.value = 20
+this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id})
+this.script.scriptNotification(item.name + " added")
\ No newline at end of file
diff --git a/scripts/FMSN5uRskkATexzB.js b/scripts/FMSN5uRskkATexzB.js
new file mode 100644
index 0000000..913a79d
--- /dev/null
+++ b/scripts/FMSN5uRskkATexzB.js
@@ -0,0 +1 @@
+game.wfrp4e.tables.rollToChat("crithead")
\ No newline at end of file
diff --git a/scripts/FSqUqSByMiztYOQM.js b/scripts/FSqUqSByMiztYOQM.js
new file mode 100644
index 0000000..5bf62e7
--- /dev/null
+++ b/scripts/FSqUqSByMiztYOQM.js
@@ -0,0 +1,2 @@
+if (args.totalWoundLoss > 0)
+ this.script.scriptMessage(`Infected: ${args.actor.name} must pass an Easy (+40) Endurance Test or gain a @UUID[Compendium.wfrp4e-core.items.kKccDTGzWzSXCBOb]{Festering Wound}`, {whisper: ChatMessage.getWhisperRecipients("GM") })
\ No newline at end of file
diff --git a/scripts/FUgCtIoj1Stgqxt7.js b/scripts/FUgCtIoj1Stgqxt7.js
new file mode 100644
index 0000000..acd0a25
--- /dev/null
+++ b/scripts/FUgCtIoj1Stgqxt7.js
@@ -0,0 +1 @@
+return !["ws", "bs", "s", "ag", "t", "dex"].includes(args.characteristic)
\ No newline at end of file
diff --git a/scripts/FXuyiJoXdAh6WhRK.js b/scripts/FXuyiJoXdAh6WhRK.js
new file mode 100644
index 0000000..6e7b684
--- /dev/null
+++ b/scripts/FXuyiJoXdAh6WhRK.js
@@ -0,0 +1 @@
+return args.skill?.name == "Ride (Horse)" && game.combat?.active
\ No newline at end of file
diff --git a/scripts/FXwfqF0jpXlBQ9Y3.js b/scripts/FXwfqF0jpXlBQ9Y3.js
new file mode 100644
index 0000000..31fa389
--- /dev/null
+++ b/scripts/FXwfqF0jpXlBQ9Y3.js
@@ -0,0 +1 @@
+return args.item?.system?.isMelee && this.actor.attacker
\ No newline at end of file
diff --git a/scripts/FYUPfYyTYZkxRLFT.js b/scripts/FYUPfYyTYZkxRLFT.js
new file mode 100644
index 0000000..35e86d3
--- /dev/null
+++ b/scripts/FYUPfYyTYZkxRLFT.js
@@ -0,0 +1 @@
+return !["NAME.Endurance", "NAME.Cool"].map(i => game.i18n.localize(i)).includes(args.skill?.name)
\ No newline at end of file
diff --git a/scripts/FZFOC7bip0oiWEzk.js b/scripts/FZFOC7bip0oiWEzk.js
new file mode 100644
index 0000000..11e7cfd
--- /dev/null
+++ b/scripts/FZFOC7bip0oiWEzk.js
@@ -0,0 +1,5 @@
+if (args.opposedTest.result.hitloc.value == this.item.system.location.key && args.totalWoundLoss > 0)
+{
+ args.actor.addCondition("bleeding", 2);
+ this.script.scriptNotification("Added Bleeding")
+}
\ No newline at end of file
diff --git a/scripts/FciJSTq7dZsZIPgl.js b/scripts/FciJSTq7dZsZIPgl.js
new file mode 100644
index 0000000..0da31e8
--- /dev/null
+++ b/scripts/FciJSTq7dZsZIPgl.js
@@ -0,0 +1,10 @@
+if (args.equipped)
+{
+ let item = await fromUuid("Compendium.wfrp4e-core.items.SfUUdOGjdYpr3KSR")
+ let data = item.toObject();
+ this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
+}
+else
+{
+ this.effect.deleteCreatedItems();
+}
\ No newline at end of file
diff --git a/scripts/FfTqCPxCoxwGDTQs.js b/scripts/FfTqCPxCoxwGDTQs.js
new file mode 100644
index 0000000..bc75552
--- /dev/null
+++ b/scripts/FfTqCPxCoxwGDTQs.js
@@ -0,0 +1,3 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.wMwSRDmgiF2IdCJr")
+let data = item.toObject()
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
diff --git a/scripts/FiD3mvWIBHNNIuO9.js b/scripts/FiD3mvWIBHNNIuO9.js
new file mode 100644
index 0000000..f9fadbe
--- /dev/null
+++ b/scripts/FiD3mvWIBHNNIuO9.js
@@ -0,0 +1,8 @@
+if (args.opposedTest.result.hitloc.value == "body")
+{
+ if ((await new Roll("1d2").roll()).total == 1)
+ {
+ args.opposedTest.result.hitloc.value = "head"
+ this.script.scriptMessage(`Hit location changed to Head`)
+ }
+}
\ No newline at end of file
diff --git a/scripts/FkTwk8hfHpRLbAp2.js b/scripts/FkTwk8hfHpRLbAp2.js
new file mode 100644
index 0000000..cd051cb
--- /dev/null
+++ b/scripts/FkTwk8hfHpRLbAp2.js
@@ -0,0 +1,6 @@
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`});
+await test.roll();
+if (test.failed)
+{
+ this.actor.addCondition("prone")
+}
\ No newline at end of file
diff --git a/scripts/FmLx9pwOkzqqU7Ph.js b/scripts/FmLx9pwOkzqqU7Ph.js
new file mode 100644
index 0000000..c54d1df
--- /dev/null
+++ b/scripts/FmLx9pwOkzqqU7Ph.js
@@ -0,0 +1 @@
+return args.skill?.name == game.i18n.localize("NAME.Track");
\ No newline at end of file
diff --git a/scripts/FqevMs0ukQ9WuUHl.js b/scripts/FqevMs0ukQ9WuUHl.js
new file mode 100644
index 0000000..d352c76
--- /dev/null
+++ b/scripts/FqevMs0ukQ9WuUHl.js
@@ -0,0 +1,9 @@
+// Each time the blade is used, the GM should secretly roll a d10.
+// On a 1, its poison has run dry,
+// and the next time it is employed it will shatter.
+
+if (this.item.getFlag("wfrp4e", "brittle"))
+{
+ ChatMessage.create({content: `${this.item.name} shatters!`})
+ this.item.update({name : `${this.item.name} (Shattered)`})
+}
\ No newline at end of file
diff --git a/scripts/Fvlc4RkeF4dHjW3m.js b/scripts/Fvlc4RkeF4dHjW3m.js
new file mode 100644
index 0000000..1fc9418
--- /dev/null
+++ b/scripts/Fvlc4RkeF4dHjW3m.js
@@ -0,0 +1,16 @@
+let caster = this.effect.sourceActor
+if (caster && (this.actor.has(game.i18n.localize("NAME.Undead")) || this.actor.has(game.i18n.localize("NAME.Daemonic")))) {
+ let wp = caster.system.characteristics.wp.value
+ if (wp > this.actor.system.characteristics.t.value) {
+ if (this.actor.has(game.i18n.localize("NAME.Unstable"))) {
+ this.actor.update({ "system.status.wounds.value": 0 })
+ this.actor.addCondition("dead")
+ }
+ else {
+ fromUuid("Compendium.wfrp4e-core.items.D0ImWEIMSDgElsnl").then(item => {
+ this.actor.createEmbeddedDocuments("Item", [item.toObject()], { fromEffect: this.effect.id })
+ ChatMessage.create({ content: `Added Unstable to ${this.actor.prototypeToken.name}`, speaker: { alias: caster.name } })
+ })
+ }
+ }
+}
\ No newline at end of file
diff --git a/scripts/G1RletYc6BzigJrK.js b/scripts/G1RletYc6BzigJrK.js
new file mode 100644
index 0000000..24f4082
--- /dev/null
+++ b/scripts/G1RletYc6BzigJrK.js
@@ -0,0 +1,2 @@
+let ablaze = parseInt(this.effect.sourceTest.result.SL) + 5
+args.actor.addCondition("ablaze", ablaze)
\ No newline at end of file
diff --git a/scripts/G7sFEnJlXZvfXL3V.js b/scripts/G7sFEnJlXZvfXL3V.js
new file mode 100644
index 0000000..758b802
--- /dev/null
+++ b/scripts/G7sFEnJlXZvfXL3V.js
@@ -0,0 +1,12 @@
+if (this.item.system.quantity.value)
+{
+ this.item.system.reduceQuantity();
+ let actor = Array.from(game.user.targets)[0]?.actor || this.actor;
+ let effectData = this.item.effects.contents[1].convertToApplied();
+ effectData.flags.wfrp4e.sourceItem = this.item.uuid
+ actor.applyEffect({effectData : [effectData]})
+}
+else
+{
+ this.script.scriptNotification("None left!", "error")
+}
\ No newline at end of file
diff --git a/scripts/GAO8AozttWOyRkta.js b/scripts/GAO8AozttWOyRkta.js
new file mode 100644
index 0000000..796ff24
--- /dev/null
+++ b/scripts/GAO8AozttWOyRkta.js
@@ -0,0 +1,5 @@
+if (!args.flags.lostHand)
+{
+ args.fields.lostHand = true;
+ args.fields.modifier += -20;
+}
\ No newline at end of file
diff --git a/scripts/GEfWIFBSrXt0ldBM.js b/scripts/GEfWIFBSrXt0ldBM.js
new file mode 100644
index 0000000..b4de7ed
--- /dev/null
+++ b/scripts/GEfWIFBSrXt0ldBM.js
@@ -0,0 +1,2 @@
+(await new Roll("1d10").roll()).toMessage(this.script.getChatData())
+await this.actor.addCondition("dead")
\ No newline at end of file
diff --git a/scripts/GFaTz8f6PBNWrlad.js b/scripts/GFaTz8f6PBNWrlad.js
new file mode 100644
index 0000000..509844b
--- /dev/null
+++ b/scripts/GFaTz8f6PBNWrlad.js
@@ -0,0 +1,3 @@
+let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, context : {failure : `Confused: Determine behaviour by @Table[bewilder] Table.`}})
+await test.roll();
+return test.failed
\ No newline at end of file
diff --git a/scripts/GFkVnx4m9OwYsKGH.js b/scripts/GFkVnx4m9OwYsKGH.js
new file mode 100644
index 0000000..864fe17
--- /dev/null
+++ b/scripts/GFkVnx4m9OwYsKGH.js
@@ -0,0 +1 @@
+args.actor.flags.ambi+= 1
\ No newline at end of file
diff --git a/scripts/GNl5Zk7BZ2jhRV1I.js b/scripts/GNl5Zk7BZ2jhRV1I.js
new file mode 100644
index 0000000..fca7f72
--- /dev/null
+++ b/scripts/GNl5Zk7BZ2jhRV1I.js
@@ -0,0 +1,4 @@
+if (args.item.type == "armour")
+{
+ args.item.system.AP.head = 0;
+}
\ No newline at end of file
diff --git a/scripts/GOq4TcnWbfyfCo2V.js b/scripts/GOq4TcnWbfyfCo2V.js
new file mode 100644
index 0000000..3a51404
--- /dev/null
+++ b/scripts/GOq4TcnWbfyfCo2V.js
@@ -0,0 +1,26 @@
+this.script.scriptNotification(`Healed ${this.actor.characteristics.t.bonus * 2} Wounds`)
+await this.actor.modifyWounds(this.actor.characteristics.t.bonus * 2)
+
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - Side Effects`,fields : {difficulty : "difficult"}})
+await test.roll();
+if (test.failed)
+{
+ let roll = await new Roll("1d10").roll();
+ await roll.toMessage(this.script.getChatData())
+ if (roll.total <= 3)
+ {
+ this.actor.addCondition("blinded", 3)
+ }
+ else if (roll.total <= 6)
+ {
+ this.actor.addCondition("broken");
+ }
+ else if (roll.total <= 9)
+ {
+ this.actor.addCondition("stunned");
+ }
+ else if (roll.total == 10)
+ {
+ this.actor.addConditon("unconscious")
+ }
+}
\ No newline at end of file
diff --git a/scripts/GRfCxtYzmEx2LYU7.js b/scripts/GRfCxtYzmEx2LYU7.js
new file mode 100644
index 0000000..dcc7340
--- /dev/null
+++ b/scripts/GRfCxtYzmEx2LYU7.js
@@ -0,0 +1,9 @@
+if (args.totalWoundLoss >= 1)
+{
+ let roll = await new Roll("1d10").roll();
+ await roll.toMessage(this.script.getChatData());
+ if (roll.total == 9)
+ {
+ this.script.scriptMessage(`Two @UUID[Compendium.wfrp4e-eis.actors.iDy8SDTwJSlCzZMl]{Blue Horror of Tzeentch} claw their way out of ${this.actor.name}'s screaming flesh, killing them in the process.`, {whisper : ChatMessage.getWhisperRecipients("GM")})
+ }
+}
\ No newline at end of file
diff --git a/scripts/GTZUO73pUJKpM1JB.js b/scripts/GTZUO73pUJKpM1JB.js
new file mode 100644
index 0000000..3d99c30
--- /dev/null
+++ b/scripts/GTZUO73pUJKpM1JB.js
@@ -0,0 +1,3 @@
+ let roll = await new Roll("1d10").roll();
+ game.dice3d?.showForRoll(roll);
+ this.script.scriptMessage(await this.actor.applyBasicDamage(roll.total, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL, suppressMsg : true}))
diff --git a/scripts/GUkpYdPwoC5pc9BT.js b/scripts/GUkpYdPwoC5pc9BT.js
new file mode 100644
index 0000000..160e012
--- /dev/null
+++ b/scripts/GUkpYdPwoC5pc9BT.js
@@ -0,0 +1 @@
+return !args.weapon?.system.properties.flaws.crewed
\ No newline at end of file
diff --git a/scripts/GZFsuynUhgZqwTGo.js b/scripts/GZFsuynUhgZqwTGo.js
new file mode 100644
index 0000000..bf5a7a7
--- /dev/null
+++ b/scripts/GZFsuynUhgZqwTGo.js
@@ -0,0 +1,10 @@
+if (args.totalWoundLoss >= 1)
+{
+ let test = await args.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, context: { failure: "Gained a Poisoned Condition", success: "Resisted the poison" }})
+ await test.roll();
+ if (test.failed)
+ {
+ args.actor.addCondition("poisoned");
+ }
+}
+
\ No newline at end of file
diff --git a/scripts/GbPEy22VuCNzlNv2.js b/scripts/GbPEy22VuCNzlNv2.js
new file mode 100644
index 0000000..be6b4de
--- /dev/null
+++ b/scripts/GbPEy22VuCNzlNv2.js
@@ -0,0 +1 @@
+return !this.actor.isMounted || (!args.skill?.name?.includes(game.i18n.localize("NAME.Ride")) && !args.options.dodge)
\ No newline at end of file
diff --git a/scripts/Gc8S5TYlVdV8NnOT.js b/scripts/Gc8S5TYlVdV8NnOT.js
new file mode 100644
index 0000000..154ee3e
--- /dev/null
+++ b/scripts/Gc8S5TYlVdV8NnOT.js
@@ -0,0 +1,8 @@
+let test = await args.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : " - " + this.effect.name, context: { failure: "Gained a Broken Condition", success: "Resisted the Broken Condition" } })
+
+ await test.roll();
+
+ if (!test.succeeded)
+ {
+ args.actor.addCondition("broken");
+ }
\ No newline at end of file
diff --git a/scripts/GcIQtshex11AMmh2.js b/scripts/GcIQtshex11AMmh2.js
new file mode 100644
index 0000000..793a7a8
--- /dev/null
+++ b/scripts/GcIQtshex11AMmh2.js
@@ -0,0 +1,25 @@
+if (this.item.system.isEquipped)
+{
+ let removeRepeater = false
+ if(!this.item.system.offhand.value) // main
+ {
+ let offhandUsed = this.actor.itemTypes.weapon.find(i => i.system.isEquipped && i.system.offhand.value)
+ if (offhandUsed)
+ {
+ removeRepeater = true;
+ }
+ }
+ else // offhand
+ {
+ let mainhandUsed = this.actor.itemTypes.weapon.find(i => i.system.isEquipped && !i.system.offhand.value)
+ if (mainhandUsed)
+ {
+ removeRepeater = true;
+ }
+ }
+
+ if (removeRepeater)
+ {
+ this.item.system.qualities.value = this.item.system.qualities.value.filter(i => i.name != "repeater")
+ }
+}
\ No newline at end of file
diff --git a/scripts/Gh7OidY6UdpWBS1g.js b/scripts/Gh7OidY6UdpWBS1g.js
new file mode 100644
index 0000000..85ee2d0
--- /dev/null
+++ b/scripts/Gh7OidY6UdpWBS1g.js
@@ -0,0 +1,3 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.KII1gWnxIZ8HzmU5")
+let data = item.toObject();
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/GjkxWj9wCAclM9WA.js b/scripts/GjkxWj9wCAclM9WA.js
new file mode 100644
index 0000000..6fefe6d
--- /dev/null
+++ b/scripts/GjkxWj9wCAclM9WA.js
@@ -0,0 +1,17 @@
+let effects = foundry.utils.deepClone(this.item.effects.contents.filter(e => e.active));
+
+effects.splice(effects.length - 1);
+
+if (effects.length == 0)
+{
+ return this.script.scriptNotification("All Effects have been used. Reset to select them again")
+}
+let choice = await ItemDialog.create(effects, 1, "Choose Power to Gain");
+
+if (choice[0])
+{
+ choice[0].update({disabled : true})
+ let effect = choice[0].convertToApplied();
+ effect.name += ` (${this.effect.name})`
+ this.actor.createEmbeddedDocuments("ActiveEffect", [effect]);
+}
\ No newline at end of file
diff --git a/scripts/GrF6tQ08jgKmUH4i.js b/scripts/GrF6tQ08jgKmUH4i.js
new file mode 100644
index 0000000..356b70b
--- /dev/null
+++ b/scripts/GrF6tQ08jgKmUH4i.js
@@ -0,0 +1 @@
+return !["ws", "bs", "s", "ag", "i"].includes(args.characteristic)
\ No newline at end of file
diff --git a/scripts/GuUCErVbk5hrFzR3.js b/scripts/GuUCErVbk5hrFzR3.js
new file mode 100644
index 0000000..85bf7f6
--- /dev/null
+++ b/scripts/GuUCErVbk5hrFzR3.js
@@ -0,0 +1 @@
+args.multiplier.tb += 1
\ No newline at end of file
diff --git a/scripts/GuxbvztcvzJz2oH1.js b/scripts/GuxbvztcvzJz2oH1.js
new file mode 100644
index 0000000..fb1c17c
--- /dev/null
+++ b/scripts/GuxbvztcvzJz2oH1.js
@@ -0,0 +1 @@
+args.item.system.qualities.value = [];
\ No newline at end of file
diff --git a/scripts/GzSFlqL1YrIK1dxh.js b/scripts/GzSFlqL1YrIK1dxh.js
new file mode 100644
index 0000000..1f5a252
--- /dev/null
+++ b/scripts/GzSFlqL1YrIK1dxh.js
@@ -0,0 +1,16 @@
+let items = await Promise.all(["Compendium.wfrp4e-wom.items.Item.EjGYZ4CgX2jZW7Ot",
+"Compendium.wfrp4e-wom.items.Item.O2v9RQiFf0obskP5",
+"Compendium.wfrp4e-wom.items.Item.2cv6hhZ57iV6z5Il",
+"Compendium.wfrp4e-wom.items.Item.YgDEUO0G0XcqQJqg",
+"Compendium.wfrp4e-wom.items.Item.J6K5TPxI8qIGQKKH",
+"Compendium.wfrp4e-wom.items.Item.K9FPtiDLwTkC7FuO",
+"Compendium.wfrp4e-wom.items.Item.CkMYRYCLrkMnyVm5",
+"Compendium.wfrp4e-wom.items.Item.0Xdm4r7l2EwC4fcg"].map(fromUuid));
+
+let choice = await game.wfrp4e.apps.ItemDialog.create(items, 1, "Select Wind")
+//this.actor.createEmbeddedDocuments("Item", items);
+
+this.item.update(choice[0]?.toObject(), {diff: false, recursive : false});
+
+//this.actor.items.getName(this.effect.item.name).delete() // For some reason this.effect.item.delete() throws an error
+
diff --git a/scripts/GzsuEg7gZy1f0ljy.js b/scripts/GzsuEg7gZy1f0ljy.js
new file mode 100644
index 0000000..3220372
--- /dev/null
+++ b/scripts/GzsuEg7gZy1f0ljy.js
@@ -0,0 +1,10 @@
+let bleeding = this.actor.hasCondition("bleeding")
+if (bleeding)
+{
+ this.script.scriptNotification(`Cleared ${bleeding.conditionValue} Bleeding Conditions`)
+ bleeding.delete();
+}
+else
+{
+ this.script.scriptNotification(`No Bleeding Conditions`)
+}
\ No newline at end of file
diff --git a/scripts/H06Ysj7oPiemW7S6.js b/scripts/H06Ysj7oPiemW7S6.js
new file mode 100644
index 0000000..8c3872b
--- /dev/null
+++ b/scripts/H06Ysj7oPiemW7S6.js
@@ -0,0 +1,18 @@
+if (args.test.options.income && !args.test.options.criminal)
+{
+ args.test.options.criminal = true;
+ let currentCareer = args.test.actor.system.currentCareer;
+ let coin = {1 : "b", 2 : "s", 3 : "s", 4 : "g"}[currentCareer.system.level.value] // b, s, or g maps to 2d10, 1d10, or 1 respectively (takes the first letter)
+ let term = {1 : "bp", 2 : "ss", 3 : "ss", 4 : "gc"}[currentCareer.system.level.value] // b, s, or g maps to 2d10, 1d10, or 1 respectively (takes the first letter)
+ let dieAmount = {1 : "2d10", 2 : "1d10", 3 : "2d10", 4 : "1"}[currentCareer.system.level.value] // b, s, or g maps to 2d10, 1d10, or 1 respectively (takes the first letter)
+ dieAmount = parseInt(dieAmount[0]) * this.item.system.Advances; // Multilpy that first letter by your standing (Brass 4 = 8d10 pennies)
+ if (coin != "g") // Don't roll for gold, just use standing value
+ {
+ dieAmount = dieAmount + "d10";
+ }
+ let moneyEarned = (await new Roll(dieAmount.toString()).roll()).total;
+ let moneyString = `${moneyEarned}${coin}`
+ let transactionString = `${moneyEarned}${term}`
+
+ this.script.scriptMessage(`Earned an additional ${game.wfrp4e.market.amountToString(game.wfrp4e.market.parseMoneyTransactionString(transactionString))}`, {whisper : ChatMessage.getWhisperRecipients("GM")})
+}
\ No newline at end of file
diff --git a/scripts/H1z3nWW7Rj3Oisxy.js b/scripts/H1z3nWW7Rj3Oisxy.js
new file mode 100644
index 0000000..a7b8f33
--- /dev/null
+++ b/scripts/H1z3nWW7Rj3Oisxy.js
@@ -0,0 +1 @@
+return args.type != "channelling"
\ No newline at end of file
diff --git a/scripts/H2CJvApKMnfGNNoo.js b/scripts/H2CJvApKMnfGNNoo.js
new file mode 100644
index 0000000..60892cb
--- /dev/null
+++ b/scripts/H2CJvApKMnfGNNoo.js
@@ -0,0 +1,7 @@
+ if (args.test.item?.type == "skill" && args.test.item.name.includes(game.i18n.localize("NAME.Stealth")))
+{
+ args.test.result.description = "Astounding Failure";
+ args.test.result.outcome = "failure";
+ ChatMessage.create({content : "SQUEAK", speaker : ChatMessage.getSpeaker({token: this.actor.getActiveTokens()[0]?.document, actor: this.actor})}, {chatBubble : true})
+ AudioHelper.play({ src: `${game.settings.get("wfrp4e", "soundPath")}squeek.wav` }, true);
+}
\ No newline at end of file
diff --git a/scripts/H3Wls12aVWAWTp9J.js b/scripts/H3Wls12aVWAWTp9J.js
new file mode 100644
index 0000000..32f6ee1
--- /dev/null
+++ b/scripts/H3Wls12aVWAWTp9J.js
@@ -0,0 +1,3 @@
+this.actor.setupCharacteristic("i", {skipTargets: true, appendTitle : " - " + this.effect.name}).then(test => {
+ test.roll();
+})
\ No newline at end of file
diff --git a/scripts/H3pZ9UeIzIz3luKh.js b/scripts/H3pZ9UeIzIz3luKh.js
new file mode 100644
index 0000000..c120317
--- /dev/null
+++ b/scripts/H3pZ9UeIzIz3luKh.js
@@ -0,0 +1,5 @@
+args.actor.addCondition("bleeding")
+
+this.actor.setFlag("wfrp4e", "isAttached", args.actor.name)
+
+this.script.scriptMessage(`Attaches to ${args.actor.name}`)
\ No newline at end of file
diff --git a/scripts/HASsi6wYHVALExWq.js b/scripts/HASsi6wYHVALExWq.js
new file mode 100644
index 0000000..93a5c23
--- /dev/null
+++ b/scripts/HASsi6wYHVALExWq.js
@@ -0,0 +1,14 @@
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, context: { failure: "1 Corruption Point Gained" } })
+await test.roll();
+
+if (test.failed && args.actor.type == "character")
+{
+ let msg = ""
+ msg += `
${this.actor.prototypeToken.name} gained a Corruption point
` + if (test.result.roll % 11 == 0 || test.result.roll == 100) + { + msg += `${args.actor.prototypeToken.name} gains a mutation (@Table[expandedmutatephys]{Physical} or @Table[expandedmutatemental]{Mental}) and gains @UUID[Compendium.wfrp4e-core.items.hiU7vhBOVpVI8c7C]{Chaos Magic (Tzeentch)}` + } + this.script.scriptMessage(msg, {whisper : ChatMessage.getWhisperRecipients("GM")}) + await this.actor.update({ "system.status.corruption.value": parseInt(args.actor.status.corruption.value) + 1 }) +} \ No newline at end of file diff --git a/scripts/HJ2X4ZtXei0BXbxf.js b/scripts/HJ2X4ZtXei0BXbxf.js new file mode 100644 index 0000000..9042978 --- /dev/null +++ b/scripts/HJ2X4ZtXei0BXbxf.js @@ -0,0 +1,19 @@ + let choices = await Promise.all([game.wfrp4e.utility.findItemId("PzimjNx9Ojq4g6mV"), game.wfrp4e.utility.findItemId("rOPmyLWa37e7s9v6")]) + let items = await game.wfrp4e.apps.ItemDialog.create(choices, 1, "Choose a Skill") + + items = items.map(i => i.toObject()) + items.forEach(i => i.system.advances.value = 20) + +items.forEach(i => equip(i)) + +this.actor.createEmbeddedDocuments("Item", items); + +function equip(item) +{ + if (item.type == "armour") + item.data.worn.value = true + else if (item.type == "weapon") + item.data.equipped = true + else if (item.type == "trapping" && item.data.trappingType.value == "clothingAccessories") + item.data.worn = true +} \ No newline at end of file diff --git a/scripts/HKhyn0kijKfzW6cw.js b/scripts/HKhyn0kijKfzW6cw.js new file mode 100644 index 0000000..bb191fa --- /dev/null +++ b/scripts/HKhyn0kijKfzW6cw.js @@ -0,0 +1,3 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty: "hard"}}) +await test.roll(); +this.item.updateSource({"flags.wfrp4e.passed" : test.succeeded}) \ No newline at end of file diff --git a/scripts/HMC6hPND9DWLFfZE.js b/scripts/HMC6hPND9DWLFfZE.js new file mode 100644 index 0000000..b975613 --- /dev/null +++ b/scripts/HMC6hPND9DWLFfZE.js @@ -0,0 +1,43 @@ +if (this.item.name.includes("(")) +{ + return; +} + +let index = game.packs +.filter(i => i.metadata.type == "Item") +.reduce((acc, pack) => acc.concat(pack.index.contents), []) +.filter(i => i.type == "skill" && i.name.includes(game.i18n.localize("NAME.Lore"))) +.map(i => { + i.id = i._id + return i +}) + +let choice = await ItemDialog.create(index, 1, "Choose a Lore") +let text; +if (!choice[0]) +{ + let custom = await Dialog.wait({ + title : "Enter Lore", + content : "", + buttons : { + confirm : { + label : game.i18n.localize("Confirm"), + callback : (dlg) => { + return dlg.find("input")[0].value + } + } + }, + default : "confirm", + close : () => { + return "" + } + }) + text = custom || "" +} +else +{ + text = game.wfrp4e.utility.extractParenthesesText(choice[0].name) +} + +await this.item.updateSource({name : this.item.name + ` (${text})`, "system.tests.value" : this.item.system.tests.value.replace("chosen Lore", text)}) +await this.effect.updateSource({name : this.effect.name + ` (${text})`}) \ No newline at end of file diff --git a/scripts/HOt2hHOiHDZ7oBgW.js b/scripts/HOt2hHOiHDZ7oBgW.js new file mode 100644 index 0000000..af34a62 --- /dev/null +++ b/scripts/HOt2hHOiHDZ7oBgW.js @@ -0,0 +1,4 @@ +if (["rLeg", "lLeg"].includes(this.effect.getFlag("wfrp4e", "location"))) +{ + args.actor.details.move.value /= 2 +} diff --git a/scripts/HX6CjNapYdC0VmQ8.js b/scripts/HX6CjNapYdC0VmQ8.js new file mode 100644 index 0000000..36a39a6 --- /dev/null +++ b/scripts/HX6CjNapYdC0VmQ8.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.epPBu7x6BRWp2PHG") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/HXJKkmpfxQUOnWOS.js b/scripts/HXJKkmpfxQUOnWOS.js new file mode 100644 index 0000000..34affd7 --- /dev/null +++ b/scripts/HXJKkmpfxQUOnWOS.js @@ -0,0 +1,4 @@ +if (!this.item.system.twohanded.value) +{ + this.item.system.flaws.value = this.item.system.flaws.value.concat([{name : "tiring"}, {name : "slow"}]) +} \ No newline at end of file diff --git a/scripts/Hcpn1gU58DIKIhty.js b/scripts/Hcpn1gU58DIKIhty.js new file mode 100644 index 0000000..6d5917a --- /dev/null +++ b/scripts/Hcpn1gU58DIKIhty.js @@ -0,0 +1,4 @@ +if (args.item.type == "skill" && args.item.name == "Melee (Flail)") +{ + args.item.system.modifier.value += 10; +} \ No newline at end of file diff --git a/scripts/HfCxNd7mFGZH4s9Y.js b/scripts/HfCxNd7mFGZH4s9Y.js new file mode 100644 index 0000000..07fcf28 --- /dev/null +++ b/scripts/HfCxNd7mFGZH4s9Y.js @@ -0,0 +1,13 @@ +// An opponent that takes more than a single Wound from a Warp Blade strike +// in melee combat must make an Average (+20) Endurance Test +// or take a Stunned Condition + + +if (args.totalWoundLoss > 1) { + let test = await args.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields : {difficulty : "average"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`}) + await test.roll(); + if(test.failed) + { + await args.actor.addCondition("stunned"); + } +} \ No newline at end of file diff --git a/scripts/HiMBS6GeOwEydWYN.js b/scripts/HiMBS6GeOwEydWYN.js new file mode 100644 index 0000000..9ad95cd --- /dev/null +++ b/scripts/HiMBS6GeOwEydWYN.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Climb"); \ No newline at end of file diff --git a/scripts/HmImVzvw6ecBy99l.js b/scripts/HmImVzvw6ecBy99l.js new file mode 100644 index 0000000..1731116 --- /dev/null +++ b/scripts/HmImVzvw6ecBy99l.js @@ -0,0 +1,5 @@ +if (args.opposedTest.result.hitloc.value == "body" && args.totalWoundLoss > 0) +{ + args.actor.addCondition("bleeding", 2) + this.script.scriptNotification("Added Bleeding") +} \ No newline at end of file diff --git a/scripts/HoNTnPphrJISSQr1.js b/scripts/HoNTnPphrJISSQr1.js new file mode 100644 index 0000000..ae73e8e --- /dev/null +++ b/scripts/HoNTnPphrJISSQr1.js @@ -0,0 +1 @@ +ChatMessage.create({content : "Speak and be known to me", speaker : ChatMessage.getSpeaker({token: this.actor.getActiveTokens()[0]?.document, actor: this.actor})}, {chatBubble : true}) \ No newline at end of file diff --git a/scripts/Hq1G30lhJYvtOSNb.js b/scripts/Hq1G30lhJYvtOSNb.js new file mode 100644 index 0000000..5dce3bd --- /dev/null +++ b/scripts/Hq1G30lhJYvtOSNb.js @@ -0,0 +1,9 @@ + + if (args.test.failed) + { + let applicableCharacteristics = ["ws", "bs", "s", "fel", "ag", "t", "dex"]; + if (applicableCharacteristics.includes(args.preData.characteristic)) + { + this.actor.addCondition("stunned"); + } + } \ No newline at end of file diff --git a/scripts/HrOBAXsEX073ReKl.js b/scripts/HrOBAXsEX073ReKl.js new file mode 100644 index 0000000..de65a28 --- /dev/null +++ b/scripts/HrOBAXsEX073ReKl.js @@ -0,0 +1,18 @@ +let skill = `Entertain (Singing)` +let currentCareer = this.actor.system.currentCareer; +let existingSkill = this.actor.itemTypes.skill.find(i => i.name == skill); + +if (!currentCareer) return + + +let inCurrentCareer = currentCareer.system.skills.includes(skill); +if (existingSkill && inCurrentCareer) +{ + existingSkill.system.advances.costModifier = -5; +} +else +{ + currentCareer.system.skills.push(skill); +} + + diff --git a/scripts/HrYchgkdZBiu1yPF.js b/scripts/HrYchgkdZBiu1yPF.js new file mode 100644 index 0000000..959e502 --- /dev/null +++ b/scripts/HrYchgkdZBiu1yPF.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.Climb"); \ No newline at end of file diff --git a/scripts/HwbgUIbpX0D8JLOR.js b/scripts/HwbgUIbpX0D8JLOR.js new file mode 100644 index 0000000..a9ddddc --- /dev/null +++ b/scripts/HwbgUIbpX0D8JLOR.js @@ -0,0 +1,2 @@ +if (args.opposedTest.result.differenceSL >= 0 && args.opposedTest.result.differenceSL <= 2 && args.opposedTest.result.winner == "attacker") + this.actor.addCondition("bleeding") \ No newline at end of file diff --git a/scripts/I0Jo6cbNAJtXUloc.js b/scripts/I0Jo6cbNAJtXUloc.js new file mode 100644 index 0000000..6066d3a --- /dev/null +++ b/scripts/I0Jo6cbNAJtXUloc.js @@ -0,0 +1,2 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.J9MK0AIaTbvd5oF6"); +this.actor.createEmbeddedDocuments("Item", [item.toObject()], {fromEffect : this.effect.id}); \ No newline at end of file diff --git a/scripts/I0oRZ7AWde5KI5jw.js b/scripts/I0oRZ7AWde5KI5jw.js new file mode 100644 index 0000000..57bbdb3 --- /dev/null +++ b/scripts/I0oRZ7AWde5KI5jw.js @@ -0,0 +1 @@ +return !["t", "int"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/I1J2m5uud84N50Lk.js b/scripts/I1J2m5uud84N50Lk.js new file mode 100644 index 0000000..5f22ef9 --- /dev/null +++ b/scripts/I1J2m5uud84N50Lk.js @@ -0,0 +1,6 @@ +if (["cast", "channelling", "pray"].includes(args.type)) +{ + args.abort = true; + this.script.scriptNotification("Cannot cast Spells or use Prayers"); +} +else return true; \ No newline at end of file diff --git a/scripts/I7ieW0hNYvvX0KFg.js b/scripts/I7ieW0hNYvvX0KFg.js new file mode 100644 index 0000000..5327a98 --- /dev/null +++ b/scripts/I7ieW0hNYvvX0KFg.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Heal"); \ No newline at end of file diff --git a/scripts/I93i49wI9ZrDHT4n.js b/scripts/I93i49wI9ZrDHT4n.js new file mode 100644 index 0000000..54906f2 --- /dev/null +++ b/scripts/I93i49wI9ZrDHT4n.js @@ -0,0 +1,2 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.Item.jt0DmVK9IiF6Sd2h"); +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/I9QAPKbaXwMMMBT4.js b/scripts/I9QAPKbaXwMMMBT4.js new file mode 100644 index 0000000..99b5ec4 --- /dev/null +++ b/scripts/I9QAPKbaXwMMMBT4.js @@ -0,0 +1,17 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {fields : {difficulty: "average"}, skipTargets: true, appendTitle : " - " + this.effect.name}) +await test.roll(); +if(test.failed) +{ + await this.actor.addCondition("stunned"); + let secondTest = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {fields : {difficulty: "easy"}, skipTargets: true, appendTitle : " - Despair"}) + await secondTest.roll(); + if(secondTest.failed) + { + this.effect.updateSource({name : "Taste of Death"}) + await this.actor.addCondition("fatigued"); + } + else + { + return false; + } +} \ No newline at end of file diff --git a/scripts/IAGla7HJlYN0wa4H.js b/scripts/IAGla7HJlYN0wa4H.js new file mode 100644 index 0000000..5840592 --- /dev/null +++ b/scripts/IAGla7HJlYN0wa4H.js @@ -0,0 +1,8 @@ +if (args.test.characteristicKey == "wp") +{ + if (args.test.failed) + { + this.actor.addSystemEffect("convulsions") + this.script.scriptMessage(`Willpower Test failed, ${this.actor.prototypeToken.name} gains @Symptom[Convulsions] for [[1d10]] hours`) + } +} \ No newline at end of file diff --git a/scripts/ID8mCcjkl7PCQhDq.js b/scripts/ID8mCcjkl7PCQhDq.js new file mode 100644 index 0000000..4691ac9 --- /dev/null +++ b/scripts/ID8mCcjkl7PCQhDq.js @@ -0,0 +1,8 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Dodge"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); + +if(test.failed) +{ + let damage = this.effect.sourceItem.system.computeSpellDamage("3", true); + this.script.scriptMessage(await this.actor.applyBasicDamage(damage, {suppressMsg: true, damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_AP})) +} \ No newline at end of file diff --git a/scripts/IG4zYqtN9fRSYE7q.js b/scripts/IG4zYqtN9fRSYE7q.js new file mode 100644 index 0000000..6fb0958 --- /dev/null +++ b/scripts/IG4zYqtN9fRSYE7q.js @@ -0,0 +1 @@ +args.actor.addCondition("ablaze"); \ No newline at end of file diff --git a/scripts/IKiZv9YSFmKmHo6a.js b/scripts/IKiZv9YSFmKmHo6a.js new file mode 100644 index 0000000..b0e3f02 --- /dev/null +++ b/scripts/IKiZv9YSFmKmHo6a.js @@ -0,0 +1 @@ +return args.spell?.system.lore.value == "fire" \ No newline at end of file diff --git a/scripts/ILqHxk7deotgI3KD.js b/scripts/ILqHxk7deotgI3KD.js new file mode 100644 index 0000000..fdb8958 --- /dev/null +++ b/scripts/ILqHxk7deotgI3KD.js @@ -0,0 +1,10 @@ +if (args.item.type != "weapon") + return + +let reach = args.item.reach.value +let reachNum = game.wfrp4e.config.reachNum[reach] +reachNum = Math.min(reachNum + 2, 7) + +let key = game.wfrp4e.utility.findKey(reachNum, game.wfrp4e.config.reachNum) + +args.item.reach.value = key \ No newline at end of file diff --git a/scripts/IPPDvZdE8kn3H9z7.js b/scripts/IPPDvZdE8kn3H9z7.js new file mode 100644 index 0000000..a78deea --- /dev/null +++ b/scripts/IPPDvZdE8kn3H9z7.js @@ -0,0 +1,7 @@ +let test = await this.actor.setupSkill("Dodge", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}); +await test.roll(); + +if (test.failed) +{ + await this.actor.addCondition("grappling") +} \ No newline at end of file diff --git a/scripts/IR5URcjnCuWBFMoN.js b/scripts/IR5URcjnCuWBFMoN.js new file mode 100644 index 0000000..69ed22a --- /dev/null +++ b/scripts/IR5URcjnCuWBFMoN.js @@ -0,0 +1,15 @@ +// If a full dose is imbibed, +// the victim must pass a Hard (-20) Endurance Test. + +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields: {difficulty: "hard"}}) +await test.roll() +if (test.failed) +{ + this.script.scriptMessage(`${this.actor.prototypeToken.name} notices nothing amiss save that they become tired a little earlier than usual. At this point it is still possible to save the victim via a powerful antidote or magical means.
+Once they fall asleep however, it is almost impossible. At this point the victim must make a Hard (-20) Endurance Test. If they fail, they never awaken.
`, + { + whisper: ChatMessage.getWhisperRecipients("GM"), + blind: true + }) +} +return test.failed; \ No newline at end of file diff --git a/scripts/IR86DuMbVdbGOJYt.js b/scripts/IR86DuMbVdbGOJYt.js new file mode 100644 index 0000000..4316d1c --- /dev/null +++ b/scripts/IR86DuMbVdbGOJYt.js @@ -0,0 +1 @@ +this.actor.addCondition("blinded") \ No newline at end of file diff --git a/scripts/IfEu1hO8sKEZBpvg.js b/scripts/IfEu1hO8sKEZBpvg.js new file mode 100644 index 0000000..0b53314 --- /dev/null +++ b/scripts/IfEu1hO8sKEZBpvg.js @@ -0,0 +1,14 @@ +let value = parseInt(this.item.specification.value) +let name = this.actor.prototypeToken.name + +if (game.user.isGM && game.user.targets.size) +{ + game.user.targets.forEach(t => { + t.actor.applyFear(value, name) + }) + game.user.updateTokenTargets([]); +} +else +{ + game.wfrp4e.utility.postFear(value, name) +} \ No newline at end of file diff --git a/scripts/IkGegSuQwwVPhrjF.js b/scripts/IkGegSuQwwVPhrjF.js new file mode 100644 index 0000000..97f7893 --- /dev/null +++ b/scripts/IkGegSuQwwVPhrjF.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.pTorrE0l3VybAbtn") +let data = item.toObject(); +data.system.specification.value = 1 +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/Ip8sctF9SIE1Z2vF.js b/scripts/Ip8sctF9SIE1Z2vF.js new file mode 100644 index 0000000..7cc82a8 --- /dev/null +++ b/scripts/Ip8sctF9SIE1Z2vF.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.UnJ25lL8aUzem5JO") +let data = item.toObject(); +data.system.specification.value = 3 +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/IpoOOjYJs6RmVrpb.js b/scripts/IpoOOjYJs6RmVrpb.js new file mode 100644 index 0000000..c6867fc --- /dev/null +++ b/scripts/IpoOOjYJs6RmVrpb.js @@ -0,0 +1,4 @@ +if (args.totalWoundLoss > 0) +{ + args.attacker.applyEffect({effectUuids : this.effect.sourceItem.effects.contents[1].uuid}) +} \ No newline at end of file diff --git a/scripts/IsLAvY9ikR1cOJWw.js b/scripts/IsLAvY9ikR1cOJWw.js new file mode 100644 index 0000000..c5a06ce --- /dev/null +++ b/scripts/IsLAvY9ikR1cOJWw.js @@ -0,0 +1 @@ +return !["NAME.Row", "NAME.Swim"].map(i => game.i18n.localize(i)).includes(args.skill?.name); \ No newline at end of file diff --git a/scripts/IslMfFgpgQq2brpu.js b/scripts/IslMfFgpgQq2brpu.js new file mode 100644 index 0000000..02c913e --- /dev/null +++ b/scripts/IslMfFgpgQq2brpu.js @@ -0,0 +1,5 @@ +if (this.actor.hasCondition("broken")) +{ + this.actor.removeCondition("broken") + this.script.scriptNotification(`Cannot have Broken`); +} \ No newline at end of file diff --git a/scripts/IukS0clr1yAleacc.js b/scripts/IukS0clr1yAleacc.js new file mode 100644 index 0000000..d71d043 --- /dev/null +++ b/scripts/IukS0clr1yAleacc.js @@ -0,0 +1,3 @@ +this.actor.system.characteristics.ag.modifier -= parseInt(this.item.system.location.value || 1) + +this.actor.system.characteristics.ws.modifier -= parseInt(this.item.system.location.value || 1) \ No newline at end of file diff --git a/scripts/IupskvzvoGyD2H5o.js b/scripts/IupskvzvoGyD2H5o.js new file mode 100644 index 0000000..87c4934 --- /dev/null +++ b/scripts/IupskvzvoGyD2H5o.js @@ -0,0 +1,23 @@ +if (this.actor.type != "character") +{ + return; +} + +let god = await ValueDialog.create("Enter a Deity", "Blessed") + +if (god) +{ + let prayers = await game.wfrp4e.utility.findAll("prayer", "Loading Prayers") + let blessings = prayers.filter(p => p.system.god.value.split(",").map(i => i.trim().toLowerCase()).includes(god.toLowerCase()) && p.system.type.value == "blessing") + if (blessings.length) + { + this.script.scriptNotification("Adding " + blessings.map(i => i.name).join(", ")) + await this.actor.createEmbeddedDocuments("Item", blessings, {fromEffect : this.effect.id}) + } + else + { + this.script.scriptNotification(`Could not find any Blessings associated with ${god}.`) + } + this.item.updateSource({name : this.item.name.replace("Any", god)}) + await this.actor.update({"system.details.god.value": god}) +} \ No newline at end of file diff --git a/scripts/IzZcsSngI8TZH4d8.js b/scripts/IzZcsSngI8TZH4d8.js new file mode 100644 index 0000000..a63265f --- /dev/null +++ b/scripts/IzZcsSngI8TZH4d8.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.fjd1u9VAgiYzhBRp"); +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/J0IWUhxada2ONowP.js b/scripts/J0IWUhxada2ONowP.js new file mode 100644 index 0000000..aec5a9d --- /dev/null +++ b/scripts/J0IWUhxada2ONowP.js @@ -0,0 +1 @@ + return args.skill?.name == "Entertain (Sing)" || args.skill?.name == "Entertain (Singing)" || (args.skill?.name.includes("Language") && (args.skill?.name.includes("Magick") || args.skill?.name.includes("Elthárin") || args.skill?.name.includes("Cathayan"))) \ No newline at end of file diff --git a/scripts/J1FPDdrXGctKDTZz.js b/scripts/J1FPDdrXGctKDTZz.js new file mode 100644 index 0000000..d72299d --- /dev/null +++ b/scripts/J1FPDdrXGctKDTZz.js @@ -0,0 +1,16 @@ +if (args.equipped) +{ + let ward = await fromUuid("Compendium.wfrp4e-core.items.Bvd2aZ0gQUXHfCTh") + wardData = ward.toObject() + wardData.system.specification.value = "8" + + let mr = await fromUuid("Compendium.wfrp4e-core.items.yrkI7ATjqLPDTFmZ") + mrData = mr.toObject() + mrData.system.specification.value = 2 + + this.actor.createEmbeddedDocuments("Item", [wardData, mrData], {fromEffect : this.effect.id}) +} +else +{ + this.effect.deleteCreatedItems() +} \ No newline at end of file diff --git a/scripts/J8aPichsl25t1QZ9.js b/scripts/J8aPichsl25t1QZ9.js new file mode 100644 index 0000000..e0eef4f --- /dev/null +++ b/scripts/J8aPichsl25t1QZ9.js @@ -0,0 +1 @@ +this.actor.addCondition("entangled", this.effect.sourceTest.result.SL) \ No newline at end of file diff --git a/scripts/JEbs0WlqhKNDOo5A.js b/scripts/JEbs0WlqhKNDOo5A.js new file mode 100644 index 0000000..83eb600 --- /dev/null +++ b/scripts/JEbs0WlqhKNDOo5A.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty: "hard"}}) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("unconscious") +} diff --git a/scripts/JFgXyb6bKjZJLmF8.js b/scripts/JFgXyb6bKjZJLmF8.js new file mode 100644 index 0000000..996b184 --- /dev/null +++ b/scripts/JFgXyb6bKjZJLmF8.js @@ -0,0 +1 @@ +return args.characteristic == "ag" \ No newline at end of file diff --git a/scripts/JQruHprM5R5vZ9DA.js b/scripts/JQruHprM5R5vZ9DA.js new file mode 100644 index 0000000..ae80286 --- /dev/null +++ b/scripts/JQruHprM5R5vZ9DA.js @@ -0,0 +1,10 @@ +let caster = this.effect.sourceActor; +if (caster) +{ + let healed= caster.system.characteristics.wp.bonus + caster.system.characteristics.int.bonus + await this.actor.modifyWounds(healed); + this.script.scriptMessage(`${this.actor.prototypeToken.name} regains ${healed} Wounds`) +} + + let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields : {difficulty : "vhard"}, context : {success : "1 Corruption point that was gained within the last hour is removed.", failure: "Nothing happens"}}) + await test.roll(); \ No newline at end of file diff --git a/scripts/JZIn1dsKHFE3smJU.js b/scripts/JZIn1dsKHFE3smJU.js new file mode 100644 index 0000000..a07962a --- /dev/null +++ b/scripts/JZIn1dsKHFE3smJU.js @@ -0,0 +1,2 @@ +let ablaze = parseInt(this.effect.sourceTest.result.SL) + 1 +args.actor.addCondition("ablaze", ablaze) \ No newline at end of file diff --git a/scripts/JaiC5P6nIgctOacH.js b/scripts/JaiC5P6nIgctOacH.js new file mode 100644 index 0000000..d3560ca --- /dev/null +++ b/scripts/JaiC5P6nIgctOacH.js @@ -0,0 +1,4 @@ +if (args.actor.system.details.species?.value?.toLowerCase() == "dwarf") +{ + args.weaponProperties.flaws.undamaging = true; +} \ No newline at end of file diff --git a/scripts/JavuFNZ9Pj5elVLc.js b/scripts/JavuFNZ9Pj5elVLc.js new file mode 100644 index 0000000..9c9591a --- /dev/null +++ b/scripts/JavuFNZ9Pj5elVLc.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.pLW9SVX0TVTYPiPv") +let data = item.toObject(); +data.system.specification.value = 4 - this.actor.characteristics.s.bonus +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/JeThJbOf6Xmbtgo1.js b/scripts/JeThJbOf6Xmbtgo1.js new file mode 100644 index 0000000..8125581 --- /dev/null +++ b/scripts/JeThJbOf6Xmbtgo1.js @@ -0,0 +1,8 @@ +this.script.scriptMessage(await this.actor.applyBasicDamage(8 + parseInt(this.effect.sourceTest.result.SL), {suppressMsg : true})) + +let test = await this.actor.setupSkill("Athletics", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("prone") +} \ No newline at end of file diff --git a/scripts/JgCcgDVZX54slrWx.js b/scripts/JgCcgDVZX54slrWx.js new file mode 100644 index 0000000..b758160 --- /dev/null +++ b/scripts/JgCcgDVZX54slrWx.js @@ -0,0 +1 @@ +return args.skill?.name.includes(game.i18n.localize("NAME.Melee")) || args.item?.isMelee || args.options.corruption \ No newline at end of file diff --git a/scripts/JibNjuQrJRnY0yf9.js b/scripts/JibNjuQrJRnY0yf9.js new file mode 100644 index 0000000..03aff09 --- /dev/null +++ b/scripts/JibNjuQrJRnY0yf9.js @@ -0,0 +1 @@ +return this.actor.flags.useless.rEye && this.actor.flags.useless.lEye && (["ws", "bs"].includes(args.characteristic) || args.skill?.name?.includes(game.i18n.localize("NAME.Ride")) || args.weapon || args.options.dodge) \ No newline at end of file diff --git a/scripts/JjDzMnUxaWQePIYh.js b/scripts/JjDzMnUxaWQePIYh.js new file mode 100644 index 0000000..70529bf --- /dev/null +++ b/scripts/JjDzMnUxaWQePIYh.js @@ -0,0 +1 @@ +return args.characteristic != "int" \ No newline at end of file diff --git a/scripts/JjiPprLSlSmmB5Ga.js b/scripts/JjiPprLSlSmmB5Ga.js new file mode 100644 index 0000000..bfe3c8a --- /dev/null +++ b/scripts/JjiPprLSlSmmB5Ga.js @@ -0,0 +1 @@ +args.item.system.damage.value += " + 1" \ No newline at end of file diff --git a/scripts/Jjq3oPYbI26zjxME.js b/scripts/Jjq3oPYbI26zjxME.js new file mode 100644 index 0000000..dcf1d23 --- /dev/null +++ b/scripts/Jjq3oPYbI26zjxME.js @@ -0,0 +1,21 @@ +let location = this.item.system.location.key; + +if (location) +{ + let dropped = this.item.system.weaponsAtLocation; + + if (dropped.length) + { + this.script.scriptNotification(`Dropped ${dropped.map(i => i.name).join(", ")}!`) + for(let weapon of dropped) + { + await weapon.system.toggleEquip(); + } + } +} + +let roll = await new Roll("1d10").roll() + +roll.toMessage(this.script.getChatData({flavor : `${this.effect.name} (Duration)`})); + +this.effect.updateSource({"duration.rounds" : roll.total}) \ No newline at end of file diff --git a/scripts/Jk7OHqx06oCUVAzb.js b/scripts/Jk7OHqx06oCUVAzb.js new file mode 100644 index 0000000..44fed7e --- /dev/null +++ b/scripts/Jk7OHqx06oCUVAzb.js @@ -0,0 +1 @@ +return !["Language (Magick)", "Channelling (Hysh)"].includes(args.skill?.name) \ No newline at end of file diff --git a/scripts/JmZQRvdWjm9ykYfn.js b/scripts/JmZQRvdWjm9ykYfn.js new file mode 100644 index 0000000..90d6edc --- /dev/null +++ b/scripts/JmZQRvdWjm9ykYfn.js @@ -0,0 +1,5 @@ +if (this.actor.hasCondition("surprised")) +{ + this.actor.removeCondition("surprised") + this.script.scriptMessage(`Cannot be Surprised`); +} \ No newline at end of file diff --git a/scripts/Jnp5c09sPzDD61EK.js b/scripts/Jnp5c09sPzDD61EK.js new file mode 100644 index 0000000..e9e5662 --- /dev/null +++ b/scripts/Jnp5c09sPzDD61EK.js @@ -0,0 +1,3 @@ +this.script.scriptNotification(`${args.actor.prototypeToken.name} must pass an Average (+20) Willpower Test to attack this target!`) + +return true; // No need to show this in the dialog \ No newline at end of file diff --git a/scripts/JstrA46EYSEuRSy5.js b/scripts/JstrA46EYSEuRSy5.js new file mode 100644 index 0000000..f5e7f96 --- /dev/null +++ b/scripts/JstrA46EYSEuRSy5.js @@ -0,0 +1,2 @@ +if (this.actor.has(game.i18n.localize("NAME.Undead")) && this.actor.has(game.i18n.localize("NAME.Construct"))) + this.actor.addCondition("dead") \ No newline at end of file diff --git a/scripts/JwYZJGkZMSM2M3Si.js b/scripts/JwYZJGkZMSM2M3Si.js new file mode 100644 index 0000000..23dc567 --- /dev/null +++ b/scripts/JwYZJGkZMSM2M3Si.js @@ -0,0 +1,10 @@ +if (args.totalWoundLoss > 0) +{ + let test = await args.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "hard"}}) + await test.roll() + if (test.failed) + { + args.totalWoundLoss += this.effect.sourceActor.system.characteristics.wp.bonus + args.modifiers.other.push({label : this.effect.name, value : this.effect.sourceActor.system.characteristics.wp.bonus}) + } +} \ No newline at end of file diff --git a/scripts/JwgFQmPQtXWAP94i.js b/scripts/JwgFQmPQtXWAP94i.js new file mode 100644 index 0000000..7c989d6 --- /dev/null +++ b/scripts/JwgFQmPQtXWAP94i.js @@ -0,0 +1 @@ +this.actor.addCondition("fatigued"); \ No newline at end of file diff --git a/scripts/JyTxUG5dNW670Sf7.js b/scripts/JyTxUG5dNW670Sf7.js new file mode 100644 index 0000000..9421a21 --- /dev/null +++ b/scripts/JyTxUG5dNW670Sf7.js @@ -0,0 +1,11 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.7mCcI3q7hgWcmbBU") +let data = item.toObject(); +data.system.location.key= this.item.system.location.key +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) + +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty: "hard"}}); +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("stunned") +} \ No newline at end of file diff --git a/scripts/K06v93N4FXb70mB7.js b/scripts/K06v93N4FXb70mB7.js new file mode 100644 index 0000000..051a245 --- /dev/null +++ b/scripts/K06v93N4FXb70mB7.js @@ -0,0 +1 @@ +args.item.system.encumbrance.value = Math.max(0, args.item.system.encumbrance.value - 1); \ No newline at end of file diff --git a/scripts/KD4nCSdSXJVJmk0R.js b/scripts/KD4nCSdSXJVJmk0R.js new file mode 100644 index 0000000..7499473 --- /dev/null +++ b/scripts/KD4nCSdSXJVJmk0R.js @@ -0,0 +1,2 @@ +this.script.scriptMessage(await this.actor.applyBasicDamage(this.effect.sourceTest.result.damage, {suppressMsg : true})) +await this.actor.addCondition("ablaze") \ No newline at end of file diff --git a/scripts/KF69WqF4PSEtpdb2.js b/scripts/KF69WqF4PSEtpdb2.js new file mode 100644 index 0000000..4f434e6 --- /dev/null +++ b/scripts/KF69WqF4PSEtpdb2.js @@ -0,0 +1,2 @@ +args.fields.slBonus += 2; + \ No newline at end of file diff --git a/scripts/KG4TxnXiLLpfWOQO.js b/scripts/KG4TxnXiLLpfWOQO.js new file mode 100644 index 0000000..14697ad --- /dev/null +++ b/scripts/KG4TxnXiLLpfWOQO.js @@ -0,0 +1 @@ +args.fields.difficulty = "average" \ No newline at end of file diff --git a/scripts/KGK9vL1Yl0qmCeCN.js b/scripts/KGK9vL1Yl0qmCeCN.js new file mode 100644 index 0000000..78b37da --- /dev/null +++ b/scripts/KGK9vL1Yl0qmCeCN.js @@ -0,0 +1,88 @@ +let specification = this.item.system.specification.value; +let choice = []; + +if (!specification || specification == "Trained Skills") +{ + choice = await ItemDialog.create(ItemDialog.objectToArray({ + broken: "Broken", + drive: "Drive", + entertain: "Entertain", + fetch: "Fetch", + guard: "Guard", + home: "Home", + magic: "Magic", + mount: "Mount", + war: "War" + }, this.effect.img), "unlimited", "Choose Training"); +} +else +{ + choice = specification.split(", ").map(i => { + return { + id : i.toLowerCase(), + name : i + } + }); +} + +if (choice.length) +{ + let changes = foundry.utils.deepClone(this.effect.changes); + + for(let training of choice) + { + switch(training.id) + { + case "broken" : + let roll = await new Roll("2d10").roll(); + roll.toMessage(this.script.getChatData()); + changes.push({value : roll.total, mode : 2, key : "system.characteristics.fel.modifier"}) + + if (this.actor.type == "creature") + { + let bestial = this.actor.itemTypes.trait.find(i => i.name == "Bestial"); + if (bestial) + { + bestial.update({"system.disabled" : true}) + } + } + break; + + case "drive" : + + break; + + case "entertain" : + + break; + + case "fetch" : + + break; + + case "guard" : + let territorial = await fromUuid("Compendium.wfrp4e-core.items.Item.JIAe7i7dqTQBu4do"); + await this.actor.createEmbeddedDocuments("Item", [territorial], {fromEffect: this.effect.id}) + setProperty(args, "options.keepId", true); + break; + + case "home" : + + break; + + case "magic" : + + break; + + case "mount" : + + break; + + case "war" : + changes.push({value : 10, mode : 2, key : "system.characteristics.ws.modifier"}) + break; + } + } + this.effect.updateSource({name : `${this.effect.name} (${choice.map(i => i.name).join(", ")})`, changes, "flags.wfrp4e.trained" : choice.map(i => i.id)}) + this.item.updateSource({"system.specification.value" : `${choice.map(i => i.name).join(", ")}`}) +} \ No newline at end of file diff --git a/scripts/KICZPwLvbUSxbDrE.js b/scripts/KICZPwLvbUSxbDrE.js new file mode 100644 index 0000000..30a0d6f --- /dev/null +++ b/scripts/KICZPwLvbUSxbDrE.js @@ -0,0 +1,18 @@ +let table = game.wfrp4e.tables.findTable("mutatemental"); +if (!table) +{ + ui.notifications.error("Cannot find table with key: mutatemental") +} +let result = (await table.roll()).results[0]; +let uuid = `Compendium.${result.documentCollection}.${result.documentId}` +let item = await fromUuid(uuid); + +if (item) +{ + this.script.scriptNotification(`${item.name} added`) + this.actor.createEmbeddedDocuments("Item", [item]) +} +else +{ + ui.notifications.error("Item could not be found: " + uuid) +} \ No newline at end of file diff --git a/scripts/KIoVBinAZK8sMOqD.js b/scripts/KIoVBinAZK8sMOqD.js new file mode 100644 index 0000000..072c254 --- /dev/null +++ b/scripts/KIoVBinAZK8sMOqD.js @@ -0,0 +1,11 @@ + + let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields: {difficulty : "average"}, skipTargets: true, appendTitle : " - Wounded"}) + await test.roll(); + if (test.failed) + { + fromUuid("Compendium.wfrp4e-core.items.kKccDTGzWzSXCBOb").then(disease => { + this.actor.createEmbeddedDocuments("Item", [disease.toObject()]) + this.script.scriptNotification("Gained " + disease.name) + }) + } + \ No newline at end of file diff --git a/scripts/KJLAan0glJlyOyqF.js b/scripts/KJLAan0glJlyOyqF.js new file mode 100644 index 0000000..e9a31c5 --- /dev/null +++ b/scripts/KJLAan0glJlyOyqF.js @@ -0,0 +1,11 @@ + this.actor.getActiveTokens().forEach(t => t.document.update({light : { + "dim": 10, + "bright": 5, + "alpha": 0.5, + "animation": { + "speed": 4, + "intensity": 4, + "type": "flame", + }, + "color": "#ac9e6c", + }})); \ No newline at end of file diff --git a/scripts/KPQfupKuaf4LCv4R.js b/scripts/KPQfupKuaf4LCv4R.js new file mode 100644 index 0000000..9dcc016 --- /dev/null +++ b/scripts/KPQfupKuaf4LCv4R.js @@ -0,0 +1,2 @@ +const talents = await Promise.all(["Schemer", "Second Sight"].map(game.wfrp4e.utility.findTalent)) +this.actor.createEmbeddedDocuments("Item", talents, {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/KQmb5B27eJ1lkbVL.js b/scripts/KQmb5B27eJ1lkbVL.js new file mode 100644 index 0000000..7adee1c --- /dev/null +++ b/scripts/KQmb5B27eJ1lkbVL.js @@ -0,0 +1 @@ +return this.item.system.quantity.value > 0 && args.type != "channelling" \ No newline at end of file diff --git a/scripts/KQzbrpb0T5a7it4k.js b/scripts/KQzbrpb0T5a7it4k.js new file mode 100644 index 0000000..1620dd8 --- /dev/null +++ b/scripts/KQzbrpb0T5a7it4k.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.Item.vMYEkrWj0ip6ZOdv"); +let data = item.toObject(); +data.name += ` (Disease)`; +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/KSjsDlsx3DD6cT16.js b/scripts/KSjsDlsx3DD6cT16.js new file mode 100644 index 0000000..f00b8b8 --- /dev/null +++ b/scripts/KSjsDlsx3DD6cT16.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Bribery"); \ No newline at end of file diff --git a/scripts/KT670CjGBEprx2fO.js b/scripts/KT670CjGBEprx2fO.js new file mode 100644 index 0000000..bbf4c65 --- /dev/null +++ b/scripts/KT670CjGBEprx2fO.js @@ -0,0 +1,2 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.Item.RWJrupj9seau0w31"); +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/KTBVDHUndI3qDOXM.js b/scripts/KTBVDHUndI3qDOXM.js new file mode 100644 index 0000000..b9aa611 --- /dev/null +++ b/scripts/KTBVDHUndI3qDOXM.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance")) +await test.roll(); +if (!test.succeeded) +{ + args.actor.addCondition("stunned") +} \ No newline at end of file diff --git a/scripts/KUx0deSF3xNzMucL.js b/scripts/KUx0deSF3xNzMucL.js new file mode 100644 index 0000000..208679d --- /dev/null +++ b/scripts/KUx0deSF3xNzMucL.js @@ -0,0 +1 @@ +return args.skill?.name.includes(game.i18n.localize("NAME.Art")); \ No newline at end of file diff --git a/scripts/KVpDUEjHhd3nLa0f.js b/scripts/KVpDUEjHhd3nLa0f.js new file mode 100644 index 0000000..a301dfb --- /dev/null +++ b/scripts/KVpDUEjHhd3nLa0f.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (test.failed) +{ + this.script.scriptMessage(await game.wfrp4e.tables.formatChatRoll("enrage-beast")) +} \ No newline at end of file diff --git a/scripts/KVuPduDztyMZQNt9.js b/scripts/KVuPduDztyMZQNt9.js new file mode 100644 index 0000000..c359f67 --- /dev/null +++ b/scripts/KVuPduDztyMZQNt9.js @@ -0,0 +1 @@ +args.fields.slBonus += this.actor.system.characteristics.ag.bonus \ No newline at end of file diff --git a/scripts/KXzDe7cN2vynHjJO.js b/scripts/KXzDe7cN2vynHjJO.js new file mode 100644 index 0000000..41a9fa8 --- /dev/null +++ b/scripts/KXzDe7cN2vynHjJO.js @@ -0,0 +1,3 @@ +this.actor.hasCondition("blinded")?.delete(); +this.actor.hasCondition("deafened")?.delete() +this.actor.hasCondition("unconscious")?.delete() \ No newline at end of file diff --git a/scripts/KkjkYAGI9Em1NgiQ.js b/scripts/KkjkYAGI9Em1NgiQ.js new file mode 100644 index 0000000..1790282 --- /dev/null +++ b/scripts/KkjkYAGI9Em1NgiQ.js @@ -0,0 +1,19 @@ +if (this.item.system.quantity.value) +{ + this.item.system.reduceQuantity(); + let test = await this.actor.setupSkill(game.i18n.localize("NAME.Heal"), { appendTitle: ` - ${this.effect.name}`, skipTargets: true }) + await test.roll(); + if (test.succeeded) + { + let actor = Array.from(game.user.targets)[0]?.actor || this.actor; + actor.applyEffect({ effectData: [this.item.effects.contents[0].convertToApplied()] }) + } + else + { + this.script.scriptNotification("Heal Test failed!", "error") + } +} +else +{ + this.script.scriptNotification("None left!", "error") +} \ No newline at end of file diff --git a/scripts/KmngDrPD72xn22kZ.js b/scripts/KmngDrPD72xn22kZ.js new file mode 100644 index 0000000..331fdca --- /dev/null +++ b/scripts/KmngDrPD72xn22kZ.js @@ -0,0 +1,11 @@ +if (this.actor.Species.toLowerCase() != "skaven") { + this.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - Used ${this.effect.name}`, fields: { difficulty: "difficult" } }).then(async test => { + await test.roll() + if (test.failed) + { + let toughnessLost = Math.ceil(CONFIG.Dice.randomUniform() * 10) + this.actor.update({ "system.characteristics.t.initial": this.actor.characteristics.t.initial - toughnessLost }) + this.script.scriptMessage(`${this.actor.prototypeToken.name} lost ${toughnessLost} Toughness`) + } + }) + } \ No newline at end of file diff --git a/scripts/KnwYZbeRSBA94hfl.js b/scripts/KnwYZbeRSBA94hfl.js new file mode 100644 index 0000000..11bc24c --- /dev/null +++ b/scripts/KnwYZbeRSBA94hfl.js @@ -0,0 +1,5 @@ +if (!args.flags.lostFingers) +{ + args.flags.lostFingers = true; + args.fields.modifier -= 5 * this.actor.flags.useless[this.item.system.location.key] +} \ No newline at end of file diff --git a/scripts/KuUkUmOOLf05I4Bp.js b/scripts/KuUkUmOOLf05I4Bp.js new file mode 100644 index 0000000..b2e2144 --- /dev/null +++ b/scripts/KuUkUmOOLf05I4Bp.js @@ -0,0 +1 @@ +this.actor.hasCondition("broken")?.delete(); diff --git a/scripts/KuuWAhoSzk0rCxxw.js b/scripts/KuuWAhoSzk0rCxxw.js new file mode 100644 index 0000000..2d3f461 --- /dev/null +++ b/scripts/KuuWAhoSzk0rCxxw.js @@ -0,0 +1 @@ +args.fields.modifier += -20; \ No newline at end of file diff --git a/scripts/KyUPYV1RXJxPOfyA.js b/scripts/KyUPYV1RXJxPOfyA.js new file mode 100644 index 0000000..5e60157 --- /dev/null +++ b/scripts/KyUPYV1RXJxPOfyA.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "veasy"}}) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("fatigued"); +} \ No newline at end of file diff --git a/scripts/KyswmGj1uG3QS3ng.js b/scripts/KyswmGj1uG3QS3ng.js new file mode 100644 index 0000000..81a6df2 --- /dev/null +++ b/scripts/KyswmGj1uG3QS3ng.js @@ -0,0 +1 @@ +args.applyAP = false; \ No newline at end of file diff --git a/scripts/L1RMLvKtRPFtnczI.js b/scripts/L1RMLvKtRPFtnczI.js new file mode 100644 index 0000000..9e11b96 --- /dev/null +++ b/scripts/L1RMLvKtRPFtnczI.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.MGEPI4jNhymNIRVz"); +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/L2cdQppcPwxz24hN.js b/scripts/L2cdQppcPwxz24hN.js new file mode 100644 index 0000000..8eabc28 --- /dev/null +++ b/scripts/L2cdQppcPwxz24hN.js @@ -0,0 +1 @@ +return !args.weapon \ No newline at end of file diff --git a/scripts/L89UcafRHqUfxoux.js b/scripts/L89UcafRHqUfxoux.js new file mode 100644 index 0000000..092415c --- /dev/null +++ b/scripts/L89UcafRHqUfxoux.js @@ -0,0 +1,3 @@ +let injury = await fromUuid("Compendium.wfrp4e-core.items.3S4OYOZLauXctmev") +injury.updateSource({"system.location.key" : this.item.system.location.key}) +this.actor.createEmbeddedDocuments("Item", [injury], {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/L9eAtDyaoHvqryk4.js b/scripts/L9eAtDyaoHvqryk4.js new file mode 100644 index 0000000..c5efbe5 --- /dev/null +++ b/scripts/L9eAtDyaoHvqryk4.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Intimidate"); \ No newline at end of file diff --git a/scripts/LAyLbcC0lOPwZP3U.js b/scripts/LAyLbcC0lOPwZP3U.js new file mode 100644 index 0000000..328bcfe --- /dev/null +++ b/scripts/LAyLbcC0lOPwZP3U.js @@ -0,0 +1 @@ +this.actor.addCondition("ablaze", parseInt(this.effect.sourceTest.result.SL)) \ No newline at end of file diff --git a/scripts/LHUUXfZVLBhWqRvb.js b/scripts/LHUUXfZVLBhWqRvb.js new file mode 100644 index 0000000..9dae93e --- /dev/null +++ b/scripts/LHUUXfZVLBhWqRvb.js @@ -0,0 +1 @@ +this.actor.status.addArmour(5, {magical: true, source : this.effect}) \ No newline at end of file diff --git a/scripts/LLqAT9wEUGMLfDhU.js b/scripts/LLqAT9wEUGMLfDhU.js new file mode 100644 index 0000000..4102c46 --- /dev/null +++ b/scripts/LLqAT9wEUGMLfDhU.js @@ -0,0 +1 @@ +return !args.item?.system.isRanged \ No newline at end of file diff --git a/scripts/LOL2TGf8p8KxP14D.js b/scripts/LOL2TGf8p8KxP14D.js new file mode 100644 index 0000000..a462357 --- /dev/null +++ b/scripts/LOL2TGf8p8KxP14D.js @@ -0,0 +1,2 @@ +let wind = this.effect.name.split(" ")[2] +return args.type != "cast" || game.wfrp4e.config.magicWind[args.item.system.lore.value] != wind; \ No newline at end of file diff --git a/scripts/LQEWSN5KnHHATPsf.js b/scripts/LQEWSN5KnHHATPsf.js new file mode 100644 index 0000000..bd8c028 --- /dev/null +++ b/scripts/LQEWSN5KnHHATPsf.js @@ -0,0 +1,4 @@ +if (args.totalWoundLoss > 0) +{ + this.script.scriptMessage(`${args.actor.name} must pass an Easy (+40) Endurance Test or gain a @UUID[Compendium.wfrp4e-core.items.kKccDTGzWzSXCBOb]{Festering Wound}`, {whisper: ChatMessage.getWhisperRecipients("GM")}) +} \ No newline at end of file diff --git a/scripts/LXEUhHuXe8keEPI9.js b/scripts/LXEUhHuXe8keEPI9.js new file mode 100644 index 0000000..0683f16 --- /dev/null +++ b/scripts/LXEUhHuXe8keEPI9.js @@ -0,0 +1,7 @@ +let test = await this.actor.setupCharacteristic("wp", {fields: {difficulty : "average"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (test.failed) +{ + let stuns = Math.max(1, Math.abs(test.result.SL)) + this.actor.addCondition("stunned", stuns) +} \ No newline at end of file diff --git a/scripts/LeKLtvEDrWh4yHsx.js b/scripts/LeKLtvEDrWh4yHsx.js new file mode 100644 index 0000000..bfe04ec --- /dev/null +++ b/scripts/LeKLtvEDrWh4yHsx.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.CharmAnimal") || args.skill?.name.includes(game.i18n.localize("NAME.AnimalTraining")); \ No newline at end of file diff --git a/scripts/LedRsrVo2f7lm3Ix.js b/scripts/LedRsrVo2f7lm3Ix.js new file mode 100644 index 0000000..647d323 --- /dev/null +++ b/scripts/LedRsrVo2f7lm3Ix.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.Intimidate"); \ No newline at end of file diff --git a/scripts/Lg1oRg4oNRvucsvi.js b/scripts/Lg1oRg4oNRvucsvi.js new file mode 100644 index 0000000..42395c3 --- /dev/null +++ b/scripts/Lg1oRg4oNRvucsvi.js @@ -0,0 +1 @@ +return !(args.skill?.name == game.i18n.localize("NAME.Climb") || args.skill?.name == game.i18n.localize("NAME.Athletics")) \ No newline at end of file diff --git a/scripts/LjXPlgdXBdllnA3i.js b/scripts/LjXPlgdXBdllnA3i.js new file mode 100644 index 0000000..402cd45 --- /dev/null +++ b/scripts/LjXPlgdXBdllnA3i.js @@ -0,0 +1 @@ +return !["s", "t"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/LkPtgN9A36OI6Frh.js b/scripts/LkPtgN9A36OI6Frh.js new file mode 100644 index 0000000..4bda5cb --- /dev/null +++ b/scripts/LkPtgN9A36OI6Frh.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.Leadership"); \ No newline at end of file diff --git a/scripts/LlRhPGorLl5qJCU8.js b/scripts/LlRhPGorLl5qJCU8.js new file mode 100644 index 0000000..3393901 --- /dev/null +++ b/scripts/LlRhPGorLl5qJCU8.js @@ -0,0 +1,8 @@ +if (this.actor.hasCondition("prone")) +{ + this.actor.addCondition("unconscious"); +} +else +{ + this.actor.addCondition("prone"); +} \ No newline at end of file diff --git a/scripts/Lm9IBkc918Duw3US.js b/scripts/Lm9IBkc918Duw3US.js new file mode 100644 index 0000000..c27cbaf --- /dev/null +++ b/scripts/Lm9IBkc918Duw3US.js @@ -0,0 +1,6 @@ +let career = this.actor.itemTypes.career.find(c => c.getFlag("wfrp4e", "doubleLife")) + +if(career) +{ + career.system.current.value = true; +} \ No newline at end of file diff --git a/scripts/Lp261O9fgEXmgPf3.js b/scripts/Lp261O9fgEXmgPf3.js new file mode 100644 index 0000000..65d054e --- /dev/null +++ b/scripts/Lp261O9fgEXmgPf3.js @@ -0,0 +1,5 @@ +// If this actor wins a defending test, swap the test +if (!args.opposedTest.result.swapped && args.opposedTest.result.winner == "defender" && args.opposedTest.attackerTest.result.damage) +{ + args.opposedTest.swap(this.effect.label); +} \ No newline at end of file diff --git a/scripts/Lpv2N9LK9loeumiW.js b/scripts/Lpv2N9LK9loeumiW.js new file mode 100644 index 0000000..ad3c30e --- /dev/null +++ b/scripts/Lpv2N9LK9loeumiW.js @@ -0,0 +1,6 @@ +if (this.actor.uuid != this.effect.sourceActor.uuid) +{ + this.actor.setupSkill(game.i18n.localize("NAME.Athletics"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty: "hard"}, context : {failure : `${this.effect.name}: cannot move or take actions`}}).then(test => { + test.roll(); + }) +} \ No newline at end of file diff --git a/scripts/Lrb1S2aK7SFVD0C7.js b/scripts/Lrb1S2aK7SFVD0C7.js new file mode 100644 index 0000000..2f40127 --- /dev/null +++ b/scripts/Lrb1S2aK7SFVD0C7.js @@ -0,0 +1,9 @@ +if (args.totalWoundLoss > 0) +{ + let test = await args.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) + await test.roll(); + if (test.failed) + { + await args.actor.addCondition("fatigued"); + } +} \ No newline at end of file diff --git a/scripts/Lu27iXtJVkrJ8bOx.js b/scripts/Lu27iXtJVkrJ8bOx.js new file mode 100644 index 0000000..73cb61d --- /dev/null +++ b/scripts/Lu27iXtJVkrJ8bOx.js @@ -0,0 +1 @@ +return !args.skill?.name?.includes(game.i18n.localize("NAME.Stealth")) \ No newline at end of file diff --git a/scripts/LxdLkPxH3SFvYrCJ.js b/scripts/LxdLkPxH3SFvYrCJ.js new file mode 100644 index 0000000..8f8a38c --- /dev/null +++ b/scripts/LxdLkPxH3SFvYrCJ.js @@ -0,0 +1,4 @@ +if (args.effect.conditionId == "ablaze") +{ + args.data.formula += ` - ${this.actor.system.characteristics.t.bonus}` +} \ No newline at end of file diff --git a/scripts/LyAK0dVDS5L09yq2.js b/scripts/LyAK0dVDS5L09yq2.js new file mode 100644 index 0000000..e8b817a --- /dev/null +++ b/scripts/LyAK0dVDS5L09yq2.js @@ -0,0 +1,9 @@ +let caster = this.effect.sourceActor + +if (caster) +{ + let bonus = caster.system.characteristics.wp.bonus + this.actor.modifyWounds(bonus) + + this.script.scriptMessage(`${this.actor.prototypeToken.name} regains ${bonus} Wounds`) +} \ No newline at end of file diff --git a/scripts/M0XhKnWjG14pk3iH.js b/scripts/M0XhKnWjG14pk3iH.js new file mode 100644 index 0000000..1431d31 --- /dev/null +++ b/scripts/M0XhKnWjG14pk3iH.js @@ -0,0 +1 @@ +return !args.skill?.name.includes("Channelling") && args.type != "channelling" && args.skill?.name != game.i18n.localize("NAME.Charm") && !args.skill?.name.includes("Language (Magick)") && args.type != "cast" \ No newline at end of file diff --git a/scripts/M2FshTX4PjKFVU8y.js b/scripts/M2FshTX4PjKFVU8y.js new file mode 100644 index 0000000..6aa49fc --- /dev/null +++ b/scripts/M2FshTX4PjKFVU8y.js @@ -0,0 +1,9 @@ +args.flags.earCount = Number.isNumeric(args.flags.earCount) ? args.flags.earCount+1 : 1; +if (args.characteristic == "fel") +{ + args.fields.modifier -= 5; +} +if (args.flags.earCount == 2 && args.skill?.name == game.i18n.localize("NAME.Perception")) +{ + args.fields.modifier -= 20; +} diff --git a/scripts/M5bh0heeafA2fQQ8.js b/scripts/M5bh0heeafA2fQQ8.js new file mode 100644 index 0000000..3583c70 --- /dev/null +++ b/scripts/M5bh0heeafA2fQQ8.js @@ -0,0 +1,8 @@ +if (args.test.spell?.getFlag("wfrp4e", "boonOfTzeentch")) +{ + if (args.test.result.minormis || args.test.result.majormis || args.test.result.catastrophicmis) + { + this.script.scriptMessage(`${this.effect.name} quits your mind in disgust and erases itself from your grimoire!`) + this.effect.sourceItem.delete(); + } +} \ No newline at end of file diff --git a/scripts/M9VgeYGiUO97ZUW4.js b/scripts/M9VgeYGiUO97ZUW4.js new file mode 100644 index 0000000..4cb39af --- /dev/null +++ b/scripts/M9VgeYGiUO97ZUW4.js @@ -0,0 +1,12 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.hCadFsTRvLN9faaY") +let data = item.toObject(); +data.system.location.value = "Jaw" +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) + +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (!test.succeeded) +{ + args.actor.addCondition("unconscious") +} + diff --git a/scripts/MCK6WyjwYT28lsTN.js b/scripts/MCK6WyjwYT28lsTN.js new file mode 100644 index 0000000..e13fea1 --- /dev/null +++ b/scripts/MCK6WyjwYT28lsTN.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.u0CFf3xwiyidD9T5") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/MDLttXplnNthncGr.js b/scripts/MDLttXplnNthncGr.js new file mode 100644 index 0000000..b7a08ee --- /dev/null +++ b/scripts/MDLttXplnNthncGr.js @@ -0,0 +1 @@ +return args.type == "cast" && ["death", "necromancy", "life", "light", "heavens"].includes(args.spell?.system.lore.value) \ No newline at end of file diff --git a/scripts/MFKhU9vp8bQpHP3I.js b/scripts/MFKhU9vp8bQpHP3I.js new file mode 100644 index 0000000..126a0b5 --- /dev/null +++ b/scripts/MFKhU9vp8bQpHP3I.js @@ -0,0 +1,14 @@ +let value = parseInt(this.item.specification.value) +let name = this.actor.prototypeToken.name + +if (game.user.isGM && game.user.targets.size) +{ + game.user.targets.forEach(t => { + t.actor.applyTerror(value, name) + }) + game.user.updateTokenTargets([]); +} +else +{ + game.wfrp4e.utility.postTerror(value, name) +} \ No newline at end of file diff --git a/scripts/MI2GgNi3fZtUCtQD.js b/scripts/MI2GgNi3fZtUCtQD.js new file mode 100644 index 0000000..4a7e8fc --- /dev/null +++ b/scripts/MI2GgNi3fZtUCtQD.js @@ -0,0 +1 @@ +return ["int", "wp"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/MJB6WbZSF6Briz30.js b/scripts/MJB6WbZSF6Briz30.js new file mode 100644 index 0000000..13bb16c --- /dev/null +++ b/scripts/MJB6WbZSF6Briz30.js @@ -0,0 +1 @@ +return args.item?.name == game.i18n.localize("NAME.Leadership") \ No newline at end of file diff --git a/scripts/MSJWJEUrX7ZmMvAD.js b/scripts/MSJWJEUrX7ZmMvAD.js new file mode 100644 index 0000000..ad91ce3 --- /dev/null +++ b/scripts/MSJWJEUrX7ZmMvAD.js @@ -0,0 +1 @@ +return !(args.skill?.name.includes(game.i18n.localize("NAME.Ranged")) || args.item?.isRanged || args.item?.name == game.i18n.localize("NAME.Charm")) \ No newline at end of file diff --git a/scripts/McLR9YcgVUG3MooC.js b/scripts/McLR9YcgVUG3MooC.js new file mode 100644 index 0000000..38225fd --- /dev/null +++ b/scripts/McLR9YcgVUG3MooC.js @@ -0,0 +1 @@ +args.applyTB = false; \ No newline at end of file diff --git a/scripts/MfxWXZwaZUjGSBqw.js b/scripts/MfxWXZwaZUjGSBqw.js new file mode 100644 index 0000000..4e012c4 --- /dev/null +++ b/scripts/MfxWXZwaZUjGSBqw.js @@ -0,0 +1,5 @@ +if (this.actor.hasCondition("ablaze")) +{ + this.script.scriptNotification("Immune to Ablaze") + await this.actor.hasCondition("ablaze")?.delete() +} \ No newline at end of file diff --git a/scripts/MfxzwJz2o9ho2hOM.js b/scripts/MfxzwJz2o9ho2hOM.js new file mode 100644 index 0000000..664e6ec --- /dev/null +++ b/scripts/MfxzwJz2o9ho2hOM.js @@ -0,0 +1 @@ +return args.skill?.name == "Lore (Apothecary)" \ No newline at end of file diff --git a/scripts/MgMMoC4Umpg7fmNI.js b/scripts/MgMMoC4Umpg7fmNI.js new file mode 100644 index 0000000..ef41566 --- /dev/null +++ b/scripts/MgMMoC4Umpg7fmNI.js @@ -0,0 +1,24 @@ +// Apply changes when the mask is worn + +if (args.equipped) { + this.actor.createEmbeddedDocuments("ActiveEffect", [this.item.effects.contents[1]?.convertToApplied()]) + this.script.scriptMessage(`${this.actor.name} dons the ${this.item.name}.${this.actor.prototypeToken.name} has gained the Magic Resistance Trait. This effect lasts for one hour.
`, {whisper: ChatMessage.getWhisperRecipients("GM"), blind: true }) +} + +if (hasMagicResistance) { + // Multiple doses may be consumed at once, with each one adding an additional 1 to the Magic Resistance rating and increasing the duration by one hour. + let msg = `${this.actor.prototypeToken.name} has enhanced their Magic Resistance by 1 to Rating ${parseInt(hasMagicResistance.system.specification.value)}. This effect lasts for one hour.
` + + // Resist toxic effect + this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), { + fields: {difficulty: "challenging"} + }).then(async test => { + await test.roll() + + // If they fail ... + if (!test.succeeded) { + msg += `However, they begin to ooze the thick, poisonous slime that coats every Dreadmaw. They have gained 1 Poisoned Condition now and should continue to receive an additional @Condition[Poisoned] Condition at the end of each of the round.
+If they are still alive at the end of 10 rounds, the effect ends and all Poisoned Conditions gained from ${this.effect.name} are removed.
` + this.actor.addCondition("poisoned", 1) + } + this.script.scriptMessage(msg, {whisper: ChatMessage.getWhisperRecipients("GM"), blind: true }) + }) +} diff --git a/scripts/PVjaKAHTKDA0rA9J.js b/scripts/PVjaKAHTKDA0rA9J.js new file mode 100644 index 0000000..8942127 --- /dev/null +++ b/scripts/PVjaKAHTKDA0rA9J.js @@ -0,0 +1,2 @@ +let test = await this.actor.setupSkill("Dodge", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}); +await test.roll(); \ No newline at end of file diff --git a/scripts/PdClojv7yNgQpOUc.js b/scripts/PdClojv7yNgQpOUc.js new file mode 100644 index 0000000..071f833 --- /dev/null +++ b/scripts/PdClojv7yNgQpOUc.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Endurance"); \ No newline at end of file diff --git a/scripts/PeZYj8b0vedyJj00.js b/scripts/PeZYj8b0vedyJj00.js new file mode 100644 index 0000000..51a0a44 --- /dev/null +++ b/scripts/PeZYj8b0vedyJj00.js @@ -0,0 +1,14 @@ +// This script needs to be separate because equipTransfer is off on the other effect, and thus won't execute when added to an actor + +let mainEffect = this.item.effects.contents[0]; +if (mainEffect.name.includes("(Lore)")) +{ + let choice = await ItemDialog.create(ItemDialog.objectToArray(game.wfrp4e.config.magicLores, this.item.img), 1, "Choose Lore"); + if (choice.length) + { + mainEffect.update({name : mainEffect.name.replace("Lore", choice[0].name)}) + this.item.update({name : this.item.name += ` (${choice[0].name})`}) + } +} + +this.effect.delete(); \ No newline at end of file diff --git a/scripts/Pg9C6nJX5QHIdqa9.js b/scripts/Pg9C6nJX5QHIdqa9.js new file mode 100644 index 0000000..f7d625b --- /dev/null +++ b/scripts/Pg9C6nJX5QHIdqa9.js @@ -0,0 +1 @@ +return !args.item?.system.attackType diff --git a/scripts/Ph3TdQw1lGiFr049.js b/scripts/Ph3TdQw1lGiFr049.js new file mode 100644 index 0000000..f7e4852 --- /dev/null +++ b/scripts/Ph3TdQw1lGiFr049.js @@ -0,0 +1,19 @@ + if (!args.test.context.phantasmal && + (this.actor.isOpposing || args.test.context.defending) && + args.test.result.roll % 11 == 0 && + args.test.succeeded && + ["Language (Magick)", "Dodge"].includes(args.test.item?.name)) + { + args.test.context.phantasmal = true; // Flag so items aren't readded if test is edited + let text = `${this.effect.name}: Adding Unstable and Ward` + args.test.result.other.push(text) + this.script.scriptNotification(text); + + let ward = await fromUuid("Compendium.wfrp4e-core.items.Bvd2aZ0gQUXHfCTh") + let wardData = ward.toObject(); + wardData.system.specification.value = 9; + + let unstable = await fromUuid("Compendium.wfrp4e-core.items.D0ImWEIMSDgElsnl") + let unstableData = unstable.toObject(); + this.actor.createEmbeddedDocuments("Item", [wardData, unstableData], {fromEffect: this.effect.id}) + } diff --git a/scripts/PjRxGuUDKGmSmVDc.js b/scripts/PjRxGuUDKGmSmVDc.js new file mode 100644 index 0000000..dd06719 --- /dev/null +++ b/scripts/PjRxGuUDKGmSmVDc.js @@ -0,0 +1,5 @@ +fromUuid("Compendium.wfrp4e-core.items.EO05HX7jql0g605A").then(item => { + item = item.toObject() + item.system.specification.value = this.actor.characteristics.ag.value + this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id}) +}) \ No newline at end of file diff --git a/scripts/PmELrzD3RmF9qKkO.js b/scripts/PmELrzD3RmF9qKkO.js new file mode 100644 index 0000000..3d5c0b3 --- /dev/null +++ b/scripts/PmELrzD3RmF9qKkO.js @@ -0,0 +1,9 @@ +if (this.item.system.specification.value == "Size") +{ + let choice = await ItemDialog.create(ItemDialog.objectToArray(game.wfrp4e.config.actorSizes, this.item.img), 1, "Choose Size"); + if (choice[0]) + { + this.item.updateSource({"system.specification.value" : choice[0].name}) + this.effect.updateSource({name : this.effect.name + ` (${choice[0].name})`}) + } +} \ No newline at end of file diff --git a/scripts/PoNnT5EqvLj2r5yf.js b/scripts/PoNnT5EqvLj2r5yf.js new file mode 100644 index 0000000..af693bc --- /dev/null +++ b/scripts/PoNnT5EqvLj2r5yf.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.OutdoorSurvival") && args.skill?.name != game.i18n.localize("NAME.Track"); \ No newline at end of file diff --git a/scripts/PwqTmw7rsG8hzqCS.js b/scripts/PwqTmw7rsG8hzqCS.js new file mode 100644 index 0000000..6ce47bf --- /dev/null +++ b/scripts/PwqTmw7rsG8hzqCS.js @@ -0,0 +1,10 @@ +if (args.test.result.critical && args.test.result.roll % 10 == 0) +{ + game.wfrp4e.tables.findTable("knuckleduster-diseases").roll().then(roll => { + let results = roll.results[0] + + this.script.scriptMessage(`${this.actor.name} contracts @UUID[Compendium.${results.documentCollection}.${results.documentId}]{${results.text}}`, {blind : true, whisper: ChatMessage.getWhisperRecipients("GM") }) + }) + + } + diff --git a/scripts/Q1trEhtqjIiDvFPF.js b/scripts/Q1trEhtqjIiDvFPF.js new file mode 100644 index 0000000..edff223 --- /dev/null +++ b/scripts/Q1trEhtqjIiDvFPF.js @@ -0,0 +1 @@ +args.prefillModifiers.modifier -= 10 * getProperty(this.effect, 'flags.wfrp4e.value') \ No newline at end of file diff --git a/scripts/Q4EQgP4gZR8TTm7S.js b/scripts/Q4EQgP4gZR8TTm7S.js new file mode 100644 index 0000000..2ae696c --- /dev/null +++ b/scripts/Q4EQgP4gZR8TTm7S.js @@ -0,0 +1,9 @@ +let penalty = 0 +if (args.item?.system.attackType) +{ + penalty -= 30 +} +if (args.actor.has("Second Sight", "talent")) + penalty += 10 + +args.prefillModifiers.modifier += penalty \ No newline at end of file diff --git a/scripts/Q68WiUWY7GxiXBbT.js b/scripts/Q68WiUWY7GxiXBbT.js new file mode 100644 index 0000000..536d1ae --- /dev/null +++ b/scripts/Q68WiUWY7GxiXBbT.js @@ -0,0 +1,5 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.9GNpAqgsKzxZKJpp") +let data = item.toObject(); +data.system.specification.value = "When Alone"; +data.effects[0].disabled = true; +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/Q9EmlWmuDac83cJw.js b/scripts/Q9EmlWmuDac83cJw.js new file mode 100644 index 0000000..65e9e2e --- /dev/null +++ b/scripts/Q9EmlWmuDac83cJw.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.Climb") || args.skill?.name?.includes(game.i18n.localize("NAME.Stealth")); \ No newline at end of file diff --git a/scripts/QF8LanKNoAlTkQG0.js b/scripts/QF8LanKNoAlTkQG0.js new file mode 100644 index 0000000..bb333fb --- /dev/null +++ b/scripts/QF8LanKNoAlTkQG0.js @@ -0,0 +1 @@ +this.actor.system.status.encumbrance.max += 2 \ No newline at end of file diff --git a/scripts/QKTA2TqZ77pvHWSJ.js b/scripts/QKTA2TqZ77pvHWSJ.js new file mode 100644 index 0000000..1a94aec --- /dev/null +++ b/scripts/QKTA2TqZ77pvHWSJ.js @@ -0,0 +1,9 @@ + this.actor.getActiveTokens().forEach(t => t.document.update({light : { + "dim": 0, + "bright": 0, + "alpha": 0.5, + "animation": { + "type": "", + }, + "color": "#000000", + }})); \ No newline at end of file diff --git a/scripts/QKjR6P1WEHXf4K77.js b/scripts/QKjR6P1WEHXf4K77.js new file mode 100644 index 0000000..1fee3fb --- /dev/null +++ b/scripts/QKjR6P1WEHXf4K77.js @@ -0,0 +1 @@ +args.fields.slBonus -= 2 diff --git a/scripts/QPVVDPcJ4Xi5FmQl.js b/scripts/QPVVDPcJ4Xi5FmQl.js new file mode 100644 index 0000000..340975c --- /dev/null +++ b/scripts/QPVVDPcJ4Xi5FmQl.js @@ -0,0 +1,9 @@ +if(this.actor.hasCondition("fatigued") && args.opposedTest.result.hitloc.value == "head" && (args.opposedTest.attackerTest.result.critical || args.actor.status.wounds.value - args.totalWoundLoss < 0)) +{ + let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), { fields: { difficulty: "average" }, skipTargets: true, appendTitle : ` - ${this.effect.name}`}) + await test.roll(); + if (test.failed) + { + this.actor.addCondition("unconscious") + } +} \ No newline at end of file diff --git a/scripts/QQ2gHThZHdO4yLLX.js b/scripts/QQ2gHThZHdO4yLLX.js new file mode 100644 index 0000000..abb25c3 --- /dev/null +++ b/scripts/QQ2gHThZHdO4yLLX.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.Swim"); \ No newline at end of file diff --git a/scripts/QQPiREc50HT5W2Tr.js b/scripts/QQPiREc50HT5W2Tr.js new file mode 100644 index 0000000..7190682 --- /dev/null +++ b/scripts/QQPiREc50HT5W2Tr.js @@ -0,0 +1,2 @@ +if (args.item.type == "weapon" && args.item.weaponGroup.value == "brawling") + args.item.damage.value += " + 1" \ No newline at end of file diff --git a/scripts/QRSACifDrvojIXHB.js b/scripts/QRSACifDrvojIXHB.js new file mode 100644 index 0000000..0527702 --- /dev/null +++ b/scripts/QRSACifDrvojIXHB.js @@ -0,0 +1,11 @@ +if (!this.actor.effects.find(e => e.isCondition)) +{ + return this.script.scriptNotification("No Conditions on this Actor") +} + +let choice = await ItemDialog.create(this.actor.effects.filter(i => i.isCondition), 1, "Choose a Condition") + +if (choice[0]) +{ + this.actor.removeCondition(choice[0].conditionId) +} diff --git a/scripts/QaGNsqKm2Nf0zGVm.js b/scripts/QaGNsqKm2Nf0zGVm.js new file mode 100644 index 0000000..3fc40b5 --- /dev/null +++ b/scripts/QaGNsqKm2Nf0zGVm.js @@ -0,0 +1 @@ +return ["t", "int", "wp", "fel"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/QbIYnshWeP1U8SUy.js b/scripts/QbIYnshWeP1U8SUy.js new file mode 100644 index 0000000..d6c5e61 --- /dev/null +++ b/scripts/QbIYnshWeP1U8SUy.js @@ -0,0 +1,2 @@ +args.applyAP = false; +args.applyTB = false; \ No newline at end of file diff --git a/scripts/Qgn92fZyc3Psn8QJ.js b/scripts/Qgn92fZyc3Psn8QJ.js new file mode 100644 index 0000000..fcfd3fd --- /dev/null +++ b/scripts/Qgn92fZyc3Psn8QJ.js @@ -0,0 +1,10 @@ +if (args.test.options.useOnesAttractive && (args.test.result.roll <= game.settings.get("wfrp4e", "automaticSuccess") || args.test.result.roll <= args.test.target)) +{ + +let SL = Math.floor(args.test.target / 10) - Math.floor(args.test.result.roll / 10) +let ones = Number(args.test.result.roll.toString().split("").pop()) + +if (ones > SL) + args.test.data.result.SL = "+" + (ones + args.test.successBonus + args.test.slBonus) + args.test.result.other.push(`${this.effect.name}: Used unit dice as SL`) +} \ No newline at end of file diff --git a/scripts/Qk7t2l5ep9RDVpgE.js b/scripts/Qk7t2l5ep9RDVpgE.js new file mode 100644 index 0000000..80de579 --- /dev/null +++ b/scripts/Qk7t2l5ep9RDVpgE.js @@ -0,0 +1 @@ +args.options.diceman= true; \ No newline at end of file diff --git a/scripts/QoEOxRruQXYrZrv3.js b/scripts/QoEOxRruQXYrZrv3.js new file mode 100644 index 0000000..c084829 --- /dev/null +++ b/scripts/QoEOxRruQXYrZrv3.js @@ -0,0 +1,17 @@ +let filters = [ + { + property : "type", + value : "skill" + }, + { + property : "name", + value : /Melee/gm, + regex: true + } +] + +let items = await game.wfrp4e.apps.ItemDialog.createFromFilters(filters, 2, "Choose 2 Skills to add +20") +items = items.map(i => i.toObject()) +items.forEach(i => i.system.advances.value = 20) + +this.actor.createEmbeddedDocuments("Item", items); \ No newline at end of file diff --git a/scripts/QqkE7rlqhkeRohFD.js b/scripts/QqkE7rlqhkeRohFD.js new file mode 100644 index 0000000..896b9a2 --- /dev/null +++ b/scripts/QqkE7rlqhkeRohFD.js @@ -0,0 +1 @@ +return !(["cast", "channelling"].includes(args.type) && this.actor.hasCondition("fatigued")) \ No newline at end of file diff --git a/scripts/QqybHxNCzPEzG1Qh.js b/scripts/QqybHxNCzPEzG1Qh.js new file mode 100644 index 0000000..05952e9 --- /dev/null +++ b/scripts/QqybHxNCzPEzG1Qh.js @@ -0,0 +1 @@ +return args.fields.dualWielding || args.options.dualWieldOffhand \ No newline at end of file diff --git a/scripts/QwHoqu2oO8QO8Mad.js b/scripts/QwHoqu2oO8QO8Mad.js new file mode 100644 index 0000000..a5972f6 --- /dev/null +++ b/scripts/QwHoqu2oO8QO8Mad.js @@ -0,0 +1,3 @@ +let content = `${this.effect.name}: All targets engaged with ${this.actor.prototypeToken.name} take [[/r 1d10]] Damage, modified by TB and AP.` + +this.script.scriptMessage(content) \ No newline at end of file diff --git a/scripts/R32U01LBjBrK1pns.js b/scripts/R32U01LBjBrK1pns.js new file mode 100644 index 0000000..4816313 --- /dev/null +++ b/scripts/R32U01LBjBrK1pns.js @@ -0,0 +1,33 @@ + const templateMap = { + 'P2e7Yx98bK3u110a' : "", + 'iuMp3KLaMT2WCmie' : "Xp4r2KUhqfjak8zq", + 'RBuYcT5tppwcmnC5' : "wYN19h3WVF1yOVq2", + 'vcGpNwNbhvfzVveQ' : "ac5ClOuaYtzOYyWp", + 'jmhKZy0w9TzkEK9c' : "IS3LTdTuay6uRHUq", + '9Byj6k7SmdTYis2V' : "LjMlx99gBGeRJUQu", + 'laJwc2l9tzJPgaaJ' : "x5wpMprsObuqMCYg", + } + let template = (await game.wfrp4e.tables.rollTable("hireling-templates", {hideDSN: true})).object; + let physicalQuirk = (await game.wfrp4e.tables.rollTable("physical-quirks", {hideDSN: true})).text; + let workEthic = (await game.wfrp4e.tables.rollTable("work-ethic", {hideDSN: true})).text; + let personalityQuirk = (await game.wfrp4e.tables.rollTable("personality-quirks", {hideDSN: true})).text; + + + let templateItem = await game.wfrp4e.utility.findItemId(templateMap[template._id]); + + let bio = + ` +Template: ${template.text}
+Phsyical Quirk: ${physicalQuirk}
+Work Ethic: ${workEthic}
+Personality Quirk: ${personalityQuirk}
+ ` + + this.script.scriptMessage(bio, {whisper : ChatMessage.getWhisperRecipients("GM")}) + + await this.actor.update({"system.details.gmnotes.value" : bio}) + + if (templateItem) + { + this.actor.createEmbeddedDocuments("Item", [templateItem.toObject()]) + } \ No newline at end of file diff --git a/scripts/R5dOZWFxE2n6tooX.js b/scripts/R5dOZWFxE2n6tooX.js new file mode 100644 index 0000000..d6c0f61 --- /dev/null +++ b/scripts/R5dOZWFxE2n6tooX.js @@ -0,0 +1 @@ +return this.item.system.usesLocation(args.weapon) \ No newline at end of file diff --git a/scripts/R6SnyF3y4Vsq6oga.js b/scripts/R6SnyF3y4Vsq6oga.js new file mode 100644 index 0000000..9cb3f07 --- /dev/null +++ b/scripts/R6SnyF3y4Vsq6oga.js @@ -0,0 +1,8 @@ +let lore = this.effect.name.split("(")[1].split(")")[0].toLowerCase(); + +// If channelling corresponding lore +if (args.type == "channelling" && args.spell.system.lore.value == lore) + args.prefillModifiers.slBonus += 1 +// If channelling or casting different lore +else if (args.spell.system.lore.value != lore && args.spell.system.lore.value != "petty") + args.prefillModifiers.slBonus -= 1 \ No newline at end of file diff --git a/scripts/R95pDZMHnD9iHAl8.js b/scripts/R95pDZMHnD9iHAl8.js new file mode 100644 index 0000000..903d7c3 --- /dev/null +++ b/scripts/R95pDZMHnD9iHAl8.js @@ -0,0 +1 @@ +return args.skill?.name.includes(this.item.system.tests.value); \ No newline at end of file diff --git a/scripts/RDtJXji3hgcKnEBk.js b/scripts/RDtJXji3hgcKnEBk.js new file mode 100644 index 0000000..84cd8d9 --- /dev/null +++ b/scripts/RDtJXji3hgcKnEBk.js @@ -0,0 +1,33 @@ +let as = (await fromUuid("Compendium.wfrp4e-core.items.Item.9h82z72XGo9tfgQS")).toObject(); +let hv = (await fromUuid("Compendium.wfrp4e-core.items.Item.Nj3tC8A5fZ3zEdMR")).toObject(); +let ms = (await fromUuid("Compendium.wfrp4e-core.items.Item.6w30u0VPsAicrqb5")).toObject(); +let ss = (await fromUuid("Compendium.wfrp4e-core.items.Item.OEjUvJKi0xmBwbS2")).toObject(); + +as.name += " (Sight)"; + +let roll = (await new Roll("1d10").roll()); +roll.toMessage(this.script.getChatData()) +let items = [] + +if (roll.total <= 2) +{ + items = items.concat([as]); +} +else if (roll.total <= 4) +{ + items = items.concat([hv]); +} +else if (roll.total <= 6) +{ + items = items.concat([ms]); +} +else if (roll.total <= 8) +{ + items = items.concat([ss]); +} +else if (roll.total <= 10) +{ + items = items.concat([as, hv, ms, ss]); +} + +this.actor.createEmbeddedDocuments("Item", items, {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/RHyBLYT5oHf7EPnG.js b/scripts/RHyBLYT5oHf7EPnG.js new file mode 100644 index 0000000..0eeaadd --- /dev/null +++ b/scripts/RHyBLYT5oHf7EPnG.js @@ -0,0 +1,21 @@ +let skills = this.actor.itemTypes.skill.filter(i => i.name.includes(game.i18n.localize("NAME.Melee"))) + +let skill = await ItemDialog.create(skills, 1, "Select the skill used by the weapon") +let group = game.wfrp4e.utility.extractParenthesesText(skill[0]?.name) +let groupKey = game.wfrp4e.utility.findKey(group, game.wfrp4e.config.weaponGroups) + +let weapon = { + name : this.effect.name, + type : "weapon", + img : this.effect.img, + system : { + "damage.value" : this.actor.system.characteristics.wp.bonus, + "weaponGroup.value" : groupKey || "basic", + "twohanded.value" : ["polearm", "twohanded"].includes(groupKey), + "reach.value" : "average", + "qualities.value" : [{name : "magical"}] + }, +} + +Item.implementation.create(foundry.utils.expandObject(weapon), {parent : this.actor, fromEffect : this.effect.id}) +this.script.scriptNotification("Item created. Further customization must be done manually within the Item's sheet"); \ No newline at end of file diff --git a/scripts/RI8crJxeD8JLDwMh.js b/scripts/RI8crJxeD8JLDwMh.js new file mode 100644 index 0000000..0a98874 --- /dev/null +++ b/scripts/RI8crJxeD8JLDwMh.js @@ -0,0 +1 @@ +return args.weapon?.system?.weaponGroup?.value != "fencing" \ No newline at end of file diff --git a/scripts/RJpglw5eVRM1f9t0.js b/scripts/RJpglw5eVRM1f9t0.js new file mode 100644 index 0000000..ab32d24 --- /dev/null +++ b/scripts/RJpglw5eVRM1f9t0.js @@ -0,0 +1 @@ +args.wounds *= 5 \ No newline at end of file diff --git a/scripts/RKIFGN583PQnqHGk.js b/scripts/RKIFGN583PQnqHGk.js new file mode 100644 index 0000000..c0633f0 --- /dev/null +++ b/scripts/RKIFGN583PQnqHGk.js @@ -0,0 +1,5 @@ +if (args.opposedTest.result.hitloc.value == "body" && args.totalWoundLoss > 0) +{ + args.actor.addCondition("bleeding", 2) + this.script.scriptMessage("Gained 2 Bleeding Conditions") +} \ No newline at end of file diff --git a/scripts/RNHrSTfMLXm5sXkC.js b/scripts/RNHrSTfMLXm5sXkC.js new file mode 100644 index 0000000..c5b8e70 --- /dev/null +++ b/scripts/RNHrSTfMLXm5sXkC.js @@ -0,0 +1 @@ +return ["ws", "bs", "s", "ag"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/RNr9CwyvLhlnwD2h.js b/scripts/RNr9CwyvLhlnwD2h.js new file mode 100644 index 0000000..2dbcde4 --- /dev/null +++ b/scripts/RNr9CwyvLhlnwD2h.js @@ -0,0 +1 @@ +return !args.skill?.name.includes(game.i18n.localize("NAME.Sail")); \ No newline at end of file diff --git a/scripts/ROXCqAFSTLouJniL.js b/scripts/ROXCqAFSTLouJniL.js new file mode 100644 index 0000000..dcc969a --- /dev/null +++ b/scripts/ROXCqAFSTLouJniL.js @@ -0,0 +1,7 @@ +if (args.test.spell.name == "Warp Lightning") +{ + if (args.test.result.minormis || args.test.result.majormis || args.test.result.catastrophicmis) + { + this.script.scriptMessage(`${this.item.name} Overloads!`) + } +} \ No newline at end of file diff --git a/scripts/RSsGiDFibuqg3sHr.js b/scripts/RSsGiDFibuqg3sHr.js new file mode 100644 index 0000000..9132550 --- /dev/null +++ b/scripts/RSsGiDFibuqg3sHr.js @@ -0,0 +1,15 @@ +let diseaseIndex = game.packs +.filter(i => i.metadata.type == "Item") +.reduce((acc, pack) => acc.concat(pack.index.contents), []) +.filter(i => i.type == "disease") +.map(i => { + i.id = i._id + return i +}) + +let choice = await ItemDialog.create(diseaseIndex , 1, "Choose a Disease") + +if (choice[0]) +{ + await this.item.updateSource({"system.specification.value" : choice[0].name}) +} \ No newline at end of file diff --git a/scripts/RZlMkxJz5apn0mUj.js b/scripts/RZlMkxJz5apn0mUj.js new file mode 100644 index 0000000..74fe1bc --- /dev/null +++ b/scripts/RZlMkxJz5apn0mUj.js @@ -0,0 +1 @@ +return args.item?.system.attackType != "ranged" \ No newline at end of file diff --git a/scripts/RprZWlnopSqZt7KZ.js b/scripts/RprZWlnopSqZt7KZ.js new file mode 100644 index 0000000..523491c --- /dev/null +++ b/scripts/RprZWlnopSqZt7KZ.js @@ -0,0 +1 @@ +return !args.skill?.name.includes(game.i18n.localize("NAME.Stealth")); \ No newline at end of file diff --git a/scripts/RqWnhnwFxaHubgiA.js b/scripts/RqWnhnwFxaHubgiA.js new file mode 100644 index 0000000..a9b12cd --- /dev/null +++ b/scripts/RqWnhnwFxaHubgiA.js @@ -0,0 +1,3 @@ +await args.actor.addCondition("blinded"); +await args.actor.addCondition("deafened"); +await args.actor.addCondition("stunned"); \ No newline at end of file diff --git a/scripts/RrchOMpEdIvceJxl.js b/scripts/RrchOMpEdIvceJxl.js new file mode 100644 index 0000000..300050b --- /dev/null +++ b/scripts/RrchOMpEdIvceJxl.js @@ -0,0 +1 @@ +return args.skill?.name == "Stealth (Rural)" \ No newline at end of file diff --git a/scripts/RuW1PWUFxIbbSlIm.js b/scripts/RuW1PWUFxIbbSlIm.js new file mode 100644 index 0000000..c333e53 --- /dev/null +++ b/scripts/RuW1PWUFxIbbSlIm.js @@ -0,0 +1 @@ +return !["t", "wp", "ag", "i", "int"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/RvipIYj9H7n4UDMe.js b/scripts/RvipIYj9H7n4UDMe.js new file mode 100644 index 0000000..4ae90e5 --- /dev/null +++ b/scripts/RvipIYj9H7n4UDMe.js @@ -0,0 +1,84 @@ + let characteristics = { + "ws" : -10, + "bs" : -10, + "s" : -5, + "t" : -5, + "i" : -10, + "ag" : -10, + "dex" : -10, + "int" : 0, + "wp" : 0, + "fel" : 0 + } + let skills = [] + let skillAdvancements = [] + let talents = [] + let trappings = [] + let items = [] + + let updateObj = this.actor.toObject(); + + for (let ch in characteristics) + { + updateObj.system.characteristics[ch].modifier += characteristics[ch]; + } + + for (let index = 0; index < skills.length; index++) + { + let skill = skills[index] + let skillItem; + skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill") + if (skillItem) + skillItem.system.advances.value += skillAdvancements[index] + else + { + skillItem = await game.wfrp4e.utility.findSkill(skill) + skillItem = skillItem.toObject(); + skillItem.system.advances.value = skillAdvancements[index]; + items.push(skillItem); + } + } + + for (let talent of talents) + { + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } + } + + for (let trapping of trappings) + { + let trappingItem = await game.wfrp4e.utility.findItem(trapping) + if (trappingItem) + { + trappingItem = trappingItem.toObject() + + equip(trappingItem) + + items.push(trappingItem); + } + else + { + ui.notifications.warn(`Could not find ${trapping}`, {permanent : true}) + } + } + + + await this.actor.update(updateObj) + this.actor.createEmbeddedDocuments("Item", items); + + function equip(item) + { + if (item.type == "armour") + item.system.worn.value = true + else if (item.type == "weapon") + item.system.equipped = true + else if (item.type == "trapping" && item.system.trappingType.value == "clothingAccessories") + item.system.worn = true + } \ No newline at end of file diff --git a/scripts/S1QihXuvdEVzeRtB.js b/scripts/S1QihXuvdEVzeRtB.js new file mode 100644 index 0000000..0194c09 --- /dev/null +++ b/scripts/S1QihXuvdEVzeRtB.js @@ -0,0 +1,40 @@ +let dice = await new Roll("1d10").roll() +let roll = dice.total +let talent +let message +let modifier = 0 + +if (roll <= 3) +{ + item = await fromUuid("Compendium.wfrp4e-core.items.mNoCuaVbFBflfO6X") +} + +else if (roll <= 6) +{ + item = await fromUuid("Compendium.wfrp4e-core.items.OEjUvJKi0xmBwbS2") + modifier = -3 +} + +else if (roll <= 9) +{ + item = await fromUuid("Compendium.wfrp4e-core.items.mdPGZsn2396dEpOf") + modifier = -3 +} + +else if (roll = 10) +{ + item = await fromUuid("Compendium.wfrp4e-core.items.qdMbxW09FUoYBzmB") + modifier = -5 +} + +message = `${roll} Rolled, gain ${item.name}, ${modifier} Strength` +dice.toMessage(this.script.getChatData()) + +let changes = duplicate(this.effect.changes) +changes[0].value = modifier + +this.effect.updateSource({changes}) + +await this.actor.createEmbeddedDocuments("Item", [item.toObject()], {fromEffect : this.effect.id}) + +this.script.scriptNotification(message) \ No newline at end of file diff --git a/scripts/S3DCTw4yJ85eSaKp.js b/scripts/S3DCTw4yJ85eSaKp.js new file mode 100644 index 0000000..666ee45 --- /dev/null +++ b/scripts/S3DCTw4yJ85eSaKp.js @@ -0,0 +1 @@ +this.actor.setupCharacteristic("s", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}).then(test => test.roll()) \ No newline at end of file diff --git a/scripts/S3Dev4hleOYqDNe9.js b/scripts/S3Dev4hleOYqDNe9.js new file mode 100644 index 0000000..82a4f59 --- /dev/null +++ b/scripts/S3Dev4hleOYqDNe9.js @@ -0,0 +1,16 @@ +if (args.test.options.healWounds) { + if (args.test.succeeded) + { + let wounds = this.actor.characteristics.int.bonus + Number(args.test.result.SL) + if (args.test.options.fieldDressing && args.test.result.reversed) + { + wounds = this.actor.characteristics.int.bonus + Math.min(1, Number(args.test.result.SL)) + } + args.test.result.woundsHealed = wounds + args.test.result.other.push(`${this.actor.name} healed ${wounds} wounds of the patient.`) + } + else if (this.actor.characteristics.int.bonus + Number(args.test.result.SL) < 0) + { + args.test.result.other.push(`The patient contracts a @UUID[Compendium.wfrp4e-core.items.Item.1hQuVFZt9QnnbWzg]{Minor Infection}.`) + } +} \ No newline at end of file diff --git a/scripts/S4793DLFhjMxpM8x.js b/scripts/S4793DLFhjMxpM8x.js new file mode 100644 index 0000000..4f2f739 --- /dev/null +++ b/scripts/S4793DLFhjMxpM8x.js @@ -0,0 +1 @@ +return !["ws", "bs"].includes(args.characteristic) && !args.item?.system.attackType && !args.options.dodge \ No newline at end of file diff --git a/scripts/S6tUyFJvGMV19mvP.js b/scripts/S6tUyFJvGMV19mvP.js new file mode 100644 index 0000000..867c8d8 --- /dev/null +++ b/scripts/S6tUyFJvGMV19mvP.js @@ -0,0 +1 @@ +this.actor.status.addArmour(2, {source: this.effect}) \ No newline at end of file diff --git a/scripts/S95QqpX1cZyIVCPy.js b/scripts/S95QqpX1cZyIVCPy.js new file mode 100644 index 0000000..3011ed7 --- /dev/null +++ b/scripts/S95QqpX1cZyIVCPy.js @@ -0,0 +1,5 @@ +if (parseInt(this.item.system.specification.value) > 0) +{ + this.actor.system.status.ward.value = parseInt(this.item.system.specification.value); +} + diff --git a/scripts/SGr50Hq1AHIEzIFN.js b/scripts/SGr50Hq1AHIEzIFN.js new file mode 100644 index 0000000..324b7a2 --- /dev/null +++ b/scripts/SGr50Hq1AHIEzIFN.js @@ -0,0 +1,6 @@ +let choice = await ItemDialog.create(ItemDialog.objectToArray({ + int : game.wfrp4e.config.characteristics.int, + fel : game.wfrp4e.config.characteristics.fel +}, this.effect.img), 1, "Choose Characteristic"); + +this.effect.updateSource({"flags.wfrp4e.characteristic" : choice[0].id}) \ No newline at end of file diff --git a/scripts/SLy1Fs3oXcHgFgjK.js b/scripts/SLy1Fs3oXcHgFgjK.js new file mode 100644 index 0000000..4add629 --- /dev/null +++ b/scripts/SLy1Fs3oXcHgFgjK.js @@ -0,0 +1,5 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.Item.pTorrE0l3VybAbtn") +let data = item.toObject(); +let value = getProperty(this.effect.sourceTest, "result.overcast.usage.other.current") || 1 +data.system.specification.value = value +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/SO4Aa9argKbuO9rQ.js b/scripts/SO4Aa9argKbuO9rQ.js new file mode 100644 index 0000000..2af913b --- /dev/null +++ b/scripts/SO4Aa9argKbuO9rQ.js @@ -0,0 +1 @@ +args.prefillModifiers.modifier -= 20 \ No newline at end of file diff --git a/scripts/SPOkFWZWziZk5b7A.js b/scripts/SPOkFWZWziZk5b7A.js new file mode 100644 index 0000000..d26b8cb --- /dev/null +++ b/scripts/SPOkFWZWziZk5b7A.js @@ -0,0 +1 @@ +return args.item?.system?.attackType != "melee" \ No newline at end of file diff --git a/scripts/SRmfstEs278bP9Pz.js b/scripts/SRmfstEs278bP9Pz.js new file mode 100644 index 0000000..4831d32 --- /dev/null +++ b/scripts/SRmfstEs278bP9Pz.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.yRhhOlt18COq4e1q") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/SSqGxyN9hw0HDmED.js b/scripts/SSqGxyN9hw0HDmED.js new file mode 100644 index 0000000..ea4faf2 --- /dev/null +++ b/scripts/SSqGxyN9hw0HDmED.js @@ -0,0 +1 @@ +this.actor.addCondition("prone"); \ No newline at end of file diff --git a/scripts/SWIJjM2RCmzfr64u.js b/scripts/SWIJjM2RCmzfr64u.js new file mode 100644 index 0000000..5a07e2e --- /dev/null +++ b/scripts/SWIJjM2RCmzfr64u.js @@ -0,0 +1,6 @@ +if (args.test.result.hitloc.result == "head") +{ + args.test.result.critModifier = args.test.result.critModifier ? args.test.result.critModifier + 40 : 40 + + args.test.result.critical += ` (+${args.test.result.critModifier})` +} diff --git a/scripts/SrCHfOJFZwDickqa.js b/scripts/SrCHfOJFZwDickqa.js new file mode 100644 index 0000000..28558bc --- /dev/null +++ b/scripts/SrCHfOJFZwDickqa.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty: "average"}}); +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("prone") +} \ No newline at end of file diff --git a/scripts/StAderQaQQsxb6Rv.js b/scripts/StAderQaQQsxb6Rv.js new file mode 100644 index 0000000..d361e9a --- /dev/null +++ b/scripts/StAderQaQQsxb6Rv.js @@ -0,0 +1,10 @@ +let target = await game.wfrp4e.tables.rollTable("fixations") +if (target) +{ + this.script.scriptNotification(target.result); + let hatred = this.actor.items.find(i => i.getFlag("wfrp4e", "fromEffect") == this.effect.id) + if (hatred) + { + hatred.update({"system.specification.value" : target.result}) + } +} \ No newline at end of file diff --git a/scripts/SvFKt9hMcFQjeILA.js b/scripts/SvFKt9hMcFQjeILA.js new file mode 100644 index 0000000..52d528c --- /dev/null +++ b/scripts/SvFKt9hMcFQjeILA.js @@ -0,0 +1 @@ +args.actor.addCondition("entangled", this.effect.sourceTest.result.overcast.usage.other.current) \ No newline at end of file diff --git a/scripts/T5fiTzhXEQAv9Drf.js b/scripts/T5fiTzhXEQAv9Drf.js new file mode 100644 index 0000000..536b32a --- /dev/null +++ b/scripts/T5fiTzhXEQAv9Drf.js @@ -0,0 +1,20 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.rlDZZTj5PXjuRXa2") +let data = item.toObject(); +data.system.location.key = this.item.system.location.key; +await this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) + +let location = this.item.system.location.key; + +if (location) +{ + let dropped = this.item.system.weaponsAtLocation; + + if (dropped.length) + { + this.script.scriptNotification(`Dropped ${dropped.map(i => i.name).join(", ")}!`) + for(let weapon of dropped) + { + await weapon.system.toggleEquip(); + } + } +} \ No newline at end of file diff --git a/scripts/T74FEjfFrh3f6MKv.js b/scripts/T74FEjfFrh3f6MKv.js new file mode 100644 index 0000000..1a4f658 --- /dev/null +++ b/scripts/T74FEjfFrh3f6MKv.js @@ -0,0 +1 @@ +args.wpb = args.sb; \ No newline at end of file diff --git a/scripts/TAw9vXnfyIAl5DGs.js b/scripts/TAw9vXnfyIAl5DGs.js new file mode 100644 index 0000000..c6062cd --- /dev/null +++ b/scripts/TAw9vXnfyIAl5DGs.js @@ -0,0 +1,11 @@ +if (this.item.system.quantity.value) +{ + game.wfrp4e.utility.postCorruptionTest("minor", this.script.getChatData()); + this.item.system.reduceQuantity(); + let actor = Array.from(game.user.targets)[0]?.actor || this.actor; + actor.applyEffect({effectData : [this.item.effects.contents[1].convertToApplied()]}) +} +else +{ + this.script.scriptNotification("None left!", "error") +} \ No newline at end of file diff --git a/scripts/TBpNFRL5uehs0fze.js b/scripts/TBpNFRL5uehs0fze.js new file mode 100644 index 0000000..be5a2fb --- /dev/null +++ b/scripts/TBpNFRL5uehs0fze.js @@ -0,0 +1,10 @@ +if (this.item.system.quantity.value) +{ + this.item.system.reduceQuantity(); + let actor = Array.from(game.user.targets)[0]?.actor || this.actor; + actor.applyEffect({effectData : [this.item.effects.contents[0]]}) +} +else +{ + this.script.scriptNotification("None left!", "error") +} \ No newline at end of file diff --git a/scripts/TEiNj5FgkoD3YbhS.js b/scripts/TEiNj5FgkoD3YbhS.js new file mode 100644 index 0000000..bcac25e --- /dev/null +++ b/scripts/TEiNj5FgkoD3YbhS.js @@ -0,0 +1 @@ +this.actor.hasCondition("bleeding")?.delete() \ No newline at end of file diff --git a/scripts/TGN070HeJLl3gSMY.js b/scripts/TGN070HeJLl3gSMY.js new file mode 100644 index 0000000..876f760 --- /dev/null +++ b/scripts/TGN070HeJLl3gSMY.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupCharacteristic("ag", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, context: { failure: "Goes Prone" }}) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("prone"); +} \ No newline at end of file diff --git a/scripts/TNWmIkuubqBn38he.js b/scripts/TNWmIkuubqBn38he.js new file mode 100644 index 0000000..8f318aa --- /dev/null +++ b/scripts/TNWmIkuubqBn38he.js @@ -0,0 +1 @@ +this.effect.deleteCreatedItems(); \ No newline at end of file diff --git a/scripts/TOyQLrugFGzwc5nY.js b/scripts/TOyQLrugFGzwc5nY.js new file mode 100644 index 0000000..1e8b373 --- /dev/null +++ b/scripts/TOyQLrugFGzwc5nY.js @@ -0,0 +1 @@ +return !(args.skill?.name.includes(game.i18n.localize("NAME.Melee")) || args.item?.isMelee || args.options.corruption); \ No newline at end of file diff --git a/scripts/TQRL4mZhZohXg1Au.js b/scripts/TQRL4mZhZohXg1Au.js new file mode 100644 index 0000000..2288bc8 --- /dev/null +++ b/scripts/TQRL4mZhZohXg1Au.js @@ -0,0 +1,2 @@ +let test = await this.actor.setupCharacteristic("wp", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +test.roll(); \ No newline at end of file diff --git a/scripts/TU2xjbJ0zFtytF3J.js b/scripts/TU2xjbJ0zFtytF3J.js new file mode 100644 index 0000000..9325462 --- /dev/null +++ b/scripts/TU2xjbJ0zFtytF3J.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.CharmAnimal"); \ No newline at end of file diff --git a/scripts/TY0xSQ00XXyEr49r.js b/scripts/TY0xSQ00XXyEr49r.js new file mode 100644 index 0000000..7b1ab7b --- /dev/null +++ b/scripts/TY0xSQ00XXyEr49r.js @@ -0,0 +1 @@ +args.fields.slBonus += 1; \ No newline at end of file diff --git a/scripts/TcqumwUFAL6V0cty.js b/scripts/TcqumwUFAL6V0cty.js new file mode 100644 index 0000000..e7a337e --- /dev/null +++ b/scripts/TcqumwUFAL6V0cty.js @@ -0,0 +1,11 @@ +if (this.item.getFlag("wfrp4e", "failedCool")) +{ + this.item.system.AP = { + "head": 0, + "lArm": 0, + "rArm": 0, + "lLeg": 0, + "rLeg": 0, + "body": 0 + } +} \ No newline at end of file diff --git a/scripts/TdjlJro0RRVSh8g8.js b/scripts/TdjlJro0RRVSh8g8.js new file mode 100644 index 0000000..a893cc5 --- /dev/null +++ b/scripts/TdjlJro0RRVSh8g8.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Gamble") && args.skill?.name != game.i18n.localize("NAME.SleightOfHand"); \ No newline at end of file diff --git a/scripts/TmaS8o33825QUMrx.js b/scripts/TmaS8o33825QUMrx.js new file mode 100644 index 0000000..599ff1b --- /dev/null +++ b/scripts/TmaS8o33825QUMrx.js @@ -0,0 +1,3 @@ +let stomp = game.wfrp4e.config.systemItems.stomp; +let test = await this.actor.setupTrait(stomp) +await test.roll(); \ No newline at end of file diff --git a/scripts/TnFobCxG4pxlYmKr.js b/scripts/TnFobCxG4pxlYmKr.js new file mode 100644 index 0000000..75668c8 --- /dev/null +++ b/scripts/TnFobCxG4pxlYmKr.js @@ -0,0 +1,16 @@ +let gorCharacteristics = { + "ws": 45, + "bs": 30, + "s": 35, + "t": 45, + "i": 30, + "ag": 35, + "dex": 25, + "int": 25, + "wp": 30, + "fel": 25 +} +for (let char in this.actor.characteristics) { + if (this.actor.characteristics[char].initial < gorCharacteristics[char]) + this.actor.characteristics[char].initial = gorCharacteristics[char] +} \ No newline at end of file diff --git a/scripts/ToKlHDAjJOsC51ag.js b/scripts/ToKlHDAjJOsC51ag.js new file mode 100644 index 0000000..2ee3319 --- /dev/null +++ b/scripts/ToKlHDAjJOsC51ag.js @@ -0,0 +1,11 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.GlShFJF2TpsNh1FX") +let data = item.toObject(); +data.system.location.key = this.item.system.location.key +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) + +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty: "hard"}}); +await test.roll(); +if (test.failed) +{ + args.actor.addCondition("unconscious") +} \ No newline at end of file diff --git a/scripts/TpZItJ5Ugbazaobd.js b/scripts/TpZItJ5Ugbazaobd.js new file mode 100644 index 0000000..414537b --- /dev/null +++ b/scripts/TpZItJ5Ugbazaobd.js @@ -0,0 +1,15 @@ +let locations = []; + +while (locations.length < 2) +{ + let loc = await game.wfrp4e.tables.rollTable("hitloc", {hideDSN : true}) + if (!locations.includes(loc.result)) + { + locations.push(loc.result); + } +} + +locationText = locations.map(i => game.wfrp4e.config.locations[i]).join(", ") + +this.item.updateSource({name : this.item.name += ` (${locationText})`, "flags.wfrp4e.locations" : locations}) +this.effect.updateSource({"flags.wfrp4e.locations" : locations}) \ No newline at end of file diff --git a/scripts/Tq45Nd8J3eTvHT41.js b/scripts/Tq45Nd8J3eTvHT41.js new file mode 100644 index 0000000..88ba249 --- /dev/null +++ b/scripts/Tq45Nd8J3eTvHT41.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Perception") && args.skill?.name != game.i18n.localize("NAME.SetTrap"); \ No newline at end of file diff --git a/scripts/TrIYdcG3jDER4WgY.js b/scripts/TrIYdcG3jDER4WgY.js new file mode 100644 index 0000000..5965a8c --- /dev/null +++ b/scripts/TrIYdcG3jDER4WgY.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.xsGbDFqK2qh7lsIj") +let data = item.toObject(); +data.system.specification.value = "Minor" +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/TwgdEucxcHloc4cX.js b/scripts/TwgdEucxcHloc4cX.js new file mode 100644 index 0000000..325d158 --- /dev/null +++ b/scripts/TwgdEucxcHloc4cX.js @@ -0,0 +1,135 @@ +let choice1 = [ + { + type : "armour", + name : "Mail Chausses" + }, + { + type : "armour", + name : "Mail Coat" + }, + { + type : "armour", + name : "Mail Coif" + }, +] +let choice2 = [ + { + type : "armour", + name : "Mail Chausses" + }, + { + type : "armour", + name : "Mail Coat" + }, + { + type : "armour", + name : "Mail Coif" + }, + { + type : "armour", + name : "Leather Leggings" + }, + { + type : "armour", + name : "Leather Skullcap" + }, + { + type : "armour", + name : "Leather Jack" + }, +] +let choice3 = [ + { + type : "armour", + name : "Plate Breastplate" + }, + { + type : "armour", + name : "Plate Bracers" + }, + { + type : "armour", + name : "Plate Helm" + }, + { + type : "armour", + name : "Plate Leggings" + }, +] + +let choice = await new Promise((resolve, reject) => { + new Dialog({ + title : "Choice", + content : + `+ Select your choice +
++ Select your choice +
+${await this.actor.applyBasicDamage(3, {suppressMsg : true, damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_AP})}
` +} + +this.script.scriptMessage(msg); \ No newline at end of file diff --git a/scripts/ZrePyV2spv3v65Tg.js b/scripts/ZrePyV2spv3v65Tg.js new file mode 100644 index 0000000..e7da169 --- /dev/null +++ b/scripts/ZrePyV2spv3v65Tg.js @@ -0,0 +1 @@ +return args.type != "weapon" && !this.actor.statuses.has("infighting") \ No newline at end of file diff --git a/scripts/ZsQR3AVKi0v5U593.js b/scripts/ZsQR3AVKi0v5U593.js new file mode 100644 index 0000000..9ecf140 --- /dev/null +++ b/scripts/ZsQR3AVKi0v5U593.js @@ -0,0 +1 @@ +args.actor.addCondition("ablaze", 2) \ No newline at end of file diff --git a/scripts/ZvbBM4gTJHPdU8jU.js b/scripts/ZvbBM4gTJHPdU8jU.js new file mode 100644 index 0000000..b8ce00a --- /dev/null +++ b/scripts/ZvbBM4gTJHPdU8jU.js @@ -0,0 +1,3 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "hard"}}) +await test.roll(); +return test.failed \ No newline at end of file diff --git a/scripts/Zxh4RAENoaAQAaNg.js b/scripts/Zxh4RAENoaAQAaNg.js new file mode 100644 index 0000000..a16ea6f --- /dev/null +++ b/scripts/Zxh4RAENoaAQAaNg.js @@ -0,0 +1 @@ +return !this.actor.flags.useless.rEye || !this.actor.flags.useless.lEye || ["wp", "t", "s"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/ZxtOdwsM2Sqj9Zam.js b/scripts/ZxtOdwsM2Sqj9Zam.js new file mode 100644 index 0000000..e58661f --- /dev/null +++ b/scripts/ZxtOdwsM2Sqj9Zam.js @@ -0,0 +1,5 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.AtpAudHA4ybXVlWM") +let data = item.toObject(); +data.system.specification.value = 0 +data.name = this.effect.name; +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/a02tlRCXpaoaDjSN.js b/scripts/a02tlRCXpaoaDjSN.js new file mode 100644 index 0000000..c70bd5f --- /dev/null +++ b/scripts/a02tlRCXpaoaDjSN.js @@ -0,0 +1,16 @@ +let careers = await game.wfrp4e.utility.findAll("career", "", true); +careers.forEach(c => { + if (!c.id) + { + c.id = c._id; + } +}); +let choice = await ItemDialog.create(careers, 1, "Choose Double Life Career"); +if (choice[0]) +{ + let career = await fromUuid(choice[0].uuid); + let data = career.toObject(); + setProperty(data, "flags.wfrp4e.doubleLife", true); + this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) + this.effect.updateSource({name : this.effect.name + ` (${data.name})`}) +} diff --git a/scripts/a0YU3whUm16wGBNu.js b/scripts/a0YU3whUm16wGBNu.js new file mode 100644 index 0000000..ed24c51 --- /dev/null +++ b/scripts/a0YU3whUm16wGBNu.js @@ -0,0 +1,7 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "average"}}) +await test.roll(); + +if (test.failed) +{ + this.actor.addCondition("fatigued"); +} \ No newline at end of file diff --git a/scripts/a4Aza4a9v8JMU8dC.js b/scripts/a4Aza4a9v8JMU8dC.js new file mode 100644 index 0000000..7ec136f --- /dev/null +++ b/scripts/a4Aza4a9v8JMU8dC.js @@ -0,0 +1,2 @@ +const talents = await Promise.all(["Frenzy", "Magic Resistance"].map(game.wfrp4e.utility.findTalent)) +this.actor.createEmbeddedDocuments("Item", talents, {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/a6gacHsvgwtsIFSQ.js b/scripts/a6gacHsvgwtsIFSQ.js new file mode 100644 index 0000000..735565f --- /dev/null +++ b/scripts/a6gacHsvgwtsIFSQ.js @@ -0,0 +1,2 @@ +if (args.test.item && args.test.item.name == game.i18n.localize("NAME.Research")) + args.test.preData.canReverse = true \ No newline at end of file diff --git a/scripts/a7pEvCycVnFBXGAQ.js b/scripts/a7pEvCycVnFBXGAQ.js new file mode 100644 index 0000000..604c31c --- /dev/null +++ b/scripts/a7pEvCycVnFBXGAQ.js @@ -0,0 +1,7 @@ +let test = await this.actor.setupCharacteristic("i", {skipTargets: true, appendTitle : " - Stunned", fields : {difficulty : "easy"}}) +await test.roll(); + +if (!test.succeeded) +{ + this.actor.addCondition("stunned"); +} \ No newline at end of file diff --git a/scripts/a8RabrnJ08O07rDX.js b/scripts/a8RabrnJ08O07rDX.js new file mode 100644 index 0000000..5ac0cfe --- /dev/null +++ b/scripts/a8RabrnJ08O07rDX.js @@ -0,0 +1,5 @@ +if (args.totalWoundLoss > 0) +{ + // I'm assuming the endurance test specified is for the end-round check + await args.actor.addCondition("poisoned", 2); +} \ No newline at end of file diff --git a/scripts/a8i0sA1RBnD8nHZt.js b/scripts/a8i0sA1RBnD8nHZt.js new file mode 100644 index 0000000..b78fb2c --- /dev/null +++ b/scripts/a8i0sA1RBnD8nHZt.js @@ -0,0 +1,42 @@ +let caster = this.effect.sourceActor +let targetedItem = this.actor.items.get(this.effect.flags.wfrp4e.itemTargets[0]) + +let qualities = foundry.utils.deepClone(game.wfrp4e.config.itemQualities); +let flaws = foundry.utils.deepClone(game.wfrp4e.config.itemFlaws); + +if (targetedItem.type == "weapon") +{ + mergeObject(qualities, game.wfrp4e.config.weaponQualities) + mergeObject(flaws, game.wfrp4e.config.weaponFlaws) +} +else if (targetedItem.type == "armour") +{ + mergeObject(qualities, game.wfrp4e.config.armorQualities) + mergeObject(flaws, game.wfrp4e.config.armorFlaws) +} + +for(let q in qualities) +{ + // If the weapon already has a flaw, don't put it in the dialog + if (targetedItem.system.properties.qualities[q]) + { + delete qualities[q] + } +} +for(let f in flaws) +{ + // If a weapon doesn't have a flaw, don't put it in the dialog + if (!targetedItem.system.properties.flaws[f]) + { + delete flaws[f] + } +} + +let added = await ItemDialog.create(ItemDialog.objectToArray(qualities), "unlimited", "Choose Qualities to add"); +let removed = [] +if (!foundry.utils.isEmpty(flaws)) +{ + removed = await ItemDialog.create(ItemDialog.objectToArray(flaws), "unlimited", "Choose Flaws to remove"); +} + +this.effect.updateSource({"flags.wfrp4e.propertiesChanged" : {added : added.map(i => i.id), removed : removed.map(i => i.id)}}) diff --git a/scripts/aAvJrAKLzXhS9qN6.js b/scripts/aAvJrAKLzXhS9qN6.js new file mode 100644 index 0000000..645c806 --- /dev/null +++ b/scripts/aAvJrAKLzXhS9qN6.js @@ -0,0 +1 @@ +return args.item?.name == game.i18n.localize("NAME.Climb") \ No newline at end of file diff --git a/scripts/aCVtaW8ag1WibcAr.js b/scripts/aCVtaW8ag1WibcAr.js new file mode 100644 index 0000000..bf9b92d --- /dev/null +++ b/scripts/aCVtaW8ag1WibcAr.js @@ -0,0 +1,2 @@ +args.attacker.modifyWounds(1) +this.script.scriptMessage(`${args.attacker.prototypeToken.name} recovers 1 Wound.`) \ No newline at end of file diff --git a/scripts/aIYUsBIDKWJ3CEtj.js b/scripts/aIYUsBIDKWJ3CEtj.js new file mode 100644 index 0000000..9779863 --- /dev/null +++ b/scripts/aIYUsBIDKWJ3CEtj.js @@ -0,0 +1 @@ +this.script.scriptMessage(await this.actor.applyBasicDamage(20, {suppressMsg: true})); \ No newline at end of file diff --git a/scripts/aMHGjWyn6BXCI4pw.js b/scripts/aMHGjWyn6BXCI4pw.js new file mode 100644 index 0000000..0f73350 --- /dev/null +++ b/scripts/aMHGjWyn6BXCI4pw.js @@ -0,0 +1,2 @@ +let frenzy = await fromUuid("Compendium.wfrp4e-core.items.Item.hXcfygzujgyMN1uI"); +this.actor.createEmbeddedDocuments("Item", [frenzy], {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/abLWYtNTu1UVDQAs.js b/scripts/abLWYtNTu1UVDQAs.js new file mode 100644 index 0000000..547de25 --- /dev/null +++ b/scripts/abLWYtNTu1UVDQAs.js @@ -0,0 +1,5 @@ +if (args.opposedTest.result.hitloc.value == this.effect.flags.wfrp4e.location) // e.g. 'head', rLeg, 'lArm' +{ + this.scriptMessage(`Gains a @Condition[Blinded] condition as their ${this.item.name} was hit`); + this.actor.addCondition("blinded"); +} \ No newline at end of file diff --git a/scripts/abVIvJBzuskNzCQv.js b/scripts/abVIvJBzuskNzCQv.js new file mode 100644 index 0000000..2fd5bf8 --- /dev/null +++ b/scripts/abVIvJBzuskNzCQv.js @@ -0,0 +1,8 @@ +let amount = this.effect.sourceTest.result.overcast.usage.other.current; + +let sss = await fromUuid("Compendium.wfrp4e-core.items.MGEPI4jNhymNIRVz"); +let strider = await fromUuid("Compendium.wfrp4e-core.items.1dUizIgLBgn4jICC"); + +let items = Array(amount).fill(sss).concat(Array(amount).fill(strider)) + +this.actor.createEmbeddedDocuments("Item", items, {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/afdmOvPGMpEdZvCb.js b/scripts/afdmOvPGMpEdZvCb.js new file mode 100644 index 0000000..20d9df6 --- /dev/null +++ b/scripts/afdmOvPGMpEdZvCb.js @@ -0,0 +1 @@ +return (args.skill?.name == game.i18n.localize("NAME.Perception") || args.characteristic == "fel") \ No newline at end of file diff --git a/scripts/agsm3NI1NDtHRG4y.js b/scripts/agsm3NI1NDtHRG4y.js new file mode 100644 index 0000000..3391c51 --- /dev/null +++ b/scripts/agsm3NI1NDtHRG4y.js @@ -0,0 +1 @@ +this.actor.getActiveTokens().forEach(t => t.document.update({texture : this.actor.prototypeToken.texture}, {animate : false})); \ No newline at end of file diff --git a/scripts/ahbA7o5G9dzMFl76.js b/scripts/ahbA7o5G9dzMFl76.js new file mode 100644 index 0000000..0937f98 --- /dev/null +++ b/scripts/ahbA7o5G9dzMFl76.js @@ -0,0 +1,2 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.Item.SfUUdOGjdYpr3KSR") +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/alJgj25l3239h2SW.js b/scripts/alJgj25l3239h2SW.js new file mode 100644 index 0000000..edd4d2f --- /dev/null +++ b/scripts/alJgj25l3239h2SW.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.hTgrGkWnmIR4xhVe") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/ayIbw2Vw2t9xg33P.js b/scripts/ayIbw2Vw2t9xg33P.js new file mode 100644 index 0000000..0af0e36 --- /dev/null +++ b/scripts/ayIbw2Vw2t9xg33P.js @@ -0,0 +1,2 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.EaqlLRQigwnsEAXX") +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/b1zMefdoZYtzCm7i.js b/scripts/b1zMefdoZYtzCm7i.js new file mode 100644 index 0000000..d165c01 --- /dev/null +++ b/scripts/b1zMefdoZYtzCm7i.js @@ -0,0 +1 @@ +return ["roll", "none"].includes(args.fields.hitLocation) || args.item?.attackType != "ranged" \ No newline at end of file diff --git a/scripts/b2Kb4IuD22RhKhR0.js b/scripts/b2Kb4IuD22RhKhR0.js new file mode 100644 index 0000000..fcbecf9 --- /dev/null +++ b/scripts/b2Kb4IuD22RhKhR0.js @@ -0,0 +1,10 @@ +let actor = Array.from(game.user.targets)[0]?.actor; + +if (actor) +{ + actor.applyEffect({effectUuids : this.effect.sourceItem.effects.contents[0].uuid}) +} +else +{ + this.script.scriptNotification("No target!", "error") +} \ No newline at end of file diff --git a/scripts/b2WaqRna5CFXmbDG.js b/scripts/b2WaqRna5CFXmbDG.js new file mode 100644 index 0000000..8f874fd --- /dev/null +++ b/scripts/b2WaqRna5CFXmbDG.js @@ -0,0 +1 @@ +args.options.stag = true; \ No newline at end of file diff --git a/scripts/b5DfAWtpV1x2R8If.js b/scripts/b5DfAWtpV1x2R8If.js new file mode 100644 index 0000000..c9f120e --- /dev/null +++ b/scripts/b5DfAWtpV1x2R8If.js @@ -0,0 +1 @@ +this.script.scriptMessage(await this.actor.applyBasicDamage(this.effect.sourceTest.result.damage, {suppressMsg: true})) \ No newline at end of file diff --git a/scripts/b5prg1FLjCAvBjLy.js b/scripts/b5prg1FLjCAvBjLy.js new file mode 100644 index 0000000..705112f --- /dev/null +++ b/scripts/b5prg1FLjCAvBjLy.js @@ -0,0 +1,13 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.zyocWSzEZEC826NS") +let data = item.toObject(); +data.system.location.key = this.item.system.location.key +this.actor.createEmbeddedDocuments("Item", [data]) + + +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields: {difficulty: "hard"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (test.failed) +{ + await this.actor.addCondition("prone") + await this.actor.addCondition("stunned") +} \ No newline at end of file diff --git a/scripts/bBdXzBmxgFFBwMMS.js b/scripts/bBdXzBmxgFFBwMMS.js new file mode 100644 index 0000000..b0eea24 --- /dev/null +++ b/scripts/bBdXzBmxgFFBwMMS.js @@ -0,0 +1,9 @@ +if(args.opposedTest.attackerTest.item?.isRanged && args.applyAP && !args.sureShot) +{ + if (args.modifiers.ap.value) + { + args.sureShot = true; + args.modifiers.ap.details.push(`${this.effect.name} (Ignore ${this.item.Advances})`) + args.modifiers.ap.ignored += this.item.Advances; + } +} \ No newline at end of file diff --git a/scripts/bEVlJOOA1kLlzpWx.js b/scripts/bEVlJOOA1kLlzpWx.js new file mode 100644 index 0000000..4a07c15 --- /dev/null +++ b/scripts/bEVlJOOA1kLlzpWx.js @@ -0,0 +1,86 @@ +let characteristics = { + "ws" : 10, + "bs" : 0, + "s" : 5, + "t" : 15, + "i" : 20, + "ag" : 15, + "dex" : 20, + "int" : 35, + "wp" : 30, + "fel" : 10 +} +let skills = ["Channelling", "Cool", "Dodge", "Entertain (Storytelling)", "Intuition", "Language (Magick)", "Leadership", "Lore (Magic)", "Lore (Theology)", "Perception"] +let skillAdvancements = [20, 25, 20, 25, 30, 25, 15, 20, 10, 30] +let talents = ["Aethyric Attunement", "Arcane Magic", "Instinctive Diction", "Instinctive Diction", "Luck", "Magical Sense", "Menacing", "Petty Magic", "Second Sight", "Sixth Sense"] +let trappings = ["Hand Weapon", "Quarterstaff", "Ritual Dress incorporating many ingredients and fetishes"] +let items = []; + +let updateObj = this.actor.toObject(); + +for (let ch in characteristics) +{ + updateObj.system.characteristics[ch].modifier += characteristics[ch]; +} + +for (let index = 0; index < skills.length; index++) +{ + let skill = skills[index] + let skillItem; + skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill") + if (skillItem) + skillItem.system.advances.value += skillAdvancements[index] + else + { + skillItem = await game.wfrp4e.utility.findSkill(skill) + skillItem = skillItem.toObject(); + skillItem.system.advances.value = skillAdvancements[index]; + items.push(skillItem); + } +} + +for (let talent of talents) +{ + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } +} + +for (let trapping of trappings) +{ + let trappingItem = await game.wfrp4e.utility.findItem(trapping) + if (trappingItem) + { + trappingItem = trappingItem.toObject() + + equip(trappingItem) + + items.push(trappingItem); + } + else + { + items.push({name : trapping, type : "trapping", "system.trappingType.value" : "clothingAccessories"}) + //ui.notifications.warn(`Could not find ${trapping}`, {permanent : true}) + } +} + +updateObj.name = updateObj.name += " " + this.effect.name + +await this.actor.update(updateObj) +this.actor.createEmbeddedDocuments("Item", items); + +function equip(item) +{ + if (item.type == "armour") + item.system.worn.value = true + else if (item.type == "weapon") + item.system.equipped = true + else if (item.type == "trapping" && item.system.trappingType.value == "clothingAccessories") + item.system.worn = true +} \ No newline at end of file diff --git a/scripts/bLkt8VpTTPoTxW0W.js b/scripts/bLkt8VpTTPoTxW0W.js new file mode 100644 index 0000000..73567e8 --- /dev/null +++ b/scripts/bLkt8VpTTPoTxW0W.js @@ -0,0 +1,5 @@ +if (args.opposedTest.result.hitloc.value == "body" && args.totalWoundLoss > 0) +{ + args.actor.addCondition("bleeding", 1); + this.script.scriptNotification("Added Bleeding") +} diff --git a/scripts/bMEFHPCei2evnZZw.js b/scripts/bMEFHPCei2evnZZw.js new file mode 100644 index 0000000..7eb94d5 --- /dev/null +++ b/scripts/bMEFHPCei2evnZZw.js @@ -0,0 +1,14 @@ +// Victims that take at least 1 Wound from a Fell Dagger +// immediately take a Poisoned Condition +// resisted with a Difficult (-10) Endurance Test. + +// TODO: Add Venom strength to message + +if (args.totalWoundLoss > 0) +{ + args.actor.addCondition("poisoned") + this.script.scriptMessage(` + ${this.effect.name}:+ Add Option? +
+${this.actor.prototypeToken.name} has gained 2 @Condition[Poisoned] Conditions.
+Any being with the Bestial Creature Trait that bites them and takes damage will not bite them again during a hostile encounter, though the creature may still attack them in other ways.
`, + { + whisper: ChatMessage.getWhisperRecipients("GM"), + blind: true + }) +} + // If they succeed, for a number of rounds equal to 3+ their SL, they have the Corrosive Blood Creature Trait. +else if (test.succeeded) +{ + // Don't attempt to add Corrosive Blood if actor already has it + const hasCorrosiveBlood = this.actor.has("Corrosive Blood") + if (hasCorrosiveBlood !== undefined) return + + let item = await fromUuid("Compendium.wfrp4e-core.items.M5QSWOYt2Rbv2yxW") + let data = item.toObject() + this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) + + const duration = 3 + parseInt(test.result.SL) + this.script.scriptMessage(`${this.actor.prototypeToken.name} gains the Corrosive Blood Trait for ${duration} rounds.
`, + { whisper: ChatMessage.getWhisperRecipients("GM"), blind: true }) +} \ No newline at end of file diff --git a/scripts/g0SzfsLyW7aD2F19.js b/scripts/g0SzfsLyW7aD2F19.js new file mode 100644 index 0000000..e319818 --- /dev/null +++ b/scripts/g0SzfsLyW7aD2F19.js @@ -0,0 +1,13 @@ +if (this.item.name.includes("(") && this.item.system.tests.value.includes("(Social Group)")) +{ + let tests = this.item.system.tests.value + let name = this.item.name + + // If name already specifies, make sure tests value reflects that + if (name.includes("(")) + { + let group = name.split("(")[1].split(")")[0] + tests = `${tests.split("(")[0].trim()} (${group})` + } + this.item.updateSource({name, "system.tests.value" : tests}) +} \ No newline at end of file diff --git a/scripts/g1L8OYO9nCOhdKGL.js b/scripts/g1L8OYO9nCOhdKGL.js new file mode 100644 index 0000000..94085c1 --- /dev/null +++ b/scripts/g1L8OYO9nCOhdKGL.js @@ -0,0 +1,16 @@ +// Everything within Fellowship Bonus yards +// of the target point is splashed with mystic poison, +// suffering 1d10 + SL damage which ignores Armour Points + +let damage = (await new Roll(`1d10 + ${parseInt(this.effect.sourceTest.result.SL)}`).roll()) + +await damage.toMessage(this.script.getChatData()) + +this.script.scriptMessage(await args.actor.applyBasicDamage( + damage.total, + {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_AP, suppressMsg: true} +)) + +// ... and gains the Poisoned Condition + +this.actor.addCondition("poisoned") \ No newline at end of file diff --git a/scripts/g4t56A09yrpZaJQ2.js b/scripts/g4t56A09yrpZaJQ2.js new file mode 100644 index 0000000..9d8a90b --- /dev/null +++ b/scripts/g4t56A09yrpZaJQ2.js @@ -0,0 +1,23 @@ + let amberTalons = foundry.utils.deepClone(game.wfrp4e.config.systemItems.unarmed); + amberTalons.name = "Amber Talons"; + amberTalons.img = this.effect.img; + amberTalons.system.damage.value = "SB + WPB" + amberTalons.system.equipped = true; + amberTalons.system.qualities.value.push({name : "magical"}) + amberTalons.effects.push({ + label : "Amber Talons", + transfer: false, + icon : "modules/wfrp4e-core/icons/spells/amber-talons.png" , + flags : { + wfrp4e : { + applicationData : { + documentType : "Item" + }, + scriptData : [{ + trigger : "applyDamage", + script : "if (args.totalWoundLoss >= 1)\n{ \n args.actor.addCondition(\"bleeding\")\n}" + }] + } + } + }) + this.actor.createEmbeddedDocuments("Item", [amberTalons], {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/gFUXBbTskQBKjxqm.js b/scripts/gFUXBbTskQBKjxqm.js new file mode 100644 index 0000000..e8f675a --- /dev/null +++ b/scripts/gFUXBbTskQBKjxqm.js @@ -0,0 +1,8 @@ +if (this.actor.hasCondition("entangled")) +{ + this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {fields : {difficulty : "average"}}).then(async test => { + await test.roll(); + if (test.failed) + this.actor.addCondition("fatigued") + }) +} \ No newline at end of file diff --git a/scripts/gKIPujyuFSn0No9v.js b/scripts/gKIPujyuFSn0No9v.js new file mode 100644 index 0000000..9359298 --- /dev/null +++ b/scripts/gKIPujyuFSn0No9v.js @@ -0,0 +1,5 @@ +for(let e of this.item.effects.contents) +{ + e.update({disabled: false}) +} +this.script.scriptNotification("Reset Powers") \ No newline at end of file diff --git a/scripts/gKPL3t4vlZAsvtGr.js b/scripts/gKPL3t4vlZAsvtGr.js new file mode 100644 index 0000000..c2422ee --- /dev/null +++ b/scripts/gKPL3t4vlZAsvtGr.js @@ -0,0 +1 @@ +return args.skill?.name == "Stealth (Underground)" \ No newline at end of file diff --git a/scripts/gL0ftUnK5TNXBRRt.js b/scripts/gL0ftUnK5TNXBRRt.js new file mode 100644 index 0000000..ccd81ab --- /dev/null +++ b/scripts/gL0ftUnK5TNXBRRt.js @@ -0,0 +1 @@ +return this.effect.sourceActor.uuid == args.actor.uuid \ No newline at end of file diff --git a/scripts/gPQrszvIgGlW9yM4.js b/scripts/gPQrszvIgGlW9yM4.js new file mode 100644 index 0000000..61a3f69 --- /dev/null +++ b/scripts/gPQrszvIgGlW9yM4.js @@ -0,0 +1,2 @@ +if (args.test.characteristicKey == "wp") + args.test.preData.canReverse = true \ No newline at end of file diff --git a/scripts/gVpFUka7qfGiEC1v.js b/scripts/gVpFUka7qfGiEC1v.js new file mode 100644 index 0000000..0306f05 --- /dev/null +++ b/scripts/gVpFUka7qfGiEC1v.js @@ -0,0 +1 @@ + this.actor.getActiveTokens().forEach(t => t.document.update({texture : {tint : "#FFD700"}})); diff --git a/scripts/ga6bQzPuoIiQQrKg.js b/scripts/ga6bQzPuoIiQQrKg.js new file mode 100644 index 0000000..2d3c447 --- /dev/null +++ b/scripts/ga6bQzPuoIiQQrKg.js @@ -0,0 +1,11 @@ +if (args.totalWoundLoss > 0) +{ + + let test = await args.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "hard"}}) + await test.roll() + if (test.failed) + { + args.totalWoundLoss += this.effect.sourceActor.system.characteristics.wp.bonus + args.modifiers.other.push({label : this.effect.name, value : this.effect.sourceActor.system.characteristics.wp.bonus}) + } +} \ No newline at end of file diff --git a/scripts/gbhxWXboV9CytWNU.js b/scripts/gbhxWXboV9CytWNU.js new file mode 100644 index 0000000..e186282 --- /dev/null +++ b/scripts/gbhxWXboV9CytWNU.js @@ -0,0 +1 @@ +await this.actor.addCondition("blinded", 2) \ No newline at end of file diff --git a/scripts/gh2KS1prBKcsSK6M.js b/scripts/gh2KS1prBKcsSK6M.js new file mode 100644 index 0000000..9db9338 --- /dev/null +++ b/scripts/gh2KS1prBKcsSK6M.js @@ -0,0 +1,2 @@ +if (args.opposedTest.attackerTest.result.critical) + args.actor.addCondition("ablaze") \ No newline at end of file diff --git a/scripts/gnVpxOeBZpNF4HIF.js b/scripts/gnVpxOeBZpNF4HIF.js new file mode 100644 index 0000000..ea6a793 --- /dev/null +++ b/scripts/gnVpxOeBZpNF4HIF.js @@ -0,0 +1,4 @@ +if (args.test.result.roll.toString().includes("9") || args.test.result.roll.toString().includes("8")) +{ + args.test.result.fumble = game.i18n.localize("Fumble") +} \ No newline at end of file diff --git a/scripts/gpPaCe6yER79l4u8.js b/scripts/gpPaCe6yER79l4u8.js new file mode 100644 index 0000000..124a438 --- /dev/null +++ b/scripts/gpPaCe6yER79l4u8.js @@ -0,0 +1,2 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.SfUUdOGjdYpr3KSR") +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/gpuBg3y9rocJL7yT.js b/scripts/gpuBg3y9rocJL7yT.js new file mode 100644 index 0000000..908e09d --- /dev/null +++ b/scripts/gpuBg3y9rocJL7yT.js @@ -0,0 +1 @@ +this.actor.status.addArmour(1, {locations: ["head"], source: this.effect}) \ No newline at end of file diff --git a/scripts/gqZLfIr6svrtdwdC.js b/scripts/gqZLfIr6svrtdwdC.js new file mode 100644 index 0000000..191bf9e --- /dev/null +++ b/scripts/gqZLfIr6svrtdwdC.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.SleightOfHand") && args.skill?.name != game.i18n.localize("NAME.MeleeBrawling") && args.weapon?.system?.weaponGroup?.value != "brawling" \ No newline at end of file diff --git a/scripts/gsCnd3mf1vXFU2ei.js b/scripts/gsCnd3mf1vXFU2ei.js new file mode 100644 index 0000000..e3c7fe1 --- /dev/null +++ b/scripts/gsCnd3mf1vXFU2ei.js @@ -0,0 +1 @@ +this.actor.system.status.ward.value = 4; \ No newline at end of file diff --git a/scripts/gu72JaTs9GrSiVTd.js b/scripts/gu72JaTs9GrSiVTd.js new file mode 100644 index 0000000..8d0ad0f --- /dev/null +++ b/scripts/gu72JaTs9GrSiVTd.js @@ -0,0 +1 @@ +return !(args.skill?.name == game.i18n.localize("NAME.Haggle") || args.skill?.name == game.i18n.localize("NAME.Gossip")) \ No newline at end of file diff --git a/scripts/h0DfPwUUOBjyAHMZ.js b/scripts/h0DfPwUUOBjyAHMZ.js new file mode 100644 index 0000000..124ecc4 --- /dev/null +++ b/scripts/h0DfPwUUOBjyAHMZ.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Perception"); \ No newline at end of file diff --git a/scripts/h1XKoMuVnS0bagRO.js b/scripts/h1XKoMuVnS0bagRO.js new file mode 100644 index 0000000..6b18992 --- /dev/null +++ b/scripts/h1XKoMuVnS0bagRO.js @@ -0,0 +1 @@ +return args.item?.name != game.i18n.localize("NAME.Endurance"); \ No newline at end of file diff --git a/scripts/h766UvswLCsxcMow.js b/scripts/h766UvswLCsxcMow.js new file mode 100644 index 0000000..cc4d0c0 --- /dev/null +++ b/scripts/h766UvswLCsxcMow.js @@ -0,0 +1,133 @@ +let characteristics = { + "ws" : 5, + "bs" : 0, + "s" : -15, + "t" : 0, + "i" : 20, + "ag" : 0, + "dex" : 0, + "int" : 5, + "wp" : 10, + "fel" : 10 +} +let skills = ["Charm", "Intimidate", "Melee (Basic)"] +let skillAdvancements = [7, 60, 7] +let talents = ["Menacing", "Shadow"] +let traits = ["Distracting"] +let trappings = [] +let items = []; +let spells = []; + +let updateObj = this.actor.toObject(); + +for (let ch in characteristics) +{ + updateObj.system.characteristics[ch].modifier += characteristics[ch]; +} + +for (let index = 0; index < skills.length; index++) +{ + let skill = skills[index] + let skillItem; + skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill") + if (skillItem) + skillItem.system.advances.value += skillAdvancements[index] + else + { + skillItem = await game.wfrp4e.utility.findSkill(skill) + skillItem = skillItem.toObject(); + skillItem.system.advances.value = skillAdvancements[index]; + items.push(skillItem); + } +} + +for (let talent of talents) +{ + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } +} + +const traitRegex = /(?:,?(.+?)(\+?\d{1,2}\+?)?\s*?(?:\((.+?)\)\s*(\+?\d{1,2})?|,|$))/gm +for (let trait of traits) +{ + let traitMatches = trait.matchAll(traitRegex).next().value + let traitName = traitMatches[1] + let traitVal = traitMatches[2] || traitMatches[4] // could be match 2 or 4 depending on if there's a specialization + let traitSpec = traitMatches[3] + + let traitItem; + try { + traitItem = await WFRP_Utility.findItem(traitName, "trait") + } + catch { } + if (!traitItem) { + ui.notifications.warn(`Could not find ${trait}`, {permanent : true}) + } + traitItem = traitItem.toObject() + + if (Number.isNumeric(traitVal)) + { + traitItem.system.specification.value = traitName.includes('Weapon','Horns','Tail','Tentacles','Bite') ? traitVal - parseInt(characteristicValues[3]/10) : traitVal; + traitItem.name = (traitItem.name + ` ${traitSpec ? "("+ traitSpec + ")" : ""}`).trim() + } + else + traitItem.system.specification.value = traitSpec + + items.push(traitItem) + +} + +for (let trapping of trappings) +{ + let trappingItem = await game.wfrp4e.utility.findItem(trapping) + if (trappingItem) + { + trappingItem = trappingItem.toObject() + + equip(trappingItem) + + items.push(trappingItem); + } + else + { + ui.notifications.warn(`Could not find ${trapping}`, {permanent : true}) + } +} + +for (let spell of spells) +{ + let spellItem = await game.wfrp4e.utility.findItem(spell) + if (spellItem) + { + spellItem = spellItem.toObject() + + items.push(spellItem); + } + else + { + ui.notifications.warn(`Could not find ${spell}`, {permanent : true}) + } +} + +updateObj.name = updateObj.name += " " + this.effect.name + +await this.actor.update(updateObj) +this.actor.createEmbeddedDocuments("Item", items); + + +function equip(item) +{ + if (item.type == "armour") + item.worn = true + else if (item.type == "weapon") + item.equipped = true + else if (item.type == "trapping" && item.trappingType?.value == "clothingAccessories") + item.worn = true +} \ No newline at end of file diff --git a/scripts/hA8PzeiCsHqqlUZm.js b/scripts/hA8PzeiCsHqqlUZm.js new file mode 100644 index 0000000..c8e212a --- /dev/null +++ b/scripts/hA8PzeiCsHqqlUZm.js @@ -0,0 +1,2 @@ +this.actor.createEmbeddedDocuments("ActiveEffect", [game.wfrp4e.config.symptomEffects["nausea"]]) +this.script.scriptMessage(`Gains @Condition[Nausea] for [[1d10]] hours`, {whisper: ChatMessage.getWhisperRecipients("GM")}) \ No newline at end of file diff --git a/scripts/hCzxUyO6mjLNIpaM.js b/scripts/hCzxUyO6mjLNIpaM.js new file mode 100644 index 0000000..1555cce --- /dev/null +++ b/scripts/hCzxUyO6mjLNIpaM.js @@ -0,0 +1,7 @@ +let woundsGained = Math.min(args.totalWoundLoss, args.actor.status.wounds.value) + +woundsGained = Math.floor(woundsGained / 2) + +args.attacker.update({ "system.status.wounds.value": args.attacker.status.wounds.value + woundsGained }) + +this.script.scriptMessage(`Gains ${woundsGained} Wounds`) \ No newline at end of file diff --git a/scripts/hDC6lroDEPVBituR.js b/scripts/hDC6lroDEPVBituR.js new file mode 100644 index 0000000..02f66dc --- /dev/null +++ b/scripts/hDC6lroDEPVBituR.js @@ -0,0 +1,12 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); + +if (test.failed) +{ + this.actor.update({"system.status.corruption.value" : parseInt(this.actor.status.corruption.value) + 1}) + this.script.scriptMessage("Gained a Corruption point", {whisper : ChatMessage.getWhisperRecipients("GM")}) + if (test.result.roll % 11 == 0 || test.result.roll == 100) + { + this.script.scriptMessage(`Fumble: immediately gain 1 @Table[mutatemental]{Mental Mutation}, and may not take a Short-term Ambition for the next [[1d10]] weeks.`, {whisper : ChatMessage.getWhisperRecipients("GM")}) + } +} \ No newline at end of file diff --git a/scripts/hK0YMJfYbpbJZizO.js b/scripts/hK0YMJfYbpbJZizO.js new file mode 100644 index 0000000..45b97af --- /dev/null +++ b/scripts/hK0YMJfYbpbJZizO.js @@ -0,0 +1,12 @@ +this.actor.getActiveTokens().forEach(t => t.document.update({light : { + "dim": 0, + "bright": 0, + "angle": 360, + "alpha": 0.5, + "animation": { + "speed": 0, + "intensity": 0, + "type": "none", + }, + "color": "", + }})); \ No newline at end of file diff --git a/scripts/hObTbWi4ZdwXimIW.js b/scripts/hObTbWi4ZdwXimIW.js new file mode 100644 index 0000000..59c8d0c --- /dev/null +++ b/scripts/hObTbWi4ZdwXimIW.js @@ -0,0 +1,4 @@ +if (args.item.type == "spell") +{ + args.item.system.cn.value = Math.floor(args.item.system.cn.value / 2); +} \ No newline at end of file diff --git a/scripts/hR1qD2kpFHF8JT8h.js b/scripts/hR1qD2kpFHF8JT8h.js new file mode 100644 index 0000000..1ee0b50 --- /dev/null +++ b/scripts/hR1qD2kpFHF8JT8h.js @@ -0,0 +1 @@ +return args.skill?.name == "Language (Magick)" \ No newline at end of file diff --git a/scripts/hSlEY2oh8quVmdXR.js b/scripts/hSlEY2oh8quVmdXR.js new file mode 100644 index 0000000..f535336 --- /dev/null +++ b/scripts/hSlEY2oh8quVmdXR.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.pTorrE0l3VybAbtn") +let data = item.toObject(); +data.system.specification.value = 2 +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/hZAax4emLahEEqcZ.js b/scripts/hZAax4emLahEEqcZ.js new file mode 100644 index 0000000..4cf471f --- /dev/null +++ b/scripts/hZAax4emLahEEqcZ.js @@ -0,0 +1,5 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.BqPZn6q3VHn9HUrW") +let data = item.toObject(); +data.system.specification.value = 7 - this.actor.characteristics.s.bonus +data.name = item.name.replace("(Feature)", "(Tusks)") +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/hfO4INH3EeETDTFt.js b/scripts/hfO4INH3EeETDTFt.js new file mode 100644 index 0000000..5bb82c4 --- /dev/null +++ b/scripts/hfO4INH3EeETDTFt.js @@ -0,0 +1 @@ +this.actor.status.addArmour(1, {locations: this.effect.flags.wfrp4e.locations, source: this.effect}) \ No newline at end of file diff --git a/scripts/hhCs5VBKx50S5IsY.js b/scripts/hhCs5VBKx50S5IsY.js new file mode 100644 index 0000000..d3aa69e --- /dev/null +++ b/scripts/hhCs5VBKx50S5IsY.js @@ -0,0 +1 @@ +return !args.options.mutate \ No newline at end of file diff --git a/scripts/hhv7PrRdlf9sfC82.js b/scripts/hhv7PrRdlf9sfC82.js new file mode 100644 index 0000000..1941c02 --- /dev/null +++ b/scripts/hhv7PrRdlf9sfC82.js @@ -0,0 +1,84 @@ +let characteristics = { + "ws" : 5, + "bs" : 0, + "s" : 5, + "t" : 5, + "i" : 10, + "ag" : 0, + "dex" : 0, + "int" : 0, + "wp" : 0, + "fel" : 0 + } + let skills = ["Cool", "Dodge"] + let skillAdvancements = [10, 10] + let talents = ["Combat Reflexes"] + let trappings = ["Leather Jack", "Leather Skullcap", "Leather Leggings", "Shield"] + let items = [] + + let updateObj = this.actor.toObject(); + + for (let ch in characteristics) + { + updateObj.system.characteristics[ch].modifier += characteristics[ch]; + } + + for (let index = 0; index < skills.length; index++) + { + let skill = skills[index] + let skillItem; + skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill") + if (skillItem) + skillItem.system.advances.value += skillAdvancements[index] + else + { + skillItem = await game.wfrp4e.utility.findSkill(skill) + skillItem = skillItem.toObject(); + skillItem.system.advances.value = skillAdvancements[index]; + items.push(skillItem); + } + } + + for (let talent of talents) + { + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } + } + + for (let trapping of trappings) + { + let trappingItem = await game.wfrp4e.utility.findItem(trapping) + if (trappingItem) + { + trappingItem = trappingItem.toObject() + + equip(trappingItem) + + items.push(trappingItem); + } + else + { + ui.notifications.warn(`Could not find ${trapping}`, {permanent : true}) + } + } + + + await this.actor.update(updateObj) + this.actor.createEmbeddedDocuments("Item", items); + + function equip(item) + { + if (item.type == "armour") + item.system.worn.value = true + else if (item.type == "weapon") + item.system.equipped = true + else if (item.type == "trapping" && item.system.trappingType.value == "clothingAccessories") + item.system.worn = true + } \ No newline at end of file diff --git a/scripts/hlHKeFWrOA8CsLr9.js b/scripts/hlHKeFWrOA8CsLr9.js new file mode 100644 index 0000000..25e12e8 --- /dev/null +++ b/scripts/hlHKeFWrOA8CsLr9.js @@ -0,0 +1,2 @@ +args.data.canReverse = true; +args.options.pilot = true; \ No newline at end of file diff --git a/scripts/hluehsCuBZYc1Ejt.js b/scripts/hluehsCuBZYc1Ejt.js new file mode 100644 index 0000000..73d83dc --- /dev/null +++ b/scripts/hluehsCuBZYc1Ejt.js @@ -0,0 +1 @@ +return args.characterisic != "fel" \ No newline at end of file diff --git a/scripts/hmk8zV1LTElHUI8A.js b/scripts/hmk8zV1LTElHUI8A.js new file mode 100644 index 0000000..00780d6 --- /dev/null +++ b/scripts/hmk8zV1LTElHUI8A.js @@ -0,0 +1,8 @@ +let msg = `${this.actor.prototypeToken.name} loses 1 Wound.+ Select your choice +
+${this.actor.prototypeToken.name} has lost all alcohol related penalties and gains the Fatigued Condition for ${duration} hours.
`, +{ + whisper: ChatMessage.getWhisperRecipients("GM"), + blind: true +}) \ No newline at end of file diff --git a/scripts/inPxRSx0CDj1nwAm.js b/scripts/inPxRSx0CDj1nwAm.js new file mode 100644 index 0000000..6fda683 --- /dev/null +++ b/scripts/inPxRSx0CDj1nwAm.js @@ -0,0 +1,4 @@ +if (args.test.result.fumble && !this.actor.itemTypes.talent.find(i => i.name == "Arcane Magic (Fire)")) +{ + this.actor.addCondition("ablaze"); +} \ No newline at end of file diff --git a/scripts/ioeTj5mx8jlA5EX5.js b/scripts/ioeTj5mx8jlA5EX5.js new file mode 100644 index 0000000..9605807 --- /dev/null +++ b/scripts/ioeTj5mx8jlA5EX5.js @@ -0,0 +1 @@ +args.actor.addCondition("stunned") \ No newline at end of file diff --git a/scripts/ipkkRffJh61WE7zR.js b/scripts/ipkkRffJh61WE7zR.js new file mode 100644 index 0000000..fe706ac --- /dev/null +++ b/scripts/ipkkRffJh61WE7zR.js @@ -0,0 +1,5 @@ +if (!args.flags.amputatedFootOrLeg) +{ + args.flags.amputatedFootOrLeg= true; + args.fields.modifier -= 20; +} \ No newline at end of file diff --git a/scripts/iuSoKntfJ4eAPafQ.js b/scripts/iuSoKntfJ4eAPafQ.js new file mode 100644 index 0000000..6f1b6d7 --- /dev/null +++ b/scripts/iuSoKntfJ4eAPafQ.js @@ -0,0 +1,8 @@ +let spells = await game.wfrp4e.utility.findAll("spell", "Loading Spells"); +spells = spells.filter(s => ["fire", "heavens", "beasts", "shadow", "light", "life", "death", "metal"].includes(s.system.lore.value)).sort((a, b) => a.system.lore.value > b.system.lore.value ? 1 : -1) + +let choice = await ItemDialog.create(spells, 1, "Choose Spell"); +if (choice[0]) +{ + this.actor.createEmbeddedDocuments("Item", choice, {fromEffect: this.effect.id}) +} diff --git a/scripts/iuYuf05BNuZ5fllI.js b/scripts/iuYuf05BNuZ5fllI.js new file mode 100644 index 0000000..2e17e76 --- /dev/null +++ b/scripts/iuYuf05BNuZ5fllI.js @@ -0,0 +1,4 @@ +if (args.test.isFumble) +{ + args.test.result.other.push("@Table[poisoned-wind-globe]") +} \ No newline at end of file diff --git a/scripts/j1AmrY1SxFJQyapo.js b/scripts/j1AmrY1SxFJQyapo.js new file mode 100644 index 0000000..843d5b1 --- /dev/null +++ b/scripts/j1AmrY1SxFJQyapo.js @@ -0,0 +1,4 @@ +if (this.actor.status.advantage.value > 0 && args.item.system.attackType) +{ + args.item.system.qualities.value.push({name : "penetrating"}) +} \ No newline at end of file diff --git a/scripts/j3zDMWkns32Yrxn3.js b/scripts/j3zDMWkns32Yrxn3.js new file mode 100644 index 0000000..2e60b32 --- /dev/null +++ b/scripts/j3zDMWkns32Yrxn3.js @@ -0,0 +1 @@ +this.effect.updateSource({"flags.wfrp4e.ward" : 9}) \ No newline at end of file diff --git a/scripts/j6Bf1iivH8cqSnnK.js b/scripts/j6Bf1iivH8cqSnnK.js new file mode 100644 index 0000000..f972bb4 --- /dev/null +++ b/scripts/j6Bf1iivH8cqSnnK.js @@ -0,0 +1,2 @@ +let target = args.data.targets[0] +return target?.actor.hasCondition("prone") || target.hasCondition("surprised") \ No newline at end of file diff --git a/scripts/j98hvy6r9G2Vjmid.js b/scripts/j98hvy6r9G2Vjmid.js new file mode 100644 index 0000000..e02fdd6 --- /dev/null +++ b/scripts/j98hvy6r9G2Vjmid.js @@ -0,0 +1,12 @@ +if (args.totalWoundLoss > 0) +{ + args.opposedTest.result.other.push( + `@Corruption[minor]{Minor Exposure to Corruption}` + ) + this.script.scriptMessage( + `${this.effect.name}: + @Corruption[minor]{Minor Exposure to Corruption}Damage all Items carried?
`}) + if (damageItems) + { + let msg = `` + let weapons = args.actor.itemTypes.weapon.filter(i => i.isEquipped); + let armour = args.actor.itemTypes.armour.filter(i => i.isEquipped); + let trappings = args.actor.itemTypes.trapping.filter(i => i.isEquipped); + for(let item of weapons) + { + if (item.system.properties.qualities.shield) + { + await item.system.damageItem(1, "shield"); + } + else + { + await item.system.damageItem(1); + } + msg += `${item.name} damage by 1
` + } + for(let item of armour) + { + await item.system.damageItem(1); + msg += `${item.name} damage by 1
` + } + for(let item of trappings) + { + await item.system.damageItem(1); + msg += `${item.name} damage by 1
` + } + if (msg) + { + this.script.scriptMessage(msg, {speaker : {alias : args.actor.name}}); + } + } +} + +if (type == "fire") +{ + await args.actor.addCondition("ablaze"); +} + +if (type == "electricity") +{ + await args.actor.addCondition("stunned"); +} + +if (type == "poison") +{ + await args.actor.addCondition("poisoned"); +} + diff --git a/scripts/jfk5VDKMTIf4ee0v.js b/scripts/jfk5VDKMTIf4ee0v.js new file mode 100644 index 0000000..bf86bc6 --- /dev/null +++ b/scripts/jfk5VDKMTIf4ee0v.js @@ -0,0 +1,2 @@ +if (args.totalWoundLoss > 0) + args.actor.addCondition("poisoned") \ No newline at end of file diff --git a/scripts/jgO1Kf60Ctt6R0qO.js b/scripts/jgO1Kf60Ctt6R0qO.js new file mode 100644 index 0000000..5fb4283 --- /dev/null +++ b/scripts/jgO1Kf60Ctt6R0qO.js @@ -0,0 +1 @@ +return args.item?.name != game.i18n.localize("NAME.Leadership") \ No newline at end of file diff --git a/scripts/jmxlpyLrIuoxQtvU.js b/scripts/jmxlpyLrIuoxQtvU.js new file mode 100644 index 0000000..097d4e0 --- /dev/null +++ b/scripts/jmxlpyLrIuoxQtvU.js @@ -0,0 +1 @@ + this.actor.getActiveTokens().forEach(t => t.document.update({texture : {scaleX : 2, scaleY: 2, src: "modules/wfrp4e-core/tokens/popout/gor.webp"}})); diff --git a/scripts/jpcU8FFWSlQ3gD0L.js b/scripts/jpcU8FFWSlQ3gD0L.js new file mode 100644 index 0000000..dfb5b37 --- /dev/null +++ b/scripts/jpcU8FFWSlQ3gD0L.js @@ -0,0 +1 @@ +return !args.skill?.name?.includes(game.i18n.localize("NAME.Trade")) \ No newline at end of file diff --git a/scripts/jrvj7bRyMBB9LixP.js b/scripts/jrvj7bRyMBB9LixP.js new file mode 100644 index 0000000..8c8d940 --- /dev/null +++ b/scripts/jrvj7bRyMBB9LixP.js @@ -0,0 +1 @@ +this.actor.addCondition("fatigued", 3) \ No newline at end of file diff --git a/scripts/jsgLEVYvMieyYT6L.js b/scripts/jsgLEVYvMieyYT6L.js new file mode 100644 index 0000000..bfcf625 --- /dev/null +++ b/scripts/jsgLEVYvMieyYT6L.js @@ -0,0 +1,18 @@ +let tokenImg = ""; // Put path to token image here, inbetween the quotation marks +if (tokenImg) +{ + if (this.effect.getFlag("wfrp4e", "transformed")) + { + await this.effect.setFlag("wfrp4e", "transformed", false); + this.actor.getActiveTokens().forEach(t => t.document.update({texture : {src: this.actor.prototypeToken.texture.src}})); + } + else + { + await this.effect.setFlag("wfrp4e", "transformed", true); + this.actor.getActiveTokens().forEach(t => t.document.update({texture : {src: tokenImg}})); + } +} +else +{ + this.script.scriptNotification("No Token Image path configured. The image path should be set in the first line of this script.", "error"); +} \ No newline at end of file diff --git a/scripts/k3FqFgsF6a3TkxAD.js b/scripts/k3FqFgsF6a3TkxAD.js new file mode 100644 index 0000000..b78e571 --- /dev/null +++ b/scripts/k3FqFgsF6a3TkxAD.js @@ -0,0 +1,3 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +test.roll(); +return true; \ No newline at end of file diff --git a/scripts/k8TC0yzp4xfOXD2n.js b/scripts/k8TC0yzp4xfOXD2n.js new file mode 100644 index 0000000..26e00ae --- /dev/null +++ b/scripts/k8TC0yzp4xfOXD2n.js @@ -0,0 +1,10 @@ +if (args.totalWoundLoss > 0) +{ + let test = await args.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}); + await test.roll(); + if (test.failed) + { + args.actor.addCondition("stunned"); + } + args.actor.hasCondition("bleeding")?.delete() +} \ No newline at end of file diff --git a/scripts/k9SvH4Lm3ZuI8S1N.js b/scripts/k9SvH4Lm3ZuI8S1N.js new file mode 100644 index 0000000..8315c45 --- /dev/null +++ b/scripts/k9SvH4Lm3ZuI8S1N.js @@ -0,0 +1 @@ +return !["wp", "ag", "i", "int"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/kBXVEnSWzaQZLkJH.js b/scripts/kBXVEnSWzaQZLkJH.js new file mode 100644 index 0000000..f8484c9 --- /dev/null +++ b/scripts/kBXVEnSWzaQZLkJH.js @@ -0,0 +1,5 @@ +if(args.test.result.critical) +{ + args.test.result.damage +=1 + args.test.result.additionalDamage += 1 +} \ No newline at end of file diff --git a/scripts/kIM4Fs1lFVV7TSnj.js b/scripts/kIM4Fs1lFVV7TSnj.js new file mode 100644 index 0000000..176adc4 --- /dev/null +++ b/scripts/kIM4Fs1lFVV7TSnj.js @@ -0,0 +1 @@ +this.actor.modifyAdvantage(1); \ No newline at end of file diff --git a/scripts/kMSdRskYDI2J1gnp.js b/scripts/kMSdRskYDI2J1gnp.js new file mode 100644 index 0000000..c06e3bc --- /dev/null +++ b/scripts/kMSdRskYDI2J1gnp.js @@ -0,0 +1,7 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields : {difficulty : "average"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("prone"); +} + \ No newline at end of file diff --git a/scripts/kWynO1lQzjiSs8RK.js b/scripts/kWynO1lQzjiSs8RK.js new file mode 100644 index 0000000..0b3b7e8 --- /dev/null +++ b/scripts/kWynO1lQzjiSs8RK.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Haggle"); \ No newline at end of file diff --git a/scripts/kYiDBPRKIokFkr4Z.js b/scripts/kYiDBPRKIokFkr4Z.js new file mode 100644 index 0000000..10222a8 --- /dev/null +++ b/scripts/kYiDBPRKIokFkr4Z.js @@ -0,0 +1,4 @@ +if (args.item.type == "skill" && args.item.name == "Ranged (Bow)") +{ + args.item.system.modifier.value += 20; +} \ No newline at end of file diff --git a/scripts/kYmscP2HuXjDovBD.js b/scripts/kYmscP2HuXjDovBD.js new file mode 100644 index 0000000..2e53be1 --- /dev/null +++ b/scripts/kYmscP2HuXjDovBD.js @@ -0,0 +1 @@ +return args.skill?.name.includes(game.i18n.localize("NAME.Stealth")) diff --git a/scripts/kiJ6AiaYVUjt6aV6.js b/scripts/kiJ6AiaYVUjt6aV6.js new file mode 100644 index 0000000..2998e2c --- /dev/null +++ b/scripts/kiJ6AiaYVUjt6aV6.js @@ -0,0 +1,7 @@ +teeth = await fromUuid("Compendium.wfrp4e-core.items.fBcZhOBn8IpoVqQ1") +teeth = teeth.toObject(); + +let roll = await new Roll("1d10").roll(); +roll.toMessage(this.script.getChatData({flavor : "Teeth Lost"})) +teeth.system.location.value = `${roll.total} ${teeth.system.location.value}` +this.actor.createEmbeddedDocuments("Item", [teeth]) \ No newline at end of file diff --git a/scripts/kkC5EhqA05U6U0gU.js b/scripts/kkC5EhqA05U6U0gU.js new file mode 100644 index 0000000..4116109 --- /dev/null +++ b/scripts/kkC5EhqA05U6U0gU.js @@ -0,0 +1,17 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); + +// Kind of insane but whatever +let opposedResult = test.opposedMessages[0]?.getOppose()?.resultMessage?.getOpposedTest()?.result + +if (opposedResult?.winner == "attacker") +{ + if (opposedResult.differenceSL < 6) + { + this.actor.addCondition("fatigued", Math.floor(opposedResult.differenceSL / 2)) + } + else if (opposedResult.differenceSL >= 6) + { + this.actor.addCondition("broken"); + } +} \ No newline at end of file diff --git a/scripts/kmsGLWGxCY8Z8jVG.js b/scripts/kmsGLWGxCY8Z8jVG.js new file mode 100644 index 0000000..3077f61 --- /dev/null +++ b/scripts/kmsGLWGxCY8Z8jVG.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Intuition"); \ No newline at end of file diff --git a/scripts/kvaN100w0nBUlLbj.js b/scripts/kvaN100w0nBUlLbj.js new file mode 100644 index 0000000..cc524fa --- /dev/null +++ b/scripts/kvaN100w0nBUlLbj.js @@ -0,0 +1,6 @@ +let poisoned = this.actor.hasCondition("poisoned") +if (poisoned) +{ + this.script.scriptMessage("Immune to Poisoned") + poisoned.delete() +} \ No newline at end of file diff --git a/scripts/l8qFKSnMpy4P7XQR.js b/scripts/l8qFKSnMpy4P7XQR.js new file mode 100644 index 0000000..523491c --- /dev/null +++ b/scripts/l8qFKSnMpy4P7XQR.js @@ -0,0 +1 @@ +return !args.skill?.name.includes(game.i18n.localize("NAME.Stealth")); \ No newline at end of file diff --git a/scripts/lCOdnKz8XpnkDs6Q.js b/scripts/lCOdnKz8XpnkDs6Q.js new file mode 100644 index 0000000..51d5386 --- /dev/null +++ b/scripts/lCOdnKz8XpnkDs6Q.js @@ -0,0 +1,2 @@ +let test = await this.actor.setupCharacteristic("t", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); \ No newline at end of file diff --git a/scripts/lFO6XdfUODmFArqx.js b/scripts/lFO6XdfUODmFArqx.js new file mode 100644 index 0000000..083ec87 --- /dev/null +++ b/scripts/lFO6XdfUODmFArqx.js @@ -0,0 +1 @@ +args.actor.addCondition("bleeding") \ No newline at end of file diff --git a/scripts/lII4KMRblqwFBlsV.js b/scripts/lII4KMRblqwFBlsV.js new file mode 100644 index 0000000..49bd3a7 --- /dev/null +++ b/scripts/lII4KMRblqwFBlsV.js @@ -0,0 +1,133 @@ +let characteristics = { + "ws" : 10, + "bs" : 0, + "s" : 0, + "t" : 0, + "i" : 10, + "ag" : 0, + "dex" : 0, + "int" : 20, + "wp" : 10, + "fel" : 15 +} +let skills = ["Channelling", "Charm", "Perform (Dancing)"] +let skillAdvancements = [0, 6, 3] +let talents = ["Attractive", "Distract", "Mimic"] +let traits = ["Distracting", "Flight (6)", "Spellcaster (Petty)"] +let trappings = [] +let items = []; +let spells = ["Marsh Lights", "Sleep"]; + +let updateObj = this.actor.toObject(); + +for (let ch in characteristics) +{ + updateObj.system.characteristics[ch].modifier += characteristics[ch]; +} + +for (let index = 0; index < skills.length; index++) +{ + let skill = skills[index] + let skillItem; + skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill") + if (skillItem) + skillItem.system.advances.value += skillAdvancements[index] + else + { + skillItem = await game.wfrp4e.utility.findSkill(skill) + skillItem = skillItem.toObject(); + skillItem.system.advances.value = skillAdvancements[index]; + items.push(skillItem); + } +} + +for (let talent of talents) +{ + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } +} + +const traitRegex = /(?:,?(.+?)(\+?\d{1,2}\+?)?\s*?(?:\((.+?)\)\s*(\+?\d{1,2})?|,|$))/gm +for (let trait of traits) +{ + let traitMatches = trait.matchAll(traitRegex).next().value + let traitName = traitMatches[1] + let traitVal = traitMatches[2] || traitMatches[4] // could be match 2 or 4 depending on if there's a specialization + let traitSpec = traitMatches[3] + + let traitItem; + try { + traitItem = await WFRP_Utility.findItem(traitName, "trait") + } + catch { } + if (!traitItem) { + ui.notifications.warn(`Could not find ${trait}`, {permanent : true}) + } + traitItem = traitItem.toObject() + + if (Number.isNumeric(traitVal)) + { + traitItem.system.specification.value = traitName.includes('Weapon','Horns','Tail','Tentacles','Bite') ? traitVal - parseInt(characteristicValues[3]/10) : traitVal; + traitItem.name = (traitItem.name + ` ${traitSpec ? "("+ traitSpec + ")" : ""}`).trim() + } + else + traitItem.system.specification.value = traitSpec + + items.push(traitItem) + +} + +for (let trapping of trappings) +{ + let trappingItem = await game.wfrp4e.utility.findItem(trapping) + if (trappingItem) + { + trappingItem = trappingItem.toObject() + + equip(trappingItem) + + items.push(trappingItem); + } + else + { + ui.notifications.warn(`Could not find ${trapping}`, {permanent : true}) + } +} + +for (let spell of spells) +{ + let spellItem = await game.wfrp4e.utility.findItem(spell) + if (spellItem) + { + spellItem = spellItem.toObject() + + items.push(spellItem); + } + else + { + ui.notifications.warn(`Could not find ${spell}`, {permanent : true}) + } +} + +updateObj.name = updateObj.name += " " + this.effect.name + +await this.actor.update(updateObj) +this.actor.createEmbeddedDocuments("Item", items); + + +function equip(item) +{ + if (item.type == "armour") + item.worn = true + else if (item.type == "weapon") + item.equipped = true + else if (item.type == "trapping" && item.trappingType?.value == "clothingAccessories") + item.worn = true +} \ No newline at end of file diff --git a/scripts/lOzkngzye4RmvALp.js b/scripts/lOzkngzye4RmvALp.js new file mode 100644 index 0000000..4f261d3 --- /dev/null +++ b/scripts/lOzkngzye4RmvALp.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.DrNUTPeodEgpWTnT") +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id}); +this.script.scriptNotification("Added " + item.name) \ No newline at end of file diff --git a/scripts/lPudo1grrVp05i7a.js b/scripts/lPudo1grrVp05i7a.js new file mode 100644 index 0000000..b96114f --- /dev/null +++ b/scripts/lPudo1grrVp05i7a.js @@ -0,0 +1,11 @@ +let loc = Math.floor(CONFIG.Dice.randomUniform() * 2) == 0 ? "head" : "body" +let damage = this.actor.system.characteristics.s.bonus + 6 + + this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : " - " + this.effect.name}).then(async test => { + await test.roll(); + if(test.failed) + { + await this.actor.addCondition("stunned") + this.script.scriptMessage(await this.actor.applyBasicDamage(damage, {loc, damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_AP, suppressMsg: true})) + } + }) \ No newline at end of file diff --git a/scripts/lQJ68n3y1xDyNicE.js b/scripts/lQJ68n3y1xDyNicE.js new file mode 100644 index 0000000..0d61d6e --- /dev/null +++ b/scripts/lQJ68n3y1xDyNicE.js @@ -0,0 +1 @@ +return !args.options.sizeModifier && args.item?.system?.attackType != "ranged" \ No newline at end of file diff --git a/scripts/lSOAZ4FG44bT4jh1.js b/scripts/lSOAZ4FG44bT4jh1.js new file mode 100644 index 0000000..fd544d6 --- /dev/null +++ b/scripts/lSOAZ4FG44bT4jh1.js @@ -0,0 +1,7 @@ +let infected = await fromUuid("Compendium.wfrp4e-core.items.V0c3qBU1CMm8bmsW") +let fear = await fromUuid("Compendium.wfrp4e-core.items.pTorrE0l3VybAbtn") + +let infectedData = infected.toObject(); +let fearData = fear.toObject(); +fearData.system.specification.value = 2; +this.actor.createEmbeddedDocuments("Item", [fearData, infectedData], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/lU4s3UTtBkU38djI.js b/scripts/lU4s3UTtBkU38djI.js new file mode 100644 index 0000000..ba1cf91 --- /dev/null +++ b/scripts/lU4s3UTtBkU38djI.js @@ -0,0 +1,4 @@ +this.actor.addCondition("entangled") +let msg = `${this.actor.prototypeToken.name} loses 1 Wound and gains 1 Entangled Condition.` +this.script.scriptMessage(msg) +this.actor.modifyWounds(-1) \ No newline at end of file diff --git a/scripts/lYYkGzqNshiYc7WI.js b/scripts/lYYkGzqNshiYc7WI.js new file mode 100644 index 0000000..d17b4c6 --- /dev/null +++ b/scripts/lYYkGzqNshiYc7WI.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("poisoned") +} \ No newline at end of file diff --git a/scripts/laptAldsT0Fm1rDt.js b/scripts/laptAldsT0Fm1rDt.js new file mode 100644 index 0000000..861ea5e --- /dev/null +++ b/scripts/laptAldsT0Fm1rDt.js @@ -0,0 +1,6 @@ +let blunt = await Dialog.confirm({label : "test", content :`Apply blunt damage reduction? (-3)
`}) + +if (blunt) +{ + args.modifiers.other.push({label : this.effect.name, details : "Blunt Damage Reduction", value : -3}) +} \ No newline at end of file diff --git a/scripts/lhemR8EP5tGNKout.js b/scripts/lhemR8EP5tGNKout.js new file mode 100644 index 0000000..a9d9356 --- /dev/null +++ b/scripts/lhemR8EP5tGNKout.js @@ -0,0 +1,14 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {fields: {difficulty : "average"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`, context : {failure : "Suffer Creeping Irrationality"}}) +await test.roll(); +if (test.failed) +{ + msg = `@UUID[${this.effect.sourceItem.uuid}]{Creeping Irratitonality} Roll: ${Math.ceil(CONFIG.Dice.randomUniform() * 10)}
` + if (test.result.roll % 11 == 0 || test.result.roll == 100) + { + msg += `${this.actor.prototypeToken.name} also gained 1 Corruption Point. If mutating, this results in a @Table[mutatemental]{Mental Corruption}
` + let newCorruption = Number(this.actor.status.corruption.value) + 1 + this.actor.update({"system.status.corruption.value" : newCorruption}) + } + + this.script.scriptMessage(msg); +} diff --git a/scripts/ljpM7muMyxGD04EX.js b/scripts/ljpM7muMyxGD04EX.js new file mode 100644 index 0000000..50ba967 --- /dev/null +++ b/scripts/ljpM7muMyxGD04EX.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.MVI0lXcg6vvtooAF") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/lol5J6h0pErzM71s.js b/scripts/lol5J6h0pErzM71s.js new file mode 100644 index 0000000..cc986ba --- /dev/null +++ b/scripts/lol5J6h0pErzM71s.js @@ -0,0 +1 @@ +return args.weapon?.system.properties.flaws.crewed \ No newline at end of file diff --git a/scripts/lvjcddwRiN9iGruy.js b/scripts/lvjcddwRiN9iGruy.js new file mode 100644 index 0000000..1f4ca7b --- /dev/null +++ b/scripts/lvjcddwRiN9iGruy.js @@ -0,0 +1,38 @@ +let test = await this.actor.setupCharacteristic("t", { appendTitle: ` - ${this.effect.name}`, fields: { difficulty: "challenging" } }) +await test.roll(); + +if (test.failed) +{ + let ageAdded = Math.ceil(CONFIG.Dice.randomUniform() * 10) + Math.ceil(CONFIG.Dice.randomUniform() * 10) + let ws = Math.ceil(CONFIG.Dice.randomUniform() * 10) + let bs = Math.ceil(CONFIG.Dice.randomUniform() * 10) + let s = Math.ceil(CONFIG.Dice.randomUniform() * 10) + let t = Math.ceil(CONFIG.Dice.randomUniform() * 10) + let ag = Math.ceil(CONFIG.Dice.randomUniform() * 10) + let dex = Math.ceil(CONFIG.Dice.randomUniform() * 10) + + let currentAge = parseInt(this.actor.system.details.age.value) + + let inline = `@ROLL` + let msg = + `${this.actor.prototypeToken.name} ages by ${inline.replace("@ROLL", ageAdded).replace("@TT", "2d10")} and loses
+${inline.replace("@ROLL", ws).replace("@TT", "1d10")} Weapon Skill
+${inline.replace("@ROLL", bs).replace("@TT", "1d10")} Ballistic Skill
+${inline.replace("@ROLL", s).replace("@TT", "1d10")} Strength
+${inline.replace("@ROLL", t).replace("@TT", "1d10")} Toughness
+${inline.replace("@ROLL", ag).replace("@TT", "1d10")} Agility
+${inline.replace("@ROLL", dex).replace("@TT", "1d10")} Dexterity
+ ` + this.script.scriptMessage(msg); + + let characteristics = duplicate(this.actor.system.characteristics) + + characteristics.ws.initial -= ws + characteristics.bs.initial -= bs + characteristics.s.initial -= s + characteristics.t.initial -= t + characteristics.ag.initial -= ag + characteristics.dex.initial -= dex + + this.actor.update({ "system.characteristics": characteristics, "data.details.age.value": ageAdded + currentAge }) +} \ No newline at end of file diff --git a/scripts/lwVhn4bSXJ3eoT9q.js b/scripts/lwVhn4bSXJ3eoT9q.js new file mode 100644 index 0000000..3a19740 --- /dev/null +++ b/scripts/lwVhn4bSXJ3eoT9q.js @@ -0,0 +1,8 @@ +if (this.item.system.weaponGroup.value == "basic") +{ + let slash = this.item.system.qualities.value.find(i => i.name == "slash") + if (slash) + { + slash.value = "2A" + } +} \ No newline at end of file diff --git a/scripts/m3qEVO5fseV6KHXa.js b/scripts/m3qEVO5fseV6KHXa.js new file mode 100644 index 0000000..ebc6391 --- /dev/null +++ b/scripts/m3qEVO5fseV6KHXa.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.qn4ZpvTQIX4rcJDl") +let data = item.toObject(); +data.system.location.key = this.item.system.location.key +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) \ No newline at end of file diff --git a/scripts/m58MpMZBblpq5LJu.js b/scripts/m58MpMZBblpq5LJu.js new file mode 100644 index 0000000..6f85774 --- /dev/null +++ b/scripts/m58MpMZBblpq5LJu.js @@ -0,0 +1,2 @@ +args.prefillModifiers.slBonus++; +args.prefillModifiers.successBonus++; diff --git a/scripts/m8qBlbH7ROoqa22o.js b/scripts/m8qBlbH7ROoqa22o.js new file mode 100644 index 0000000..17577b3 --- /dev/null +++ b/scripts/m8qBlbH7ROoqa22o.js @@ -0,0 +1 @@ +return args.options.reload \ No newline at end of file diff --git a/scripts/mBcLf11upaHS8AQq.js b/scripts/mBcLf11upaHS8AQq.js new file mode 100644 index 0000000..4234181 --- /dev/null +++ b/scripts/mBcLf11upaHS8AQq.js @@ -0,0 +1 @@ +this.actor.status.addArmour(1, {source: this.effect}) \ No newline at end of file diff --git a/scripts/mJ9eMPub4epJSf00.js b/scripts/mJ9eMPub4epJSf00.js new file mode 100644 index 0000000..4144fbb --- /dev/null +++ b/scripts/mJ9eMPub4epJSf00.js @@ -0,0 +1 @@ +return args.weapon?.system.qualities.value.find(i => i.name == "shield") && this.actor.attacker \ No newline at end of file diff --git a/scripts/mPxmCsXYirAIT913.js b/scripts/mPxmCsXYirAIT913.js new file mode 100644 index 0000000..84284a1 --- /dev/null +++ b/scripts/mPxmCsXYirAIT913.js @@ -0,0 +1,3 @@ +let key = await ItemDialog.create(ItemDialog.objectToArray(game.wfrp4e.config.characteristics, this.effect.img), 1, "Choose Characteristic"); + +this.effect.updateSource({changes : [{key : `system.characteristics.${key[0].id}.modifier`, mode : 2, value : 10}]}) \ No newline at end of file diff --git a/scripts/mRvLsSVxNyt8LVZb.js b/scripts/mRvLsSVxNyt8LVZb.js new file mode 100644 index 0000000..f68402d --- /dev/null +++ b/scripts/mRvLsSVxNyt8LVZb.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.GRRN3XAKIpEVCY7z") +let data = item.toObject(); +data.name += " (To Be Determined)" +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/mTnmPcjWmvScIBWY.js b/scripts/mTnmPcjWmvScIBWY.js new file mode 100644 index 0000000..14c7aaf --- /dev/null +++ b/scripts/mTnmPcjWmvScIBWY.js @@ -0,0 +1 @@ +return args.skill?.name.includes("Channelling") || args.type == "channelling" \ No newline at end of file diff --git a/scripts/mV4Tmc0yfpL09KV7.js b/scripts/mV4Tmc0yfpL09KV7.js new file mode 100644 index 0000000..3b9f40b --- /dev/null +++ b/scripts/mV4Tmc0yfpL09KV7.js @@ -0,0 +1 @@ +args.actor.addCondition("entangled") \ No newline at end of file diff --git a/scripts/mYL4i1vNlMl4vFYy.js b/scripts/mYL4i1vNlMl4vFYy.js new file mode 100644 index 0000000..a5211a8 --- /dev/null +++ b/scripts/mYL4i1vNlMl4vFYy.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Perception") && args.skill?.name != game.i18n.localize("NAME.Track"); \ No newline at end of file diff --git a/scripts/ma0sWhebqwdRHWvY.js b/scripts/ma0sWhebqwdRHWvY.js new file mode 100644 index 0000000..c1779e5 --- /dev/null +++ b/scripts/ma0sWhebqwdRHWvY.js @@ -0,0 +1,5 @@ +if (!args.flags.trained) +{ + args.flags.trained = true; + args.fields.modifier += 10; +} \ No newline at end of file diff --git a/scripts/maKr58mvvyKxFyC3.js b/scripts/maKr58mvvyKxFyC3.js new file mode 100644 index 0000000..f941ab6 --- /dev/null +++ b/scripts/maKr58mvvyKxFyC3.js @@ -0,0 +1,2 @@ +if (args.item.type == "prayer" && (args.item.damage.value || args.item.damage.dice)) + args.item.damage.value += "+1" \ No newline at end of file diff --git a/scripts/masOBNgSi5HYkf3m.js b/scripts/masOBNgSi5HYkf3m.js new file mode 100644 index 0000000..ed60b79 --- /dev/null +++ b/scripts/masOBNgSi5HYkf3m.js @@ -0,0 +1 @@ +return args.type != "cast" && args.type != "channelling" \ No newline at end of file diff --git a/scripts/mgLGN1XPzPE4dReN.js b/scripts/mgLGN1XPzPE4dReN.js new file mode 100644 index 0000000..0433903 --- /dev/null +++ b/scripts/mgLGN1XPzPE4dReN.js @@ -0,0 +1 @@ +args.fields.slBonus--; \ No newline at end of file diff --git a/scripts/mr8qm5Bg6k1idZ6Q.js b/scripts/mr8qm5Bg6k1idZ6Q.js new file mode 100644 index 0000000..c28b926 --- /dev/null +++ b/scripts/mr8qm5Bg6k1idZ6Q.js @@ -0,0 +1 @@ +return args.item?.name == "Play (Lute)" \ No newline at end of file diff --git a/scripts/mziJBUYcsrhkdcCJ.js b/scripts/mziJBUYcsrhkdcCJ.js new file mode 100644 index 0000000..0308dbf --- /dev/null +++ b/scripts/mziJBUYcsrhkdcCJ.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("prone") +} \ No newline at end of file diff --git a/scripts/n5RJqJL9fdRIxkuN.js b/scripts/n5RJqJL9fdRIxkuN.js new file mode 100644 index 0000000..5fa0e06 --- /dev/null +++ b/scripts/n5RJqJL9fdRIxkuN.js @@ -0,0 +1,12 @@ +if (this.actor.system.status.advantage.value > 0) +{ + await this.actor.modifyAdvantage(-1); + this.script.scriptNotification("Advantage Subtracted") +} +else +{ + return this.script.scriptNotification("Not enough Advantage!", "error") +} + +let test = await this.actor.setupTrait(this.item) +await test.roll(); \ No newline at end of file diff --git a/scripts/nCWAflBj7Si2BI1Q.js b/scripts/nCWAflBj7Si2BI1Q.js new file mode 100644 index 0000000..af67a69 --- /dev/null +++ b/scripts/nCWAflBj7Si2BI1Q.js @@ -0,0 +1,4 @@ +if (args.item.type == "spell" && args.item.system.lore.value != "petty") +{ + args.item.cn.value = Math.max(4, args.item.cn.value * 2) +} \ No newline at end of file diff --git a/scripts/nD2QVg3DrPK3foMf.js b/scripts/nD2QVg3DrPK3foMf.js new file mode 100644 index 0000000..0101c82 --- /dev/null +++ b/scripts/nD2QVg3DrPK3foMf.js @@ -0,0 +1,7 @@ +args.actor.setupSkill("Dodge", { fields: { difficulty: "average" } }).then(async test => { + await test.roll(); + if (test.failed) { + await args.actor.addCondition("bleeding") + await args.actor.addCondition("entangled") + } + }) \ No newline at end of file diff --git a/scripts/nEaF3jbCiVYD8jia.js b/scripts/nEaF3jbCiVYD8jia.js new file mode 100644 index 0000000..c39fb2f --- /dev/null +++ b/scripts/nEaF3jbCiVYD8jia.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.Charm") && !args.skill?.name.includes(game.i18n.localize("NAME.Lore")); \ No newline at end of file diff --git a/scripts/nGTxNWBUBgTr87wU.js b/scripts/nGTxNWBUBgTr87wU.js new file mode 100644 index 0000000..c078cd8 --- /dev/null +++ b/scripts/nGTxNWBUBgTr87wU.js @@ -0,0 +1,5 @@ +if (args.opposedTest.result.differenceSL >= 0 && args.opposedTest.result.differenceSL <= 2 && args.opposedTest.result.winner == "attacker") +{ + this.script.scriptMessage(`Becomes lodged in the armour or flesh of the opponent. See @UUID[${this.item.uuid}]{${this.item.name}}.`, speaker : {alias : this.item.name}, {blind: true, whisper : ChatMessage.getWhisperRecipients("GM")}) +} + \ No newline at end of file diff --git a/scripts/nHJdlqbOP0ECgywb.js b/scripts/nHJdlqbOP0ECgywb.js new file mode 100644 index 0000000..6bf5cf6 --- /dev/null +++ b/scripts/nHJdlqbOP0ECgywb.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.CnydL8p3PVAuF98w") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/nSXzktHyNjGUXjaw.js b/scripts/nSXzktHyNjGUXjaw.js new file mode 100644 index 0000000..33216f3 --- /dev/null +++ b/scripts/nSXzktHyNjGUXjaw.js @@ -0,0 +1 @@ +return args.item?.system.isRanged \ No newline at end of file diff --git a/scripts/nYtAjSArsNbrU2ob.js b/scripts/nYtAjSArsNbrU2ob.js new file mode 100644 index 0000000..f092926 --- /dev/null +++ b/scripts/nYtAjSArsNbrU2ob.js @@ -0,0 +1,8 @@ +if (["ag", "i", "int"].includes(args.characteristic)) +{ + args.fields.modifier -= 10; +} +else if (["wp"].includes(args.characteristic)) +{ + args.fields.modifier += 10; +} \ No newline at end of file diff --git a/scripts/naF5EWr1CBkYRZTK.js b/scripts/naF5EWr1CBkYRZTK.js new file mode 100644 index 0000000..ecdafaa --- /dev/null +++ b/scripts/naF5EWr1CBkYRZTK.js @@ -0,0 +1,26 @@ +if (args.opposedTest?.attackerTest?.item?.system?.isRanged) +{ + let choice = await Dialog.wait({ + title: this.effect.name, + content: `Abort damage with ${this.effect.name}?`,
+ buttons: {
+ yes: {
+ label: "Yes",
+ callback: () => {
+ return true;
+ }
+ },
+ no: {
+ label: "No",
+ callback: () => {
+ return false;
+ }
+ }
+ }
+ })
+
+ if (choice)
+ {
+ args.abort = `${this.effect.name}: Damage cancelled`
+ }
+}
\ No newline at end of file
diff --git a/scripts/ncIjDE6TFx88IQA1.js b/scripts/ncIjDE6TFx88IQA1.js
new file mode 100644
index 0000000..223a1a3
--- /dev/null
+++ b/scripts/ncIjDE6TFx88IQA1.js
@@ -0,0 +1 @@
+return args.skill?.name == game.i18n.localize("NAME.Climb") || args.skill?.name == game.i18n.localize("NAME.Athletics");
\ No newline at end of file
diff --git a/scripts/neaaVy6D6tfcst5P.js b/scripts/neaaVy6D6tfcst5P.js
new file mode 100644
index 0000000..123137f
--- /dev/null
+++ b/scripts/neaaVy6D6tfcst5P.js
@@ -0,0 +1 @@
+args.fields.slBonus += this.actor.characteristics.i.bonus;
diff --git a/scripts/ngMm7SgtVqVovFJG.js b/scripts/ngMm7SgtVqVovFJG.js
new file mode 100644
index 0000000..8d5af65
--- /dev/null
+++ b/scripts/ngMm7SgtVqVovFJG.js
@@ -0,0 +1,4 @@
+if (args.test.result.critical && args.test.result.critical != "Total Power")
+{
+ args.test.result.other.push(` Bonecrusher Critical (+20) (only if Critical Cast selected)`)
+}
\ No newline at end of file
diff --git a/scripts/njPP9wDAsdh4WHIj.js b/scripts/njPP9wDAsdh4WHIj.js
new file mode 100644
index 0000000..be455e6
--- /dev/null
+++ b/scripts/njPP9wDAsdh4WHIj.js
@@ -0,0 +1,4 @@
+if (args.totalWoundLoss > 0 && ["trait", "weapon"].includes(args.opposedTest.attackerTest.item?.type))
+{
+ this.script.scriptMessage(`Infected: ${args.actor.name} must pass an Easy (+40) Endurance Test or gain a @UUID[Compendium.wfrp4e-core.items.kKccDTGzWzSXCBOb]{Festering Wound}`, {whisper: ChatMessage.getWhisperRecipients("GM")})
+}
\ No newline at end of file
diff --git a/scripts/nkbTnaeBpthyhw4J.js b/scripts/nkbTnaeBpthyhw4J.js
new file mode 100644
index 0000000..da73508
--- /dev/null
+++ b/scripts/nkbTnaeBpthyhw4J.js
@@ -0,0 +1,6 @@
+let fortunePoints = this.effect.sourceTest.result.overcast.usage.other.current
+let current = this.actor.status.fortune.value
+
+this.actor.update({"system.status.fortune.value" : fortunePoints + current})
+
+this.script.scriptMessage(`${this.actor.prototypeToken.name} fortune points increased from ${current} to ${fortunePoints + current}`)
\ No newline at end of file
diff --git a/scripts/nkdKBJ8ItqWiRAWL.js b/scripts/nkdKBJ8ItqWiRAWL.js
new file mode 100644
index 0000000..da8ed4c
--- /dev/null
+++ b/scripts/nkdKBJ8ItqWiRAWL.js
@@ -0,0 +1,21 @@
+// Apply changes when the mask is worn
+
+if (args.equipped) {
+ this.actor.createEmbeddedDocuments("ActiveEffect", [this.item.effects.contents[1]?.convertToApplied()])
+ this.script.scriptMessage(`${this.actor.name} dons the ${this.item.name}.
+ They gain +50 to Swim Tests and can breathe underwater.
+ If they wear the mask for more than an hour or benefit from any of its effects, they are exposed to @Corruption[moderate]{Moderate Corruption}.
+ `,
+ {whisper: ChatMessage.getWhisperRecipients("GM")})
+}
+
+// Notify of lingering effects when mask is removed
+else if (!args.equipped)
+{
+ await this.item.effects.contents[0].delete();
+ await this.item.update({name : this.item.name += " (Used)"})
+ this.script.scriptMessage(`${this.item.name} on ${this.actor.name} has been taken off and loses its properties. However, the effects last for [[1d10+4]] days, after which they should be manually removed.`,
+ {whisper: ChatMessage.getWhisperRecipients("GM")}
+ )
+
+}
diff --git a/scripts/nuIpPD4uaZRuJni8.js b/scripts/nuIpPD4uaZRuJni8.js
new file mode 100644
index 0000000..43c5bf3
--- /dev/null
+++ b/scripts/nuIpPD4uaZRuJni8.js
@@ -0,0 +1,3 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.qdMbxW09FUoYBzmB")
+let data = item.toObject();
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/nvrFhHHVq3KzirlR.js b/scripts/nvrFhHHVq3KzirlR.js
new file mode 100644
index 0000000..ba0fdde
--- /dev/null
+++ b/scripts/nvrFhHHVq3KzirlR.js
@@ -0,0 +1 @@
+return !args.skill?.name.includes(game.i18n.localize("NAME.Stealth"))
diff --git a/scripts/nxNqWmmF6mJTnrLo.js b/scripts/nxNqWmmF6mJTnrLo.js
new file mode 100644
index 0000000..142e606
--- /dev/null
+++ b/scripts/nxNqWmmF6mJTnrLo.js
@@ -0,0 +1 @@
+return args.weapon?.system.usesHands.includes(this.item.system.location.key);
\ No newline at end of file
diff --git a/scripts/nzh8d46l1ikhkz8Q.js b/scripts/nzh8d46l1ikhkz8Q.js
new file mode 100644
index 0000000..a11f1bf
--- /dev/null
+++ b/scripts/nzh8d46l1ikhkz8Q.js
@@ -0,0 +1 @@
+return (args.type == "weapon" && (args.item.system.weaponGroup.value == "blackpowder" || args.item.system.weaponGroup.value == "engineering")) || (args.type == "cast" && args.item.system.lore.value == "fire")
\ No newline at end of file
diff --git a/scripts/o1zD8mej9TWKNxUq.js b/scripts/o1zD8mej9TWKNxUq.js
new file mode 100644
index 0000000..9cc92e5
--- /dev/null
+++ b/scripts/o1zD8mej9TWKNxUq.js
@@ -0,0 +1 @@
+args.fields.slBonus -= 1;
\ No newline at end of file
diff --git a/scripts/o3JUBKLvE6bBxK2n.js b/scripts/o3JUBKLvE6bBxK2n.js
new file mode 100644
index 0000000..9ccae0a
--- /dev/null
+++ b/scripts/o3JUBKLvE6bBxK2n.js
@@ -0,0 +1,20 @@
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), { fields: { difficulty: "average" } })
+await test.roll();
+if (test.failed)
+{
+ await this.actor.addCondition("prone")
+ let injury = await fromUuid("Compendium.wfrp4e-core.items.ZhMADOqoo0y8Q9bx");
+ injury = injury.toObject()
+ let toes = Math.clamped(Math.abs(test.result.SL) + 1, 1, 5)
+ injury.system.location.key = this.item.system.location.key[0] + injury.system.location.value
+ if (injury.system.location.key[0] == "r")
+ {
+ injury.system.location.value = `${toes} Right ${injury.system.location.value}s`
+ }
+ else if (injury.system.location.key[0] == "l")
+ {
+ injury.system.location.value = `${toes} Left ${injury.system.location.value}s`
+ }
+ setProperty(injury, "system.wfrp4e.count", toes)
+ this.actor.createEmbeddedDocuments("Item", [injury])
+}
\ No newline at end of file
diff --git a/scripts/o88xuUConwt0vFLw.js b/scripts/o88xuUConwt0vFLw.js
new file mode 100644
index 0000000..ae9e06f
--- /dev/null
+++ b/scripts/o88xuUConwt0vFLw.js
@@ -0,0 +1,5 @@
+let points = this.effect.sourceTest.result.overcast.usage.other.current;
+
+this.actor.update({"system.status.fortune.value" : this.actor.system.status.fortune.value + points});
+
+this.script.scriptMessage(`Gained ${points} Fortune Points`)
\ No newline at end of file
diff --git a/scripts/oDNfCNyt5KaUYmg2.js b/scripts/oDNfCNyt5KaUYmg2.js
new file mode 100644
index 0000000..7efcdf8
--- /dev/null
+++ b/scripts/oDNfCNyt5KaUYmg2.js
@@ -0,0 +1,10 @@
+if(args.opposedTest.result.winner == "defender")
+{
+ let roll = Math.ceil(CONFIG.Dice.randomUniform() * 10)
+ let msg = `Rolled ${roll}.`
+ if (roll >= 7)
+ {
+ msg = `Attack hits with an SL of ${roll - 6}.`
+ }
+ this.script.scriptMessage(msg, {blind: true, whisper : ChatMessage.getWhisperRecipients("GM")})
+}
\ No newline at end of file
diff --git a/scripts/oEsUsI74yGTZ9CwU.js b/scripts/oEsUsI74yGTZ9CwU.js
new file mode 100644
index 0000000..c57ed37
--- /dev/null
+++ b/scripts/oEsUsI74yGTZ9CwU.js
@@ -0,0 +1 @@
+return args.item?.name == game.i18n.localize("NAME.CharmAnimal")
\ No newline at end of file
diff --git a/scripts/oGdsGPgJWcyWkiWl.js b/scripts/oGdsGPgJWcyWkiWl.js
new file mode 100644
index 0000000..b6511a1
--- /dev/null
+++ b/scripts/oGdsGPgJWcyWkiWl.js
@@ -0,0 +1,6 @@
+this.actor.addCondition("broken")
+
+if (this.actor.has(game.i18n.localize("NAME.Undead")))
+{
+ this.script.scriptMessage(await this.actor.applyBasicDamage(this.effect.sourceTest.result.damage, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL, suppressMsg: true}))
+}
\ No newline at end of file
diff --git a/scripts/oHenUKtaS3jT5xQn.js b/scripts/oHenUKtaS3jT5xQn.js
new file mode 100644
index 0000000..c399b90
--- /dev/null
+++ b/scripts/oHenUKtaS3jT5xQn.js
@@ -0,0 +1,4 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.4xF7M6ylIiGntekh")
+item = item.toObject()
+item.name = this.effect.name
+this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id})
diff --git a/scripts/oPg4se8iQRD14kmB.js b/scripts/oPg4se8iQRD14kmB.js
new file mode 100644
index 0000000..a61008d
--- /dev/null
+++ b/scripts/oPg4se8iQRD14kmB.js
@@ -0,0 +1,27 @@
+let filters = [
+ {
+ property : "type",
+ value : "weapon"
+ },
+ {
+ property : "system.weaponGroup.value",
+ value : ["twohanded", "polearm"]
+ }
+]
+
+let items = await game.wfrp4e.apps.ItemDialog.createFromFilters(filters, 1, "Choose an appropriate Polearm or Two-Handed Weapon")
+items = items.map(i => i.toObject())
+
+items.forEach(i => equip(i))
+
+this.actor.createEmbeddedDocuments("Item", items);
+
+function equip(item)
+{
+ if (item.type == "armour")
+ item.system.worn.value = true
+ else if (item.type == "weapon")
+ item.system.equipped = true
+ else if (item.type == "trapping" && item.system.trappingType.value == "clothingAccessories")
+ item.system.worn = true
+}
\ No newline at end of file
diff --git a/scripts/oV81zgbZsuTFG6L2.js b/scripts/oV81zgbZsuTFG6L2.js
new file mode 100644
index 0000000..c49d598
--- /dev/null
+++ b/scripts/oV81zgbZsuTFG6L2.js
@@ -0,0 +1,5 @@
+let caster = this.effect.sourceActor;
+
+this.actor.modifyWounds(caster.system.characteristics.fel.bonus);
+
+this.script.scriptMessage(`Healed ${caster.system.characteristics.fel.bonus} Wounds`);
\ No newline at end of file
diff --git a/scripts/oW1gtYVT5nrxDjM7.js b/scripts/oW1gtYVT5nrxDjM7.js
new file mode 100644
index 0000000..0f97f92
--- /dev/null
+++ b/scripts/oW1gtYVT5nrxDjM7.js
@@ -0,0 +1 @@
+return args.characteristic != "ag"
\ No newline at end of file
diff --git a/scripts/oWM43EdUiyHgUlfW.js b/scripts/oWM43EdUiyHgUlfW.js
new file mode 100644
index 0000000..2c1af1d
--- /dev/null
+++ b/scripts/oWM43EdUiyHgUlfW.js
@@ -0,0 +1,2 @@
+if (args.test.item && args.test.item.name == game.i18n.localize("NAME.ConsumeAlcohol"))
+ args.test.preData.canReverse = true
\ No newline at end of file
diff --git a/scripts/oWa7RkScnl6lR5vd.js b/scripts/oWa7RkScnl6lR5vd.js
new file mode 100644
index 0000000..cba5818
--- /dev/null
+++ b/scripts/oWa7RkScnl6lR5vd.js
@@ -0,0 +1,11 @@
+if (args.test.characteristicKey == "wp")
+{
+ if (args.test.failed)
+ {
+ let item = await fromUuid("Compendium.wfrp4e-core.items.AGcJl5rHjkyIQBPP")
+ let data = item.toObject();
+ this.actor.createEmbeddedDocuments("Item", [data])
+
+ this.script.scriptMessage(`Willpower Test failed, ${this.actor.prototypeToken.name} gains @UUID[Compendium.wfrp4e-core.items.AGcJl5rHjkyIQBPP] for [[1d10]] hours`)
+ }
+}
\ No newline at end of file
diff --git a/scripts/obIXhQXKFyyQoNNV.js b/scripts/obIXhQXKFyyQoNNV.js
new file mode 100644
index 0000000..2df4ad3
--- /dev/null
+++ b/scripts/obIXhQXKFyyQoNNV.js
@@ -0,0 +1,7 @@
+this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {appendTitle: ` - ${this.effect.name}`, fields: { difficulty: "average" } }).then(async test => {
+ await test.roll()
+ if (test.failed) {
+ this.actor.modifyWounds(-1);
+ this.script.scriptMessage("Takes 1 Damage")
+ }
+})
\ No newline at end of file
diff --git a/scripts/ocBW3osTFnb5JCfe.js b/scripts/ocBW3osTFnb5JCfe.js
new file mode 100644
index 0000000..59d46c5
--- /dev/null
+++ b/scripts/ocBW3osTFnb5JCfe.js
@@ -0,0 +1,3 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.MVI0lXcg6vvtooAF")
+let data = item.toObject()
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
diff --git a/scripts/ofddAHvzn1xUueSG.js b/scripts/ofddAHvzn1xUueSG.js
new file mode 100644
index 0000000..1b43518
--- /dev/null
+++ b/scripts/ofddAHvzn1xUueSG.js
@@ -0,0 +1,15 @@
+args.AP.head.value -= tinDifference(args.AP.head.layers)
+args.AP.body.value -= tinDifference(args.AP.body.layers)
+args.AP.lArm.value -= tinDifference(args.AP.lArm.layers)
+args.AP.rArm.value -= tinDifference(args.AP.rArm.layers)
+args.AP.rLeg.value -= tinDifference(args.AP.rLeg.layers)
+args.AP.lLeg.value -= tinDifference(args.AP.lLeg.layers)
+
+function tinDifference(layers)
+{
+ let metalAP = layers.filter(i => i.metal).reduce((prev, current) => prev + current.value, 0)
+
+ let tinAP = layers.filter(i => i.metal).reduce((prev, current) => prev + Math.max(0, current.value - 2), 0)
+
+ return metalAP - tinAP;
+}
\ No newline at end of file
diff --git a/scripts/ogJBAXTXyhTqACPO.js b/scripts/ogJBAXTXyhTqACPO.js
new file mode 100644
index 0000000..2b4b34e
--- /dev/null
+++ b/scripts/ogJBAXTXyhTqACPO.js
@@ -0,0 +1 @@
+return args.item?.system.attackType != "melee"
\ No newline at end of file
diff --git a/scripts/ohl803m0tUwNfKAk.js b/scripts/ohl803m0tUwNfKAk.js
new file mode 100644
index 0000000..c503b57
--- /dev/null
+++ b/scripts/ohl803m0tUwNfKAk.js
@@ -0,0 +1,4 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.pLW9SVX0TVTYPiPv")
+let data = item.toObject();
+data.system.specification.value = 5 - this.actor.characteristics.s.bonus
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/okW06V9UiPC4Vcrn.js b/scripts/okW06V9UiPC4Vcrn.js
new file mode 100644
index 0000000..f8d4264
--- /dev/null
+++ b/scripts/okW06V9UiPC4Vcrn.js
@@ -0,0 +1,86 @@
+let characteristics = {
+ "ws" : 5,
+ "bs" : 0,
+ "s" : 5,
+ "t" : 5,
+ "i" : 10,
+ "ag" : 0,
+ "dex" : 0,
+ "int" : 0,
+ "wp" : 5,
+ "fel" : 5
+}
+let skills = ["Cool", "Dodge"]
+let skillAdvancements = [10, 10]
+let talents = ["Combat Reflexes", "Resolute"]
+let trappings = ["Leather Jack", "Leather Leggings", "Leather Skullcap", "Hand Weapon", "Spear", "Shield"]
+let items = [];
+
+let updateObj = this.actor.toObject();
+
+for (let ch in characteristics)
+{
+ updateObj.system.characteristics[ch].modifier += characteristics[ch];
+}
+
+for (let index = 0; index < skills.length; index++)
+{
+ let skill = skills[index]
+ let skillItem;
+ skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill")
+ if (skillItem)
+ skillItem.system.advances.value += skillAdvancements[index]
+ else
+ {
+ skillItem = await game.wfrp4e.utility.findSkill(skill)
+ skillItem = skillItem.toObject();
+ skillItem.system.advances.value = skillAdvancements[index];
+ items.push(skillItem);
+ }
+}
+
+for (let talent of talents)
+{
+ let talentItem = await game.wfrp4e.utility.findTalent(talent)
+ if (talentItem)
+ {
+ items.push(talentItem.toObject());
+ }
+ else
+ {
+ ui.notifications.warn(`Could not find ${talent}`, {permanent : true})
+ }
+}
+
+for (let trapping of trappings)
+{
+ let trappingItem = await game.wfrp4e.utility.findItem(trapping)
+ if (trappingItem)
+ {
+ trappingItem = trappingItem.toObject()
+
+ equip(trappingItem)
+
+ items.push(trappingItem);
+ }
+ else
+ {
+ ui.notifications.warn(`Could not find ${trapping}`, {permanent : true})
+ }
+}
+
+updateObj.name = updateObj.name += " " + this.effect.name
+
+await this.actor.update(updateObj)
+this.actor.createEmbeddedDocuments("Item", items);
+
+
+function equip(item)
+{
+ if (item.type == "armour")
+ item.system.worn.value = true
+ else if (item.type == "weapon")
+ item.system.equipped = true
+ else if (item.type == "trapping" && item.system.trappingType.value == "clothingAccessories")
+ item.system.worn = true
+}
\ No newline at end of file
diff --git a/scripts/okr3TtzpFoefUuJS.js b/scripts/okr3TtzpFoefUuJS.js
new file mode 100644
index 0000000..ef551e2
--- /dev/null
+++ b/scripts/okr3TtzpFoefUuJS.js
@@ -0,0 +1,4 @@
+let item = await fromUuid('Compendium.wfrp4e-core.items.EaqlLRQigwnsEAXX')
+let data = item.toObject();
+data.system.location.value = "Collar Bone"
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/oqgd9G6oI1ncPYLw.js b/scripts/oqgd9G6oI1ncPYLw.js
new file mode 100644
index 0000000..067d1ec
--- /dev/null
+++ b/scripts/oqgd9G6oI1ncPYLw.js
@@ -0,0 +1,2 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.CV9btQn09S9Fn8Jk");
+this.actor.createEmbeddedDocuments("Item", [item.toObject()], {fromEffect : this.effect.id});
\ No newline at end of file
diff --git a/scripts/p222EiR8RRtlPm31.js b/scripts/p222EiR8RRtlPm31.js
new file mode 100644
index 0000000..f757919
--- /dev/null
+++ b/scripts/p222EiR8RRtlPm31.js
@@ -0,0 +1,3 @@
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "hard"}})
+await test.roll();
+return test.failed;
\ No newline at end of file
diff --git a/scripts/pAgiAGyaLJY10894.js b/scripts/pAgiAGyaLJY10894.js
new file mode 100644
index 0000000..13da9da
--- /dev/null
+++ b/scripts/pAgiAGyaLJY10894.js
@@ -0,0 +1 @@
+return args.skill?.name == game.i18n.localize("NAME.Charm");
\ No newline at end of file
diff --git a/scripts/pBMioPUtDn1mk9f5.js b/scripts/pBMioPUtDn1mk9f5.js
new file mode 100644
index 0000000..a13d279
--- /dev/null
+++ b/scripts/pBMioPUtDn1mk9f5.js
@@ -0,0 +1,3 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.5KP9sOoLSGvj9EXp")
+let data = item.toObject();
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id});
\ No newline at end of file
diff --git a/scripts/pG5OVokZzCRHIrwz.js b/scripts/pG5OVokZzCRHIrwz.js
new file mode 100644
index 0000000..cf36c5e
--- /dev/null
+++ b/scripts/pG5OVokZzCRHIrwz.js
@@ -0,0 +1,3 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.mgeiaDZXei7JBEgo")
+let data = item.toObject();
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/pHyXdPnWwoFrUA5n.js b/scripts/pHyXdPnWwoFrUA5n.js
new file mode 100644
index 0000000..954e03e
--- /dev/null
+++ b/scripts/pHyXdPnWwoFrUA5n.js
@@ -0,0 +1 @@
+return !args.skill?.name.includes(game.i18n.localize("NAME.Entertain"));
\ No newline at end of file
diff --git a/scripts/pLKv4moua6XhNdmA.js b/scripts/pLKv4moua6XhNdmA.js
new file mode 100644
index 0000000..edd666b
--- /dev/null
+++ b/scripts/pLKv4moua6XhNdmA.js
@@ -0,0 +1,4 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.1dUizIgLBgn4jICC");
+let data = item.toObject();
+data.name += " (Woodlands)";
+this.actor.createEmbeddedDocuments("Item", Array(this.effect.sourceTest.result.overcast.usage.other.current).fill(data), {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/pNPjXEoQGHLKzq0r.js b/scripts/pNPjXEoQGHLKzq0r.js
new file mode 100644
index 0000000..26641f9
--- /dev/null
+++ b/scripts/pNPjXEoQGHLKzq0r.js
@@ -0,0 +1,12 @@
+let talent = this.actor.has("Arcane Magic (Light)", "talent")
+let demon = this.actor.has(game.i18n.localize("NAME.Daemonic"))
+
+if (!talent)
+{
+ await this.actor.addCondition("blinded")
+}
+
+if (demon)
+{
+ await this.actor.addCondition("stunned")
+}
\ No newline at end of file
diff --git a/scripts/pPV9oEydXb7oi6jX.js b/scripts/pPV9oEydXb7oi6jX.js
new file mode 100644
index 0000000..fe3715e
--- /dev/null
+++ b/scripts/pPV9oEydXb7oi6jX.js
@@ -0,0 +1,4 @@
+ if (args.totalWoundLoss > 0)
+ {
+ args.actor.addCondition('ablaze')
+ }
\ No newline at end of file
diff --git a/scripts/pR4Q2OnPxXtwRVli.js b/scripts/pR4Q2OnPxXtwRVli.js
new file mode 100644
index 0000000..31251d6
--- /dev/null
+++ b/scripts/pR4Q2OnPxXtwRVli.js
@@ -0,0 +1,12 @@
+let criticals = this.actor.itemTypes.critical;
+
+if (criticals.length)
+{
+ this.script.scriptNotification("Cannot suffer Critical Wounds");
+ this.actor.deleteEmbeddedDocuments("Item", criticals.map(i => i.id))
+}
+
+if (getProperty(args.data, "system.status.wounds.value") == 0)
+{
+ this.script.scriptNotification(`Dormant for ${Math.ceil(CONFIG.Dice.randomUniform() * 10)} Rounds`)
+}
\ No newline at end of file
diff --git a/scripts/pnB9TzSEytkxk3Rb.js b/scripts/pnB9TzSEytkxk3Rb.js
new file mode 100644
index 0000000..33f3dcc
--- /dev/null
+++ b/scripts/pnB9TzSEytkxk3Rb.js
@@ -0,0 +1 @@
+return this.actor.hasSystemEffect("infighting")
\ No newline at end of file
diff --git a/scripts/pq1YQffxtOcqCRTn.js b/scripts/pq1YQffxtOcqCRTn.js
new file mode 100644
index 0000000..b6f09a8
--- /dev/null
+++ b/scripts/pq1YQffxtOcqCRTn.js
@@ -0,0 +1,6 @@
+let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {appendTitle: ` - ${this.effect.name}`})
+await test.roll();
+if (!test.succeeded)
+{
+ this.actor.addCondition("prone")
+}
\ No newline at end of file
diff --git a/scripts/px7eEdhOEt7zOTrq.js b/scripts/px7eEdhOEt7zOTrq.js
new file mode 100644
index 0000000..0e4b4f9
--- /dev/null
+++ b/scripts/px7eEdhOEt7zOTrq.js
@@ -0,0 +1 @@
+return ["int", "t", "wp", "i"].includes(args.characteristic)
\ No newline at end of file
diff --git a/scripts/pzimrxrqpv282Oqb.js b/scripts/pzimrxrqpv282Oqb.js
new file mode 100644
index 0000000..6c30f0d
--- /dev/null
+++ b/scripts/pzimrxrqpv282Oqb.js
@@ -0,0 +1,2 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.TaYriYcJkFuIdBKp")
+this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id});
diff --git a/scripts/pzknBcJtZWeliE27.js b/scripts/pzknBcJtZWeliE27.js
new file mode 100644
index 0000000..1fcf80e
--- /dev/null
+++ b/scripts/pzknBcJtZWeliE27.js
@@ -0,0 +1 @@
+return args.item?.name == game.i18n.localize("NAME.Leadership") || args.item?.name == game.i18n.localize("NAME.Cool")
\ No newline at end of file
diff --git a/scripts/q0LvphC8RDSyR0oY.js b/scripts/q0LvphC8RDSyR0oY.js
new file mode 100644
index 0000000..3e6ac9e
--- /dev/null
+++ b/scripts/q0LvphC8RDSyR0oY.js
@@ -0,0 +1,8 @@
+let choice = await ItemDialog.create(ItemDialog.objectToArray({
+ ws : game.wfrp4e.config.characteristics.ws,
+ t : game.wfrp4e.config.characteristics.t,
+ ag : game.wfrp4e.config.characteristics.ag,
+ wp : game.wfrp4e.config.characteristics.wp
+}, this.effect.img), 1, "Choose Characteristic");
+
+this.effect.updateSource({"flags.wfrp4e.characteristic" : choice[0].id})
\ No newline at end of file
diff --git a/scripts/q3nRyXaxksdCiLFM.js b/scripts/q3nRyXaxksdCiLFM.js
new file mode 100644
index 0000000..49cee4f
--- /dev/null
+++ b/scripts/q3nRyXaxksdCiLFM.js
@@ -0,0 +1,3 @@
+let item = await fromUuid("Compendium.wfrp4e-core.items.j6v78dnOOdCB6c3d")
+let data = item.toObject();
+this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/qAEZgtu5CrfUkxhx.js b/scripts/qAEZgtu5CrfUkxhx.js
new file mode 100644
index 0000000..c5c12b1
--- /dev/null
+++ b/scripts/qAEZgtu5CrfUkxhx.js
@@ -0,0 +1,16 @@
+if (args.test.options.staunchBleeding)
+{
+ if (args.test.succeeded)
+ {
+ let staunch = Number(args.test.result.SL) + 1
+ if (args.test.options.fieldDressing && args.test.result.reversed)
+ {
+ staunch = Math.min(1, Number(args.test.result.SL)) + 1
+ }
+ args.test.result.other.push(`${this.actor.name} removed ${staunch} Bleeding conditions from the patient.`)
+ }
+ else if (this.actor.characteristics.int.bonus + Number(args.test.result.SL) < 0)
+ {
+ args.test.result.other.push(`The patient contracts a @UUID[Compendium.wfrp4e-core.items.Item.1hQuVFZt9QnnbWzg]{Minor Infection}.`)
+ }
+}
\ No newline at end of file
diff --git a/scripts/qK4q4o6cQhcGzFX3.js b/scripts/qK4q4o6cQhcGzFX3.js
new file mode 100644
index 0000000..e7c6e3b
--- /dev/null
+++ b/scripts/qK4q4o6cQhcGzFX3.js
@@ -0,0 +1,7 @@
+let fear = await fromUuid("Compendium.wfrp4e-core.items.Item.pTorrE0l3VybAbtn")
+let leader = await fromUuid("Compendium.wfrp4e-core.items.Item.vCgEAetBMngR53aT")
+let fearData = fear.toObject();
+let leaderData = leader.toObject();
+fearData.system.specification.value = this.effect.sourceTest.result.overcast.usage.other.current;
+talents = new Array(1 + this.effect.sourceTest.result.overcast.available).fill(leaderData); // Assume any unused overcast is for war leader
+this.actor.createEmbeddedDocuments("Item", [fearData].concat(talents), {fromEffect : this.effect.id})
\ No newline at end of file
diff --git a/scripts/qSwCYMMiIHmSV1X5.js b/scripts/qSwCYMMiIHmSV1X5.js
new file mode 100644
index 0000000..1379278
--- /dev/null
+++ b/scripts/qSwCYMMiIHmSV1X5.js
@@ -0,0 +1,13 @@
+if (this.item.system.quantity.value)
+{
+ this.item.system.reduceQuantity();
+ let actor = Array.from(game.user.targets)[0]?.actor || this.actor;
+ let effectData = this.item.effects.contents[0].convertToApplied();
+ effectData.flags.wfrp4e.sourceItem = this.item.uuid
+ effectData.duration.seconds = 10800
+ actor.applyEffect({effectData : [effectData]})
+}
+else
+{
+ this.script.scriptNotification("None left!", "error")
+}
\ No newline at end of file
diff --git a/scripts/qT0WBPxLMMO9gvCd.js b/scripts/qT0WBPxLMMO9gvCd.js
new file mode 100644
index 0000000..fd89c3b
--- /dev/null
+++ b/scripts/qT0WBPxLMMO9gvCd.js
@@ -0,0 +1,4 @@
+if (!this.actor.has("Night Vision") && !this.actor.has("Night Vision", "talent") && !this.actor.hasCondition("blinded"))
+{
+ this.actor.addCondition("blinded", 1, {"flags.wfrp4e.nightshroud" : true})
+}
\ No newline at end of file
diff --git a/scripts/qUwnVlWpsmDom3RK.js b/scripts/qUwnVlWpsmDom3RK.js
new file mode 100644
index 0000000..e82109e
--- /dev/null
+++ b/scripts/qUwnVlWpsmDom3RK.js
@@ -0,0 +1 @@
+args.fields.modifier -= 5;
\ No newline at end of file
diff --git a/scripts/qZschZU0nee0kJlk.js b/scripts/qZschZU0nee0kJlk.js
new file mode 100644
index 0000000..0064f3f
--- /dev/null
+++ b/scripts/qZschZU0nee0kJlk.js
@@ -0,0 +1 @@
+args.fields.modifier -= 30;
\ No newline at end of file
diff --git a/scripts/qaVde0sTuMBRi2nl.js b/scripts/qaVde0sTuMBRi2nl.js
new file mode 100644
index 0000000..2bd32fd
--- /dev/null
+++ b/scripts/qaVde0sTuMBRi2nl.js
@@ -0,0 +1 @@
+return ["NAME.Evaluate", "NAME.Gamble"].map(i => game.i18n.localize(i)).includes(args.skill?.name)
\ No newline at end of file
diff --git a/scripts/qcyl98GYD55BkJsD.js b/scripts/qcyl98GYD55BkJsD.js
new file mode 100644
index 0000000..510b62f
--- /dev/null
+++ b/scripts/qcyl98GYD55BkJsD.js
@@ -0,0 +1,2 @@
+this.actor.status.encumbrance.state = 0;
+this.actor.status.encumbrance.pct = 0;
\ No newline at end of file
diff --git a/scripts/qijgjcOBCDmhglRX.js b/scripts/qijgjcOBCDmhglRX.js
new file mode 100644
index 0000000..49dfaeb
--- /dev/null
+++ b/scripts/qijgjcOBCDmhglRX.js
@@ -0,0 +1 @@
+return args.skill?.name == game.i18n.localize("NAME.SleightOfHand");
\ No newline at end of file
diff --git a/scripts/qjli5evn8UA9uTeZ.js b/scripts/qjli5evn8UA9uTeZ.js
new file mode 100644
index 0000000..4f6fabe
--- /dev/null
+++ b/scripts/qjli5evn8UA9uTeZ.js
@@ -0,0 +1 @@
+return args.actor.uuid == this.effect.sourceActor.uuid;
\ No newline at end of file
diff --git a/scripts/qmOt7h17hGAKqQe0.js b/scripts/qmOt7h17hGAKqQe0.js
new file mode 100644
index 0000000..cd2dd07
--- /dev/null
+++ b/scripts/qmOt7h17hGAKqQe0.js
@@ -0,0 +1,24 @@
+
+let choice = await Dialog.wait({
+ title: this.effect.name,
+ content: `
${this.effect.name}: Is this a ranged or magical attack that orignates outside the Dome?
`, + buttons: { + yes: { + label: "Yes", + callback: () => { + return true; + } + }, + no: { + label: "No", + callback: () => { + return false; + } + } + } +}) + +if (choice) +{ + args.ward = 6; +} \ No newline at end of file diff --git a/scripts/qu194dVXm9Vx1TGk.js b/scripts/qu194dVXm9Vx1TGk.js new file mode 100644 index 0000000..c99393f --- /dev/null +++ b/scripts/qu194dVXm9Vx1TGk.js @@ -0,0 +1,10 @@ +if (args.test.options.useOnesSupportive && (args.test.result.roll <= game.settings.get("wfrp4e", "automaticSuccess") || args.test.result.roll <= args.test.target)) +{ + +let SL = Math.floor(args.test.target / 10) - Math.floor(args.test.result.roll / 10) +let ones = Number(args.test.result.roll.toString().split("").pop()) + +if (ones > SL) + args.test.data.result.SL = "+" + (ones + args.test.successBonus + args.test.slBonus) + args.test.result.other.push(`${this.effect.name}: Used unit dice as SL`) +} \ No newline at end of file diff --git a/scripts/quPcuKsq2fcild4a.js b/scripts/quPcuKsq2fcild4a.js new file mode 100644 index 0000000..3ebda0b --- /dev/null +++ b/scripts/quPcuKsq2fcild4a.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty: "easy"}, context: {failure : `${this.effect.name}: Vomit!`} }) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("prone") +} \ No newline at end of file diff --git a/scripts/qxzhPtysAjPWspKf.js b/scripts/qxzhPtysAjPWspKf.js new file mode 100644 index 0000000..934561e --- /dev/null +++ b/scripts/qxzhPtysAjPWspKf.js @@ -0,0 +1,4 @@ +if (this.actor.has("Undead") || this.actor.has("Daemonic")) +{ + this.script.scriptNotification(`Cannot enter ${this.effect.name}!`); +} \ No newline at end of file diff --git a/scripts/r6hi5vMdLhTaaPfb.js b/scripts/r6hi5vMdLhTaaPfb.js new file mode 100644 index 0000000..c37780d --- /dev/null +++ b/scripts/r6hi5vMdLhTaaPfb.js @@ -0,0 +1 @@ +args.actor.details.move.value += this.effect.sourceTest.result.overcast.usage.other.current \ No newline at end of file diff --git a/scripts/rCh3ltUrUMovd2Kc.js b/scripts/rCh3ltUrUMovd2Kc.js new file mode 100644 index 0000000..4b1b1b1 --- /dev/null +++ b/scripts/rCh3ltUrUMovd2Kc.js @@ -0,0 +1,5 @@ +if (this.actor.hasCondition("surprised")) +{ + this.script.scriptNotification("Cannot be surprised"); + this.actor.removeCondition("surprised"); +} \ No newline at end of file diff --git a/scripts/rF0Z3hTUUnSxL3Mq.js b/scripts/rF0Z3hTUUnSxL3Mq.js new file mode 100644 index 0000000..93d9ab0 --- /dev/null +++ b/scripts/rF0Z3hTUUnSxL3Mq.js @@ -0,0 +1,37 @@ +let armour = (await fromUuid("Compendium.wfrp4e-core.items.VUJUZVN3VYhOaPjj")).toObject() +let bite = (await fromUuid("Compendium.wfrp4e-core.items.pLW9SVX0TVTYPiPv")).toObject() +let fear = (await fromUuid("Compendium.wfrp4e-core.items.pTorrE0l3VybAbtn")).toObject() +let nightVision = (await fromUuid("Compendium.wfrp4e-core.items.FmHDbCOy3pH8yKhm")).toObject() +let tracker = (await fromUuid("Compendium.wfrp4e-core.items.ClOlztW6hH8rslbp")).toObject() +let weapon = (await fromUuid("Compendium.wfrp4e-core.items.AtpAudHA4ybXVlWM")).toObject() + +armour.name = "Armour (Hide)" +armour.system.specification.value = 2 +bite.system.specification.value = 3 +fear.system.specification.value = 2 +weapon.system.specification.value = 4 +let items = [armour, bite, fear, nightVision, tracker, weapon] + + +let belligerent = (await fromUuid("Compendium.wfrp4e-core.items.GbDyBCu8ZjDp6dkj")).toObject()//{Belligerent} +let bestial = (await fromUuid("Compendium.wfrp4e-core.items.AGcJl5rHjkyIQBPP")).toObject()//{Bestial} +let big = (await fromUuid("Compendium.wfrp4e-core.items.a8MC97PLzl10WocT")).toObject()//{Big} +let blessed = (await fromUuid("Compendium.wfrp4e-core.items.5muSFXd6oc760uVj")).toObject()//{Blessed (Ulric)} +let champion = (await fromUuid("Compendium.wfrp4e-core.items.4mF5Sp3t09kZhBYc")).toObject()//{Champion} +let die = (await fromUuid("Compendium.wfrp4e-core.items.UsJ2uIOOtHA7JqD5")).toObject()//{Die Hard} +let fast = (await fromUuid("Compendium.wfrp4e-core.items.9MjH4xyVrd3Inzak")).toObject()//{Fast} +let frenzy = (await fromUuid("Compendium.wfrp4e-core.items.yRhhOlt18COq4e1q")).toObject()//{Frenzy} +let immunity = (await fromUuid("Compendium.wfrp4e-core.items.IAWyzDfC286a9MPz")).toObject()//{Immunity to Psychology} +let regenerate = (await fromUuid("Compendium.wfrp4e-core.items.SfUUdOGjdYpr3KSR")).toObject()//{Regenerate} +let size = (await fromUuid("Compendium.wfrp4e-core.items.8slW8CJ2oVTxeQ6q")).toObject()//{Size (Large)} + +blessed.system.specification.value = "Ulric" +size.system.specification.value = "Large" + +let optional = [belligerent, bestial, big, blessed, champion, die, fast, frenzy, immunity, regenerate, size]; + +let chosen = await ItemDialog.create(optional, "unlimited", "Choose Optional Traits"); + +items = items.concat(chosen || []) +this.script.scriptNotification(`Adding ${items.map(i => i.name).join(", ")}`); +this.actor.createEmbeddedDocuments("Item", items, {fromEffect : this.effect.id}) diff --git a/scripts/rIISfbCShejmJNKw.js b/scripts/rIISfbCShejmJNKw.js new file mode 100644 index 0000000..d2d5e54 --- /dev/null +++ b/scripts/rIISfbCShejmJNKw.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.oRx92ByVNEBN6YkK") +let data = item.toObject() +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) diff --git a/scripts/rLMaVNEGdZ6xj5Au.js b/scripts/rLMaVNEGdZ6xj5Au.js new file mode 100644 index 0000000..bf2dfbe --- /dev/null +++ b/scripts/rLMaVNEGdZ6xj5Au.js @@ -0,0 +1 @@ +return !["i", "int", "fel"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/rRfff55c7elyvbCb.js b/scripts/rRfff55c7elyvbCb.js new file mode 100644 index 0000000..9756192 --- /dev/null +++ b/scripts/rRfff55c7elyvbCb.js @@ -0,0 +1 @@ +return this.actor.flags.useless[this.item.system.location.key] && args.weapon?.system.usesHands.includes(this.item.system.location.key[0] + "Arm") \ No newline at end of file diff --git a/scripts/rUGSx06BuBvX9kgf.js b/scripts/rUGSx06BuBvX9kgf.js new file mode 100644 index 0000000..8c3a76f --- /dev/null +++ b/scripts/rUGSx06BuBvX9kgf.js @@ -0,0 +1,9 @@ +if (args.test.result.charging) +{ + args.test.result.damage += 1 + args.test.result.additionalDamage += 1 + if (!args.test.result.resolute) { + args.test.result.breakdown.damage.other.push({label : this.effect.name, value : this.item.Advances}); + args.test.result.resolute = true // Prevent duplicate messages + } +} diff --git a/scripts/rVpPNILEzWL9lj6b.js b/scripts/rVpPNILEzWL9lj6b.js new file mode 100644 index 0000000..6007696 --- /dev/null +++ b/scripts/rVpPNILEzWL9lj6b.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.kJNAY1YRaCy9IgmT") +let terrorTraitItem = item.toObject() +terrorTraitItem.system.specification.value = Number(this.effect.item.system.specification.value) +this.actor.createEmbeddedDocuments("Item", [terrorTraitItem]); \ No newline at end of file diff --git a/scripts/rXMylpnEtZpwou6x.js b/scripts/rXMylpnEtZpwou6x.js new file mode 100644 index 0000000..d0c2d7f --- /dev/null +++ b/scripts/rXMylpnEtZpwou6x.js @@ -0,0 +1,8 @@ +this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty : "average"}}).then(async test => +{ + await test.roll() + if (test.failed) + { + this.actor.addCondition("fatigued") + } +}) \ No newline at end of file diff --git a/scripts/ramav4ymrDDkPKK4.js b/scripts/ramav4ymrDDkPKK4.js new file mode 100644 index 0000000..639558d --- /dev/null +++ b/scripts/ramav4ymrDDkPKK4.js @@ -0,0 +1,9 @@ +if (this.actor.hasCondition("bleeding")) +{ + this.actor.removeCondition("bleeding"); + this.script.scriptNotification("Removed 1 Bleeding Condition") +} +else +{ + this.script.scriptNotification("No Bleeding Conditions"); +} \ No newline at end of file diff --git a/scripts/ratP9ByLjQPiLlFK.js b/scripts/ratP9ByLjQPiLlFK.js new file mode 100644 index 0000000..5e33cd1 --- /dev/null +++ b/scripts/ratP9ByLjQPiLlFK.js @@ -0,0 +1 @@ +args.data.canReverse = true \ No newline at end of file diff --git a/scripts/rdaMhMyHrJjQ6vVC.js b/scripts/rdaMhMyHrJjQ6vVC.js new file mode 100644 index 0000000..f5d1678 --- /dev/null +++ b/scripts/rdaMhMyHrJjQ6vVC.js @@ -0,0 +1 @@ +game.wfrp4e.utility.postFear(this.item.Advances, this.actor.name) \ No newline at end of file diff --git a/scripts/re1UFtxvRRjpPB7Z.js b/scripts/re1UFtxvRRjpPB7Z.js new file mode 100644 index 0000000..332391e --- /dev/null +++ b/scripts/re1UFtxvRRjpPB7Z.js @@ -0,0 +1,13 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.nF5z1OEhpi4t6a6S"); +let data = item.toObject(); +data.system.location.key = this.item.system.location.key +if (data.system.location.key[0] == "r") +{ + data.system.location.value = "Right Ankle" +} +else if (data.system.location.key[0] == "l") +{ + data.system.location.value = "Left Ankle" +} + +this.actor.createEmbeddedDocuments("Item", [data], {skipLocationValue : true, fromEffect: this.effect.id}) diff --git a/scripts/red2bt4PGgIWAdTR.js b/scripts/red2bt4PGgIWAdTR.js new file mode 100644 index 0000000..c4ba998 --- /dev/null +++ b/scripts/red2bt4PGgIWAdTR.js @@ -0,0 +1,14 @@ +if (this.item.system.quantity.value) +{ + this.item.system.reduceQuantity(); + let actor = Array.from(game.user.targets)[0]?.actor || this.actor; + let effectData = this.item.effects.contents[0].convertToApplied(); + let minutes = Math.ceil(CONFIG.Dice.randomUniform() * 10) * 10; + effectData.duration.seconds = 60 * minutes + this.script.scriptMessage(`Duration: ${minutes} minutes`, {whisper : ChatMessage.getWhisperRecipients("GM")}) + actor.applyEffect({effectData : [effectData]}) +} +else +{ + this.script.scriptNotification("None left!", "error") +} \ No newline at end of file diff --git a/scripts/rgSwSeB3shIMVMb6.js b/scripts/rgSwSeB3shIMVMb6.js new file mode 100644 index 0000000..2532014 --- /dev/null +++ b/scripts/rgSwSeB3shIMVMb6.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.x0WMGwuQzReXcQrs") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}); \ No newline at end of file diff --git a/scripts/rnioLwiJP7ps5Jwy.js b/scripts/rnioLwiJP7ps5Jwy.js new file mode 100644 index 0000000..7163d7f --- /dev/null +++ b/scripts/rnioLwiJP7ps5Jwy.js @@ -0,0 +1,4 @@ +if (args.item.type == "skill" && args.item.name == "Melee (Basic)") +{ + args.item.system.modifier.value += 30; +} \ No newline at end of file diff --git a/scripts/roKvPHDSpX4IV11C.js b/scripts/roKvPHDSpX4IV11C.js new file mode 100644 index 0000000..2210782 --- /dev/null +++ b/scripts/roKvPHDSpX4IV11C.js @@ -0,0 +1 @@ +return !args.skill?.name.includes(game.i18n.localize("NAME.Perform")) && args.characteristic != "ag" \ No newline at end of file diff --git a/scripts/rpxQU26BU7nwjtqY.js b/scripts/rpxQU26BU7nwjtqY.js new file mode 100644 index 0000000..85e811c --- /dev/null +++ b/scripts/rpxQU26BU7nwjtqY.js @@ -0,0 +1,20 @@ +let location = this.item.system.location.key +let test = await this.actor.setupCharacteristic("dex", {context : {failure : `${this.effect.name}: Drop the item!`}, skipTargets: true, appendTitle : " - " + this.effect.name, fields : {difficulty : "average"}}) +await test.roll(); + + +if (location && test.failed) +{ + let dropped = this.item.system.weaponsAtLocation; + + if (dropped.length) + { + this.script.scriptNotification(`Dropped ${dropped.map(i => i.name).join(", ")}!`) + for(let weapon of dropped) + { + await weapon.system.toggleEquip(); + } + } +} + +return test.succeeded \ No newline at end of file diff --git a/scripts/rr4htuVq45onXdRG.js b/scripts/rr4htuVq45onXdRG.js new file mode 100644 index 0000000..e494852 --- /dev/null +++ b/scripts/rr4htuVq45onXdRG.js @@ -0,0 +1,2 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {appendTitle: ` - ${this.effect.name}`, fields : {difficulty : "average"}}) +test.roll(); \ No newline at end of file diff --git a/scripts/rxB1AqfVMDqTRieE.js b/scripts/rxB1AqfVMDqTRieE.js new file mode 100644 index 0000000..132e672 --- /dev/null +++ b/scripts/rxB1AqfVMDqTRieE.js @@ -0,0 +1 @@ +return !["ws", "bs", "ag"].includes(args.characteristic) && args.skill?.name != game.i18n.localize("NAME.Perception") \ No newline at end of file diff --git a/scripts/s0kTuDE0qv68V2KI.js b/scripts/s0kTuDE0qv68V2KI.js new file mode 100644 index 0000000..3f54ebc --- /dev/null +++ b/scripts/s0kTuDE0qv68V2KI.js @@ -0,0 +1 @@ + this.actor.getActiveTokens().forEach(t => t.document.update({texture : {tint : "#FFBF00"}})); diff --git a/scripts/s5bO0Sf0qpS27Tve.js b/scripts/s5bO0Sf0qpS27Tve.js new file mode 100644 index 0000000..81a8160 --- /dev/null +++ b/scripts/s5bO0Sf0qpS27Tve.js @@ -0,0 +1,2 @@ +await args.actor.addCondition("ablaze", 3) +await args.actor.addCondition("prone"); \ No newline at end of file diff --git a/scripts/s6eZXfZkC1My6EXl.js b/scripts/s6eZXfZkC1My6EXl.js new file mode 100644 index 0000000..79d1abc --- /dev/null +++ b/scripts/s6eZXfZkC1My6EXl.js @@ -0,0 +1,5 @@ +let lore = this.effect.name.split(" ")[2].toLowerCase(); +if (args.item.type == "spell" && args.item.system.lore.value == lore) +{ + args.item.system.cn.value -= 1 +} diff --git a/scripts/s7gJQdzuM3fz2zQK.js b/scripts/s7gJQdzuM3fz2zQK.js new file mode 100644 index 0000000..86e431a --- /dev/null +++ b/scripts/s7gJQdzuM3fz2zQK.js @@ -0,0 +1,11 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.QluSTTTq3viHJJUh") +let data = item.toObject(); +data.system.location.value = "Hip" +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) + +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("prone") +} \ No newline at end of file diff --git a/scripts/s8idWt9YdMTRfnjV.js b/scripts/s8idWt9YdMTRfnjV.js new file mode 100644 index 0000000..ffe18b2 --- /dev/null +++ b/scripts/s8idWt9YdMTRfnjV.js @@ -0,0 +1,5 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.BqPZn6q3VHn9HUrW") +let data = item.toObject(); +data.system.specification.value = 4 - this.actor.characteristics.s.bonus +data.name = item.name.replace("(Feature)", ""); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/s8xU6OOZbbfo6VIw.js b/scripts/s8xU6OOZbbfo6VIw.js new file mode 100644 index 0000000..4574772 --- /dev/null +++ b/scripts/s8xU6OOZbbfo6VIw.js @@ -0,0 +1 @@ +args.fields.slBonus += this.actor.system.characteristics.ag.bonus diff --git a/scripts/s94yKZ4o5XN4JWM1.js b/scripts/s94yKZ4o5XN4JWM1.js new file mode 100644 index 0000000..28925d7 --- /dev/null +++ b/scripts/s94yKZ4o5XN4JWM1.js @@ -0,0 +1,6 @@ +// Any attack with such ammunition which inflicts at least one Wound, +// also inflicts one Bleeding Condition. + +if (args.totalWoundLoss > 0) { + args.actor.addCondition("bleeding") +} diff --git a/scripts/sAVpm7hFRHpbCLXm.js b/scripts/sAVpm7hFRHpbCLXm.js new file mode 100644 index 0000000..88f9ad9 --- /dev/null +++ b/scripts/sAVpm7hFRHpbCLXm.js @@ -0,0 +1 @@ +return ["ws", "bs", "s", "t", "ag", "i"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/sB4KB9bT3nQhAoqG.js b/scripts/sB4KB9bT3nQhAoqG.js new file mode 100644 index 0000000..4401b71 --- /dev/null +++ b/scripts/sB4KB9bT3nQhAoqG.js @@ -0,0 +1,14 @@ +// This script needs to be separate because equipTransfer is off on the other effect, and thus won't execute when added to an actor + +let mainEffect = this.item.effects.contents[0]; +if (mainEffect.name.includes("By imbibing this potion, ${this.actor.prototypeToken.name} has becomes subject to Frenzy. This Frenzy lasts [[1d10]] Rounds, and may not be ended sooner.
`, + {whisper: ChatMessage.getWhisperRecipients("GM"), blind: true }) \ No newline at end of file diff --git a/scripts/sYlGRLApZ3Ub24ea.js b/scripts/sYlGRLApZ3Ub24ea.js new file mode 100644 index 0000000..ee66235 --- /dev/null +++ b/scripts/sYlGRLApZ3Ub24ea.js @@ -0,0 +1 @@ +this.actor.system.status.addArmour(3, {source: this.effect.name, magical: true}) \ No newline at end of file diff --git a/scripts/sZwLitzwKBTaFca3.js b/scripts/sZwLitzwKBTaFca3.js new file mode 100644 index 0000000..4d00d6e --- /dev/null +++ b/scripts/sZwLitzwKBTaFca3.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.Item.5hH73j2NgPdsLCZN") +let data = item.toObject(); +data.name = data.name.replace("Target", "Greenskins, Undead, Chaos") +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/sagKJM6oDFlw4ED2.js b/scripts/sagKJM6oDFlw4ED2.js new file mode 100644 index 0000000..4392e3b --- /dev/null +++ b/scripts/sagKJM6oDFlw4ED2.js @@ -0,0 +1,3 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}); +await test.roll(); +return test.failed; \ No newline at end of file diff --git a/scripts/sbK1a7txpSoXFzyB.js b/scripts/sbK1a7txpSoXFzyB.js new file mode 100644 index 0000000..079b4dc --- /dev/null +++ b/scripts/sbK1a7txpSoXFzyB.js @@ -0,0 +1,10 @@ +if (args.test.options.useOnesArgumentative && (args.test.result.roll <= game.settings.get("wfrp4e", "automaticSuccess") || args.test.result.roll <= args.test.target)) +{ + +let SL = Math.floor(args.test.target / 10) - Math.floor(args.test.result.roll / 10) +let ones = Number(args.test.result.roll.toString().split("").pop()) + +if (ones > SL) + args.test.data.result.SL = "+" + (ones + args.test.successBonus + args.test.slBonus) + args.test.result.other.push(`${this.effect.name}: Used unit dice as SL`) +} \ No newline at end of file diff --git a/scripts/scfm5iWWBxWI6QaK.js b/scripts/scfm5iWWBxWI6QaK.js new file mode 100644 index 0000000..117c336 --- /dev/null +++ b/scripts/scfm5iWWBxWI6QaK.js @@ -0,0 +1,6 @@ +let darkvision = await fromUuid("Compendium.wfrp4e-core.items.Item.JQa5DLnTs2SEzRrc") +let fear = await fromUuid("Compendium.wfrp4e-core.items.Item.pTorrE0l3VybAbtn") +let acutesense = await fromUuid("Compendium.wfrp4e-core.items.Item.9h82z72XGo9tfgQS") +fear = fear.toObject(); +fear.system.specification.value = 1; +this.actor.createEmbeddedDocuments("Item", [darkvision, fear, acutesense], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/sgS9rblPkQB36C8S.js b/scripts/sgS9rblPkQB36C8S.js new file mode 100644 index 0000000..49348b1 --- /dev/null +++ b/scripts/sgS9rblPkQB36C8S.js @@ -0,0 +1,29 @@ +if (this.item.name.includes("(")) +{ + let trade = this.item.parenthesesText; + if (trade?.toLowerCase() != "any") + return this.item.updateSource({"system.tests.value" : this.item.system.tests.value.replace("any one", trade)}) +} + +let index = game.packs +.filter(i => i.metadata.type == "Item") +.reduce((acc, pack) => acc.concat(pack.index.contents), []) +.filter(i => i.type == "skill" && i.name.includes(game.i18n.localize("NAME.Trade"))) +.map(i => { + i.id = i._id + return i +}) + +let choice = await ItemDialog.create(index, 1, "Choose a Trade Skill") +let text; +if (!choice[0]) +{ + let custom = await ValueDialog.create("Enter Custom Trade Skill", "Custom Trade"); + text = custom || "" +} +else +{ + text = game.wfrp4e.utility.extractParenthesesText(choice[0].name) +} + +await this.item.updateSource({name : this.item.name.replace("(Any)", "").replace("(any)", "").trim() + ` (${text})`, "system.tests.value" : this.item.system.tests.value.replace("any one", text)}); \ No newline at end of file diff --git a/scripts/shkBUtUuMPDKvFm7.js b/scripts/shkBUtUuMPDKvFm7.js new file mode 100644 index 0000000..641a6b6 --- /dev/null +++ b/scripts/shkBUtUuMPDKvFm7.js @@ -0,0 +1,10 @@ +let test = await this.actor.setupSkill("Dodge", {fields : {difficulty : "average"}}) +let caster = this.effect.sourceActor + +let fallen = this.effect.sourceTest.result.SL + caster.characteristics.wp.bonus +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("prone") + this.script.scriptMessage(`${this.actor.prototypeToken.name} falls ${fallen} yards`) +} \ No newline at end of file diff --git a/scripts/skVq3eDEYKFF2iZp.js b/scripts/skVq3eDEYKFF2iZp.js new file mode 100644 index 0000000..312dc79 --- /dev/null +++ b/scripts/skVq3eDEYKFF2iZp.js @@ -0,0 +1,2 @@ +// I'm assuming the endurance test specified is for the end-round check +await this.actor.addCondition("poisoned", 4); diff --git a/scripts/sm9d5lk6cM0OuUkf.js b/scripts/sm9d5lk6cM0OuUkf.js new file mode 100644 index 0000000..97c8f33 --- /dev/null +++ b/scripts/sm9d5lk6cM0OuUkf.js @@ -0,0 +1 @@ +this.actor.applyFear(Math.min(4, this.effect.sourceTest.result.overcast.usage.other.current)) \ No newline at end of file diff --git a/scripts/sx7Ikn8WW00gBFb4.js b/scripts/sx7Ikn8WW00gBFb4.js new file mode 100644 index 0000000..d413850 --- /dev/null +++ b/scripts/sx7Ikn8WW00gBFb4.js @@ -0,0 +1,32 @@ +let location = (Math.ceil(CONFIG.Dice.randomUniform() * 2) == 2 ? "r" : "l") + "Arm" + +if (location == "lArm") +{ + this.script.scriptNotification("Rolled Left") +} +else if (location == "rArm") +{ + this.script.scriptNotification("Rolled Right") +} + +this.effect.updateSource({"flags.wfrp4e.location" : location}); + +if (location) +{ + let dropped = this.actor.itemTypes.weapon.filter(i => i.isEquipped & i.system.usesHands.includes(location)); + + if (dropped.length) + { + this.script.scriptNotification(`Dropped ${dropped.map(i => i.name).join(", ")}!`) + for(let weapon of dropped) + { + await weapon.system.toggleEquip(); + } + } +} + +let roll = await new Roll("1d10").roll() + +roll.toMessage(this.script.getChatData({flavor : `${this.effect.name} (Duration)`})); + +this.effect.updateSource({"duration.rounds" : roll.total}) \ No newline at end of file diff --git a/scripts/syBgPp7rOymCZejX.js b/scripts/syBgPp7rOymCZejX.js new file mode 100644 index 0000000..3007947 --- /dev/null +++ b/scripts/syBgPp7rOymCZejX.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("stunned") +} \ No newline at end of file diff --git a/scripts/syqqBkyP5tGqZ78t.js b/scripts/syqqBkyP5tGqZ78t.js new file mode 100644 index 0000000..265c5fd --- /dev/null +++ b/scripts/syqqBkyP5tGqZ78t.js @@ -0,0 +1,8 @@ +this.actor.has("Immunity to Psychology")?.delete(); + +let roll = await new Roll("1d10").roll(); + +roll.toMessage(this.script.getChatData()); + +this.script.scriptNotification(`Removed Immunity to Psychology, Adding ${roll.total} Broken Conditions`) +this.actor.addCondition("broken", roll.total, {"flags.wfrp4e.blasted-mind" : true}) \ No newline at end of file diff --git a/scripts/t48hkacYdOpzWvK9.js b/scripts/t48hkacYdOpzWvK9.js new file mode 100644 index 0000000..6e8c53a --- /dev/null +++ b/scripts/t48hkacYdOpzWvK9.js @@ -0,0 +1 @@ +args.options.beatBlade = true; \ No newline at end of file diff --git a/scripts/t56mnblo1kv3gM1M.js b/scripts/t56mnblo1kv3gM1M.js new file mode 100644 index 0000000..ce5fba9 --- /dev/null +++ b/scripts/t56mnblo1kv3gM1M.js @@ -0,0 +1 @@ +return args.skill?.name.includes("Melee (Basic)") || (args.type == "weapon" && args.item?.system.weaponGroup.value == "basic"); \ No newline at end of file diff --git a/scripts/t8LYOuN5peEdWeXP.js b/scripts/t8LYOuN5peEdWeXP.js new file mode 100644 index 0000000..4aeed96 --- /dev/null +++ b/scripts/t8LYOuN5peEdWeXP.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.mNoCuaVbFBflfO6X") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/tCIT1a12Gt6k2ohA.js b/scripts/tCIT1a12Gt6k2ohA.js new file mode 100644 index 0000000..e054b71 --- /dev/null +++ b/scripts/tCIT1a12Gt6k2ohA.js @@ -0,0 +1,21 @@ +let resistance +if (this.item.name.includes("(")) +{ + resistance = this.item.parenthesesText +} +else +{ + resistance = await ValueDialog.create("Enter Resistance", "Resistance") + + if (resistance) + { + this.item.updateSource({name : this.item.name + ` (${resistance})`}) + this.effect.updateSource({name : this.effect.name + ` (${resistance})`}) + } +} +this.item.updateSource({"system.tests.value" : this.item.system.tests.value.replace("the associated Threat", resistance)}) + +if (resistance && !this.effect.name.includes("(")) +{ + this.effect.updateSource({name : this.effect.name += ` (${resistance})`}) +} \ No newline at end of file diff --git a/scripts/tDrs0aNIYmZPsOoS.js b/scripts/tDrs0aNIYmZPsOoS.js new file mode 100644 index 0000000..51bdf06 --- /dev/null +++ b/scripts/tDrs0aNIYmZPsOoS.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}); +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("prone") +} diff --git a/scripts/tFAKRRRfTjQfdQz3.js b/scripts/tFAKRRRfTjQfdQz3.js new file mode 100644 index 0000000..566dcbb --- /dev/null +++ b/scripts/tFAKRRRfTjQfdQz3.js @@ -0,0 +1 @@ +this.actor.getActiveTokens().forEach(t => t.document.update({"texture.tint" : ""})); \ No newline at end of file diff --git a/scripts/tG1qGqzBLmAR3WHm.js b/scripts/tG1qGqzBLmAR3WHm.js new file mode 100644 index 0000000..64fa199 --- /dev/null +++ b/scripts/tG1qGqzBLmAR3WHm.js @@ -0,0 +1,15 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); +if (test.failed) +{ + let add = 0 + + if (test.result.roll % 11 == 0 || test.result.roll == 100) + { + add = 1 // can't use isFumble if no hit location + } + + await this.actor.addCondition("stunned", Math.max(1, Math.abs(test.result.SL)) + add) + await this.actor.addCondition("blinded", Math.max(1, Math.abs(test.result.SL))) + +} \ No newline at end of file diff --git a/scripts/tGVEV6TLl310mFLP.js b/scripts/tGVEV6TLl310mFLP.js new file mode 100644 index 0000000..686b84a --- /dev/null +++ b/scripts/tGVEV6TLl310mFLP.js @@ -0,0 +1,7 @@ +let nonmagical = args.modifiers.ap.value - args.modifiers.ap.magical +if (args.applyAP && nonmagical) +{ + let nonmagical = args.modifiers.ap.value - args.modifiers.ap.magical + args.modifiers.ap.ignored += nonmagical + args.modifiers.ap.details.push("" + this.effect.name + ": Ignore Non-Magical AP (" + nonmagical + ")"); +} \ No newline at end of file diff --git a/scripts/tKBq1nGZo8t6vvQ6.js b/scripts/tKBq1nGZo8t6vvQ6.js new file mode 100644 index 0000000..acbf367 --- /dev/null +++ b/scripts/tKBq1nGZo8t6vvQ6.js @@ -0,0 +1,2 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.5hH73j2NgPdsLCZN"); +this.actor.createEmbeddedDocuments("Item", [item.toObject()], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/tNTO1LVN7JqHf4YN.js b/scripts/tNTO1LVN7JqHf4YN.js new file mode 100644 index 0000000..f35b126 --- /dev/null +++ b/scripts/tNTO1LVN7JqHf4YN.js @@ -0,0 +1,8 @@ +if (args.test.characteristicKey == "wp") +{ + if (args.test.failed) + { + this.actor.createEmbeddedDocuments("ActiveEffect", [game.wfrp4e.config.symptomEffects["malaise"]]) + this.script.scriptMessage(`Willpower Test failed, ${this.actor.prototypeToken.name} gains @Condition[Malaise] for [[1d10]] hours`, {whisper: ChatMessage.getWhisperRecipients("GM")}) + } +} \ No newline at end of file diff --git a/scripts/tUwP7TjrOOOnaCYJ.js b/scripts/tUwP7TjrOOOnaCYJ.js new file mode 100644 index 0000000..c502cf0 --- /dev/null +++ b/scripts/tUwP7TjrOOOnaCYJ.js @@ -0,0 +1,10 @@ +let fatigued = this.actor.hasCondition("fatigued") +if (fatigued) +{ + this.script.scriptNotification(`Cleared ${fatigued.conditionValue} Fatigued Conditions`) + fatigued.delete(); +} +else +{ + this.script.scriptNotification(`No Fatigued Conditions`) +} \ No newline at end of file diff --git a/scripts/tcZug8ehU6lyYBd9.js b/scripts/tcZug8ehU6lyYBd9.js new file mode 100644 index 0000000..3ac13c4 --- /dev/null +++ b/scripts/tcZug8ehU6lyYBd9.js @@ -0,0 +1 @@ +return args.skill?.name != "Ranged (Blackpowder)" \ No newline at end of file diff --git a/scripts/tdICiJ26rJrDbxT6.js b/scripts/tdICiJ26rJrDbxT6.js new file mode 100644 index 0000000..233b805 --- /dev/null +++ b/scripts/tdICiJ26rJrDbxT6.js @@ -0,0 +1 @@ +return args.characteristic != "i" \ No newline at end of file diff --git a/scripts/tn6SwmjAuNzqE6dx.js b/scripts/tn6SwmjAuNzqE6dx.js new file mode 100644 index 0000000..a7bacb4 --- /dev/null +++ b/scripts/tn6SwmjAuNzqE6dx.js @@ -0,0 +1,14 @@ +let damage = 0 +let test = await this.actor.setupSkill("Dodge", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}); +await test.roll(); + +if (test.succeeded) +{ + damage = 10; +} +else if (test.failed) +{ + damage = 20; +} + +this.script.scriptMessage(await this.actor.applyBasicDamage(damage, {loc : "roll", hideDSN: true, suppressMsg : true})) \ No newline at end of file diff --git a/scripts/tnE8LF6E3svIlLca.js b/scripts/tnE8LF6E3svIlLca.js new file mode 100644 index 0000000..4058efe --- /dev/null +++ b/scripts/tnE8LF6E3svIlLca.js @@ -0,0 +1 @@ +return args.skill?.name == game.i18n.localize("NAME.Research"); \ No newline at end of file diff --git a/scripts/tnilBagajWM8UGQt.js b/scripts/tnilBagajWM8UGQt.js new file mode 100644 index 0000000..1b8e882 --- /dev/null +++ b/scripts/tnilBagajWM8UGQt.js @@ -0,0 +1 @@ +return args.item?.name != game.i18n.localize("NAME.ConsumeAlcohol") \ No newline at end of file diff --git a/scripts/toSrgcvWq9b5eN0K.js b/scripts/toSrgcvWq9b5eN0K.js new file mode 100644 index 0000000..f3fabed --- /dev/null +++ b/scripts/toSrgcvWq9b5eN0K.js @@ -0,0 +1,4 @@ +let location = await game.wfrp4e.tables.rollTable("hitloc", {hideDSN: true}) + +this.item.updateSource({name : `${this.item.name} (${location.description})`}) +this.script.scriptMessage(`Location: ${location.description}`, { whisper: ChatMessage.getWhisperRecipients("GM") }) \ No newline at end of file diff --git a/scripts/tolkNN5P7oOC8GKZ.js b/scripts/tolkNN5P7oOC8GKZ.js new file mode 100644 index 0000000..e030d9d --- /dev/null +++ b/scripts/tolkNN5P7oOC8GKZ.js @@ -0,0 +1,11 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields : {difficulty : "difficult"}}) +await test.roll(); + +if (test.failed) +{ + let sourceActor = this.effect.sourceActor; + if (sourceActor) + { + this.script.scriptMessage(await this.actor.applyBasicDamage(sourceActor.system.characteristics.wp.bonus, {suppressMsg : true, damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL})) + } +} \ No newline at end of file diff --git a/scripts/u3olS2p7Ls1JXfAH.js b/scripts/u3olS2p7Ls1JXfAH.js new file mode 100644 index 0000000..5ee90b2 --- /dev/null +++ b/scripts/u3olS2p7Ls1JXfAH.js @@ -0,0 +1 @@ +this.script.scriptMessage(await game.wfrp4e.tables.formatChatRoll("mutatephys", {}, "Tzeentch")); \ No newline at end of file diff --git a/scripts/u5dNZ0s3lWfL8KFb.js b/scripts/u5dNZ0s3lWfL8KFb.js new file mode 100644 index 0000000..3d18bb7 --- /dev/null +++ b/scripts/u5dNZ0s3lWfL8KFb.js @@ -0,0 +1 @@ +return args.fields.charging \ No newline at end of file diff --git a/scripts/u6CYMSZADrfXd48Q.js b/scripts/u6CYMSZADrfXd48Q.js new file mode 100644 index 0000000..ad9447a --- /dev/null +++ b/scripts/u6CYMSZADrfXd48Q.js @@ -0,0 +1 @@ +args.fields.modifier += 20; \ No newline at end of file diff --git a/scripts/uACa6u4JLNMRgFlr.js b/scripts/uACa6u4JLNMRgFlr.js new file mode 100644 index 0000000..b4b0244 --- /dev/null +++ b/scripts/uACa6u4JLNMRgFlr.js @@ -0,0 +1,2 @@ +const talents = await Promise.all(["Furious Assault", "Sea Legs"].map(game.wfrp4e.utility.findTalent)) +this.actor.createEmbeddedDocuments("Item", talents, {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/uAy4w7y8Uu9POF8C.js b/scripts/uAy4w7y8Uu9POF8C.js new file mode 100644 index 0000000..c07db00 --- /dev/null +++ b/scripts/uAy4w7y8Uu9POF8C.js @@ -0,0 +1 @@ +args.item.system.qualities.value.push({name : "impact"}) \ No newline at end of file diff --git a/scripts/uLBDnWC3S0lRitbj.js b/scripts/uLBDnWC3S0lRitbj.js new file mode 100644 index 0000000..e858a83 --- /dev/null +++ b/scripts/uLBDnWC3S0lRitbj.js @@ -0,0 +1,22 @@ +let test = await this.actor.setupCharacteristic("int", {skipTargets: true, appendTitle : ` - ${this.effect.name}`}) +await test.roll(); + +let opposedResult = test.opposedMessages[0]?.getOppose()?.resultMessage?.getOpposedTest()?.result + +if (opposedResult?.winner == "attacker") +{ + if (test.failed && (test.result.roll % 11 == 0 || test.result.roll == 100)) + { + this.actor.addCondition("unconscious") + await this.actor.update({"system.status.corruption.value" : parseInt(this.actor.status.corruption.value) + 1}) + this.script.scriptMessage("Gained a Corruption point", {whisper : ChatMessage.getWhisperRecipients("GM")}) + } + else + { + await this.actor.addCondition("stunned", 1 + opposedResult.differenceSL); + } +} +else +{ + return false; +} \ No newline at end of file diff --git a/scripts/uNYstk3eXmWamhzs.js b/scripts/uNYstk3eXmWamhzs.js new file mode 100644 index 0000000..4a76cd7 --- /dev/null +++ b/scripts/uNYstk3eXmWamhzs.js @@ -0,0 +1 @@ +args.actor.addCondition("blinded") \ No newline at end of file diff --git a/scripts/uOHAsKlkFuIaAmjb.js b/scripts/uOHAsKlkFuIaAmjb.js new file mode 100644 index 0000000..85f570c --- /dev/null +++ b/scripts/uOHAsKlkFuIaAmjb.js @@ -0,0 +1 @@ +args.actor.modifyWounds(1) \ No newline at end of file diff --git a/scripts/uSwkYENTOcnfRrqA.js b/scripts/uSwkYENTOcnfRrqA.js new file mode 100644 index 0000000..05d9ada --- /dev/null +++ b/scripts/uSwkYENTOcnfRrqA.js @@ -0,0 +1 @@ +return !args.skill?.name.includes(game.i18n.localize("NAME.Melee")) && args.weapon?.system?.attackType != "melee" \ No newline at end of file diff --git a/scripts/ucF4aiJ1gpDB333G.js b/scripts/ucF4aiJ1gpDB333G.js new file mode 100644 index 0000000..7d00add --- /dev/null +++ b/scripts/ucF4aiJ1gpDB333G.js @@ -0,0 +1,5 @@ +if (args.test.options.catfall && (args.test.result.roll <= game.settings.get("wfrp4e", "automaticSuccess") || args.test.result.roll <= args.test.target) && !args.test.result.catfall) +{ + args.test.result.other.push(`${this.effect.name}: Fall distance damage reduced by ${Number(args.test.result.SL) + 1} yards`) + args.test.result.catfall = true; // Prevent duplicate messages +} \ No newline at end of file diff --git a/scripts/ugL5IBB6R2yWyMWd.js b/scripts/ugL5IBB6R2yWyMWd.js new file mode 100644 index 0000000..1616e69 --- /dev/null +++ b/scripts/ugL5IBB6R2yWyMWd.js @@ -0,0 +1,23 @@ +if (args.totalWoundLoss > 0) +{ + let apply = await Dialog.confirm({title : this.effect.name, content : `Appy ${this.effect.name} Damage? Attacker must have used bare hands or a melee weapon made of metal.`}) + if (apply) + { + + let damage = 5 + this.actor.characteristics.wp.bonus; + + let loc = args.opposedTest.attackerTest.weapon?.system.usesHands[0] || "rArm"; + + let APatLoc = args.opposedTest.attacker.system.status.armour[loc]; + + let metalAP = APatLoc.layers.reduce((metal, layer) => metal += (layer.metal ? layer.value : 0), 0) + + let APused = Math.max(0, APatLoc.value - metalAP); // remove metal AP at location; + + damage -= (APused + args.opposedTest.attacker.system.characteristics.t.bonus) + + let msg = await args.opposedTest.attacker.applyBasicDamage(damage, {suppressMsg : true, damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL}); + msg += ` (ignored ${metalAP} metal AP on ${game.wfrp4e.config.locations[loc]})` + this.script.scriptMessage(msg) + } +} \ No newline at end of file diff --git a/scripts/upfK6GM33qZCZjll.js b/scripts/upfK6GM33qZCZjll.js new file mode 100644 index 0000000..91935c0 --- /dev/null +++ b/scripts/upfK6GM33qZCZjll.js @@ -0,0 +1 @@ +return args.item?.name != "Play (Lute)" \ No newline at end of file diff --git a/scripts/uwdQvZtzy2HVeEzx.js b/scripts/uwdQvZtzy2HVeEzx.js new file mode 100644 index 0000000..685fa84 --- /dev/null +++ b/scripts/uwdQvZtzy2HVeEzx.js @@ -0,0 +1,14 @@ +if (args.totalWoundLoss > 0) +{ + let roll = await new Roll("1d10").roll(); + roll.toMessage(this.script.getChatData()); + args.modifiers.other.push({label : this.effect.name, value : roll.total}) + + args.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields : {difficulty : "hard"}, skipTargets: true, appendTitle : " - " + this.effect.name}).then(async test => { + await test.roll(); + if (test.failed) + { + this.script.scriptMessage("" + args.actor.name + " takes a @Table[critbody]{Critical Hit} to the torse", {whisper: ChatMessage.getWhisperRecipients("GM")}) + } + }) +} diff --git a/scripts/ux3jaLpAUhZ5YqA6.js b/scripts/ux3jaLpAUhZ5YqA6.js new file mode 100644 index 0000000..66cae1b --- /dev/null +++ b/scripts/ux3jaLpAUhZ5YqA6.js @@ -0,0 +1 @@ +return args.item?.name != game.i18n.localize("NAME.Leadership") && args.item?.name != game.i18n.localize("NAME.Cool") \ No newline at end of file diff --git a/scripts/v00nVCRKqqRvY28t.js b/scripts/v00nVCRKqqRvY28t.js new file mode 100644 index 0000000..7d632a2 --- /dev/null +++ b/scripts/v00nVCRKqqRvY28t.js @@ -0,0 +1,6 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, fields: {difficulty: "hard"}}); +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("stunned", 3) +} diff --git a/scripts/v4CCxVaVGf9i8U7X.js b/scripts/v4CCxVaVGf9i8U7X.js new file mode 100644 index 0000000..abab0d3 --- /dev/null +++ b/scripts/v4CCxVaVGf9i8U7X.js @@ -0,0 +1,24 @@ +let cured = await Dialog.wait({ + title : this.effect.name, + content : "
Enter the number of diseases/poisons cured
", + buttons : { + confirm : { + label : "Confirm", + callback : (dlg) => { + let input = dlg.find("input"); + value = parseInt(input[0].value); + return value; + } + } + } +}) + + +let damage = 0; + +let rolls = new Array(cured).fill("").map(i => `max(0, 1d10 - ${this.actor.system.characteristics.fel.bonus})`) + +let test = new Roll(`${rolls.join(" + ")}`); +await test.roll(); +test.toMessage({speaker : {alias : this.actor.name}, flavor : this.effect.name}); +this.script.scriptMessage(await this.actor.applyBasicDamage(test.total, { damageType: game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL, suppressMsg : true })) \ No newline at end of file diff --git a/scripts/v4ITTsSY9EvCbhZP.js b/scripts/v4ITTsSY9EvCbhZP.js new file mode 100644 index 0000000..b42194c --- /dev/null +++ b/scripts/v4ITTsSY9EvCbhZP.js @@ -0,0 +1,2 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.Item.9h82z72XGo9tfgQS") +this.actor.createEmbeddedDocuments("Item", [item], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/v5xrDWcrTNFJkyQB.js b/scripts/v5xrDWcrTNFJkyQB.js new file mode 100644 index 0000000..da60300 --- /dev/null +++ b/scripts/v5xrDWcrTNFJkyQB.js @@ -0,0 +1,90 @@ +let choice1 = [ + { + type : "skill", + name : "Ranged (Bow)", + diff : { + system : { + advances : { + value : 10 + } + } + } + }, + { + type : "weapon", + name : "Longbow", + }, + { + type : "ammunition", + name : "Arrow", + } +] +let choice2 = [ +] + +let choice = await Dialog.wait({ + title : "Option", + content : + `+ Add Option? +
+${item.name} loses all Qualities
` + } + else + { + msg += `${item.name} crumbles into dust!
` + await item.update({name : item.name + " (Dust)"}) + } +} +if(msg) +{ + this.script.scriptMessage(msg); +} \ No newline at end of file diff --git a/scripts/whUSkaR1yem21bXp.js b/scripts/whUSkaR1yem21bXp.js new file mode 100644 index 0000000..c2c2f1b --- /dev/null +++ b/scripts/whUSkaR1yem21bXp.js @@ -0,0 +1,133 @@ +let characteristics = { + "ws" : 10, + "bs" : 5, + "s" : 0, + "t" : 5, + "i" : 10, + "ag" : 0, + "dex" : 6, + "int" : -5, + "wp" : 0, + "fel" : 10 +} +let skills = ["Melee (Basic)", "Track"] +let skillAdvancements = [8, 7] +let talents = ["Berserk Charge", "Careful Strike", "Strike to Injure"] +let traits = ["Flight (8)", "Fury", "Swarm", "Tracker"] +let trappings = [] +let items = []; +let spells = []; + +let updateObj = this.actor.toObject(); + +for (let ch in characteristics) +{ + updateObj.system.characteristics[ch].modifier += characteristics[ch]; +} + +for (let index = 0; index < skills.length; index++) +{ + let skill = skills[index] + let skillItem; + skillItem = updateObj.items.find(i => i.name == skill && i.type == "skill") + if (skillItem) + skillItem.system.advances.value += skillAdvancements[index] + else + { + skillItem = await game.wfrp4e.utility.findSkill(skill) + skillItem = skillItem.toObject(); + skillItem.system.advances.value = skillAdvancements[index]; + items.push(skillItem); + } +} + +for (let talent of talents) +{ + let talentItem = await game.wfrp4e.utility.findTalent(talent) + if (talentItem) + { + items.push(talentItem.toObject()); + } + else + { + ui.notifications.warn(`Could not find ${talent}`, {permanent : true}) + } +} + +const traitRegex = /(?:,?(.+?)(\+?\d{1,2}\+?)?\s*?(?:\((.+?)\)\s*(\+?\d{1,2})?|,|$))/gm +for (let trait of traits) +{ + let traitMatches = trait.matchAll(traitRegex).next().value + let traitName = traitMatches[1] + let traitVal = traitMatches[2] || traitMatches[4] // could be match 2 or 4 depending on if there's a specialization + let traitSpec = traitMatches[3] + + let traitItem; + try { + traitItem = await WFRP_Utility.findItem(traitName, "trait") + } + catch { } + if (!traitItem) { + ui.notifications.warn(`Could not find ${trait}`, {permanent : true}) + } + traitItem = traitItem.toObject() + + if (Number.isNumeric(traitVal)) + { + traitItem.system.specification.value = traitName.includes('Weapon','Horns','Tail','Tentacles','Bite') ? traitVal - parseInt(characteristicValues[3]/10) : traitVal; + traitItem.name = (traitItem.name + ` ${traitSpec ? "("+ traitSpec + ")" : ""}`).trim() + } + else + traitItem.system.specification.value = traitSpec + + items.push(traitItem) + +} + +for (let trapping of trappings) +{ + let trappingItem = await game.wfrp4e.utility.findItem(trapping) + if (trappingItem) + { + trappingItem = trappingItem.toObject() + + equip(trappingItem) + + items.push(trappingItem); + } + else + { + ui.notifications.warn(`Could not find ${trapping}`, {permanent : true}) + } +} + +for (let spell of spells) +{ + let spellItem = await game.wfrp4e.utility.findItem(spell) + if (spellItem) + { + spellItem = spellItem.toObject() + + items.push(spellItem); + } + else + { + ui.notifications.warn(`Could not find ${spell}`, {permanent : true}) + } +} + +updateObj.name = updateObj.name += " " + this.effect.name + +await this.actor.update(updateObj) +this.actor.createEmbeddedDocuments("Item", items); + + +function equip(item) +{ + if (item.type == "armour") + item.worn = true + else if (item.type == "weapon") + item.equipped = true + else if (item.type == "trapping" && item.trappingType?.value == "clothingAccessories") + item.worn = true +} \ No newline at end of file diff --git a/scripts/wsqNM4NHnwaAAQym.js b/scripts/wsqNM4NHnwaAAQym.js new file mode 100644 index 0000000..a07f054 --- /dev/null +++ b/scripts/wsqNM4NHnwaAAQym.js @@ -0,0 +1,11 @@ + args.applyAP = false; + + this.script.scriptNotification("This test only applies to criminals, otherwise close the dialog."); + this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields : {difficulty : "average"}, skipTargets: true, appendTitle : ` - ${this.effect.name}`}).then(async test => + { + await test.roll(); + if (test.failed) + { + args.actor.addCondition("unconscious"); + } + }); \ No newline at end of file diff --git a/scripts/wyTCozh9qGTx6yK0.js b/scripts/wyTCozh9qGTx6yK0.js new file mode 100644 index 0000000..c2afa63 --- /dev/null +++ b/scripts/wyTCozh9qGTx6yK0.js @@ -0,0 +1,5 @@ +if (args.options.terror || args.extendedTest?.getFlag("wfrp4e", "fear")) +{ + args.abort = true; + this.script.scriptNotification("Does not need to make Fear or Terror tests"); +} \ No newline at end of file diff --git a/scripts/wzkxiKjxVEeNS1di.js b/scripts/wzkxiKjxVEeNS1di.js new file mode 100644 index 0000000..7625d68 --- /dev/null +++ b/scripts/wzkxiKjxVEeNS1di.js @@ -0,0 +1,11 @@ +let roll = await new Roll("1d10").roll(); +this.script.scriptMessage(await this.actor.applyBasicDamage(roll.total, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL, suppressMsg: true})) + +await this.actor.addCondition("deafened", 3) + +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {fields : {difficulty: "average" }, skipTargets: true, appendTitle : ` - ${this.effect.name}`, context : {failure: "Gain a Broken Condition", success : "Avoided Broken Condition"}}) +await test.roll(); +if (test.failed) +{ + this.actor.addCondition("broken") +} \ No newline at end of file diff --git a/scripts/x2RLUUNB7BiIDYCP.js b/scripts/x2RLUUNB7BiIDYCP.js new file mode 100644 index 0000000..0ab5fe7 --- /dev/null +++ b/scripts/x2RLUUNB7BiIDYCP.js @@ -0,0 +1,16 @@ + + let difficulty = "" + if (this.effect.name.includes("Moderate")) + difficulty = "easy" + else if (this.effect.name.includes("Severe")) + difficulty = "average" + else + difficulty = "veasy" + + let test = await this.actor.setupSkill(game.i18n.localize("NAME.Endurance"), {context : {failure : this.actor.name + " dies from Blight"}, fields: {difficulty}, skipTargets: true, appendTitle : " - Blight"}) + await test.roll(); + if (test.failed) + { + this.actor.addCondition("dead"); + } + \ No newline at end of file diff --git a/scripts/x76tKw4L8dX00ikE.js b/scripts/x76tKw4L8dX00ikE.js new file mode 100644 index 0000000..c98eddb --- /dev/null +++ b/scripts/x76tKw4L8dX00ikE.js @@ -0,0 +1,5 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.uqGxFOEqeurwkAO3") +let data = item.toObject(); +setProperty(data, "flags.wfrp4e.breath", "fire") +data.system.specification.value = 5 +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/x8XK2fzzXCnSwfjt.js b/scripts/x8XK2fzzXCnSwfjt.js new file mode 100644 index 0000000..d42e514 --- /dev/null +++ b/scripts/x8XK2fzzXCnSwfjt.js @@ -0,0 +1,7 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Athletics")) +await test.roll(); + +if (test.succeeded) +{ + this.actor.removeCondition("prone"); +} \ No newline at end of file diff --git a/scripts/x9G6Du5EWV6byf4C.js b/scripts/x9G6Du5EWV6byf4C.js new file mode 100644 index 0000000..79042f3 --- /dev/null +++ b/scripts/x9G6Du5EWV6byf4C.js @@ -0,0 +1,8 @@ +if (parseInt(this.effect.sourceTest.result.SL) >= 3) +{ + this.actor.modifyWounds(this.actor.system.characteristics.t.bonus * 2) +} +else +{ + this.actor.modifyWounds(this.actor.system.characteristics.t.bonus) +} \ No newline at end of file diff --git a/scripts/x9iKFYYc4Ocy8PTS.js b/scripts/x9iKFYYc4Ocy8PTS.js new file mode 100644 index 0000000..9f078b6 --- /dev/null +++ b/scripts/x9iKFYYc4Ocy8PTS.js @@ -0,0 +1,30 @@ +let item = this.effect.getCreatedItems()?.[0]; +ChatMessage.create({content : "Grace is beyond style", speaker : ChatMessage.getSpeaker({token: this.actor.getActiveTokens()[0]?.document, actor: this.actor})}, {chatBubble : true}) + +let choice = await ItemDialog.create(ItemDialog.objectToArray({ + "nobles" : "Nobles", + "guilders" : "Guilders", + "servants" : "Servants" +}), 1, "Choose Group") + +let name = choice[0]?.name + +if (!name) +{ + return; +} + +if (item) +{ + item.update({ + name : item.name.split("(")[0] + ` (${name})`, + "system.tests.value" : item.system.tests.value.split("(")[0] + ` (${name}` + }) +} +else +{ + item = await fromUuid("Compendium.wfrp4e-core.items.Item.sYbgpSnRqSZWgwFP"); + let data = item.toObject(); + data.name += ` (${name})` + this.actor.createEmbeddedDocuments("Item", [data], {fromEffect: this.effect.id}) +} \ No newline at end of file diff --git a/scripts/xBpLQa7yBPczDMY8.js b/scripts/xBpLQa7yBPczDMY8.js new file mode 100644 index 0000000..dd7547f --- /dev/null +++ b/scripts/xBpLQa7yBPczDMY8.js @@ -0,0 +1,7 @@ + let scythe = (await fromUuid("Compendium.wfrp4e-core.items.CXg7XOFJwu4LZ9LM")).toObject(); + scythe.name = "Scythe of Shyish"; + scythe.system.damage.value = "WPB + 3" + scythe.system.equipped = true; + scythe.img = this.effect.icon; + scythe.system.qualities.value.push({name : "magical"}) + this.actor.createEmbeddedDocuments("Item", [scythe], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/xIRU2SaqLeWmqGDI.js b/scripts/xIRU2SaqLeWmqGDI.js new file mode 100644 index 0000000..01cabd4 --- /dev/null +++ b/scripts/xIRU2SaqLeWmqGDI.js @@ -0,0 +1,4 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.vMYEkrWj0ip6ZOdv") +let data = item.toObject(); +data.name += " (Disease)" +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/xL4S0H1RP8hhXW7c.js b/scripts/xL4S0H1RP8hhXW7c.js new file mode 100644 index 0000000..7aa1d03 --- /dev/null +++ b/scripts/xL4S0H1RP8hhXW7c.js @@ -0,0 +1,3 @@ +let item = await fromUuid("Compendium.wfrp4e-core.items.xneBqGOs1QS7kfUr") +let data = item.toObject(); +this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) \ No newline at end of file diff --git a/scripts/xLKAuD6yzwjAL6tJ.js b/scripts/xLKAuD6yzwjAL6tJ.js new file mode 100644 index 0000000..15ad6a7 --- /dev/null +++ b/scripts/xLKAuD6yzwjAL6tJ.js @@ -0,0 +1 @@ +return !args.weapon || args.weapon?.system.properties?.qualities.shield || !this.item.system.usesLocation(args.weapon) \ No newline at end of file diff --git a/scripts/xMhhVol8Is3DJ3gb.js b/scripts/xMhhVol8Is3DJ3gb.js new file mode 100644 index 0000000..bd75d66 --- /dev/null +++ b/scripts/xMhhVol8Is3DJ3gb.js @@ -0,0 +1,5 @@ +if (this.effect.sourceTest.succeeded) +{ + let blinded = 1 + this.effect.sourceTest.result.overcast.usage.other.count + this.actor.addCondition("blinded", blinded) +} \ No newline at end of file diff --git a/scripts/xPDMpOvC1ZBVxrNg.js b/scripts/xPDMpOvC1ZBVxrNg.js new file mode 100644 index 0000000..40f6360 --- /dev/null +++ b/scripts/xPDMpOvC1ZBVxrNg.js @@ -0,0 +1 @@ +args.fields.modifier += 10; \ No newline at end of file diff --git a/scripts/xPwa3NftkpMBc2AO.js b/scripts/xPwa3NftkpMBc2AO.js new file mode 100644 index 0000000..0b6eef8 --- /dev/null +++ b/scripts/xPwa3NftkpMBc2AO.js @@ -0,0 +1 @@ +return !["ws", "s", "ag"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/xQ3xR2Wf0wHFa76H.js b/scripts/xQ3xR2Wf0wHFa76H.js new file mode 100644 index 0000000..99df4ab --- /dev/null +++ b/scripts/xQ3xR2Wf0wHFa76H.js @@ -0,0 +1 @@ +return ["ws", "bs", "fel", "dex"].includes(args.characteristic) || args.weapon \ No newline at end of file diff --git a/scripts/xQnoRTHotZKrwPrx.js b/scripts/xQnoRTHotZKrwPrx.js new file mode 100644 index 0000000..036d4f5 --- /dev/null +++ b/scripts/xQnoRTHotZKrwPrx.js @@ -0,0 +1 @@ +return args.type == "cast" && args.item?.system.lore?.value == "shadow" \ No newline at end of file diff --git a/scripts/xRTmMwNfdirjsi8X.js b/scripts/xRTmMwNfdirjsi8X.js new file mode 100644 index 0000000..4a8886f --- /dev/null +++ b/scripts/xRTmMwNfdirjsi8X.js @@ -0,0 +1,3 @@ +this.actor.addCondition("ablaze"); + +this.actor.applyBasicDamage(this.effect.sourceTest.result.damage) \ No newline at end of file diff --git a/scripts/xRd6oA1QWLVpfoBm.js b/scripts/xRd6oA1QWLVpfoBm.js new file mode 100644 index 0000000..db785fb --- /dev/null +++ b/scripts/xRd6oA1QWLVpfoBm.js @@ -0,0 +1,6 @@ +if (!this.actor.has("Night Vision")) +{ + let item = await fromUuid("Compendium.wfrp4e-core.items.FmHDbCOy3pH8yKhm"); + let data = item.toObject(); + this.actor.createEmbeddedDocuments("Item", [data], {fromEffect : this.effect.id}) +} \ No newline at end of file diff --git a/scripts/xS2su09zcza9du09.js b/scripts/xS2su09zcza9du09.js new file mode 100644 index 0000000..592e0c2 --- /dev/null +++ b/scripts/xS2su09zcza9du09.js @@ -0,0 +1,8 @@ +if (["Minor", "Moderate", "Major"].includes(this.item.system.specification.value)) +{ + return +} + +let choice = await ItemDialog.create(ItemDialog.objectToArray({minor : "Minor", moderate : "Moderate", major : "Major"}, this.item.img), 1, "Choose Corruption Severity"); + +this.item.updateSource({"system.specification.value" : choice[0]?.name || ""}) \ No newline at end of file diff --git a/scripts/xUpKYT7BZCSmAfUy.js b/scripts/xUpKYT7BZCSmAfUy.js new file mode 100644 index 0000000..6e013b0 --- /dev/null +++ b/scripts/xUpKYT7BZCSmAfUy.js @@ -0,0 +1,10 @@ +if (this.item.system.quantity.value) +{ + this.item.system.reduceQuantity(); + let actor = Array.from(game.user.targets)[0]?.actor || this.actor; + actor.applyEffect({effectData : [this.item.effects.contents[0].convertToApplied()]}) +} +else +{ + this.script.scriptNotification("None left!", "error") +} \ No newline at end of file diff --git a/scripts/xYTkj8jhSVOSoLbC.js b/scripts/xYTkj8jhSVOSoLbC.js new file mode 100644 index 0000000..f319a92 --- /dev/null +++ b/scripts/xYTkj8jhSVOSoLbC.js @@ -0,0 +1 @@ +this.actor.flags.useless[this.item.system.location.key[0] + "Arm"] = true; \ No newline at end of file diff --git a/scripts/xcy5GOUSZ0meIejZ.js b/scripts/xcy5GOUSZ0meIejZ.js new file mode 100644 index 0000000..9d4ae4a --- /dev/null +++ b/scripts/xcy5GOUSZ0meIejZ.js @@ -0,0 +1,4 @@ +if (args.test.isFumble) +{ + args.test.result.other.push("@Table[warp-grinder-fumble]") +} \ No newline at end of file diff --git a/scripts/xgdhf0wlNP2cHIQx.js b/scripts/xgdhf0wlNP2cHIQx.js new file mode 100644 index 0000000..af39144 --- /dev/null +++ b/scripts/xgdhf0wlNP2cHIQx.js @@ -0,0 +1 @@ +await this.actor.addCondition("entangled", this.effect.sourceTest.result.overcast.usage.other.current) \ No newline at end of file diff --git a/scripts/xgplXZMs459X7XXM.js b/scripts/xgplXZMs459X7XXM.js new file mode 100644 index 0000000..af8f73d --- /dev/null +++ b/scripts/xgplXZMs459X7XXM.js @@ -0,0 +1,21 @@ +// Apply changes when the mask is worn + +if (args.equipped) { + this.actor.createEmbeddedDocuments("ActiveEffect", [this.item.effects.contents[1]?.convertToApplied()]) + this.script.scriptMessage(`${this.actor.name} dons the ${this.item.name}.${await this.actor.applyBasicDamage(8, {loc : "roll", suppressMsg: true, hideDSN: true})}
` +msg += `${await this.actor.applyBasicDamage(8, {loc : "roll", suppressMsg: true, hideDSN: true})}
` +msg += `${await this.actor.applyBasicDamage(8, {loc : "roll", suppressMsg: true, hideDSN: true})}
` + +this.script.scriptMessage(msg); \ No newline at end of file diff --git a/scripts/ynoHNXXCGRS6fTqF.js b/scripts/ynoHNXXCGRS6fTqF.js new file mode 100644 index 0000000..9c5e860 --- /dev/null +++ b/scripts/ynoHNXXCGRS6fTqF.js @@ -0,0 +1,26 @@ +let msg = "" + +let i_gain = (await new Roll("1d10").roll()).total + +if (args.actor.characteristics.i.value <= 0) +{ + i_gain += (await new Roll("2d10").roll()).total +} + +msg = `${this.actor.prototypeToken.name} gains ${i_gain} Initiative` + +let newValue = i_gain + args.actor.characteristics.i.modifier + +this.actor.update({"system.characteristics.i.modifier" : newValue}) + + +let hitloc = await game.wfrp4e.tables.rollTable("hitloc") + +let value = hitloc.result +let desc = hitloc.description + +this.effect.updateSource({"flags.wfrp4e.location" : value}) + +msg += ` as eyes push out of their ${desc}` + +this.script.scriptMessage(msg) \ No newline at end of file diff --git a/scripts/yzN7ZNlgCiSVJqsU.js b/scripts/yzN7ZNlgCiSVJqsU.js new file mode 100644 index 0000000..ac583fa --- /dev/null +++ b/scripts/yzN7ZNlgCiSVJqsU.js @@ -0,0 +1,7 @@ +let sourceItem = this.effect.sourceItem; + +if (sourceItem) +{ + this.actor.applyEffect({effectUuids : [sourceItem.effects.contents[1].uuid]}) + this.script.scriptNotification("Applied after effects"); +} \ No newline at end of file diff --git a/scripts/z5HfNUrHy5MS3K7a.js b/scripts/z5HfNUrHy5MS3K7a.js new file mode 100644 index 0000000..e635110 --- /dev/null +++ b/scripts/z5HfNUrHy5MS3K7a.js @@ -0,0 +1,7 @@ +let test = await this.actor.setupSkill(game.i18n.localize("NAME.Cool"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`, context : {failure: "1 Corruption Point Gained"}}) +await test.roll(); +if (test.failed && this.actor.type == "character") +{ + this.actor.update({"system.status.corruption.value" : parseInt(this.actor.status.corruption.value) + 1}) + this.script.scriptMessage("Gained a Corruption point", {whisper : ChatMessage.getWhisperRecipients("GM")}) +} \ No newline at end of file diff --git a/scripts/z926Cl2vxUfyLY0V.js b/scripts/z926Cl2vxUfyLY0V.js new file mode 100644 index 0000000..accff96 --- /dev/null +++ b/scripts/z926Cl2vxUfyLY0V.js @@ -0,0 +1,4 @@ +if (!["rArm", "lArm"].includes(this.effect.getFlag("wfrp4e", "location"))) + return true + +return ["fel", "wp", "int", "t"].includes(args.characteristic) \ No newline at end of file diff --git a/scripts/z9NEbIUBsKMaTuCz.js b/scripts/z9NEbIUBsKMaTuCz.js new file mode 100644 index 0000000..144e2e4 --- /dev/null +++ b/scripts/z9NEbIUBsKMaTuCz.js @@ -0,0 +1,4 @@ +if (args.opposedTest.result.hitloc && args.opposedTest.result.hitloc.value == "head") +{ + args.actor.addCondition("entangled") +} \ No newline at end of file diff --git a/scripts/zA6TDttpwMSMl7D8.js b/scripts/zA6TDttpwMSMl7D8.js new file mode 100644 index 0000000..898b642 --- /dev/null +++ b/scripts/zA6TDttpwMSMl7D8.js @@ -0,0 +1,14 @@ +// An imbiber must take a Consume Alcohol Test. +this.actor.setupSkill(game.i18n.localize("NAME.ConsumeAlcohol"), {skipTargets: true, appendTitle : ` - ${this.effect.name}`}).then(async test => { + await test.roll() + // If they succeed, + // as a result of whatever potential futures they glimpse, + // they can spend a Fortune Point within the next hour to reverse the dice of any failed Test. + if (test.succeeded) { + this.script.scriptMessage(`As a result of whatever potential futures they glimpse, ${this.actor.prototypeToken.name} can spend a Fortune Point within the next hour to reverse the dice of any failed Test.`, + { + whisper: ChatMessage.getWhisperRecipients("GM"), + blind: true + }) + } +}) \ No newline at end of file diff --git a/scripts/zBHTIBU8OlYj1YIO.js b/scripts/zBHTIBU8OlYj1YIO.js new file mode 100644 index 0000000..36139f8 --- /dev/null +++ b/scripts/zBHTIBU8OlYj1YIO.js @@ -0,0 +1 @@ +args.fields.modifier += this.effect.sourceActor?.system.characteristics.wp.value; \ No newline at end of file diff --git a/scripts/zFYCaGR0wbFWjl4T.js b/scripts/zFYCaGR0wbFWjl4T.js new file mode 100644 index 0000000..fbb0202 --- /dev/null +++ b/scripts/zFYCaGR0wbFWjl4T.js @@ -0,0 +1 @@ +return args.skill?.name != game.i18n.localize("NAME.OutdoorSurvival"); \ No newline at end of file diff --git a/scripts/zK38Rl5t9zbFi4Se.js b/scripts/zK38Rl5t9zbFi4Se.js new file mode 100644 index 0000000..029af27 --- /dev/null +++ b/scripts/zK38Rl5t9zbFi4Se.js @@ -0,0 +1,5 @@ +if (args.opposedTest.result.hitloc.value == this.item.system.location.key && args.totalWoundLoss > 0) +{ + args.actor.addCondition("bleeding", 1); + this.script.scriptNotification("Added Bleeding") +} \ No newline at end of file diff --git a/scripts/zR4WAjzXHTZuiu5G.js b/scripts/zR4WAjzXHTZuiu5G.js new file mode 100644 index 0000000..a366058 --- /dev/null +++ b/scripts/zR4WAjzXHTZuiu5G.js @@ -0,0 +1,52 @@ +let actor = this.actor; + let effect = this.effect; + let bleedingAmt; + let bleedingRoll; + let msg = "" + + let damage = effect.conditionValue; + let scriptArgs = {msg, damage}; + await Promise.all(actor.runScripts("preApplyCondition", {effect, data : scriptArgs})) + msg = scriptArgs.msg; + damage = scriptArgs.damage; + msg += await actor.applyBasicDamage(damage, {damageType : game.wfrp4e.config.DAMAGE_TYPE.IGNORE_ALL, minimumOne : false, suppressMsg : true}) + + if (actor.status.wounds.value == 0 && !actor.hasCondition("unconscious")) + { + await actor.addCondition("unconscious") + msg += "