-
Result = {{roll1}}
-
Custom Result = {{computed::roll1}}
+
+
+
+
+
Dice Roll
+
{{diceroll}}
+
Mod {{modifier}}
+
{{computed::diceroll}}
+ {{#desc}}
+
{{desc}}
+ {{/desc}}
diff --git a/Palladium Rifts by Grinning Gecko/sheet.json b/Palladium Rifts by Grinning Gecko/sheet.json
index 0503fea3c3..2edabc0806 100644
--- a/Palladium Rifts by Grinning Gecko/sheet.json
+++ b/Palladium Rifts by Grinning Gecko/sheet.json
@@ -4,9 +4,17 @@
"authors": "Grinning Gecko",
"roll20userid": "6479616",
"preview": "preview.jpg",
- "instructions": "Rifts is a complicated game, and this is a complicated sheet. Please expand and review the instructions on each tab of the sheet in order to use it to its fullest. Happy gaming!",
+ "instructions": "Rifts is a complicated game, and this is a complicated sheet. Please expand and review the instructions on the Options tab of the sheet in order to use it to its fullest. Happy gaming!",
"legacy": false,
"useroptions": [
+ {
+ "attribute": "opt_dodge_penalty",
+ "displayname": "Apply Rifts: Ultimate Edition penalties to dodging gunfire",
+ "description": "In Rifts: Ultimate Edition, characters are -10 to dodge gunfire at less than 10 feet, and -5 between 10 and 50 feet.",
+ "type": "checkbox",
+ "value": "?{Dodging gunfire?|> 50 feet,0|10-50 feet,5|< 10 feet,10}",
+ "checked": "checked"
+ },
{
"attribute": "opt_pp_extras",
"displayname": "Add PP bonus to Disarm and Entangle",
@@ -37,6 +45,13 @@
"type": "checkbox",
"value": "1",
"checked": "checked"
+ },
+ {
+ "attribute": "opt_iq_bonus",
+ "displayname": "Apply IQ bonus to skill-based abilities",
+ "description": "Adds IQ bonus to abilities/magic/psionic that use a skill-based percentage. Some examples include, but are not limited to, Telemechanics, Object Read, Locate, etc.",
+ "type": "checkbox",
+ "value": "1"
}
]
}
diff --git a/Palladium Rifts by Grinning Gecko/src/js/armor.js b/Palladium Rifts by Grinning Gecko/src/js/armor.js
index 0aac9266b0..0a55e3d7a2 100644
--- a/Palladium Rifts by Grinning Gecko/src/js/armor.js
+++ b/Palladium Rifts by Grinning Gecko/src/js/armor.js
@@ -3,7 +3,7 @@ async function applyDamageToNextActiveArmor(section, damage) {
const ids = await getSectionIDsOrderedAsync(section);
const attrKeys = ids.flatMap((id) => [
`repeating_${section}_${id}_is_active`,
- `repeating_${section}_${id}_currentmdc`,
+ `repeating_${section}_${id}_mdc`,
]);
const attrs = {};
const a = await getAttrsAsync(attrKeys);
@@ -19,21 +19,49 @@ async function applyDamageToNextActiveArmor(section, damage) {
}, []);
let i = 0;
- for (const id of activeIds) {
- currentMdc = +a[`repeating_${section}_${id}_currentmdc`] - damageCarry;
+ let activeRowId;
+ for (activeRowId of activeIds) {
+ currentMdc = +a[`repeating_${section}_${activeRowId}_mdc`] - damageCarry;
if (currentMdc < 0 && ++i < activeIds.length) {
- attrs[`repeating_${section}_${id}_currentmdc`] = 0;
+ attrs[`repeating_${section}_${activeRowId}_mdc`] = 0;
damageCarry = Math.abs(currentMdc);
} else {
- attrs[`repeating_${section}_${id}_currentmdc`] = currentMdc;
+ attrs[`repeating_${section}_${activeRowId}_mdc`] = currentMdc;
break;
}
}
await setAttrsAsync(attrs);
+ await updateActiveArmor(activeRowId);
+}
+
+/**
+ * Updates the global active_armor attributes with the values
+ * from the currently active repeating armor row
+ * @param {string} rowId Row ID of the active armor row
+ */
+async function updateActiveArmor(rowId) {
+ console.log("updateActiveArmor", ARMOR_KEYS.length);
+ const attrKeys = ARMOR_KEYS.map((key) => `repeating_armor_${rowId}_${key}`);
+ const a = await getAttrsAsync(attrKeys);
+ const attrs = ARMOR_KEYS.reduce((acc, cur) => {
+ if (a[`repeating_armor_${rowId}_${cur}`] !== undefined) {
+ if (cur === "mdc") {
+ acc[`active_armor_mdc`] = a[`repeating_armor_${rowId}_${cur}`];
+ } else if (cur === "mdc_max") {
+ acc[`active_armor_mdc_max`] = a[`repeating_armor_${rowId}_${cur}`];
+ } else {
+ acc[`active_armor_${cur}`] = a[`repeating_armor_${rowId}_${cur}`];
+ acc[`active_armor_${cur}_max`] = a[`repeating_armor_${rowId}_${cur}`];
+ }
+ }
+ return acc;
+ }, {});
+ console.log(attrs);
+ await setAttrsAsync(attrs);
}
on("change:repeating_armor:movementpenalty", async (e) => {
- recalculateMovement();
+ await recalculateMovement();
});
on("clicked:armorapplydamage", async (e) => {
@@ -45,11 +73,13 @@ on("clicked:armorapplydamage", async (e) => {
on("clicked:repeating_armor:resetmdc", async (e) => {
console.log("clicked:repeating_armor:resetmdc", e);
const [r, section, rowId] = e.sourceAttribute.split("_");
- const a = await getAttrsAsync([`repeating_armor_${rowId}_basemdc`]);
+ const a = await getAttrsAsync([`repeating_armor_${rowId}_mdc_max`]);
await setAttrsAsync({
- [`repeating_armor_${rowId}_currentmdc`]:
- a[`repeating_armor_${rowId}_basemdc`],
+ [`repeating_armor_${rowId}_mdc`]: a[`repeating_armor_${rowId}_mdc_max`],
});
});
-on("change:repeating_armor:is_active", (e) => recalculateMovement());
+on("change:repeating_armor:is_active", async (e) => {
+ await recalculateMovement();
+ await applyDamageToNextActiveArmor("armor", 0);
+});
diff --git a/Palladium Rifts by Grinning Gecko/src/js/bonuses.js b/Palladium Rifts by Grinning Gecko/src/js/bonuses.js
index 3e9f9aca30..2567bf96ea 100644
--- a/Palladium Rifts by Grinning Gecko/src/js/bonuses.js
+++ b/Palladium Rifts by Grinning Gecko/src/js/bonuses.js
@@ -94,14 +94,17 @@ async function repeatingAbsoluteAttributes(rowIds, destinationPrefix) {
rowIds.forEach((rowId) => {
const rowFieldAbs = a[`repeating_bonuses_${rowId}_${field}_abs`];
if (Boolean(Number(rowFieldAbs)) == true) {
- rowFieldValue = a[`repeating_bonuses_${rowId}_mod_${field}`];
- fieldAbsValue =
- fieldAbsValue > rowFieldValue ? fieldAbsValue : rowFieldValue;
+ rowFieldValue = +a[`repeating_bonuses_${rowId}_mod_${field}`];
+ fieldAbsValue = +(fieldAbsValue > rowFieldValue
+ ? fieldAbsValue
+ : rowFieldValue);
}
});
if (fieldAbsValue) {
// compare the modified absolute value against the original attribute
- const coreValue = (await getAttrsAsync([field]))[field];
+ // const coreValue = (await getAttrsAsync([field]))[field];
+ const { [field]: rawCoreValue } = await getAttrsAsync([field]);
+ const coreValue = +rawCoreValue;
const newValue = coreValue > fieldAbsValue ? coreValue : fieldAbsValue;
const attr = {
[`${destinationPrefix}_mod_${field}`]: newValue,
@@ -191,6 +194,7 @@ async function combineBonuses(rowIds, destinationPrefix) {
"initiative",
"pull",
"roll",
+ "breakfall",
"strike_range",
"strike_range_single",
"strike_range_burst",
@@ -210,6 +214,9 @@ async function combineBonuses(rowIds, destinationPrefix) {
"dodge_motion",
"dodge_underwater",
"flipthrow",
+ "tackle",
+ "leghook",
+ "backwardsweepkick",
];
const ppExtras = ["disarm", "entangle"];
diff --git a/Palladium Rifts by Grinning Gecko/src/js/combat_skills.js b/Palladium Rifts by Grinning Gecko/src/js/combat_skills.js
new file mode 100644
index 0000000000..fe004de8bf
--- /dev/null
+++ b/Palladium Rifts by Grinning Gecko/src/js/combat_skills.js
@@ -0,0 +1,66 @@
+async function updateHandToHands(section, newCharacterLevel) {
+ const ids = await getSectionIDsAsync(section);
+ const attrNames = ids.map((id) => `repeating_${section}_${id}_name`);
+ const a = await getAttrsAsync(attrNames);
+ for (rowId of ids) {
+ const rowPrefix = `repeating_${section}_${rowId}`;
+ await calculateH2h(
+ section,
+ rowId,
+ rowPrefix,
+ a[`${rowPrefix}_name`],
+ newCharacterLevel
+ );
+ }
+}
+
+async function calculateH2h(section, rowId, keyPrefix, name, level) {
+ console.log("calculateH2h", name, keyPrefix, level);
+ const lowerCaseName = name.toLowerCase();
+ if (!Object.keys(H2H).includes(lowerCaseName)) {
+ // Exit if this isn't one of the pre-defined skills
+ return;
+ }
+ const attrs = {};
+ const levelBonuses = H2H[lowerCaseName].slice(0, level);
+ const totalBonuses = mergeAndAddObjects(levelBonuses);
+ console.log(totalBonuses);
+ for (const [key, val] of Object.entries(totalBonuses)) {
+ attrs[`${keyPrefix}_${key}`] = val;
+ }
+ attrs[`${keyPrefix}_level`] = level;
+ console.log(attrs);
+ await setAttrsAsync(attrs);
+ await addModifierToBonusesAsync(section, rowId);
+}
+
+on("change:repeating_h2h", async (e) => {
+ /**
+ * Allow custom Hand to Hand
+ */
+ if (e.sourceType === "sheetworker") {
+ return;
+ }
+
+ const [r, section, rowId] = e.sourceAttribute.split("_");
+ const rowPrefix = `repeating_${section}_${rowId}`;
+ const { [`${rowPrefix}_name`]: h2hName } = await getAttrsAsync([
+ `${rowPrefix}_name`,
+ ]);
+ const lowerCaseName = h2hName.toLowerCase();
+ if (Object.keys(H2H).includes(lowerCaseName)) {
+ return;
+ }
+
+ console.log("change:repeating_h2h", e);
+ await addModifierToBonusesAsync(section, rowId);
+});
+
+on("change:repeating_h2h:name change:repeating_h2h:level", async (e) => {
+ console.log("change:repeating_h2h:name change:repeating_h2h:level", e);
+ const [r, section, rowId] = e.sourceAttribute.split("_");
+ const rowPrefix = `repeating_${section}_${rowId}`;
+ const { [`${rowPrefix}_level`]: level, [`${rowPrefix}_name`]: h2hName } =
+ await getAttrsAsync([`${rowPrefix}_level`, `${rowPrefix}_name`]);
+ await calculateH2h(section, rowId, rowPrefix, h2hName, +level);
+});
diff --git a/Palladium Rifts by Grinning Gecko/src/js/definitions.js b/Palladium Rifts by Grinning Gecko/src/js/definitions.js
index 600ee0b278..dbe89f9f80 100644
--- a/Palladium Rifts by Grinning Gecko/src/js/definitions.js
+++ b/Palladium Rifts by Grinning Gecko/src/js/definitions.js
@@ -1,3 +1,899 @@
+/**
+ * Run this function in the console, and modify as needed
+ * for other definitions
+ */
+function getKeysFromH2h() {
+ const keys = new Set();
+ Object.entries(H2H).forEach(([name, skill]) => {
+ skill.forEach((level) => {
+ Object.keys(level).forEach((mod) => {
+ keys.add(mod);
+ });
+ });
+ });
+ console.log(JSON.stringify([...keys]));
+}
+
+const H2H = {
+ "hand to hand: basic": [
+ { attacks: 4, pull: 2, roll: 2 },
+ { parry: 2, dodge: 2 },
+ { description: "Kick attack does 1D8 points of damage\n" },
+ { attacks: 1 },
+ { strike: 1, disarm: 1 },
+ { critical: 19 },
+ { damage: 2 },
+ {
+ description:
+ "Judo-style body flip/throw; does 1D6 damage, and victim loses initiative and one attack\n",
+ },
+ { attacks: 1 },
+ { pull: 2, roll: 2 },
+ { parry: 1, dodge: 1 },
+ { strike: 1 },
+ { description: "Critical Strike or knockout from behind\n" },
+ { damage: 2 },
+ { attacks: 1 },
+ ],
+ "hand to hand: expert": [
+ { attacks: 4, pull: 2, roll: 2, description: "kick attack 1D8 damage\n" },
+ { parry: 3, dodge: 3, pull: 1 },
+ { strike: 2, disarm: 2, description: "can perform a Karate Punch\n" },
+ { attacks: 1 },
+ { description: "Can perform a Karate Kick, does 2D6 damage\n" },
+ { critical: 18 },
+ {
+ description:
+ "W.P. Paired Weapons\nbackhand strike (average, does 1D4 damage)\n",
+ },
+ {
+ description:
+ "Body flip/throw; does 1D6 damage, and victim loses initiative and one attack\n",
+ },
+ { attacks: 1, disarm: 1 },
+ { damage: 3 },
+ { knockout: 18 },
+ { parry: 2, dodge: 2 },
+ {
+ description: "Critical Strike or knockout from behind (triple damage)\n",
+ },
+ { attacks: 1 },
+ { deathblow: 20 },
+ ],
+ "hand to hand: martial arts": [
+ {
+ attacks: 4,
+ pull: 3,
+ roll: 3,
+ description:
+ "body flip/throw; does ID6 damage, victim loses initiative and one attack\n",
+ },
+ {
+ parry: 3,
+ dodge: 3,
+ strike: 2,
+ description: "may perform KaÂrate and any hand strike/punch\n",
+ },
+ {
+ initiative: 1,
+ description:
+ "may perform a Karate-style kick (does 2D6 damage) and any foot strike except Leap Kick\n",
+ },
+ { attacks: 1 },
+ {
+ entangle: 2,
+ description: "Leap Kick (3D8 damage, but counts as two melee attacks)\n",
+ },
+ { critical: 18 },
+ { disarm: 2, description: "W.P. Paired Weapons\ncan perform Holds\n" },
+ { description: "Back flip and back flip escape\n" },
+ { attacks: 1 },
+ { disarm: 2, description: "Back flip attack\n" },
+ { damage: 4, initiative: 1 },
+ { parry: 2, dodge: 2 },
+ { knockout: 18 },
+ { attacks: 1 },
+ { deathblow: 20 },
+ ],
+ "hand to hand: assassin": [
+ { attacks: 3, strike: 2, description: "W.P. Paired Weapons\n" },
+ { initiative: 1, attacks: 2 },
+ { pull: 3, roll: 2, description: "Karate Punch (2D4 damage)\n" },
+ { damage: 4, initiative: 1, description: "Karate Kick (2D6 damage)\n" },
+ { attacks: 1, throw: 1 },
+ {
+ parry: 3,
+ dodge: 3,
+ entangle: 2,
+ description: "backhand strike (martial arts 1D6)\n",
+ },
+ {
+ knockout: 17,
+ description: "leap kick (3D8 damage, but counts as two melee attacks)\n",
+ },
+ { attacks: 1, strike_range: 1, initiative: 1 },
+ { initiative: 1 },
+ { critical: 19 },
+ {
+ strike: 2,
+ throw: 1,
+ strike_range: 1,
+ description: "can perform back flip attack\n",
+ },
+ { pull: 2, deathblow: 19 },
+ { attacks: 1 },
+ { damage: 2, description: "can perform Holds\n" },
+ { strike: 2, strike_range: 1 },
+ ],
+ "hand to hand: commando": [
+ {
+ attacks: 4,
+ horrorfactor: 2,
+ description: "W.P. Paired Weapons, body flip/throw, body block/tackle\n",
+ },
+ {
+ initiative: 1,
+ strike: 1,
+ parry: 2,
+ dodge: 2,
+ roll: 3,
+ pull: 3,
+ description:
+ "Backward sweep kick, used only against opponents coming up behind the character. Does no damage; it is purely a knockdown attack (same penalties as body flip) but cannot be parried (an opponent can try to dodge it but is -2 to do so)\n",
+ },
+ {
+ initiative: 1,
+ disarm: 1,
+ description: "Karate punch/strike (does 2D4 damage)\n",
+ },
+ {
+ attacks: 1,
+ description:
+ "Karate kick (does 2D6). The karate-style kick starts with bringing the knee, folded, up to chest level, then the foot is completely extended\n",
+ },
+ { dodge_auto: 2, description: "Automatic dodge, all foot strikes\n" },
+ { initiative: 1, strike: 1, parry: 1, dodge: 1, flipthrow: 1 },
+ { damage: 2, horrorfactor: 1, disarm: 1, dodge_auto: 1, pull: 2 },
+ { attacks: 1, flipthrow: 2, roll: 1 },
+ { deathblow: 18, pull: 2 },
+ { horrorfactor: 2, initiative: 1, strike: 1 },
+ { disarm: 1, pull: 1, flipthrow: 2 },
+ { damage: 2, parry: 1, dodge: 1, dodge_auto: 2 },
+ { attacks: 1 },
+ { initiative: 1, description: "Can perform holds\n" },
+ { critical: 17 },
+ ],
+ "hand to hand: aikido": [
+ {
+ attacks: 4,
+ breakfall: 3,
+ roll: 2,
+ flipthrow: 2,
+ pull: 2,
+ mod_pp: 1,
+ mod_pe: 1,
+ description: "+2D6 S.D.C., +1D4 to M.E.\n",
+ },
+ { initiative: 1, parry: 2, dodge: 2 },
+ { disarm: 1, description: "Automatic dodge\n" },
+ { attacks: 1, flipthrow: 1 },
+ {
+ description:
+ "Critical body flip/throw on Natural 18-20 (double damage)\n",
+ },
+ { parry: 1, dodge: 1, flipthrow: 1 },
+ { pull: 2, description: "Automatic flip/throw\n" },
+ { attacks: 1 },
+ { initiative: 1, strike: 1, parry: 1, dodge: 1 },
+ { disarm: 1, description: "Double existing P.P.E. (inner spirit)\n" },
+ { parry: 1, dodge: 2, flipthrow: 1 },
+ { attacks: 1 },
+ { initiative: 1, tackle: 2 },
+ { critical: 18 },
+ { attacks: 1 },
+ ],
+ "hand to hand: judo": [
+ {
+ attacks: 4,
+ roll: 3,
+ pull: 3,
+ mod_me: 1,
+ mod_pp: 1,
+ description:
+ "+2D4 S.D.C.\nBody block/tackle, body flip/throw, break fall, disarm, roll with punch/fall/impact, strike, parry, dodge, and pull punch are available at first level.\n",
+ },
+ { parry: 2, dodge: 2, strike: 1 },
+ { flipthrow: 1, tackle: 1, disarm: 1 },
+ { attacks: 1, description: "Karate-style kick (2D6 damage).\n" },
+ { critical: 19 },
+ { strike: 1, parry: 1, dodge: 1, flipthrow: 1 },
+ { damage: 2, description: "W.P. Paired Weapons\n" },
+ { roll: 1, description: "Jump kick\n" },
+ { attacks: 1 },
+ { initiative: 2, parry: 1, dodge: 1 },
+ { breakfall: 1, disarm: 1 },
+ { critical: 18 },
+ { damage: 2, knockout: 19 },
+ { attacks: 1 },
+ { description: "Automatic body flip/throw.\n" },
+ ],
+ "hand to hand: jujitsu": [
+ {
+ mod_ps: 2,
+ mod_pp: 1,
+ attacks: 4,
+ roll: 3,
+ parry: 2,
+ dodge: 2,
+ pull: 2,
+ description:
+ "+3D6 S.D.C.\nsnap kick (1D6 damage), knife hand (2D4 damage)\nMaintain balance, break fall, disarm, body block/tackle, body flip/throw, holds, roll with punch/fall/impact, pull punch, kick attack (2D4 damage), knee and elbow strikes (1D6 damage), and the usual strike, parry and dodge.\n",
+ },
+ { strike: 1, leghook: 1, backwardsweepkick: 1 },
+ { initiative: 1, description: "Critical strike from behind.\n" },
+ { attacks: 1, damage: 2 },
+ { description: "Palm strike (2D4 damage) and drop kick.\n" },
+ { critical: 18 },
+ { strike: 1, flipthrow: 1, disarm: 1 },
+ { attacks: 1, maintainbalance: 1 },
+ { description: "Critical body flip/throw on natural 1 7-20.\n" },
+ { description: "Jump kick and leap attacks.\n" },
+ { attacks: 1, pull: 2 },
+ { initiative: 1, parry: 1, dodge: 1, strike: 1 },
+ { damage: 2, pull: 2, breakfall: 2 },
+ { attacks: 1 },
+ { description: "Death blow!\n" },
+ ],
+ "hand to hand: karate": [
+ {
+ mod_pe: 2,
+ mod_spd: 2,
+ attacks: 4,
+ initiative: 1,
+ roll: 2,
+ parry: 2,
+ dodge: 1,
+ breakfall: 1,
+ pull: 2,
+ description:
+ "+3D6 S.D.C., +1D4 to P.S.\nBreak fall, body block/tackle, roll with punch/fall/impact, pull punch, kick atÂtack (2D4 damage), karate kick (2D6 damage), karate punch (2D4 damage), knees and elbow strikes (1D6 damage), and the usual strike, parry and dodge.\n",
+ },
+ { strike: 1, leghook: 1, backwardsweepkick: 1 },
+ { attacks: 1, damage: 2 },
+ {
+ initiative: 1,
+ disarm: 1,
+ description: "roundhouse kick (3D6 damage).\n",
+ },
+ { description: "Power punch and palm strike (2D4 damage).\n" },
+ { attacks: 1, pull: 2 },
+ {
+ strike: 1,
+ parry: 1,
+ breakfall: 1,
+ description: "Power kick, wheel kick\n",
+ },
+ {
+ critical: 18,
+ deathblow: 20,
+ description: "critical strike from behind.\n",
+ },
+ { attacks: 1, damage: 2 },
+ { description: "Jump kick and leap attacks.\n" },
+ { initiative: 1, parry: 1, dodge: 1, strike: 1 },
+ { attacks: 1, pull: 2 },
+ { description: "Death Blow!\n" },
+ { damage: 2, pull: 2, breakfall: 2 },
+ { attacks: 1 },
+ ],
+ "hand to hand: kendo": [
+ {
+ mod_ps: 1,
+ mod_pp: 1,
+ mod_spd: 2,
+ attacks: 4,
+ initiative: 1,
+ roll: 2,
+ disarm: 1,
+ parry: 1,
+ dodge: 1,
+ breakfall: 1,
+ pull: 2,
+ description:
+ "+2D4 S.D.C.\n+2 to parry with sword or staff (in addition to W.P. bonuses)\nDisarm, break fall, roll with punch/fall/impact, pull punch, karate punch (2D4 damage), kick attack (2D4), knees and elbow strikes (1D6 damage), and the usual strike, parry and dodge.\n",
+ },
+ { strike: 1, description: "W.P. Paired Weapons\n" },
+ { attacks: 1, damage: 2 },
+ { initiative: 1, disarm: 1, parry: 1 },
+ { description: "Tripping/leg hook and backward sweep kicks.\n" },
+ { description: "Power punch and palm strike (2D4 damage).\n" },
+ { attacks: 1, pull: 2 },
+ {
+ critical: 18,
+ deathblow: 19,
+ description: "critical strike from behind\n",
+ },
+ { attacks: 1, damage: 4 },
+ { description: "Automatic dodge.\n" },
+ { initiative: 1, strike: 1, breakfall: 2 },
+ { attacks: 1, pull: 2 },
+ { description: "Jump kick and leap attacks.\n" },
+ { description: "Death Blow!\n" },
+ { attacks: 1 },
+ ],
+ "hand to hand: ninjitsu": [
+ {
+ mod_ma: 2,
+ mod_ps: 1,
+ mod_pe: 1,
+ mod_pp: 1,
+ mod_spd: 4,
+ attacks: 4,
+ roll: 2,
+ initiative: 2,
+ parry: 1,
+ dodge: 2,
+ pull: 2,
+ description:
+ "snap kick (1D6 damÂage), knife hand (2D4 damage)\nW.P. Paired Weapons\nMaintain balance, back flip, body block/tackle, body flip/throw, holds, roll with punch/fall/impact, pull punch, drop kick, kick attack (2D4 damage), knee and elbow strikes (1D6 damage), paired weapons, and the usual strike, parry and dodge. Also see Samurai Hand to Hand combat.",
+ },
+ {
+ strike: 1,
+ description:
+ "cartwheel (attack), back flip (escape), back flip (defensive), and back flip (attack).\n",
+ },
+ { attacks: 1, description: "palm strike (2D4 damage).\n" },
+ {
+ description:
+ "Leap attack, axe kick, and +2 to strike when performing any backflip or cartwheel.\n",
+ },
+ { description: "Tripping/leg hook and backward sweep kicks\n", damage: 2 },
+ { attacks: 1, description: "roundhouse kick (3D6).\n" },
+ { critical: 18, deathblow: 20, description: "Critical from behind.\n" },
+ { initiative: 1, strike: 1, parry: 1, roll: 1, maintainbalance: 2 },
+ { description: "Death Blow!\n" },
+ { attacks: 1, pull: 2 },
+ { description: "Double existing P.P.E. (inner spirit)!\n" },
+ { initiative: 1, roll: 2 },
+ { damage: 2, disarm: 1 },
+ { damage: 2, description: "Jump kick, +2 to back flip/cartwheel\n" },
+ { attacks: 1 },
+ ],
+ "hand to hand: samurai": [
+ {
+ mod_me: 2,
+ mod_pp: 2,
+ mod_pe: 1,
+ attacks: 4,
+ initiative: 2,
+ roll: 2,
+ dodge: 3,
+ damage: 2,
+ pull: 2,
+ description:
+ "+3D6 S.D.C.\n+2 to parry with sword or staff (in addition to W.P. bonuses)\nDisarm, maintain balance, roll with punch/fall/im pact, pull punch, Karate punch (2D4 damage), kick attack (2D4), knee and elbow strikes (1D6 damage), and the usual strike, parry and dodge.\n",
+ },
+ { attacks: 1, disarm: 1, maintainbalance: 1 },
+ {
+ initiative: 1,
+ strike: 1,
+ parry: 1,
+ deathblow: 20,
+ description: "critical strike from behind\n",
+ },
+ { attacks: 1, damage: 2 },
+ { critical: 18, maintainbalance: 1 },
+ { roll: 1, dodge: 1, maintainbalance: 1 },
+ {
+ description:
+ "Power punch/stab (with hand or sword), jump kick and backward sweep kick.\n",
+ },
+ { attacks: 1, dodge: 1 },
+ { description: "Death Blow!\n" },
+ { initiative: 1, horrorfactor: 1, maintainbalance: 1 },
+ { attacks: 1 },
+ {
+ damage: 2,
+ horrorfactor: 1,
+ description:
+ 'the knowledge and skill to create a "true" samurai sword.\n',
+ },
+ { attacks: 1 },
+ { disarm: 1, description: "Double existing P.P.E. (inner spirit)\n" },
+ { attacks: 1 },
+ ],
+ "hand to hand: teng-jutsu": [
+ {
+ attacks: 4,
+ dodge: 2,
+ pull: 2,
+ disarm: 1,
+ roll: 1,
+ maintainbalance: 3,
+ breakfall: 1,
+ description:
+ "Break fall, roll with punch/fall/impact, maintain balance, back flip escape, back flip attack, cartwheel (attack), body block/tackle, pull punch, kick attack (2D4 damage), karate kick (2D6 damage), karate punch (2D4 damage), knees and elbow strikes (1D6 damage), and the usual strike, parry and dodge, plus the Tengu special mystic martial art powers.\n",
+ },
+ {
+ initiative: 1,
+ description: "Drop kick, +2 on all back flips.\n",
+ },
+ { strike: 1, disarm: 1, description: "+1 to leap dodge." },
+ { attacks: 1 },
+ {
+ description:
+ "Critical strike from all kicks (double damage) and jump kick and leap attacks.\n",
+ },
+ { roll: 1, pull: 2, description: "+ 1 to leap dodge.\n" },
+ {
+ initiative: 1,
+ description: "tripping/leg hook and backward sweep kicks.\n",
+ },
+ { attacks: 1 },
+ {
+ disarm: 2,
+ description: "+1 on all back flips, and +1 on cartwheel attack.\n",
+ },
+ { initiative: 1, parry: 1, description: "Axe kick\n" },
+ { attacks: 1 },
+ { disarm: 1, description: "+1 to leap dodge\n" },
+ { description: "Snap kick and wheel kick.\n" },
+ { pull: 1, description: "+1 to leap dodge\n" },
+ { attacks: 1 },
+ ],
+ "hand to hand: dragon": [
+ {
+ attacks: 3,
+ roll: 2,
+ pull: 1,
+ description:
+ "Instinctively knows the following attack types: Bite, punch, kick, Claw Swipe, and standard use of breath weapon (counts as one melee attack). Dragon metamorÂphosis takes one full melee (15 seconds).\n",
+ },
+ {
+ parry: 2,
+ dodge: 2,
+ description: "Tail Slap, Wing AtÂtack: Basic, and Crush\n",
+ },
+ {
+ damage: 2,
+ description:
+ "Dragon metamorphosis takes half a melee round (7 secÂonds), and Tail Slap Power Strike\n",
+ },
+ { attacks: 1, description: "Bite & Grip, and Tail Sweep\n" },
+ { strike: 1, parry: 1, dodge_flight: 2, description: "Tail Parry\n" },
+ {
+ mod_spellstrength: 1,
+ description: "gains the Wing Sweep and Grappling Hold.\n",
+ },
+ { disarm: 2, entangle: 2, pull: 2, description: "Wing Attack: Advanced\n" },
+ {
+ attacks: 1,
+ strike: 1,
+ parry: 1,
+ dodge_flight: 1,
+ description: "Wing Gliding Sweep Attack\n",
+ },
+ {
+ roll: 1,
+ pull: 1,
+ description:
+ "Gains Breath Weapon Concentrated Beam, and an additional +5% to Dimensional Teleport (a natural ability).\n",
+ },
+ { initiative: 1, critical: 19, description: "Teleport Dodge\n" },
+ { damage: 2, dodge_flight: 2, mod_spellstrength: 1 },
+ { attacks: 1, strike: 1, dodge_teleport: 1 },
+ { initiative: 1, description: "Breath Weapon Cone\n" },
+ { dodge_teleport: 1, pull: 1 },
+ { mod_spellstrength: 1, description: "+ 1D4x10 to M.D.C\n" },
+ { attacks: 1, damage: 2 },
+ { dodge_teleport: 1, dodge_flight: 1 },
+ { strike: 1, parry: 1, description: "+ 1 to Spell Strength\n" },
+ {
+ dodge_teleport: 1,
+ disarm: 1,
+ roll: 1,
+ description: "+1D4x10 to physical M.D.C.\n",
+ },
+ { attacks: 1 },
+ ],
+ "rpa combat: basic": [
+ {
+ attacks: 1,
+ strike: 1,
+ parry: 1,
+ dodge: 1,
+ roll: 1,
+ description:
+ "Power Armor Body Block/Tackle/Ram: 1D4 M.D. plus a 01-50% chance of knocking an opponent down, causing him to lose initiative and one melee attack/action. Counts as two of the power armor's melee attacks.\n" +
+ "Robot Body Block/Tackle/Ram: M.D. equal to Robot Punch M.D. plus a 01-60% chance of knocking down an opponent that is approxi mately the same size or larger. Increase the odds of knocking down an opponent that is half the size or smaller than the robot to 0 1 -80%. The victim suffers M.D. and loses initiative and two melee attacks/actions. Counts as two ofthe robot's melee attacks.\n",
+ },
+ ],
+ "rpa combat: flying power armor": [
+ {
+ attacks: 1,
+ initiative: 2,
+ strike_range: 2,
+ strike: 2,
+ parry: 2,
+ dodge: 2,
+ dodge_flight: 5,
+ disarm: 2,
+ pull: 3,
+ roll: 4,
+ description:
+ "Punch Damage: As per Robot (or Augmented) P.S.\nPower Punch: Double damage, but counts as two melee attacks. Tear or Pry with Hands: 1D4 M.D.\nKick Damage: As per Robot (or Augmented) P.S.\nBody B1ock/Ram: Equal to the Robot P.S. punch damage.\nFull Speed Running Ram: Double Robot P.S. punch damage, plus 01-60% likelihood of knocking an opponent off his feet if the opponent is the same size or smaller (reduce by half if twice as big). Victim takes M.D. and is knocked off his feet, losing initiative and two melee atÂtacks/actions.\n",
+ },
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ ],
+ "rpa combat: ground-based power armor": [
+ {
+ attacks: 1,
+ initiative: 1,
+ strike_range: 2,
+ strike: 3,
+ parry: 2,
+ dodge: 2,
+ disarm: 3,
+ pull: 3,
+ roll: 2,
+ description:
+ "Punch Damage: As per Robot (or Augmented) P.S.\nPower Punch: Double damage, but counts as two melee attacks.\nTear or Pry with Hands: 1D4 M.D.\nKick Damage: As per Robot (or Augmented) P.S.\nBody B1ock/Ram: Equal to the Robot P.S. punch damage.\nFull Speed Running Ram: Double Robot P.S. punch damage, plus 01-50% likelihood of knocking an opponent off his feet if the opponent is the same size or smaller (reduce by half if twice as big). Victim takes M.D. and is knocked off his feet, losing initiative and two melee atÂtacks/actions.\n",
+ },
+ {},
+ { attacks: 1 },
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ ],
+ "rpa combat: heavy vehicular style robots": [
+ {
+ attacks: 1,
+ initiative: 1,
+ strike_range: 3,
+ strike: 1,
+ parry: 1,
+ dodge: 1,
+ dodge_motion: 2,
+ roll: 1,
+ description:
+ "Punch/Kick Damage: As per Robot P.S.\n" +
+ "Power Punch/Kick: Double damage, but counts as two melee attacks.\n" +
+ "Kick Damage: As per Robot P.S.\n" +
+ "Body Block/Ram: Equal to the Robot P.S. punch damage.\n" +
+ "Full Speed Running Ram: Triple the Robot P.S. punch damage, plus 01-80% likelihood of knocking opponent off his feet if the opponent is the same size or smaller. Victim takes M.D. and is knocked off his feet, losing initiative and two melee attacks/actions.\n" +
+ "Stomp: 1D6 M.D.; effective only against objects smaller than one third the robot's total height.\n",
+ },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ ],
+ "rpa combat: heavy ground robots": [
+ {
+ attacks: 1,
+ initiative: 1,
+ strike_range: 1,
+ strike: 2,
+ parry: 3,
+ dodge: 1,
+ dodge_motion: 2,
+ disarm: 1,
+ pull: 2,
+ roll: 3,
+ description:
+ "Punch Damage: As per Robot P.S.\n" +
+ "Power Punch: Double damage, but counts as two melee attacks.\n" +
+ "Tear or Pry with Hands: 1D6 M.D.\n" +
+ "Kick Damage: As per Robot P.S.\n" +
+ "Body Block/Ram: Equal to the Robot P.S. punch damage.\n" +
+ "Full Speed Running Ram: Double the Robot P.S. punch damage, plus 01-85% likelihood of knocking opponent off his feet if the opponent is the same size or smaller. Victim takes M.D. and is knocked off his feet, losing initiative and two melee attacks/actions.\n" +
+ "Stomp: 1D6 M.D.; effective only against objects smaller than one third the robot's total height.\n",
+ },
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ ],
+ "rpa combat: light ground robots": [
+ {
+ attacks: 1,
+ initiative: 2,
+ strike_range: 1,
+ strike: 3,
+ parry: 3,
+ dodge: 2,
+ dodge_motion: 3,
+ disarm: 2,
+ pull: 4,
+ roll: 4,
+ description:
+ "Punch Damage: As per Robot P.S.\n" +
+ "Power Punch: Double damage, but counts as two melee attacks.\n" +
+ "Tear or Pry with Hands: 1D4 M.D.\n" +
+ "Kick Damage: As per Robot P.S.\n" +
+ "Body Block/Ram: Equal to the Robot P.S. punch damage.\n" +
+ "Full Speed Running Ram: Double the Robot P.S. punch damage, plus 01-70% likelihood of knocking opponent off his feet if the opponent is the same size or smaller. Victim takes M.D. and is knocked off his feet, losing initiative and two melee attacks/actions.\n" +
+ "Stomp: 1D4 M.D.; effective only against objects smaller than one third the robot's total height.\n",
+ },
+ {},
+ { attacks: 1 },
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ ],
+ "rpa combat: glitter boy": [
+ {
+ attacks: 2,
+ initiative: 2,
+ strike_range: 2,
+ strike: 2,
+ parry: 2,
+ dodge: 2,
+ disarm: 1,
+ pull: 4,
+ roll: 3,
+ description:
+ "Punch Damage: 1D4 M.D. on a restrained punch, 1D6 M.D. on a full strength punch.\n" +
+ "Power Punch: 2D6 M.D., but counts as two melee attacks.\n" +
+ "Kick Damage: 2D4 M.D., Power Kick is not possible.\n" +
+ "Running Leap Kick: 4D6 M.D., but counts as three attacks.\n" +
+ "Tear or Pry with Hands (Special): 1D6 M.D.\n" +
+ "Body BlocklRam: 2D4 M.D.\n" +
+ "Full Speed Running Ram: 3D6 M.D., but this attack uses up three melee actions.\n" +
+ "Stomp: 1D6 M.D.; effective only against objects smaller than three feet (0.9 m) tall.\n" +
+ "Pylon Impalement: 1D6 M.D., not very useful in most combat situaÂtions.\n",
+ },
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ {},
+ ],
+ "rpa combat: silverhawk": [
+ {
+ strike: 2,
+ parry: 4,
+ dodge: 4,
+ dodge_flight: 6,
+ roll: 3,
+ pull: 2,
+ attacks: 2,
+ description:
+ "Restrained Punch - 1D6 M.D.\n" +
+ "Full Strength Punch - 3D6 M.D.\n" +
+ "Power Punch - 6D6 M.D. (counts as two attacks) Kick - 4D6 M.D.\n" +
+ "Leap Kick - 6D6 +3 (counts as two attacks) Body Block/Ram (on the ground) - 2D6 M.D.\n" +
+ "Body Block/Ram (flying) - 4D6 M.D.\n",
+ },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ ],
+ "rpa combat: battleram": [
+ {
+ strike: 1,
+ parry: 1,
+ dodge_flight: 1,
+ description:
+ "Restrained Punch - 4D6 M.D.\n" +
+ "Full Strength Punch - 2D6x10 M.D.\n" +
+ "Power Punch - 4D6x10 M.D. (counts as two attacks)\n" +
+ "Crush, Pry or Tear - 2D6x10 M.D.\n" +
+ "Kick - 3D4x10 M.D.\n" +
+ "Leap Kick (only while flying) - 4D6x10 M.D.\n" +
+ "Body Flip/Throw - 4D6 M.D.\n" +
+ "Body BlocklRam (on the ground ) - 2D4x10 M.D.\n" +
+ "Flying Ram - 5D6x10 M.D.\n" +
+ "Stomp - 6D6 M.D. against targets 15 feet (4.5 m) tall or smaller.\n",
+ },
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ ],
+ "rpa combat: bombard": [
+ {
+ strike: 2,
+ parry: 4,
+ dodge: 2,
+ roll: 3,
+ pull: 4,
+ attacks: 2,
+ description:
+ "Restrained Punch - 1D6 M.D.\n" +
+ "Full Strength Punch - 2D6 M.D.\n" +
+ "Power Punch - 4D6 M.D. (counts as two attacks) Vibro-blade - 4D6 M.D.\n" +
+ "Crush, Pry or Tear - 1D6 M.D.\n" +
+ "Kick - 2D6 M.D.\n" +
+ "Body Flip/Throw - 1D6 M.D.\n" +
+ "Body Block/Ram - 2D4 M.D.\n" +
+ "Stomp - 2D4 M.D. against man-sized targets\n",
+ },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ ],
+ "space fighter: basic": [
+ {
+ attacks: 1,
+ strike_range: 2,
+ dodge_flight: 3,
+ description:
+ "+1 to dog-fighting rolls\n" +
+ "Critical strike, same as pilot's hand to hand.\n",
+ },
+ {},
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ {},
+ ],
+ "space fighter: elite": [
+ {
+ attacks: 2,
+ strike_range: 2,
+ dodge_flight: 5,
+ description:
+ "+3 to dog-fighting rolls\n" +
+ "Critical strike, same as pilot's hand to hand.\n",
+ },
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ {},
+ { attacks: 1 },
+ {},
+ {},
+ {},
+ {},
+ {},
+ ],
+};
+
+const H2H_KEYS = [
+ "name",
+ "level",
+ "attacks",
+ "pull",
+ "roll",
+ "breakfall",
+ "parry",
+ "dodge",
+ "description",
+ "strike",
+ "disarm",
+ "critical",
+ "damage",
+ "knockout",
+ "deathblow",
+ "initiative",
+ "entangle",
+ "throw",
+ "strike_range",
+ "horrorfactor",
+ "dodge_auto",
+ "flipthrow",
+ "tackle",
+ "leghook",
+ "backwardsweepkick",
+ "maintainbalance",
+ "dodge_flight",
+ "dodge_teleport",
+ "dodge_motion",
+ "mod_spellstrength",
+ "mod_me",
+ "mod_ma",
+ "mod_ps",
+ "mod_pp",
+ "mod_pe",
+ "mod_spd",
+];
+
const WP = {
"w.p. archery": [
{ strike: 1, parry: 1, rof: 2 },
@@ -546,6 +1442,7 @@ const COMBAT_KEYS = [
"entangle",
"pull",
"roll",
+ "breakfall",
"damage",
"damage_paired",
"damage_mainhand",
@@ -574,6 +1471,9 @@ const COMBAT_KEYS = [
"knockout",
"deathblow",
"flipthrow",
+ "tackle",
+ "leghook",
+ "backwardsweepkick",
"description",
];
const SAVE_KEYS_ATTRIBUTE_BONUSES = {
@@ -607,6 +1507,7 @@ const SKILL_KEYS = [
"perlevel",
"level",
"total",
+ "description",
];
const ABILITIES_REPEATERS = ["magic", "psionics", "powersabilities"];
@@ -622,19 +1523,20 @@ const MAGIC_KEYS = REPEATING_BONUS_KEYS.concat([
"ppecost",
"range_starting",
"range_per_level",
- "range_units",
+ "range_unit",
"damage_starting",
"damage_per_level",
- "damage_units",
+ "damage_unit",
"dc_starting",
"dc_per_level",
- "dc_units",
+ "dc_unit",
"duration_starting",
"duration_per_level",
- "duration_units",
+ "duration_unit",
"percentage_starting",
"percentage_per_level",
"addtobonuses",
+ "description",
]);
const PSIONICS_KEYS = REPEATING_BONUS_KEYS.concat([
@@ -646,19 +1548,20 @@ const PSIONICS_KEYS = REPEATING_BONUS_KEYS.concat([
"ispcost",
"range_starting",
"range_per_level",
- "range_units",
+ "range_unit",
"damage_starting",
"damage_per_level",
- "damage_units",
+ "damage_unit",
"dc_starting",
"dc_per_level",
- "dc_units",
+ "dc_unit",
"duration_starting",
"duration_per_level",
- "duration_units",
+ "duration_unit",
"percentage_starting",
"percentage_per_level",
"addtobonuses",
+ "description",
]);
const ABILITIES_KEYS = REPEATING_BONUS_KEYS.concat([
@@ -669,22 +1572,23 @@ const ABILITIES_KEYS = REPEATING_BONUS_KEYS.concat([
"percentage",
"range_starting",
"range_per_level",
- "range_units",
+ "range_unit",
"damage_starting",
"damage_per_level",
- "damage_units",
+ "damage_unit",
"dc_starting",
"dc_per_level",
- "dc_units",
+ "dc_unit",
"duration_starting",
"duration_per_level",
- "duration_units",
+ "duration_unit",
"frequency_starting",
"frequency_per_level",
- "frequency_units",
+ "frequency_unit",
"percentage_starting",
"percentage_per_level",
"addtobonuses",
+ "description",
]);
const PROFILES_KEYS = REPEATING_BONUS_KEYS.concat(["bonus_ids", "bonus_names"]);
@@ -754,19 +1658,14 @@ const CORE_KEYS = [
"credits_blackmarketmerchandise",
];
-const ARMOR_KEYS = [
- "is_active",
- "name",
- "movementpenalty",
- "basemdc",
- "currentmdc",
-];
+const ARMOR_KEYS = ["is_active", "name", "movementpenalty", "mdc", "mdc_max"];
const MOVEMENT_KEYS = ["name", "mph", "ft_melee", "cruising", "dur_at_max"];
const EQUIPMENT_KEYS = ["equipment"];
const SECTIONS = {
+ h2h: H2H_KEYS,
wp: WP_KEYS.wp,
wpmodern: WP_KEYS.wpmodern,
skills: SKILL_KEYS,
diff --git a/Palladium Rifts by Grinning Gecko/src/js/import_export.js b/Palladium Rifts by Grinning Gecko/src/js/import_export.js
index 364c065ec1..a5bf2f84d7 100644
--- a/Palladium Rifts by Grinning Gecko/src/js/import_export.js
+++ b/Palladium Rifts by Grinning Gecko/src/js/import_export.js
@@ -33,6 +33,7 @@
on("clicked:export", async (e) => {
console.log("export", e);
const attrs = {};
+ attrs.h2h = await getRepeatingRowsAsync("h2h");
attrs.wp = await getRepeatingRowsAsync("wp");
attrs.wpmodern = await getRepeatingRowsAsync("wpmodern");
attrs.skills = await getRepeatingRowsAsync("skills");
@@ -98,6 +99,7 @@
// importAll(data);
// return;
await setAttrsAsync(data.core);
+ await setRepeatingRowsAsync("h2h", data.h2h);
await setRepeatingRowsAsync("wp", data.wp);
await setRepeatingRowsAsync("wpmodern", data.wpmodern);
await setRepeatingRowsAsync("skills", data.skills);
diff --git a/Palladium Rifts by Grinning Gecko/src/js/migrate.js b/Palladium Rifts by Grinning Gecko/src/js/migrate.js
index 7543fb33fd..0e9c1dc738 100644
--- a/Palladium Rifts by Grinning Gecko/src/js/migrate.js
+++ b/Palladium Rifts by Grinning Gecko/src/js/migrate.js
@@ -12,6 +12,21 @@ async function migrateAttributes() {
},
],
},
+ {
+ version: "1.2.0",
+ attributes: [
+ {
+ repeating: ["armor"],
+ from: "currentmdc",
+ to: ["mdc"],
+ },
+ {
+ repeating: ["armor"],
+ from: "basemdc",
+ to: ["mdc_max"],
+ },
+ ],
+ },
];
const { version, migrated } = await getAttrsAsync(["version", "migrated"]);
diff --git a/Palladium Rifts by Grinning Gecko/src/js/profiles.js b/Palladium Rifts by Grinning Gecko/src/js/profiles.js
index 75d161d260..7d3663fe84 100644
--- a/Palladium Rifts by Grinning Gecko/src/js/profiles.js
+++ b/Palladium Rifts by Grinning Gecko/src/js/profiles.js
@@ -3,6 +3,24 @@ async function getDefaultProfileID() {
return default_profile;
}
+async function updateActiveProfile(rowId) {
+ console.log("updateActiveProfile", REPEATING_BONUS_KEYS.length);
+ const attrKeys = REPEATING_BONUS_KEYS.map(
+ (key) => `repeating_profiles_${rowId}_${key}`
+ );
+ const a = await getAttrsAsync(attrKeys);
+ const attrs = REPEATING_BONUS_KEYS.reduce((acc, cur, idx) => {
+ if (a[`repeating_profiles_${rowId}_${cur}`] !== undefined) {
+ acc[`active_profile_${cur}`] = a[`repeating_profiles_${rowId}_${cur}`];
+ acc[`active_profile_${cur}_max`] =
+ a[`repeating_profiles_${rowId}_${cur}`];
+ }
+ return acc;
+ }, {});
+ console.log(attrs);
+ await setAttrsAsync(attrs);
+}
+
async function updateProfile(rowId) {
const bonusIds = (
await getAttrsAsync(["repeating_profiles_bonus_ids"])
@@ -20,6 +38,10 @@ async function updateProfile(rowId) {
[`repeating_profiles_${rowId}_rowid`]: `repeating_profiles_${rowId}_`,
});
await combineBonuses(bonusIds, `repeating_profiles_${rowId}`);
+ const isActive = await isDefault("profiles", rowId);
+ if (isActive) {
+ await updateActiveProfile(rowId);
+ }
}
async function setSingleAttributeFromDefaultProfile(attrName, profileAttrName) {
@@ -124,6 +146,7 @@ on("change:default_profile", async (e) => {
const a = await getAttrsAsync([`${prefix}_mdc`]);
await setAttrsAsync({ default_mdc: a[`${prefix}_mdc`] });
await updateSkills();
+ await updateActiveProfile(e.newValue);
});
on("change:repeating_profiles:is_default", async (e) => {
@@ -212,32 +235,10 @@ on("clicked:getdefaultprofile", async (e) => {
console.log(a);
});
-/**
- * Add a token {attack} times to the Turn Tracker in order against other tokens.
- * Requires API script access.
- * For use on an action button.
- *
- * [[d20+@{selected|repeating_profiles_-MibcwHG5hZXUJn6A7OG_initiative} &{tracker}]]
- */
-async function palladiumAddToTurnTracker(e) {
- const [r, section, rowId] = e.sourceAttribute.split("_");
- const rowPrefix = `${r}_${section}_${rowId}`;
- const {
- [`${rowPrefix}_initiative`]: init,
- [`${rowPrefix}_attacks`]: attacks,
- } = await getAttrsAsync([`${rowPrefix}_initiative`, `${rowPrefix}_attacks`]);
- const roll = await startRoll(
- `&{template:test} {{name=Test}} {{roll1=[[1d20]]}}`
+on("clicked:active_profile_initiative_turntracker", async (e) => {
+ console.log("clicked:active_profile_initiative_turntracker", e);
+ await palladiumAddToTurnTracker(
+ "active_profile_initiative",
+ "active_profile_attacks"
);
- console.log(roll);
- const computed = roll.results.roll1.result + init;
- console.log(computed);
- finishRoll(roll.rollId, {
- roll1: computed,
- });
- const addToTracker = await startRoll(`[[[[${computed}]] &{tracker}]]`);
- finishRoll(addToTracker.rollId);
- // https://app.roll20.net/forum/post/6817409/multiple-initiative-values-for-a-single-character/?pageforid=6817748#post-6817748
- const dupeTracker = await startRoll(`!dup-turn ${attacks}`);
- finishRoll(dupeTracker.rollId);
-}
+});
diff --git a/Palladium Rifts by Grinning Gecko/src/js/skills.js b/Palladium Rifts by Grinning Gecko/src/js/skills.js
index d05afc9d18..72b4e778ce 100644
--- a/Palladium Rifts by Grinning Gecko/src/js/skills.js
+++ b/Palladium Rifts by Grinning Gecko/src/js/skills.js
@@ -105,7 +105,9 @@ async function updateSkillLevels(newCharacterLevel, oldCharacterLevel) {
on("change:repeating_skills", async (e) => {
console.log("change:repeating_skills", e);
- if (e.sourceType === "sheetworker") return;
+ if (e.sourceType === "sheetworker" && !e.sourceAttribute.endsWith("_level")) {
+ return;
+ }
if (e.sourceAttribute.endsWith("_name")) return;
const sourceParts = e.sourceAttribute.split("_");
// Return if no attribute is changed and it's the row itself
diff --git a/Palladium Rifts by Grinning Gecko/src/js/utils.js b/Palladium Rifts by Grinning Gecko/src/js/utils.js
index ae86c6683b..7b4523198b 100644
--- a/Palladium Rifts by Grinning Gecko/src/js/utils.js
+++ b/Palladium Rifts by Grinning Gecko/src/js/utils.js
@@ -258,7 +258,11 @@ function mergeAndAddObjects(data) {
data.forEach((obj) => {
for (let [key, value] of Object.entries(obj)) {
if (result[key]) {
- result[key] += value;
+ if (key === "critical" || key === "knockout" || key === "deathblow") {
+ result[key] = result[key] > value ? value : result[key];
+ } else {
+ result[key] += value;
+ }
} else {
result[key] = value;
}
@@ -280,3 +284,34 @@ async function getSectionIDsOrderedAsync(sectionName) {
];
return ids;
}
+
+/**
+ * Add a token {attack} times to the Turn Tracker in order against other tokens.
+ * Requires API script access.
+ * For use on an action button.
+ *
+ * [[d20+@{selected|repeating_profiles_-MibcwHG5hZXUJn6A7OG_initiative} &{tracker}]]
+ */
+async function palladiumAddToTurnTracker(initKey, attacksKey) {
+ const { [initKey]: init, [attacksKey]: attacks } = await getAttrsAsync([
+ initKey,
+ attacksKey,
+ ]);
+ const initString = init > 0 ? `+${init}` : `${init}`;
+ const roll = await startRoll(
+ `&{template:initiative} {{title=@{selected|character_name} rolls initiative!}} {{diceroll=[[1d20]]}} {{modifier=${initString}}}`
+ );
+ console.log(roll);
+ const computed = roll.results.diceroll.result + init;
+ console.log(computed);
+ finishRoll(roll.rollId, {
+ diceroll: computed,
+ });
+ const addToTracker = await startRoll(
+ `Setting @{selected|character_name}'s initiative to [[[[${computed}]] &{tracker}]] in the Turn Tracker.`
+ );
+ finishRoll(addToTracker.rollId);
+ // https://app.roll20.net/forum/post/6817409/multiple-initiative-values-for-a-single-character/?pageforid=6817748#post-6817748
+ const dupeTracker = await startRoll(`!dup-turn ${attacks}`);
+ finishRoll(dupeTracker.rollId);
+}
diff --git a/Palladium Rifts by Grinning Gecko/src/partials/active.html b/Palladium Rifts by Grinning Gecko/src/partials/active.html
new file mode 100644
index 0000000000..764f7dcd49
--- /dev/null
+++ b/Palladium Rifts by Grinning Gecko/src/partials/active.html
@@ -0,0 +1,1454 @@
+
+
+
+
Armor:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Profile:
+
+
+
+
+
Combat
+
+
+
+
+
+
+
⚔ Ancient 🏹
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
🔫 Modern/Range 💣
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
🛡 Defense 🥷
+
+
+
+
+
+
+
+
+
+
+
+
🍀 Saving Throws 🪦
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Attributes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Palladium Rifts by Grinning Gecko/src/partials/armor.html b/Palladium Rifts by Grinning Gecko/src/partials/armor.html
index 42f208662a..a50b57027e 100644
--- a/Palladium Rifts by Grinning Gecko/src/partials/armor.html
+++ b/Palladium Rifts by Grinning Gecko/src/partials/armor.html
@@ -3,12 +3,12 @@
/>
-
+
diff --git a/Palladium Rifts by Grinning Gecko/src/partials/datalists.html b/Palladium Rifts by Grinning Gecko/src/partials/datalists.html
index 9c9ff2898a..2a00876b49 100644
--- a/Palladium Rifts by Grinning Gecko/src/partials/datalists.html
+++ b/Palladium Rifts by Grinning Gecko/src/partials/datalists.html
@@ -4,6 +4,7 @@
+
-