From 2c8a364a3678ad5ff3a17921ab98e6f1b469c46d Mon Sep 17 00:00:00 2001 From: fredhicks Date: Fri, 14 May 2021 18:34:08 -0400 Subject: [PATCH] Packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added support for character Packages — collections of skill point spends, aspects, and stunts which you can choose to add to your sheet — in support of It's Not My Fault. The feature set for Packages will likely expand in the nebulous future, but this feels like the right start. --- Fate/FateOmni.html | 510 ++++++++++++++++++++++++++++++++++++++++-- Fate/sheet.json | 9 + Fate/translation.json | 92 ++++++++ 3 files changed, 594 insertions(+), 17 deletions(-) diff --git a/Fate/FateOmni.html b/Fate/FateOmni.html index 06c32611d1..b3bf99aa75 100644 --- a/Fate/FateOmni.html +++ b/Fate/FateOmni.html @@ -67,6 +67,7 @@ Logo Modes Notes + Packages Powers Refresh Roles @@ -244,22 +245,24 @@
Add Role
@@ -914,6 +917,75 @@ + + +
+
+ Packages +
+
+ +
+
+ Edit Packages + +
+
+
+ +
+ +
Enter a list of aspects from this package, separated by commas: Aspect, Aspect2, etc
+
+ +
Enter a list of skills and the points to allocate to each of them in this format: First:1, Second:2, etc. The named skills must already exist on your sheet, so make sure to establish those first.
+
+ +
Enter a list of stunts, one per line, in the format: Stunt Name: Stunt Description.
+
+
Add Package Sets
+ +
+
+
+ +
+
+ + + + +
+
+ + + +
+ +
+ : +
+ +
+ : +
+ +
+ : +
+
+
+
+ +
+
+ + +
@@ -2312,6 +2384,213 @@ var gamesets = { } }; +var packages = { + "inmf": { + "inmf-alchemist": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Forceful") + ":1", + "aspects": getTranslationByKey("inmf-alchemist"), + "stunts": getTranslationByKey("inmf-alchemist-stunt") + }, + "inmf-assassin": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmf-assassin"), + "stunts": getTranslationByKey("inmf-assassin-stunt") + }, + "inmf-barbarian": { + "skills": getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmf-barbarian"), + "stunts": getTranslationByKey("inmf-barbarian-stunt") + }, + "inmf-burglar": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmf-burglar"), + "stunts": getTranslationByKey("inmf-burglar-stunt") + }, + "inmf-conartist": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmf-conartist"), + "stunts": getTranslationByKey("inmf-conartist-stunt") + }, + "inmf-cutpurse": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Quick") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmf-cutpurse"), + "stunts": getTranslationByKey("inmf-cutpurse-stunt") + }, + "inmf-diplomat": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmf-diplomat"), + "stunts": getTranslationByKey("inmf-diplomat-stunt") + }, + "inmf-illusionist": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Quick") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmf-illusionist"), + "stunts": getTranslationByKey("inmf-illusionist-stunt") + }, + "inmf-merchant": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Flashy") + ":1", + "aspects": getTranslationByKey("inmf-merchant"), + "stunts": getTranslationByKey("inmf-merchant-stunt") + }, + "inmf-performer": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmf-performer"), + "stunts": getTranslationByKey("inmf-performer-stunt") + }, + "inmf-pirate": { + "skills": getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmf-pirate"), + "stunts": getTranslationByKey("inmf-pirate-stunt") + }, + "inmf-ranger": { + "skills": getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Quick") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmf-ranger"), + "stunts": getTranslationByKey("inmf-ranger-stunt") + }, + "inmf-scholar": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmf-scholar"), + "stunts": getTranslationByKey("inmf-scholar-stunt") + }, + "inmf-sharpshooter": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmf-sharpshooter"), + "stunts": getTranslationByKey("inmf-sharpshooter-stunt") + }, + "inmf-soldier": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmf-soldier"), + "stunts": getTranslationByKey("inmf-soldier-stunt") + }, + "inmf-sorcerer": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Forceful") + ":1", + "aspects": getTranslationByKey("inmf-sorcerer"), + "stunts": getTranslationByKey("inmf-sorcerer-stunt") + }, + "inmf-strategist": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmf-strategist"), + "stunts": getTranslationByKey("inmf-strategist-stunt") + }, + "inmf-swashbuckler": { + "skills": getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Quick") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmf-swashbuckler"), + "stunts": getTranslationByKey("inmf-swashbuckler-stunt") + }, + "inmf-warrior": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Forceful") + ":1", + "aspects": getTranslationByKey("inmf-warrior"), + "stunts": getTranslationByKey("inmf-warrior-stunt") + }, + "inmf-wizard": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Flashy") + ":1", + "aspects": getTranslationByKey("inmf-wizard"), + "stunts": getTranslationByKey("inmf-wizard-stunt") + } + }, + "inmfif": { + "inmfif-beastblooded": { + "skills": getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Quick") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmfif-beastblooded"), + "stunts": getTranslationByKey("inmfif-beastblooded-stunt") + }, + "inmfif-centaur": { + "skills": getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmfif-centaur"), + "stunts": getTranslationByKey("inmfif-centaur-stunt") + }, + "inmfif-clockwork": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Forceful") + ":1", + "aspects": getTranslationByKey("inmfif-clockwork"), + "stunts": getTranslationByKey("inmfif-clockwork-stunt") + }, + "inmfif-demonspawn": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmfif-demonspawn"), + "stunts": getTranslationByKey("inmfif-demonspawn-stunt") + }, + "inmfif-doppelganger": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Quick") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmfif-doppelganger"), + "stunts": getTranslationByKey("inmfif-doppelganger-stunt") + }, + "inmfif-dragonkin": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmfif-dragonkin"), + "stunts": getTranslationByKey("inmfif-dragonkin-stunt") + }, + "inmfif-dwarf": { + "skills": getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmfif-dwarf"), + "stunts": getTranslationByKey("inmfif-dwarf-stunt") + }, + "inmfif-elemental": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Flashy") + ":1", + "aspects": getTranslationByKey("inmfif-elemental"), + "stunts": getTranslationByKey("inmfif-elemental-stunt") + }, + "inmfif-elf": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmfif-elf"), + "stunts": getTranslationByKey("inmfif-elf-stunt") + }, + "inmfif-faerie": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Quick") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmfif-faerie"), + "stunts": getTranslationByKey("inmfif-faerie-stunt") + }, + "inmfif-giant": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Forceful") + ":1", + "aspects": getTranslationByKey("inmfif-giant"), + "stunts": getTranslationByKey("inmfif-giant-stunt") + }, + "inmfif-gnome": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmfif-gnome"), + "stunts": getTranslationByKey("inmfif-gnome-stunt") + }, + "inmfif-goblin": { + "skills": getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Quick") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmfif-goblin"), + "stunts": getTranslationByKey("inmfif-goblin-stunt") + }, + "inmfif-halfling": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmfif-halfling"), + "stunts": getTranslationByKey("inmfif-halfling-stunt") + }, + "inmfif-merfolk": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmfif-merfolk"), + "stunts": getTranslationByKey("inmfif-merfolk-stunt") + }, + "inmfif-minotaur": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Forceful") + ":1", + "aspects": getTranslationByKey("inmfif-minotaur"), + "stunts": getTranslationByKey("inmfif-minotaur-stunt") + }, + "inmfif-nephilim": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Quick") + ":1", + "aspects": getTranslationByKey("inmfif-nephilim"), + "stunts": getTranslationByKey("inmfif-nephilim-stunt") + }, + "inmfif-orc": { + "skills": getTranslationByKey("Careful") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmfif-orc"), + "stunts": getTranslationByKey("inmfif-orc-stunt") + }, + "inmfif-vampire": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Forceful") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmfif-vampire"), + "stunts": getTranslationByKey("inmfif-vampire-stunt") + }, + "inmfif-zombie": { + "skills": getTranslationByKey("Clever") + ":1, " + getTranslationByKey("Flashy") + ":1, " + getTranslationByKey("Sneaky") + ":1", + "aspects": getTranslationByKey("inmfif-zombie"), + "stunts": getTranslationByKey("inmfif-zombie-stunt") + } + } +}; + var roles = { "brain": getTranslationByKey("Computers") + ", " + getTranslationByKey("Gadgetry") + ", " + getTranslationByKey("Insight") + ", " + getTranslationByKey("Knowledge"), "brawler": getTranslationByKey("Athletics") + ", " + getTranslationByKey("Fight") + ", " + getTranslationByKey("Provoke") + ", " + getTranslationByKey("Will"), @@ -3121,6 +3400,193 @@ var addExtra = function(values) { setAttrs(attrs); }; +var addPackages = function(values) { + var packagename = values.addpackage; + if ( typeof packages[packagename] !== "undefined" ) { + var packageset = packages[packagename]; + log(packageset); + attrs = { "addpackage": "" }; + for(var [pkgname,pkg] of Object.entries(packageset) ) { + var newid = generateActuallyUniqueRowID(); + var packageid = "repeating_packages_" + newid + "_package"; + var skillsid = "repeating_packages_" + newid + "_skills"; + var aspectsid = "repeating_packages_" + newid + "_aspects"; + var stuntsid = "repeating_packages_" + newid + "_stunts"; + attrs[packageid] = getTranslationByKey(pkgname); + attrs[skillsid] = pkg.skills; + attrs[aspectsid] = pkg.aspects; + attrs[stuntsid] = pkg.stunts; + } + setAttrs(attrs); + } else { + log("package "+packagename+" not recognized"); + } +}; + +on("clicked:repeating_packages:add", function(e) { + const rowprefix = (e.sourceAttribute).slice(0,-3); // Strips off the add + const skillsid = rowprefix + "skills"; + const aspectsid = rowprefix + "aspects"; + const stuntsid = rowprefix + "stunts"; + getSectionIDs("skills", function(s) { + var fields = [skillsid,aspectsid,stuntsid]; + for(var i=0; i < s.length; i++) { + fields[i*2+3] = "repeating_skills_" + s[i] + "_skill"; + fields[i*2+4] = "repeating_skills_" + s[i] + "_rating"; + } + getAttrs(fields, function(v) { + log(v); + var attrs = {}; + var alist = v[aspectsid].toString().split(/\s*,\s*/); + var sklist = v[skillsid].toString().split(/\s*,\s*/); + var stlist = v[stuntsid].toString().split(/\s*\n\s*/); + log(alist); + for(var j=0; j < alist.length; j++ ) { + if ( typeof alist[j] !== "undefined" && alist[j] !== "" ) { + var newarowid = generateActuallyUniqueRowID(); + var newaid = "repeating_aspects_" + newarowid + "_aspect"; + attrs[newaid] = alist[j]; + } + } + log(stlist); + for(var j=0; j < stlist.length; j++ ) { + if ( typeof stlist[j] !== "undefined" && stlist[j] !== "" ) { + var newstrowid = generateActuallyUniqueRowID(); + var newstnameid = "repeating_stunts_" + newstrowid + "_name"; + var newstdescid = "repeating_stunts_" + newstrowid + "_desc"; + var stuntpart = stlist[j].toString().split(/\s*:\s*/); + attrs[newstnameid] = stuntpart[0]; + attrs[newstdescid] = stuntpart[1]; + } + } + log(sklist); + for(var j=0; j < sklist.length; j++ ) { + if ( typeof sklist[j] !== "undefined" && sklist[j] !== "" ) { + var skillpart = sklist[j].toString().split(/\s*:\s*/); + var skillname = skillpart[0]; + var skillpoint = Number(skillpart[1]); + if ( skillpoint === Number.NaN ) { + continue; // No point in adding a non-numeric value; skip to next iteration in loop + } + // Now find the skill that matches the skill name + for(var i = 0; i < s.length; i++ ) { + var sid = "repeating_skills_" + s[i] + "_skill"; + var rid = "repeating_skills_" + s[i] + "_rating"; + // These values should already exist in v + var sname = v[sid]; + var sval = Number(v[rid]); + if ( sval === Number.NaN ) { sval = 0; } + if ( sname === skillname ) { + // Then we have a match! + attrs[rid] = sval + skillpoint; // Make sure we're setting the skill's new value to its existing rating value plus the skill point allocation + v[rid] = attrs[rid]; // Make sure we're updating the current understanding of the skill's rating is in case we encounter another add to it later + break; // we can break out of this for loop as we've found our candidate skill + } + } + } + } + // ZOD + setAttrs(attrs); + log(attrs); + }); + }); +}); + +on("clicked:repeating_packages:subtract", function(e) { // this is to remove an already-added package; has some heavy lifting to do! + + const rowprefix = (e.sourceAttribute).slice(0,-8); // Strips off the subtract + const skillsid = rowprefix + "skills"; + const aspectsid = rowprefix + "aspects"; + const stuntsid = rowprefix + "stunts"; + + getSectionIDs("skills", function(sk) { getSectionIDs("stunts", function(st) { getSectionIDs("aspects", function(asp) { + var fields = [skillsid,aspectsid,stuntsid]; + var adder = fields.length; + for(var i=0; i < sk.length; i++) { + fields[i*2+adder] = "repeating_skills_" + sk[i] + "_skill"; + fields[i*2+adder+1] = "repeating_skills_" + sk[i] + "_rating"; + } + var adder = adder + sk.length*2; + for(var i=0; i < st.length; i++) { + fields[i*2+adder] = "repeating_stunts_" + st[i] + "_name"; + fields[i*2+adder+1] = "repeating_stunts_" + st[i] + "_desc"; + } + var adder = adder + st.length*2; + for(var i=0; i < asp.length; i++) { + fields[i*1+adder] = "repeating_aspects_" + asp[i] + "_aspect"; + } + + getAttrs(fields, function(v) { + log(v); + var attrs = {}; + var alist = v[aspectsid].toString().split(/\s*,\s*/); + var sklist = v[skillsid].toString().split(/\s*,\s*/); + var stlist = v[stuntsid].toString().split(/\s*\n\s*/); + + log(alist); + for(var j=0; j < alist.length; j++ ) { + if ( typeof alist[j] !== "undefined" && alist[j] !== "" ) { + for(var i = 0; i < asp.length; i++ ) { + var arowid = "repeating_aspects_" + asp[i]; + var aid = arowid + "_aspect"; + if ( alist[j] === v[aid] ) { + removeRepeatingRow(arowid); + break; // Only need to do this to the first one encountered + } + } + } + } + + log(stlist); + for(var j=0; j < stlist.length; j++ ) { + if ( typeof stlist[j] !== "undefined" && stlist[j] !== "" ) { + for(var i = 0; i < st.length; i++ ) { + var strowid = "repeating_stunts_" + st[i]; + var stnid = strowid + "_name"; + var stdid = strowid + "_desc"; + var stuntpart = stlist[j].toString().split(/\s*:\s*/); + log(v); log(stuntpart); + if ( stuntpart[0] === v[stnid] && stuntpart[1] === v[stdid] ) { + removeRepeatingRow(strowid); + break; // Only need to do this to the first one encountered + } + } + } + } + + log(sklist); + for(var j=0; j < sklist.length; j++ ) { + if ( typeof sklist[j] !== "undefined" && sklist[j] !== "" ) { + var skillpart = sklist[j].toString().split(/\s*:\s*/); + var skillname = skillpart[0]; + var skillpoint = Number(skillpart[1]); + if ( skillpoint === Number.NaN ) { + continue; // No point in subtracting a non-numeric value; skip to next iteration in loop + } + // Now find the skill that matches the skill name + for(var i = 0; i < sk.length; i++ ) { + var sid = "repeating_skills_" + sk[i] + "_skill"; + var rid = "repeating_skills_" + sk[i] + "_rating"; + // These values should already exist in v + var sname = v[sid]; + var sval = Number(v[rid]); + if ( sval === Number.NaN ) { sval = 0; } + if ( sname === skillname ) { + // Then we have a match! + attrs[rid] = sval - skillpoint; // Make sure we're setting the skill's new value to its existing rating value MINUS the skill point allocation + v[rid] = attrs[rid]; // Make sure we're updating the current understanding of the skill's rating is in case we encounter another subtract from it later + break; // we can break out of this for loop as we've found our candidate skill + } + } + } + } + + setAttrs(attrs); + log(attrs); + }); + }); }); }); +}); + var addRole = function(values) { var rolename = values.addrole; if ( typeof roles[rolename] !== "undefined" ) { @@ -3865,6 +4331,16 @@ on("change:addrole", function() { }); }); +on("change:addpackage", function() { + log("Event: addpackage change"); + getAttrs(["addpackage"], function(values) { + if ( values.addpackage !== "" ) { + log("addpackage: non null package detected"); + addPackages(values); + } + }); +}); + on("change:addmode", function() { log("Event: addmode change"); getAttrs(["addmode"], function(values) { @@ -3982,7 +4458,7 @@ on("change:repeating_skills:rollthis change:combomulti", function(e) { attrs["combotext"] = ""; var colused = [false,false,false,false]; // The 0 position is n/a, but I don't care, convenient this way var multi = v["combomulti"]; - if ( e.sourceAttribute !== "combomulti" && multi !== "1" && e.newValue == "1" ) { // ZOD + if ( e.sourceAttribute !== "combomulti" && multi !== "1" && e.newValue == "1" ) { log("we have a situation where the triggering attribute is not combomulti, and combomulti is disabled (meaning multiple selections from the same column are disallowed), and the triggering attribute was toggled on; therefore we must make sure only the triggering attribute is counted for that column"); var columnid = e.sourceAttribute.replace(/_rollthis$/,"_column"); var mycol = v[columnid]; diff --git a/Fate/sheet.json b/Fate/sheet.json index 4ed59359d6..71b5dcdfe9 100644 --- a/Fate/sheet.json +++ b/Fate/sheet.json @@ -134,6 +134,15 @@ "optiontranslationkeys": [ "show", "hide" ], "default": "1" }, + { + "attribute": "Show-Packages", + "displayname": "Packages", + "displaytranslationkey": "packages", + "type": "select", + "options": [ "Show|1", "Hide|0" ], + "optiontranslationkeys": [ "show", "hide" ], + "default": "0" + }, { "attribute": "Show-Powers", "displayname": "Powers", diff --git a/Fate/translation.json b/Fate/translation.json index 48950ed373..16b3f70d35 100644 --- a/Fate/translation.json +++ b/Fate/translation.json @@ -80,6 +80,88 @@ "High Concept": "High Concept", "indebted": "Indebted (sticky)", "initialize": "Initialize", + "inmf": "It's Not My Fault", + "inmfif": "It's Not My Fault I'm Fantastic", + "inmf-alchemist": "Alchemist", + "inmf-alchemist-stunt": "There’s a Flask For That: Once per session, produce an alchemical flask that lets you instantly succeed-with-style on an Overcome task without rolling.", + "inmf-assassin": "Assassin", + "inmf-assassin-stunt": "Backstab: When Sneakily Attacking a foe from hiding, they may not use their stress track to absorb the blow.", + "inmf-barbarian": "Barbarian", + "inmf-barbarian-stunt": "Great Sword: When you use a big sword to successfully, Forcefully Attack a target, add 2 stress to the result.", + "inmf-burglar": "Burglar", + "inmf-burglar-stunt": "It Was Open When I Found It: Once per session, you may bypass any lock in an instant, without rolling.", + "inmf-conartist": "Con Artist", + "inmf-conartist-stunt": "Fast Talking: Gain +2 to Cleverly Create an Advantage on someone based entirely on telling them lies.", + "inmf-cutpurse": "Cutpurse", + "inmf-cutpurse-stunt": "Dodge the Mark: Gain +2 to Quick Defense rolls made against someone you’ve stolen something from.", + "inmf-diplomat": "Diplomat", + "inmf-diplomat-stunt": "Talk It Out: Once per session, you may forestall violence with your words. When you do, no one may take any attack actions until you allow it, or until any one character overcomes your defense.", + "inmf-illusionist": "Illusionist", + "inmf-illusionist-stunt": "Vanishing Act: Once per session, when you fail a defense roll, you may ignore the result, and reveal that the real you was somewhere else all along.", + "inmf-merchant": "Merchant", + "inmf-merchant-stunt": "Fat Sacks of Cash: Twice per session, you may use Flashy instead of any other approach in order to take an action using an ostentatious display of wealth.", + "inmf-performer": "Performer", + "inmf-performer-stunt": "All The World’s A Stage: When invoking aspects to aid a Flashy effort to delight, impress, or provoke an audience, gain +3 per invoke instead of the usual +2.", + "inmf-pirate": "Pirate", + "inmf-pirate-stunt": "There Be Plunder: When using stealth or trickery to Sneakily Overcome obstacles that stand between you and a payout, all successes count as a Success With Style.", + "inmf-ranger": "Ranger", + "inmf-ranger-stunt": "Run Far, Run Fast: When Quickly Overcoming terrain obstacles or covering distances on foot, get +2 on your roll.", + "inmf-scholar": "Scholar", + "inmf-scholar-stunt": "Book Learning: Twice per session, you may use Clever instead of any other approach, thanks to your extensive studies on the topic.", + "inmf-sharpshooter": "Sharpshooter", + "inmf-sharpshooter-stunt": "Stay On Target: Gain one extra free invoke when you Carefully Create Advantages by aiming your bow (or other ranged weapon) at a target.", + "inmf-soldier": "Soldier", + "inmf-soldier-stunt": "Shield Wall: When Carefully Defending against a physical attack, gain +2 to your defense if you have a shield (or something like it).", + "inmf-sorcerer": "Sorcerer", + "inmf-sorcerer-stunt": "Earth-Shattering Kaboom: Once per session, you may make a sorcerous Attack at full strength against all enemies in a zone.", + "inmf-strategist": "Strategist", + "inmf-strategist-stunt": "Plan B: Once per session, when your side has used all its advantages, you may instantly create a new advantage with two free invokes.", + "inmf-swashbuckler": "Swashbuckler", + "inmf-swashbuckler-stunt": "Three Against One?: When you’re surrounded by two or more foes, use your surroundings to make a Flashy Defense at +1 per foe.", + "inmf-warrior": "Warrior", + "inmf-warrior-stunt": "Bend Bars, Smash Gates: Gain +2 to Forcefully Overcome physical barriers you intend to (and can) destroy.", + "inmf-wizard": "Wizard", + "inmf-wizard-stunt": "Prismatic Spray: When you Cleverly Attack two or more foes at once, gain +1 per foe for your roll, then split the results as usual.", + "inmfif-beastblooded": "Beastblooded", + "inmfif-beastblooded-stunt": "Release the Beast: At the beginning of a fight, before any actions are taken, you may make a Quick Create an Advantage roll to unleash your bestial nature.", + "inmfif-centaur": "Centaur", + "inmfif-centaur-stunt": "Skirmisher: When you make a Quick Attack on open ground, you may move both before and after your attack.", + "inmfif-clockwork": "Clockwork", + "inmfif-clockwork-stunt": "Replacement Parts: After a fight has concluded, you may permanently reduce the length of your stress track by 1 to immediately clear all consequences.", + "inmfif-demonspawn": "Demonspawn", + "inmfif-demonspawn-stunt": "My Little Friend: Twice per session you may summon an imp to help you succeed with style on any one task — so long as you are willing to pay its price.", + "inmfif-doppelganger": "Doppelganger", + "inmfif-doppelganger-stunt": "Perfect Mimic: Twice per session you may take on the appearance and voice of any humanoid you’ve seen. Convincing others you’re that person is up to you.", + "inmfif-dragonkin": "Dragonkin", + "inmfif-dragonkin-stunt": "Breath Weapon: When you Flashily Attack and hit with your breath weapon, you may add 1 stress to the result or deal 1 stress to an adjacent target.", + "inmfif-dwarf": "Dwarf", + "inmfif-dwarf-stunt": "Dwarven Mettle: Twice per session, you may gain +4 on a single attack against a heavily armored foe.", + "inmfif-elemental": "Elemental", + "inmfif-elemental-stunt": "Elemental Communion: When Flashily Overcoming an obstacle associated with or vulnerable to your element, a tie or better becomes a success with style.", + "inmfif-elf": "Elf", + "inmfif-elf-stunt": "Literally Superior: Gain +2 to attempt an Overcome action another character in the scene just failed (does not stack in the case of multiple failures).", + "inmfif-faerie": "Faerie", + "inmfif-faerie-stunt": "Vanishing Act: When you Sneakily Defend against an attack, you may spend a fate point or free invoke to immediately disappear into hiding.", + "inmfif-giant": "Giant", + "inmfif-giant-stunt": "Living Wall: When you successfully, Forcefully Defend against a physical attack, give a boost to one ally in the same zone as you.", + "inmfif-gnome": "Gnome", + "inmfif-gnome-stunt": "Deception is a Virtue: When you Sneakily Create an Advantage as part of an elaborate ruse, gain one additional free invoke on the resulting aspect.", + "inmfif-goblin": "Goblin", + "inmfif-goblin-stunt": "Goblin Machinery: Given tools and time, you can build a device out of scrap with 3 free invokes on an aspect you define. After they’re used up it falls apart.", + "inmfif-halfling": "Halfling", + "inmfif-halfling-stunt": "Underestimated: When you Cleverly Defend against an attack, spend 1 FP or free invoke to treat your shifts of defense as an attack against your attacker.", + "inmfif-merfolk": "Merfolk", + "inmfif-merfolk-stunt": "Aquatic: Gain +2 to Carefully Overcome any obstacle involving water, swimming, or aquatic life.", + "inmfif-minotaur": "Minotaur", + "inmfif-minotaur-stunt": "Home Turf Advantage: Gain +2 to Cleverly Overcome any obstacle that presents itself as a puzzle, maze, or trap.", + "inmfif-nephilim": "Nephilim", + "inmfif-nephilim-stunt": "Divine Heritage: When you Carefully Attack following prayer and preparation, any aspects you invoke yield a +3 instead of +2 on the attack roll.", + "inmfif-orc": "Orc", + "inmfif-orc-stunt": "Shock & Awe: Gain +2 to Forcefully Create Advantages when enacting a bold and reckless battle plan.", + "inmfif-vampire": "Vampire", + "inmfif-vampire-stunt": "Drink Blood: Twice per session, when you inflict a physical consequence on a living creature in your zone, you may immediately clear your stress track.", + "inmfif-zombie": "Zombie", + "inmfif-zombie-stunt": "Dead Again: Once per session, when you are Taken Out, you may rise on your next turn with any Mild (-2) or Moderate (-4) consequences cleared.", "inperil": "In Peril (sticky)", "Intellect": "Intellect", "Investigate": "Investigate", @@ -99,6 +181,16 @@ "Other Aspect": "Other Aspect", "Other": "Other", "other": "other", + "package": "Package", + "packages": "Packages", + "package-add": "Add This Package", + "package-subtract": "Subtract This Package", + "package-add-set": "Add Package Sets", + "package-choose": "[Choose a package set]", + "packages-instructions": "Pick the packages you want to add to your character, which will add the indicated skill point spends, aspects, and stunts to your sheet. Once you've picked all you want, you can turn off the Packages display preference at the top of the sheet. Define your available packages using the edit controls for this section. Skills added by a package need to be in the skill list already, so make sure you've loaded those up first!", + "package-aspects-instruct": "Enter a list of aspects from this package, separated by commas: Aspect, Aspect2, etc", + "package-skills-instruct": "Enter a list of skills and the points to allocate to each of them in this format: First:1, Second:2, etc. The named skills must already exist on your sheet, so make sure to establish those first.", + "package-stunts-instruct": "Enter a list of stunts, one per line, in the format: Stunt Name: Stunt Description.", "Persuade": "Persuade", "physical": "Physical", "Physique": "Physique",