From e5739b50d86ef851e2241961fc0cd63aede8153a Mon Sep 17 00:00:00 2001 From: Ken Date: Sat, 10 Sep 2022 19:47:30 -0700 Subject: [PATCH 01/12] update gurps Initial GCA5 import of attributes --- GURPS/gurps.css | 3 +- GURPS/gurps.html | 425 ++++++-- GURPS/readme/assets/Rampage (NPC) export.json | 959 ++++++++++++++++++ GURPS/translation.json | 3 +- 4 files changed, 1303 insertions(+), 87 deletions(-) create mode 100644 GURPS/readme/assets/Rampage (NPC) export.json diff --git a/GURPS/gurps.css b/GURPS/gurps.css index c67e81a9ca..69eedc7a86 100644 --- a/GURPS/gurps.css +++ b/GURPS/gurps.css @@ -4888,7 +4888,8 @@ input[name="attr_combat_tabs"][value="ranged"] ~ .sheet-tabs .sheet-tabbed-heade /* Options Tab > sub tabs */ input[name="attr_options_tabs"][value="sheet"] ~ .sheet-tabs.sheet-options > div:nth-of-type(1), input[name="attr_options_tabs"][value="rules"] ~ .sheet-tabs.sheet-options > div:nth-of-type(2), -input[name="attr_options_tabs"][value="import"] ~ .sheet-tabs.sheet-options > div:nth-of-type(3) { +input[name="attr_options_tabs"][value="import"] ~ .sheet-tabs.sheet-options > div:nth-of-type(3), +input[name="attr_options_tabs"][value="import-json"] ~ .sheet-tabs.sheet-options > div:nth-of-type(4) { display: block; } diff --git a/GURPS/gurps.html b/GURPS/gurps.html index 1bd92f48a5..b2d35e0e1c 100644 --- a/GURPS/gurps.html +++ b/GURPS/gurps.html @@ -14672,7 +14672,11 @@ Slam uses either DX, Brawling, or Sumo Wrestling. Note that the -4 to hit and ef + @@ -15663,6 +15667,73 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm +
+ +
+ +

Import Tool

+ +

+ Imports a file using json data based on a standard for use with GURPS Roll20 Charactersheet. + Exporter tools can be developed for a character generator int this format, instead of + creating a special import for each character generator. +

+

+ Initial version is designed for a one time import. Future iterations will allow re-import. +

+ +

GCA5

+ +
How to Install
+ +
    +
  • Open GCA5
  • +
  • Click on Tools -> Plugins...
  • +
  • Find the section titled Export Character to Roll20
  • +
  • Enable this plugin
  • +
+ +
How to export
+ +
    +
  • Open GCA5 and a character
  • +
  • Click on File ->harExport...
  • +
  • Save the character and note where you saved it.
  • +
  • Open the file in a text editor, NOT a web browser.
  • +
  • Copy the content and paste it into the box to the right.
  • +
+ +
+ +
+ +
+

JSON DATA

+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+ + +
+ +
+ +
+ +
+ @@ -18118,6 +18189,95 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm ]); let rawDefenseNotes = {}; + + + /* -------- async functions -------- */ + /* see: https://github.com/onyxring/Roll20Async */ + + function setActiveCharacterId(charId) { + var oldAcid = getActiveCharacterId(); + var ev = new CustomEvent("message"); + ev.data = { "id": "0", "type": "setActiveCharacter", "data": charId }; + self.dispatchEvent(ev); + return oldAcid; + } + var _sIn = setInterval; + setInterval = function (callback, timeout) { + var acid = getActiveCharacterId(); + _sIn( + function () { + var prevAcid = setActiveCharacterId(acid); + callback(); + setActiveCharacterId(prevAcid); + } + , timeout); + } + var _sto = setTimeout + setTimeout = function (callback, timeout) { + var acid = getActiveCharacterId(); + _sto( + function () { + var prevAcid = setActiveCharacterId(acid); + callback(); + setActiveCharacterId(prevAcid); + } + , timeout); + } + function getAttrsAsync(props) { + var acid = getActiveCharacterId(); //save the current activeCharacterID in case it has changed when the promise runs + var prevAcid = null; //local variable defined here, because it needs to be shared across the promise callbacks defined below + return new Promise((resolve, reject) => { + prevAcid = setActiveCharacterId(acid); //in case the activeCharacterId has changed, restore it to what we were expecting and save the current value to restore later + try { + getAttrs(props, (values) => { resolve(values); }); + } + catch { reject(); } + }).finally(() => { + setActiveCharacterId(prevAcid); //restore activeCharcterId to what it was when the promise first ran + }); + } + //use the same pattern for each of the following... + function setAttrsAsync(propObj, options) { + var acid = getActiveCharacterId(); + var prevAcid = null; + return new Promise((resolve, reject) => { + prevAcid = setActiveCharacterId(acid); + try { + setAttrs(propObj, options, (values) => { resolve(values); }); + } + catch { reject(); } + }).finally(() => { + setActiveCharacterId(prevAcid); + }); + } + + function getSectionIDsAsync(sectionName) { + var acid = getActiveCharacterId(); + var prevAcid = null; + return new Promise((resolve, reject) => { + prevAcid = setActiveCharacterId(acid); + try { + getSectionIDs(sectionName, (values) => { resolve(values); }); + } + catch { reject(); } + }).finally(() => { + setActiveCharacterId(prevAcid); + }); + } + function getSingleAttrAsync(prop) { + var acid = getActiveCharacterId(); + var prevAcid = null; + return new Promise((resolve, reject) => { + prevAcid = setActiveCharacterId(acid); + try { + getAttrs([prop], (values) => { resolve(values[prop]); }); + } + catch { reject(); } + }).finally(() => { + setActiveCharacterId(prevAcid); + }); + } + /*------------------*/ const styleCount = 9; // THIS NUMBER MUST BE EQUAL TO THE NUMBER OF COLOR SETTINGS on("change:sheetstyle sheet:opened", function (event) { @@ -33869,91 +34029,186 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - /* async functions */ - /* see: https://github.com/onyxring/Roll20Async */ + // close roll modifiers, no updates + on("clicked:import_json", (event) => { + + setAttrs({ "import_json_message": "Processing..." }, null, () => { - function setActiveCharacterId(charId) { - var oldAcid = getActiveCharacterId(); - var ev = new CustomEvent("message"); - ev.data = { "id": "0", "type": "setActiveCharacter", "data": charId }; - self.dispatchEvent(ev); - return oldAcid; - } - var _sIn = setInterval; - setInterval = function (callback, timeout) { - var acid = getActiveCharacterId(); - _sIn( - function () { - var prevAcid = setActiveCharacterId(acid); - callback(); - setActiveCharacterId(prevAcid); - } - , timeout); - } - var _sto = setTimeout - setTimeout = function (callback, timeout) { - var acid = getActiveCharacterId(); - _sto( - function () { - var prevAcid = setActiveCharacterId(acid); - callback(); - setActiveCharacterId(prevAcid); - } - , timeout); - } - function getAttrsAsync(props) { - var acid = getActiveCharacterId(); //save the current activeCharacterID in case it has changed when the promise runs - var prevAcid = null; //local variable defined here, because it needs to be shared across the promise callbacks defined below - return new Promise((resolve, reject) => { - prevAcid = setActiveCharacterId(acid); //in case the activeCharacterId has changed, restore it to what we were expecting and save the current value to restore later - try { - getAttrs(props, (values) => { resolve(values); }); - } - catch { reject(); } - }).finally(() => { - setActiveCharacterId(prevAcid); //restore activeCharcterId to what it was when the promise first ran - }); - } - //use the same pattern for each of the following... - function setAttrsAsync(propObj, options) { - var acid = getActiveCharacterId(); - var prevAcid = null; - return new Promise((resolve, reject) => { - prevAcid = setActiveCharacterId(acid); - try { - setAttrs(propObj, options, (values) => { resolve(values); }); - } - catch { reject(); } - }).finally(() => { - setActiveCharacterId(prevAcid); - }); - } + importCharacterJson(); - function getSectionIDsAsync(sectionName) { - var acid = getActiveCharacterId(); - var prevAcid = null; - return new Promise((resolve, reject) => { - prevAcid = setActiveCharacterId(acid); - try { - getSectionIDs(sectionName, (values) => { resolve(values); }); - } - catch { reject(); } - }).finally(() => { - setActiveCharacterId(prevAcid); - }); - } - function getSingleAttrAsync(prop) { - var acid = getActiveCharacterId(); - var prevAcid = null; - return new Promise((resolve, reject) => { - prevAcid = setActiveCharacterId(acid); - try { - getAttrs([prop], (values) => { resolve(values[prop]); }); - } - catch { reject(); } - }).finally(() => { - setActiveCharacterId(prevAcid); - }); - } + }); + + }); + + on("clicked:import_reset", (event) => { + + setAttrs({ + "import_json_message": "Start Import", + "character_json_data": "" + }); + + }); + + importCharacterJson = () => { + + getAttrs(["character_json_data"], values => { + + let data = String(values.character_json_data).trim(); + + let success = true; + + let message = ""; + + // schema file + let character; + + if (data) { + + try { + + character = JSON.parse(data); + + } catch (ex) { + + success = false; + + message = "Invalid JSON Data. " + ex.message; + + } + } else { + + success = false; + + message = "Please copy/paste JSON Data into text area."; + + } + + if (success) { + + importAttributes(character); + + // very last attribute to get updated + const applyCombatReflexes = character.CombatReflexes ? "1" : "0"; + + setAttrsAsync({combat_reflexes: applyCombatReflexes}); + + } else { + + setAttrs({ "import_json_message": message }); + + } + + }); + + } + + importAttributes = character => { + + const applySizeModifier = character.ApplySizeModifier ? "1" : "0"; + const flightChecked = character.FlightChecked ? "1" : "0"; + const amphibiousChecked = character.AmphibiousChecked ? "1" : "0"; + + const baseAttributes = { + fullname: character.CharacterName, + playername: character.Playername, + nickname: character.Nickname, + race: character.Race, + gender: character.Gender, + size: parseInt(character.Size), + apply_size_modifier: applySizeModifier, + reactions: character.Reactions, + campaign_tl: parseInt(character.CampaignTl), + tl: parseInt(character.Tl), + tl_pts: parseInt(character.TlPts), + status: character.Status, + wealth: character.Wealth, + income: character.Income, + cost_of_living: character.CostOfLiving, + stash: character.Stash, + age: character.Age, + height: character.Height, + weight: parseFloat(character.Weight), + appearance: parseInt(character.Appearance), + general_appearance: character.GeneralAppearance, + strength_points: parseInt(character.StrengthPoints), + dexterity_points: parseInt(character.DexterityPoints), + intelligence_points: parseInt(character.IntelligencePoints), + health_points: parseInt(character.HealthPoints) + }; + + const baseAttributeMods = { + strength_mod: parseInt(character.StrengthMod), + dexterity_mod: parseInt(character.DexterityMod), + intelligence_mod: parseInt(character.IntelligenceMod), + health_mod: parseInt(character.HealthMod), + }; + + const secondaryAttributesPoints = { + perception_points: parseInt(character.PerceptionPoints), + vision_points: parseInt(character.VisionPoints), + hearing_points: parseInt(character.HearingPoints), + taste_smell_points: parseInt(character.TasteSmellPoints), + touch_points: parseInt(character.TouchPoints), + willpower_points: parseInt(character.WillpowerPoints), + fear_check_points: parseInt(character.FearCheckPoints), + unconscious_check_points: parseInt(character.UnconsciousCheckPoints), + death_check_points: parseInt(character.death_check_points), + basic_speed_points: parseInt(character.BasicSpeedPoints), + basic_move_points: parseInt(character.BasicMovePoints), + enhanced_ground_move_points: parseInt(character.EnhancedGroundMovePoints), + lift_st_points: parseInt(character.LiftStPoints), + striking_st_points: parseInt(character.StrikingStPoints), + hit_points_points: parseInt(character.HitPointsPoints), + hit_points: parseInt(character.HitPoints), + fatigue_points_points: parseInt(character.FatiguePointsPoints), + fatigue_points: parseInt(character.FatiguePoints), + flight_checked: flightChecked, + flight_points: parseInt(character.FlightPoints), + basic_air_move_points: parseInt(character.BasicAirMovePoints), + enhanced_air_move_points: parseInt(character.EnhancedAirMovePoints), + amphibious_checked: amphibiousChecked, + amphibious_points: parseInt(character.AmphibiousPoints), + basic_water_move_points: parseInt(character.BasicWaterMovePoints), + enhanced_water_move_points: parseInt(character.EnhancedWaterMovePoints), + super_jump_points: parseInt(character.SuperJumpPoints) + }; + + const secondaryAttributesMods = { + perception_mod: parseInt(character.PerceptionMod), + vision_mod: parseInt(character.VisionMod), + hearing_mod: parseInt(character.HearingMod), + taste_smell_mod: parseInt(character.TasteSmellMod), + touch_mod: parseInt(character.TouchMod), + willpower_mod: parseInt(character.WillpowerMod), + fear_check_mod: parseInt(character.FearCheckMod), + stun_check_mod: parseInt(character.StunCheckMod), + knockdown_check_mod: parseInt(character.KnockdownCheckMod), + unconscious_check_mod: parseInt(character.UnconsciousCheckMod), + death_check_mod: parseInt(character.DeathCheckMod), + basic_speed_mod: Number(character.BasicSpeedMod), + basic_move_mod: parseInt(character.BasicMoveMod), + enhanced_ground_move_mod: Number(character.EnhancedGroundMoveMod), + dodge_mod: parseInt(character.DodgeMod), + lift_st_mod: parseInt(character.LiftStMod), + striking_st_mod: parseInt(character.StrikingStMod), + hit_points_mod: parseInt(character.HitPointsMod), + fatigue_points_mod: parseInt(character.FatiguePointsMod), + basic_air_move_mod: parseInt(character.BasicAirMoveMod), + enhanced_air_level: Number(character.EnhancedAirLevel), + basic_water_move_mod: parseInt(character.BasicWaterMoveMod), + enhanced_water_level: Number(character.EnhancedWaterLevel), + super_jump_entered_level: parseInt(character.SuperJumpEnteredLevel), + spell_bonus: parseInt(character.SpellBonus) + }; + + setAttrsAsync(baseAttributes); + + setAttrsAsync(baseAttributeMods); + + setAttrsAsync(secondaryAttributesPoints); + + setAttrsAsync(secondaryAttributesMods); + + } diff --git a/GURPS/readme/assets/Rampage (NPC) export.json b/GURPS/readme/assets/Rampage (NPC) export.json new file mode 100644 index 0000000000..a705018441 --- /dev/null +++ b/GURPS/readme/assets/Rampage (NPC) export.json @@ -0,0 +1,959 @@ +{ + "CharacterName": "Rampage", + "Fullname": "Rampage (NPC)", + "Playername": "NPC", + "Nickname": "", + "Race": "Human", + "RaceRef": "", + "TemplateNames": "", + "Gender": "", + "Size": 0.0, + "ApplySizeModifier": false, + "Reactions": "+2 from 'Charisma 2'\nConditional:\n-2 from 'Reputation 2 (Gang Leader; 7 or less, +1, *1/3; Large class, +1, *1/2)'", + "CampaignTl": 8.0, + "TotalPoints": 150.0, + "Tl": 8.0, + "TlPts": 0.0, + "Status": "0", + "Wealth": "Comfortable", + "Income": 5200.0, + "CostOfLiving": 600.0, + "Stash": 5169.6, + "Age": "27", + "Height": "6'", + "Weight": 210.0, + "Appearance": 0.0, + "GeneralAppearance": "Short mohawk, painted face, likes to wear chains, like something out of Road Warrior.", + "StrengthMod": 1.0, + "StrengthPoints": 60.0, + "DexterityMod": 0.0, + "DexterityPoints": 40.0, + "IntelligenceMod": 0.0, + "IntelligencePoints": 0.0, + "HealthMod": 0.0, + "HealthPoints": 20.0, + "PerceptionMod": 0.0, + "PerceptionPoints": 10.0, + "VisionMod": 0.0, + "VisionPoints": 0.0, + "HearingMod": 0.0, + "HearingPoints": 0.0, + "TasteSmellMod": 0.0, + "TasteSmellPoints": 0.0, + "TouchMod": 0.0, + "TouchPoints": 0.0, + "WillpowerMod": 0.0, + "WillpowerPoints": 10.0, + "FearCheckMod": 2.0, + "FearCheckPoints": 0.0, + "StunCheckMod": 0.0, + "KnockdownCheckMod": 0.0, + "UnconsciousCheckMod": 1.0, + "UnconsciousCheckPoints": 0.0, + "DeathCheckMod": 1.0, + "DeathCheckPoints": 0.0, + "BasicSpeedMod": 0.0, + "BasicSpeedPoints": 0.0, + "BasicMoveMod": 0.0, + "BasicMovePoints": 0.0, + "EnhancedGroundMoveMod": 0.5, + "EnhancedGroundMovePoints": 0.0, + "DodgeMod": 2.0, + "LiftStMod": 7.0, + "LiftStPoints": 15.0, + "StrikingStMod": 4.0, + "StrikingStPoints": 0.0, + "HitPointsMod": 0.0, + "HitPointsPoints": 8.0, + "HitPoints": 21.0, + "FatiguePointsMod": 0.0, + "FatiguePointsPoints": 0.0, + "FatiguePoints": 12.0, + "FlightChecked": false, + "FlightPoints": 0.0, + "BasicAirMoveMod": 0.0, + "BasicAirMovePoints": 0.0, + "EnhancedAirLevel": 0.0, + "EnhancedAirMovePoints": 0.0, + "AmphibiousChecked": false, + "AmphibiousPoints": 0.0, + "BasicWaterMoveMod": 0.0, + "BasicWaterMovePoints": 0.0, + "EnhancedWaterLevel": 0.0, + "EnhancedWaterMovePoints": 0.0, + "SuperJumpEnteredLevel": 0.0, + "SuperJumpPoints": 0.0, + "SpellBonus": 0.0, + "CombatReflexes": true, + "RepeatingLanguages": [], + "RepeatingCultures": [ + { + "Idkey": "12982", + "Name": "European (Native)", + "Points": 0.0 + }, + { + "Idkey": "12983", + "Name": "Western", + "Points": 1.0 + } + ], + "RepeatingTraits": [ + { + "Idkey": "10717", + "Name": "Ambidexterity", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B39", + "Notes": "" + }, + { + "Idkey": "10800", + "Name": "Appearance", + "TraitLevel": "1", + "Foa": "", + "Points": 4.0, + "Ref": "B21", + "Notes": "\nAttractive" + }, + { + "Idkey": "10704", + "Name": "Body Control Talent", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "P121,P167-169", + "Notes": "\nInnate Attack (Projectile), +0" + }, + { + "Idkey": "10799", + "Name": "Charisma", + "TraitLevel": "2", + "Foa": "", + "Points": 10.0, + "Ref": "B41", + "Notes": "" + }, + { + "Idkey": "10698", + "Name": "Combat Reflexes", + "TraitLevel": "1", + "Foa": "", + "Points": 14.0, + "Ref": "B43", + "Notes": "\nBiological, -10%" + }, + { + "Idkey": "12986", + "Name": "Contact (Rival Gang)", + "TraitLevel": "1", + "Foa": "9", + "Points": 1.0, + "Ref": "B44", + "Notes": "My notes here\nEffective Skill 12\nRival Gang\n9 or less, *1\nSomewhat Reliable, *1\nMy notes here\nUgly dude with twisted lips" + }, + { + "Idkey": "10720", + "Name": "Crossbow (Armor Piercing)", + "TraitLevel": "3", + "Foa": "", + "Points": 38.0, + "Ref": "B61, P53", + "Notes": "\nArmor Piercing\nArmor Divisor, 2, +50%\nGadget/Breakable: DR 3-5, -15%\nGadget/Breakable: Size -3 or -4, -15%\nGadget/Can Be Stolen: Must be forcefully removed, -10%\nInaccurate, -1, -5%\nIncreased Range, x2, +10%\nIncreased Range, 1/2D Range only, x5, +10%\nNo Signature, +20%\nRicochet, +10%" + }, + { + "Idkey": "10730", + "Name": "Crossbow (Explosive)", + "TraitLevel": "3", + "Foa": "", + "Points": 7.0, + "Ref": "B61, P53", + "Notes": "\nExplosive\nAlternative Attack, *1/5\nDouble Knockback, +20%\nExplosive, Damage / 2xYards, +100%\nGadget/Breakable: DR 3-5, -15%\nGadget/Breakable: Size -3 or -4, -15%\nGadget/Can Be Stolen: Must be forcefully removed, -10%\nInaccurate, -1, -5%\nIncreased Range, x2, +10%\nIncreased Range, 1/2D Range only, x10, +15%\nNo Signature, +20%" + }, + { + "Idkey": "10741", + "Name": "Crossbow (Smoke Arrow)", + "TraitLevel": "6", + "Foa": "", + "Points": 5.0, + "Ref": "B72, P64", + "Notes": "\nSmoke Arrow\nAlternative Ability, *1/5\nArea Effect, 4 yd, +50%\nGadget/Breakable: DR 3-5, -15%\nGadget/Breakable: Size -3 or -4, -15%\nGadget/Can Be Stolen: Must be forcefully removed, -10%\nInaccurate, -1, -5%\nIncreased Range, x2, +10%\nIncreased Range, 1/2D Range Only, x5, +10%\nNo Signature, +20%\nRanged, +50%" + }, + { + "Idkey": "10666", + "Name": "Damage Resistance", + "TraitLevel": "2", + "Foa": "", + "Points": 5.0, + "Ref": "B46, P45", + "Notes": "\nBiological, -10%\nTough Skin, -40%" + }, + { + "Idkey": "10700", + "Name": "Enhanced Dodge", + "TraitLevel": "1", + "Foa": "", + "Points": 14.0, + "Ref": "B51", + "Notes": "\nBiological, -10%" + }, + { + "Idkey": "10715", + "Name": "Enhanced Move (Ground)", + "TraitLevel": "1", + "Foa": "", + "Points": 9.0, + "Ref": "B52, P49", + "Notes": "\n#list(LevelName Step 0.5)\nGround\nBiological, -10%" + }, + { + "Idkey": "10702", + "Name": "Enhanced Muscle", + "TraitLevel": "4", + "Foa": "", + "Points": 29.0, + "Ref": "Bio213", + "Notes": "\nBiological, -10%" + }, + { + "Idkey": "10718", + "Name": "Extra Attack", + "TraitLevel": "1", + "Foa": "", + "Points": 23.0, + "Ref": "B54, P49", + "Notes": "\nBiological, -10%" + }, + { + "Idkey": "11893", + "Name": "Extra ST", + "TraitLevel": "1", + "Foa": "", + "Points": 10.0, + "Ref": "B14", + "Notes": "\nAffects ST, +0%\nSize, +0%\nThe Extra ST advantage allows you to take extra levels of the attribute which you can then apply enhancements and limitations to. The \"Affects displayed score\" modifier causes the Extra ST advantage to affect the displayed attribute score. If you don't wish this advantage to affect the displayed score remove that modifier." + }, + { + "Idkey": "10712", + "Name": "Fit", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B55", + "Notes": "" + }, + { + "Idkey": "11891", + "Name": "Lifting ST", + "TraitLevel": "3", + "Foa": "", + "Points": 9.0, + "Ref": "B65, P58", + "Notes": "\nSize, +0%" + }, + { + "Idkey": "10709", + "Name": "Protected Vision", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B78, P69", + "Notes": "\nBiological, -10%" + }, + { + "Idkey": "10714", + "Name": "Rapid Healing", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B79", + "Notes": "" + }, + { + "Idkey": "10711", + "Name": "Resilience", + "TraitLevel": "20", + "Foa": "", + "Points": 18.0, + "Ref": "", + "Notes": "\nBiological, -10%" + }, + { + "Idkey": "10705", + "Name": "Resistant (Metabolic Hazards)", + "TraitLevel": "4", + "Foa": "", + "Points": 9.0, + "Ref": "B80, P71", + "Notes": "\nVery Common\nMetabolic Hazards\nBiological, -10%\n+3, *1/3" + }, + { + "Idkey": "10835", + "Name": "Signature Gear (Advanced Body Armor)", + "TraitLevel": "1", + "Foa": "", + "Points": 1.0, + "Ref": "B85", + "Notes": "\n%SigGearAliasList%\nAdvanced Body Armor" + }, + { + "Idkey": "11890", + "Name": "Wealth", + "TraitLevel": "1", + "Foa": "", + "Points": 10.0, + "Ref": "B25", + "Notes": "\nComfortable" + } + ], + "RepeatingPerks": [ + { + "Idkey": "10756", + "Name": "Alcohol Tolerance", + "Foa": "", + "Points": 1.0, + "Ref": "B100, B100,PU2:13", + "Notes": "" + }, + { + "Idkey": "10757", + "Name": "Base (Bar)", + "Foa": "", + "Points": 1.0, + "Ref": "PU2:17", + "Notes": "\nBar" + }, + { + "Idkey": "10794", + "Name": "Teamwork (Concrete Savages)", + "Foa": "", + "Points": 1.0, + "Ref": "MA52, PU2:6", + "Notes": "\nConcrete Savages" + } + ], + "RepeatingQuirks": [ + { + "Idkey": "10774", + "Name": "Chauvinistic", + "ControlRating": "", + "Points": -1.0, + "Ref": "B164", + "Notes": "" + }, + { + "Idkey": "10773", + "Name": "wears chains", + "ControlRating": "", + "Points": -1.0, + "Ref": "", + "Notes": "" + } + ], + "RepeatingDisadvantages": [ + { + "Idkey": "10758", + "Name": "Bad Temper", + "TraitLevel": "1", + "ControlRating": "12", + "Points": -10.0, + "Ref": "B124", + "Notes": "\n12 or less, *1" + }, + { + "Idkey": "10769", + "Name": "Enemy (Police)", + "TraitLevel": "1", + "ControlRating": "", + "Points": -10.0, + "Ref": "B135", + "Notes": "\nSmall group (3-5 people)\nPolice\n9 or less, *1\nHunter, *1" + }, + { + "Idkey": "10760", + "Name": "Greed", + "TraitLevel": "1", + "ControlRating": "12", + "Points": -15.0, + "Ref": "B137", + "Notes": "\n12 or less, *1" + }, + { + "Idkey": "10762", + "Name": "Reputation (Gang Leader)", + "TraitLevel": "2", + "ControlRating": "", + "Points": -1.0, + "Ref": "B27", + "Notes": "\nGang Leader\n7 or less, *1/3\nLarge class, *1/2" + } + ], + "RepeatingRacial": [], + "RepeatingSkills": [ + { + "Idkey": "10784", + "Name": "Area Knowledge (local)", + "Tl": "", + "Base": "", + "Difficulty": "IQ/E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 11.0, + "Ref": "B176", + "SkillModNotes": "", + "Notes": "\nlocal" + }, + { + "Idkey": "10753", + "Name": "Brawling", + "Tl": "", + "Base": "", + "Difficulty": "DX/E", + "Bonus": 0.0, + "Points": 4.0, + "Skill": 14.0, + "Ref": "B182", + "SkillModNotes": "", + "Notes": "\nNotes: Calculated damage takes into account bonuses from Teeth, Weak Bite, Claws, and skill level. You may add the modifier \"Has Gauntlets/Brass Knuckles\" or \"Has Boots\" to apply the +1 damage to Punch or Kick, as appropriate." + }, + { + "Idkey": "10780", + "Name": "Carousing", + "Tl": "", + "Base": "", + "Difficulty": "HT/E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "B183", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "10776", + "Name": "Connoisseur (Music)", + "Tl": "", + "Base": "", + "Difficulty": "IQ/A", + "Bonus": 0.0, + "Points": 3.0, + "Skill": 11.0, + "Ref": "B185", + "SkillModNotes": "", + "Notes": "\nMusic" + }, + { + "Idkey": "10777", + "Name": "Dancing", + "Tl": "", + "Base": "", + "Difficulty": "DX/A", + "Bonus": 0.0, + "Points": 1.0, + "Skill": 11.0, + "Ref": "B187", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "10781", + "Name": "Forced Entry", + "Tl": "", + "Base": "", + "Difficulty": "DX/E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "B196", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "10775", + "Name": "Guns (Pistol)", + "Tl": "8", + "Base": "", + "Difficulty": "DX/E", + "Bonus": 0.0, + "Points": 4.0, + "Skill": 14.0, + "Ref": "B198", + "SkillModNotes": "", + "Notes": "\nuns/TL8 (Pistol" + }, + { + "Idkey": "10752", + "Name": "Innate Attack (Projectile)", + "Tl": "", + "Base": "", + "Difficulty": "DX/E", + "Bonus": 1.0, + "Points": 12.0, + "Skill": 17.0, + "Ref": "B201", + "SkillModNotes": "+1 from 'Body Control Talent 1 (Innate Attack (Projectile), +0)'", + "Notes": "\nProjectile" + }, + { + "Idkey": "10782", + "Name": "Intimidation", + "Tl": "", + "Base": "", + "Difficulty": "Will/A", + "Bonus": 0.0, + "Points": 4.0, + "Skill": 13.0, + "Ref": "B202", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "10798", + "Name": "Leadership", + "Tl": "", + "Base": "", + "Difficulty": "IQ/A", + "Bonus": 2.0, + "Points": 4.0, + "Skill": 13.0, + "Ref": "B204", + "SkillModNotes": "+2 from 'Charisma 2'", + "Notes": "" + }, + { + "Idkey": "10778", + "Name": "Musical Instrument (Guitar)", + "Tl": "", + "Base": "", + "Difficulty": "IQ/H", + "Bonus": 0.0, + "Points": 12.0, + "Skill": 12.0, + "Ref": "B211", + "SkillModNotes": "", + "Notes": "\nGuitar" + }, + { + "Idkey": "13357", + "Name": "Navigation (Land)", + "Tl": "8", + "Base": "", + "Difficulty": "IQ/A", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 10.0, + "Ref": "B211", + "SkillModNotes": "", + "Notes": "\navigation/TL8 (Land" + }, + { + "Idkey": "13175", + "Name": "Shield (Force)", + "Tl": "", + "Base": "", + "Difficulty": "DX/E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "B220", + "SkillModNotes": "", + "Notes": "\nForce" + }, + { + "Idkey": "10779", + "Name": "Singing", + "Tl": "", + "Base": "", + "Difficulty": "HT/E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "B220", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "10783", + "Name": "Streetwise", + "Tl": "", + "Base": "", + "Difficulty": "IQ/A", + "Bonus": 0.0, + "Points": 8.0, + "Skill": 12.0, + "Ref": "B223", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "13174", + "Name": "Wrestling", + "Tl": "", + "Base": "", + "Difficulty": "DX/A", + "Bonus": 0.0, + "Points": 1.0, + "Skill": 11.0, + "Ref": "B228", + "SkillModNotes": "", + "Notes": "" + } + ], + "RepeatingTechniquesrevised": [ + { + "Idkey": "13172", + "Name": "Aggressive Parry (Brawling)", + "Parent": "Brawling", + "BaseLevel": "10", + "Default": -1.0, + "MaxModifier": 0.0, + "Difficulty": "Tech/H", + "SkillModifier": 0.0, + "Points": 2.0, + "Skill": 11.0, + "Ref": "MA65", + "SkillModNotes": "", + "Notes": "\nBrawling" + }, + { + "Idkey": "13173", + "Name": "Arm Lock (Wrestling)", + "Parent": "Wrestling", + "BaseLevel": "11", + "Default": 0.0, + "MaxModifier": 4.0, + "Difficulty": "Tech/A", + "SkillModifier": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "MA65, B230", + "SkillModNotes": "", + "Notes": "\nWrestling" + } + ], + "RepeatingDefense": [ + { + "Idkey": "10704_mode_34", + "Name": "Body Control Talent (Power Dodge)", + "Type": "Power Dodge", + "Info": "", + "Skill": 9.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "10704_mode_35", + "Name": "Body Control Talent (Power Block/Physical)", + "Type": "Power Block", + "Info": "", + "Skill": 9.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "10704_mode_36", + "Name": "Body Control Talent (Power Block/Mental)", + "Type": "Power Block Mental", + "Info": "", + "Skill": 9.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "10753_mode_88", + "Name": "Brawling (Punch)", + "Type": "Unarmed Parry", + "Info": "", + "Skill": 11.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "10613_mode_19", + "Name": "Punch", + "Type": "Unarmed Parry", + "Info": "", + "Skill": 11.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "13175_block", + "Name": "Shield (Force)", + "Type": "Block", + "Info": "", + "Skill": 10.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + } + ], + "RepeatingMelee": [ + { + "Idkey": "13172_mode_87", + "Name": "Aggressive Parry (Brawling)", + "Damage": "2d6-2", + "Type": "cr", + "Reach": "C", + "Skill": 11.0, + "ReasonForMod": "", + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "10525_mode_1", + "Name": "Bite", + "Damage": "2d6+1", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ReasonForMod": "", + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + }, + { + "Idkey": "10753_mode_88", + "Name": "Brawling (Punch)", + "Damage": "2d6+1", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ReasonForMod": "", + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "10753_mode_89", + "Name": "Brawling (Bite)", + "Damage": "2d6+1", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ReasonForMod": "", + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "10753_mode_90", + "Name": "Brawling (Kick)", + "Damage": "2d6+2", + "Type": "cr", + "Reach": "C,1", + "Skill": 12.0, + "ReasonForMod": "", + "ArmorDivisor": 1.0, + "Notes": "{If you miss with a kick, roll vs. DX to avoid falling.}" + }, + { + "Idkey": "13176_mode_100", + "Name": "Force Shield (Bash)", + "Damage": "2d6", + "Type": "cr", + "Reach": "1", + "Skill": 13.0, + "ReasonForMod": "", + "ArmorDivisor": 1.0, + "Notes": "{Worn on the wrist, leaving the hand free.}" + }, + { + "Idkey": "13176_mode_101", + "Name": "Force Shield (Rush)", + "Damage": "slam+3", + "Type": "cr", + "Reach": "1", + "Skill": 13.0, + "ReasonForMod": "", + "ArmorDivisor": 1.0, + "Notes": "{Worn on the wrist, leaving the hand free.}" + }, + { + "Idkey": "10558_mode_12", + "Name": "Kick", + "Damage": "2d6+2", + "Type": "cr", + "Reach": "C,1", + "Skill": 12.0, + "ReasonForMod": "", + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + }, + { + "Idkey": "10613_mode_19", + "Name": "Punch", + "Damage": "2d6+1", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ReasonForMod": "", + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + } + ], + "RepeatingRanged": [ + { + "Idkey": "10720_mode_46", + "Name": "Crossbow (Armor Piercing) (Primary)", + "Damage": "3d6", + "Type": "imp", + "Acc": "2", + "Range": "100/200", + "Rof": "1", + "Shots": "", + "Bulk": "", + "Recoil": "1", + "Skill": 17.0, + "ReasonForMod": "", + "Malfunction": "", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 2.0, + "Notes": "" + }, + { + "Idkey": "10730_mode_52", + "Name": "Crossbow (Explosive) (Primary)", + "Damage": "3d6", + "Type": "cr dkb ex/2", + "Acc": "2", + "Range": "200", + "Rof": "1", + "Shots": "n/a", + "Bulk": "", + "Recoil": "1", + "Skill": 17.0, + "ReasonForMod": "", + "Malfunction": "", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "10786_mode_102", + "Name": "Revolver, .357M", + "Damage": "3d6-1", + "Type": "pi", + "Acc": "2", + "Range": "185/2000", + "Rof": "3", + "Shots": "6(3i)", + "Bulk": "-2", + "Recoil": "3", + "Skill": 15.0, + "ReasonForMod": "", + "Malfunction": "17", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 1.0, + "Notes": "" + } + ], + "RepeatingItem": [ + { + "Idkey": "10833", + "Name": "Advanced Body Armor", + "Tl": "8", + "LegalityClass": "2", + "Ref": "HT66", + "Count": 1.0, + "Cost": 4600.0, + "Weight": 17.0, + "Notes": "\nSignature Gear, +0\nTL:8 LC:2 DR:35/5* Location:torso Notes:[1] Concealable as or under clothing. [5] Use the lower DR versus crushing attacks only." + }, + { + "Idkey": "10790", + "Name": "Boots, Steel-Toed", + "Tl": "6", + "LegalityClass": "4", + "Ref": "HT68", + "Count": 1.0, + "Cost": 100.0, + "Weight": 4.0, + "Notes": "\nTL:6 LC:4 DR:6/2 Location:feet Notes:[1] Concealable as or under clothing. [2] Give +1 to kicking damage (p. B271). [4] Split DR: use the first, higher DR when - in the GM's opinion - the boot's steel toe box would protect (e. g. , dropping an item on the foot or crushing the toes in heavy machinery) or when an attack on the foot hits the toe (2/6 protection); use the second, lower DR against all other attacks." + }, + { + "Idkey": "13358", + "Name": "Compass", + "Tl": "6", + "LegalityClass": "", + "Ref": "B288", + "Count": 1.0, + "Cost": 50.0, + "Weight": 0.0, + "Notes": "\nTL:6 Notes: +1 to Navigation skill" + }, + { + "Idkey": "13176", + "Name": "Force Shield", + "Tl": "^", + "LegalityClass": "3", + "Ref": "B273, B287", + "Count": 1.0, + "Cost": 1500.0, + "Weight": 0.5, + "Notes": "\nTL:^ LC:3 DB:3 Dam:thr cr Reach:1 Parry:No ST:-- DR:100 HP:-- Skill:Shield (Force) Notes: [3,5] Also available as a buckler. You can ready a buckler in one turn and drop it as a free action, just like a weapon - but it always occupies one hand, and it does not allow a shield rush. Use Shield (Buckler) instead of regular shield skill. No effect on statistics. Worn on the wrist, leaving the hand free. DR is hardened (treat as Hardened enhancement, p. B47)." + }, + { + "Idkey": "13355", + "Name": "Holster, Belt", + "Tl": "5", + "LegalityClass": "", + "Ref": "B289", + "Count": 1.0, + "Cost": 1180.4, + "Weight": 7.62, + "Notes": "\nTL:5 Notes: Fits most pistols." + }, + { + "Idkey": "10788", + "Name": "Laser Sight", + "Tl": "8", + "LegalityClass": "", + "Ref": "B289", + "Count": 1.0, + "Cost": 100.0, + "Weight": 0.0, + "Notes": "\nTL:8 Notes: +1 to skill, see Laser Sights (p. B412)" + }, + { + "Idkey": "10792", + "Name": "Personal Basics", + "Tl": "0", + "LegalityClass": "", + "Ref": "B288", + "Count": 1.0, + "Cost": 5.0, + "Weight": 1.0, + "Notes": "\nTL:0 Notes: Minimum gear for camping: -2 to any Survival roll without it. Includes utensils, tinderbox or flint and steel, towel, etc., as TL permits." + }, + { + "Idkey": "10786", + "Name": "Revolver, .357M", + "Tl": "7", + "LegalityClass": "3", + "Ref": "B278", + "Count": 1.0, + "Cost": 1100.0, + "Weight": 3.6, + "Notes": "\nRugged, *2\nReceives Skill Bonus, +1, +0\nTL:7 LC:3 Damage:3d-1 pi Acc:2 Range:185/2000 RoF:3 Shots:6(3i) ST:10 Bulk:-2 Rcl:3 Skill:Guns (Pistol)" + }, + { + "Idkey": "13356", + "Name": "Revolver, .357M (Ammunition)", + "Tl": "7", + "LegalityClass": "3", + "Ref": "", + "Count": 12.0, + "Cost": 50.4, + "Weight": 2.52, + "Notes": "\nAmmunition" + } + ], + "RepeatingSpells": [] +} \ No newline at end of file diff --git a/GURPS/translation.json b/GURPS/translation.json index b03b5b83bb..46c4e3a9e3 100644 --- a/GURPS/translation.json +++ b/GURPS/translation.json @@ -1072,7 +1072,8 @@ "latest-changes-updated-label": "Latest Changes: Updated", "sheet-options-label": "Sheet Options", "rules-label": "Rules", - "import-label": "Import", + "import-label": "Import GCA4", + "import-json-label": "Import", "critical-roll-options-label": "Critical Roll Options", "user-rules-as-written-label": "Use rules as written", "critical-miss-notes": "Roll on the appropriate Critical Miss Table (B556).", From 76408686ecfdf985e0d39bdf33b350bfffa777d3 Mon Sep 17 00:00:00 2001 From: Ken Date: Sat, 10 Sep 2022 23:43:42 -0700 Subject: [PATCH 02/12] update gurps add repeating tables to import! --- GURPS/gurps.css | 2 +- GURPS/gurps.html | 597 +++++- .../assets/Artillery Mage (NPC) export.json | 1063 +++++++++ GURPS/readme/assets/Rampage (NPC) export.json | 1902 ++++++++--------- 4 files changed, 2605 insertions(+), 959 deletions(-) create mode 100644 GURPS/readme/assets/Artillery Mage (NPC) export.json diff --git a/GURPS/gurps.css b/GURPS/gurps.css index 69eedc7a86..d10acdf6f9 100644 --- a/GURPS/gurps.css +++ b/GURPS/gurps.css @@ -3746,7 +3746,7 @@ input[name="attr_inventory_item_carried"][value="1"] ~ span.sheet-item-weight-to } .sheet-spells .sheet-text-college-width { - width: 185px; + width: 184px; } /* -- if edit mode, hide toggle notes -- */ diff --git a/GURPS/gurps.html b/GURPS/gurps.html index b2d35e0e1c..d7cf0af609 100644 --- a/GURPS/gurps.html +++ b/GURPS/gurps.html @@ -34084,9 +34084,39 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } if (success) { - + + // TODO: figure out async/await + let uniqueKeys = getUniqueKeysForCharacter(); + importAttributes(character); + importRepeatingCultures(character, uniqueKeys); + + importRepeatingTraits(character, uniqueKeys); + + importRepeatingPerks(character, uniqueKeys); + + importRepeatingQuirks(character, uniqueKeys); + + importRepeatingDisadvantages(character, uniqueKeys); + + // TODO: test + importRepeatingRacial(character, uniqueKeys); + + importRepeatingSkills(character, uniqueKeys); + + importRepeatingTechniquesrevised(character, uniqueKeys); + + importRepeatingDefense(character, uniqueKeys); + + importRepeatingMelee(character, uniqueKeys); + + importRepeatingRanged(character, uniqueKeys); + + importRepeatingItem(character, uniqueKeys); + + importRepeatingSpells(character, uniqueKeys); + // very last attribute to get updated const applyCombatReflexes = character.CombatReflexes ? "1" : "0"; @@ -34102,6 +34132,69 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } + getUniqueKeysForCharacter = () => { + + let uniqueKeys = {}; + + //getUniqueKeysByTableAsync("repeating_languages", uniqueKeys); + + //getUniqueKeysByTableAsync("repeating_cultures", uniqueKeys); + + return uniqueKeys; + + } + + getUniqueKeysByTableAsync = (table, uniqueKeys) => { + + getSectionIDsAsync(table, ids => { + + if (ids.length === 0) { + callback(); + return; + } + + // get the idkey for each row. + let fields = []; + + for (let i = 0; i < ids.length; i++) { + + fields.push(`${table}_${ids[i]}_idkey`); + + } + + getAttrsAsync(fields, values => { + + // loop through each row + for (let key in values) { + + let idkey; + + let rowId; + + if (values.hasOwnProperty(key)) { + + idkey = values[key]; + + // get row id from the key name + // example: repeating_melee_KEYHERE_idkey + rowId = getRowIdFromRowFieldKey(key, table); + + if (idkey && rowId) { + + // add new key/value pair! + uniqueKeys[idkey] = rowId; + + } + + } + + } + }); + + }); + + } + importAttributes = character => { const applySizeModifier = character.ApplySizeModifier ? "1" : "0"; @@ -34211,4 +34304,506 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } + importRepeatingCultures = (character, uniqueKeys) => { + + character.RepeatingCultures.forEach(culture => { + + let rowId = generateOrGetRowId(uniqueKeys, culture.Idkey); + + let baseFieldName = `repeating_cultures_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = culture.Idkey; + + attributes[`${baseFieldName}_name`] = culture.Name; + + attributes[`${baseFieldName}_points`] = parseInt(culture.Points); + + setAttrsAsync(attributes); + + }); + + } + + importRepeatingTraits = (character, uniqueKeys) => { + + character.RepeatingTraits.forEach(trait => { + + let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); + + let baseFieldName = `repeating_traits_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = trait.Idkey; + + attributes[`${baseFieldName}_name`] = trait.Name; + + attributes[`${baseFieldName}_trait_level`] = trait.TraitLevel; + + attributes[`${baseFieldName}_foa`] = trait.Foa; + + attributes[`${baseFieldName}_points`] = parseInt(trait.Points); + + attributes[`${baseFieldName}_ref`] = trait.Ref; + + attributes[`${baseFieldName}_notes`] = trait.Notes; + + setAttrsAsync(attributes); + + }); + + } + + importRepeatingPerks = (character, uniqueKeys) => { + + character.RepeatingPerks.forEach(trait => { + + let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); + + let baseFieldName = `repeating_perks_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = trait.Idkey; + + attributes[`${baseFieldName}_name`] = trait.Name; + + attributes[`${baseFieldName}_foa`] = trait.Foa; + + attributes[`${baseFieldName}_points`] = parseInt(trait.Points); + + attributes[`${baseFieldName}_ref`] = trait.Ref; + + attributes[`${baseFieldName}_notes`] = trait.Notes; + + setAttrsAsync(attributes); + + }); + + } + + importRepeatingQuirks = (character, uniqueKeys) => { + + character.RepeatingQuirks.forEach(trait => { + + let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); + + let baseFieldName = `repeating_quirks_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = trait.Idkey; + + attributes[`${baseFieldName}_name`] = trait.Name; + + attributes[`${baseFieldName}_control_rating`] = trait.ControlRating; + + attributes[`${baseFieldName}_points`] = parseInt(trait.Points); + + attributes[`${baseFieldName}_ref`] = trait.Ref; + + attributes[`${baseFieldName}_notes`] = trait.Notes; + + setAttrsAsync(attributes); + + }); + + } + + importRepeatingDisadvantages = (character, uniqueKeys) => { + + character.RepeatingDisadvantages.forEach(trait => { + + let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); + + let baseFieldName = `repeating_disadvantages_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = trait.Idkey; + + attributes[`${baseFieldName}_name`] = trait.Name; + + attributes[`${baseFieldName}_trait_level`] = trait.TraitLevel; + + attributes[`${baseFieldName}_control_rating`] = trait.ControlRating; + + attributes[`${baseFieldName}_points`] = parseInt(trait.Points); + + attributes[`${baseFieldName}_ref`] = trait.Ref; + + attributes[`${baseFieldName}_notes`] = trait.Notes; + + setAttrsAsync(attributes); + + }); + + } + + // TODO: need test character + importRepeatingRacial = (character, uniqueKeys) => { + + character.RepeatingRacial.forEach(trait => { + + let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); + + let baseFieldName = `repeating_racial_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = trait.Idkey; + + attributes[`${baseFieldName}_name`] = trait.Name; + + attributes[`${baseFieldName}_trait_level`] = trait.TraitLevel; + + attributes[`${baseFieldName}_control_rating`] = trait.ControlRating; + + attributes[`${baseFieldName}_points`] = parseInt(trait.Points); + + attributes[`${baseFieldName}_ref`] = trait.Ref; + + attributes[`${baseFieldName}_notes`] = trait.Notes; + + setAttrsAsync(attributes); + + }); + + } + + // TODO: Check for wildcard! + importRepeatingSkills = (character, uniqueKeys) => { + + character.RepeatingSkills.forEach(skill => { + + let rowId = generateOrGetRowId(uniqueKeys, skill.Idkey); + + let baseFieldName = `repeating_skills_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = skill.Idkey; + + attributes[`${baseFieldName}_name`] = skill.Name; + + attributes[`${baseFieldName}_tl`] = skill.Tl; + + attributes[`${baseFieldName}_base`] = skill.Base; + + attributes[`${baseFieldName}_difficulty`] = getSKillDifficultyValue(skill.Difficulty); + + attributes[`${baseFieldName}_bonus`] = parseInt(skill.Bonus); + + attributes[`${baseFieldName}_points`] = parseInt(skill.Points); + + attributes[`${baseFieldName}_ref`] = skill.Ref; + + attributes[`${baseFieldName}_skill_mod_notes`] = skill.SkillModNotes; + + attributes[`${baseFieldName}_notes`] = skill.Notes; + + setAttrsAsync(attributes); + + }); + + } + + /** + * Converts difficulty name to a number + * TODO: checks for wildcard! + */ + getSKillDifficultyValue = difficulty => { + + let difficultyValue = "-1"; + + switch (difficulty) { + + case "A": + difficultyValue = "-2"; + break; + + case "H": + difficultyValue = "-3"; + break; + + case "VH": + difficultyValue = "-4"; + break; + + case "WC": + difficultyValue = "-5 + 1"; + break; + + case "E": + default: + difficultyValue = "-1"; + break; + } + + return difficultyValue; + + } + + importRepeatingTechniquesrevised = (character, uniqueKeys) => { + + character.RepeatingTechniquesrevised.forEach(skill => { + + let rowId = generateOrGetRowId(uniqueKeys, skill.Idkey); + + let baseFieldName = `repeating_techniquesrevised_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = skill.Idkey; + + attributes[`${baseFieldName}_name`] = skill.Name; + + attributes[`${baseFieldName}_parent`] = skill.Parent; + + attributes[`${baseFieldName}_base_level`] = skill.BaseLevel; + + attributes[`${baseFieldName}_default`] = parseInt(skill.Default); + + attributes[`${baseFieldName}_max_modifier`] = parseInt(skill.MaxModifier); + + attributes[`${baseFieldName}_difficulty`] = getTechniqueDifficultyValue(skill.Difficulty); + + attributes[`${baseFieldName}_skill_modifier`] = parseInt(skill.SkillModifier); + + attributes[`${baseFieldName}_points`] = parseInt(skill.Points); + + attributes[`${baseFieldName}_ref`] = skill.Ref; + + attributes[`${baseFieldName}_skill_mod_notes`] = skill.SkillModNotes; + + attributes[`${baseFieldName}_notes`] = skill.Notes; + + setAttrsAsync(attributes); + + }); + + } + + getTechniqueDifficultyValue = difficulty => { + + let difficultyValue = "Average"; + + switch (difficulty) { + + case "H": + difficultyValue = "Hard"; + break; + + case "A": + default: + difficultyValue = "Average"; + break; + } + + return difficultyValue; + + } + + importRepeatingDefense = (character, uniqueKeys) => { + + character.RepeatingDefense.forEach(trait => { + + let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); + + let baseFieldName = `repeating_defense_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = trait.Idkey; + + attributes[`${baseFieldName}_name`] = trait.Name; + + attributes[`${baseFieldName}_type`] = trait.Type; + + attributes[`${baseFieldName}_info`] = trait.Info; + + attributes[`${baseFieldName}_skill`] = parseInt(trait.Skill); + + attributes[`${baseFieldName}_skill_mod`] = parseInt(trait.SkillMod); + + attributes[`${baseFieldName}_defense_mod_reason`] = trait.DefenseModReason; + + attributes[`${baseFieldName}_info_description`] = parseInt(trait.InfoDescription); + + setAttrsAsync(attributes); + + }); + + } + + importRepeatingMelee = (character, uniqueKeys) => { + + character.RepeatingMelee.forEach(trait => { + + let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); + + let baseFieldName = `repeating_melee_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = trait.Idkey; + + attributes[`${baseFieldName}_name`] = trait.Name; + + attributes[`${baseFieldName}_damage`] = trait.Damage; + + attributes[`${baseFieldName}_type`] = getDamageTypeFromGca(trait.Type); + + attributes[`${baseFieldName}_reach`] = trait.Reach; + + attributes[`${baseFieldName}_skill`] = parseInt(trait.Skill); + + attributes[`${baseFieldName}_armor_divisor`] = Number(trait.ArmorDivisor); + + attributes[`${baseFieldName}_notes`] = trait.Notes; + + setAttrsAsync(attributes); + + }); + + } + + importRepeatingRanged = (character, uniqueKeys) => { + + character.RepeatingRanged.forEach(trait => { + + let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); + + let baseFieldName = `repeating_ranged_${rowId}`; + + const malfunctionVerify = trait.MalfunctionVerify ? "1" : "0"; + + const malfunctionVeryReliable = trait.MalfunctionVeryReliable ? "1" : "0"; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = trait.Idkey; + + attributes[`${baseFieldName}_name`] = trait.Name; + + attributes[`${baseFieldName}_damage`] = trait.Damage; + + attributes[`${baseFieldName}_type`] = getDamageTypeFromGca(trait.Type); + + attributes[`${baseFieldName}_acc`] = trait.Acc; + + attributes[`${baseFieldName}_range`] = trait.Range; + + attributes[`${baseFieldName}_rof`] = trait.Rof; + + attributes[`${baseFieldName}_shots`] = trait.Shots; + + attributes[`${baseFieldName}_bulk`] = trait.Bulk; + + attributes[`${baseFieldName}_recoil`] = trait.Recoil; + + attributes[`${baseFieldName}_skill`] = parseInt(trait.Skill); + + attributes[`${baseFieldName}_malfunction`] = trait.Malfunction; + + attributes[`${baseFieldName}_malfunction_verify`] = malfunctionVerify; + + attributes[`${baseFieldName}_malfunction_very_reliable`] = malfunctionVeryReliable; + + attributes[`${baseFieldName}_armor_divisor`] = Number(trait.ArmorDivisor); + + attributes[`${baseFieldName}_notes`] = trait.Notes; + + setAttrsAsync(attributes); + + }); + + } + + importRepeatingItem = (character, uniqueKeys) => { + + character.RepeatingItem.forEach(trait => { + + let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); + + let baseFieldName = `repeating_item_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = trait.Idkey; + + attributes[`${baseFieldName}_name`] = trait.Name; + + attributes[`${baseFieldName}_tl`] = trait.Tl; + + attributes[`${baseFieldName}_legality_class`] = trait.LegalityClass; + + attributes[`${baseFieldName}_ref`] = trait.Ref; + + attributes[`${baseFieldName}_count`] = parseInt(trait.Count); + + attributes[`${baseFieldName}_cost`] = Number(trait.Cost); + + attributes[`${baseFieldName}_weight`] = Number(trait.Weight); + + attributes[`${baseFieldName}_notes`] = trait.Notes; + + setAttrsAsync(attributes); + + }); + + } + + importRepeatingSpells = (character, uniqueKeys) => { + + character.RepeatingSpells.forEach(skill => { + + let rowId = generateOrGetRowId(uniqueKeys, skill.Idkey); + + let baseFieldName = `repeating_spells_${rowId}`; + + let attributes = {}; + + attributes[`${baseFieldName}_idkey`] = skill.Idkey; + + attributes[`${baseFieldName}_name`] = skill.Name; + + attributes[`${baseFieldName}_difficulty`] = getSKillDifficultyValue(skill.Difficulty); + + attributes[`${baseFieldName}_spell_modifier`] = parseInt(skill.SpellModifier); + + attributes[`${baseFieldName}_points`] = parseInt(skill.Points); + + attributes[`${baseFieldName}_spell_resisted_by`] = skill.SpellResistedBy; + + attributes[`${baseFieldName}_duration`] = skill.Duration; + + attributes[`${baseFieldName}_cost`] = skill.Cost; + + attributes[`${baseFieldName}_ref`] = skill.Ref; + + attributes[`${baseFieldName}_ref`] = skill.Ref; + + attributes[`${baseFieldName}_casttime`] = skill.Casttime; + + attributes[`${baseFieldName}_maintain`] = skill.Maintain; + + attributes[`${baseFieldName}_spell_class`] = skill.SpellClass; + + attributes[`${baseFieldName}_spell_college`] = skill.SpellCollege; + + attributes[`${baseFieldName}_spell_college_secondary`] = skill.SpellCollegeSecondary; + + attributes[`${baseFieldName}_spell_mod_notes`] = skill.SpellModNotes; + + attributes[`${baseFieldName}_notes`] = skill.SpellNotes; + + setAttrsAsync(attributes); + + }); + + } + diff --git a/GURPS/readme/assets/Artillery Mage (NPC) export.json b/GURPS/readme/assets/Artillery Mage (NPC) export.json new file mode 100644 index 0000000000..02f728ab93 --- /dev/null +++ b/GURPS/readme/assets/Artillery Mage (NPC) export.json @@ -0,0 +1,1063 @@ +{ + "CharacterName": "Artillery Mage", + "Fullname": "Artillery Mage (NPC)", + "Playername": "NPC", + "Nickname": "", + "Race": "Human", + "RaceRef": "", + "TemplateNames": "", + "Gender": "", + "Size": 0.0, + "ApplySizeModifier": false, + "Reactions": "", + "CampaignTl": 3.0, + "TotalPoints": 250.0, + "Tl": 3.0, + "TlPts": 0.0, + "Status": "1", + "Wealth": "Comfortable", + "Income": 1400.0, + "CostOfLiving": 1200.0, + "Stash": 1135.0, + "Age": "", + "Height": "", + "Weight": 0.0, + "Appearance": 0.0, + "GeneralAppearance": "", + "StrengthMod": 0.0, + "StrengthPoints": -10.0, + "DexterityMod": 0.0, + "DexterityPoints": 0.0, + "IntelligenceMod": 0.0, + "IntelligencePoints": 60.0, + "HealthMod": 0.0, + "HealthPoints": 0.0, + "PerceptionMod": 0.0, + "PerceptionPoints": 0.0, + "VisionMod": 0.0, + "VisionPoints": 0.0, + "HearingMod": 0.0, + "HearingPoints": 0.0, + "TasteSmellMod": 0.0, + "TasteSmellPoints": 0.0, + "TouchMod": 0.0, + "TouchPoints": 0.0, + "WillpowerMod": 0.0, + "WillpowerPoints": 0.0, + "FearCheckMod": 0.0, + "FearCheckPoints": 0.0, + "StunCheckMod": 0.0, + "KnockdownCheckMod": 0.0, + "UnconsciousCheckMod": 0.0, + "UnconsciousCheckPoints": 0.0, + "DeathCheckMod": 0.0, + "DeathCheckPoints": 0.0, + "BasicSpeedMod": 0.0, + "BasicSpeedPoints": 0.0, + "BasicMoveMod": 0.0, + "BasicMovePoints": 0.0, + "EnhancedGroundMoveMod": 0.0, + "EnhancedGroundMovePoints": 0.0, + "DodgeMod": 0.0, + "LiftStMod": 0.0, + "LiftStPoints": 0.0, + "StrikingStMod": 0.0, + "StrikingStPoints": 0.0, + "HitPointsMod": 0.0, + "HitPointsPoints": 0.0, + "HitPoints": 9.0, + "FatiguePointsMod": 0.0, + "FatiguePointsPoints": 0.0, + "FatiguePoints": 10.0, + "FlightChecked": false, + "FlightPoints": 0.0, + "BasicAirMoveMod": 0.0, + "BasicAirMovePoints": 0.0, + "EnhancedAirLevel": 0.0, + "EnhancedAirMovePoints": 0.0, + "AmphibiousChecked": false, + "AmphibiousPoints": 0.0, + "BasicWaterMoveMod": 0.0, + "BasicWaterMovePoints": 0.0, + "EnhancedWaterLevel": 0.0, + "EnhancedWaterMovePoints": 0.0, + "SuperJumpEnteredLevel": 0.0, + "SuperJumpPoints": 0.0, + "SpellBonus": 3.0, + "CombatReflexes": false, + "RepeatingLanguages": [], + "RepeatingCultures": [], + "RepeatingTraits": [ + { + "Idkey": "186", + "Name": "Energy Reserve (Magical)", + "TraitLevel": "3", + "Foa": "", + "Points": 9.0, + "Ref": "P119", + "Notes": "Magical" + }, + { + "Idkey": "184", + "Name": "Magery", + "TraitLevel": "3", + "Foa": "", + "Points": 30.0, + "Ref": "B66", + "Notes": "WARNING: Always use the Magery modifiers with Magery and the Magery 0 modifiers with Magery 0. Using the Magery modifiers with any other trait can cause your spells to be miscalculated. For standard magic use Magery, for Ritual Magic use Ritual Magery, for Wildcard! magic use Wildcard Magery!, for Clerical Magic use Power Investiture, for Syntactic magic use Syntactic Magery, For standard magic use Magery; for Ritual Magic use Ritual Magery; for Wildcard! Magic use Wildcard Magery!; for Clerical Magic use Power Investiture." + }, + { + "Idkey": "185", + "Name": "Magery 0", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B66", + "Notes": "Magery 0 is included as a separate item from the normal Magery advantage, due to the fact that many kinds of enhancements and limitations are meant to only affect the levels above 0, not the base 5 points from Magery 0. The Magery advantage is set to have Magery 0 as a pre-req. WARNING: Always use the Magery modifiers with Magery and the Magery 0 modifiers with Magery 0. Using the Magery modifiers with any other item can cause your spells to be miscalculated." + }, + { + "Idkey": "231", + "Name": "Status", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B28", + "Notes": "+1" + }, + { + "Idkey": "232", + "Name": "Wealth", + "TraitLevel": "1", + "Foa": "", + "Points": 10.0, + "Ref": "B25", + "Notes": "Comfortable" + } + ], + "RepeatingPerks": [], + "RepeatingQuirks": [], + "RepeatingDisadvantages": [ + { + "Idkey": "233", + "Name": "Loner", + "TraitLevel": "1", + "ControlRating": "12", + "Points": -5.0, + "Ref": "B142", + "Notes": "12 or less, *1" + } + ], + "RepeatingRacial": [], + "RepeatingSkills": [ + { + "Idkey": "187", + "Name": "Innate Attack (Projectile)", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "E", + "Bonus": 0.0, + "Points": 8.0, + "Skill": 13.0, + "Ref": "B201", + "SkillModNotes": "", + "Notes": "Projectile" + }, + { + "Idkey": "188", + "Name": "Staff", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "A", + "Bonus": 0.0, + "Points": 4.0, + "Skill": 11.0, + "Ref": "B208", + "SkillModNotes": "", + "Notes": "" + } + ], + "RepeatingTechniquesrevised": [], + "RepeatingDefense": [ + { + "Idkey": "128_mode_20", + "Name": "Punch", + "Type": "Unarmed Parry", + "Info": "", + "Skill": 8.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "189_mode_47", + "Name": "Quarterstaff (Staff Swing)", + "Type": "Parry", + "Info": "", + "Skill": 10.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "189_mode_48", + "Name": "Quarterstaff (Staff Thrust)", + "Type": "Parry", + "Info": "", + "Skill": 10.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "189_mode_49", + "Name": "Quarterstaff (2H Sword Swing)", + "Type": "Parry", + "Info": "", + "Skill": 5.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "189_mode_50", + "Name": "Quarterstaff (2H Sword Thrust)", + "Type": "Parry", + "Info": "", + "Skill": 5.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + } + ], + "RepeatingMelee": [ + { + "Idkey": "226_mode_36", + "Name": "Air Jet", + "Damage": "~2d6", + "Type": "knock", + "Reach": "~2", + "Skill": 11.0, + "ArmorDivisor": 1.0, + "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" + }, + { + "Idkey": "14_mode_1", + "Name": "Bite", + "Damage": "1d6-3", + "Type": "cr", + "Reach": "C", + "Skill": 10.0, + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + }, + { + "Idkey": "13350_mode_37", + "Name": "Breathe Fire", + "Damage": "~1d6+1", + "Type": "burn", + "Reach": "~1", + "Skill": 11.0, + "ArmorDivisor": 1.0, + "Notes": "{~1-4 energy. Multiply spell effect based on enegy spent.}" + }, + { + "Idkey": "13351_mode_39", + "Name": "Flame Jet", + "Damage": "~1d6", + "Type": "burn", + "Reach": "~1", + "Skill": 11.0, + "ArmorDivisor": 1.0, + "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" + }, + { + "Idkey": "69_mode_13", + "Name": "Kick", + "Damage": "1d6-2", + "Type": "cr", + "Reach": "C,1", + "Skill": 8.0, + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + }, + { + "Idkey": "128_mode_20", + "Name": "Punch", + "Damage": "1d6-3", + "Type": "cr", + "Reach": "C", + "Skill": 10.0, + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + }, + { + "Idkey": "189_mode_47", + "Name": "Quarterstaff (Staff Swing)", + "Damage": "1d6+1", + "Type": "cr", + "Reach": "1,2", + "Skill": 11.0, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "189_mode_48", + "Name": "Quarterstaff (Staff Thrust)", + "Damage": "1d6", + "Type": "cr", + "Reach": "1,2", + "Skill": 11.0, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "189_mode_49", + "Name": "Quarterstaff (2H Sword Swing)", + "Damage": "1d6+1", + "Type": "cr", + "Reach": "1,2", + "Skill": 5.0, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "189_mode_50", + "Name": "Quarterstaff (2H Sword Thrust)", + "Damage": "1d6-1", + "Type": "cr", + "Reach": "2", + "Skill": 5.0, + "ArmorDivisor": 1.0, + "Notes": "" + } + ], + "RepeatingRanged": [ + { + "Idkey": "216_mode_38", + "Name": "Fireball", + "Damage": "~1d6", + "Type": "burn", + "Acc": "1", + "Range": "25/50", + "Rof": "", + "Shots": "", + "Bulk": "", + "Recoil": "", + "Skill": 13.0, + "Malfunction": "", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 1.0, + "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" + }, + { + "Idkey": "222_mode_40", + "Name": "Ice Dagger", + "Damage": "~1d6-1", + "Type": "imp", + "Acc": "3", + "Range": "30/60", + "Rof": "", + "Shots": "", + "Bulk": "", + "Recoil": "", + "Skill": 13.0, + "Malfunction": "", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 1.0, + "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" + }, + { + "Idkey": "223_mode_41", + "Name": "Ice Sphere", + "Damage": "~1d6", + "Type": "cr", + "Acc": "2", + "Range": "40/80", + "Rof": "", + "Shots": "", + "Bulk": "", + "Recoil": "", + "Skill": 13.0, + "Malfunction": "", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 1.0, + "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" + }, + { + "Idkey": "225_mode_45", + "Name": "Pistol Crossbow (ST 10) (Barbed-head)", + "Damage": "1d6-4", + "Type": "imp", + "Acc": "1", + "Range": "0", + "Rof": "1", + "Shots": "1(4)", + "Bulk": "-4", + "Recoil": "-", + "Skill": 6.0, + "Malfunction": "", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 1.0, + "Notes": "{Requires two hands to ready, but only one hand to attack.}" + }, + { + "Idkey": "201_mode_42", + "Name": "Stone Missile", + "Damage": "~1d6+1", + "Type": "cr", + "Acc": "2", + "Range": "40/80", + "Rof": "", + "Shots": "", + "Bulk": "", + "Recoil": "", + "Skill": 13.0, + "Malfunction": "", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 1.0, + "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" + } + ], + "RepeatingItem": [ + { + "Idkey": "191", + "Name": "Cloth Armor Suit", + "Tl": "1", + "LegalityClass": "", + "Ref": "L18", + "Count": 1.0, + "Cost": 250.0, + "Weight": 12.0, + "Notes": "Deflect, +1, +100\nTL:1 LC:-- DR:1* Locations: all Notes:This is a full suit of armor from GURPS Lite. It includes an article of light, common clothing to wear underneath - or padding, if this is usual for the armor. The statistics already reflect this; you do not have to buy clothing or padding seperately, or account for its DR and weight." + }, + { + "Idkey": "225", + "Name": "Pistol Crossbow (ST 10)", + "Tl": "3", + "LegalityClass": "4", + "Ref": "LT75", + "Count": 1.0, + "Cost": 150.0, + "Weight": 4.0, + "Notes": "ST 10\nTL:3 LC:4, Dam:thr+2 imp ACC:1 Range:ST*15/ST*20 ROF:1 Shots:1(4) ST:7 Bulk:-4 Rcl:- Skill:Crossbow, DX-4 Notes: [2, 3]" + }, + { + "Idkey": "193", + "Name": "Powerstone (Energy 4)", + "Tl": "", + "LegalityClass": "", + "Ref": "M20", + "Count": 1.0, + "Cost": 425.0, + "Weight": 0.0, + "Notes": "Energy 4" + }, + { + "Idkey": "189", + "Name": "Quarterstaff", + "Tl": "0", + "LegalityClass": "4", + "Ref": "LT69", + "Count": 1.0, + "Cost": 40.0, + "Weight": 4.0, + "Notes": "Staff, +30\nTL:0 LC:4 \\par [Dam:sw+2 cr Reach:1, 2 Parry:2 ST:7 Skill:Staff, DX-5, Polearm-4, Spear-2] \\par [Dam:thr+2 cr Reach:1, 2 Parry:2 ST:7 Skill:Staff, DX-5, Polearm-4, Spear-2] \\par [Dam:sw+2 cr Reach:1, 2 Parry:0 ST:9 Skill:Two-Handed Sword, DX-5, Broadsword-4, Force Sword-4] \\par [Dam:thr+1 cr Reach:2 Parry:0 ST:9 Skill:Two-Handed Sword, DX-5, Broadsword-4, Force Sword-4]" + } + ], + "RepeatingSpells": [ + { + "Idkey": "226", + "Name": "Air Jet", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "1 sec.", + "Cost": "1 to 3/S", + "Skill": 15.0, + "Ref": "M24", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Air", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 3 Prerequisites: Shape Air" + }, + { + "Idkey": "13349", + "Name": "Body of Flames", + "Difficulty": "VH", + "SpellModifier": 0.0, + "Points": 1.0, + "SpellResistedBy": "R-HT", + "Duration": "1 min.", + "Cost": "12/4", + "Skill": 13.0, + "Ref": "M76", + "Casttime": "5 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 8 Prerequisites: Magery 1, Breathe Fire" + }, + { + "Idkey": "13350", + "Name": "Breathe Fire", + "Difficulty": "VH", + "SpellModifier": 0.0, + "Points": 1.0, + "SpellResistedBy": "", + "Duration": "1 sec.", + "Cost": "1 to 4", + "Skill": 13.0, + "Ref": "M76", + "Casttime": "2 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 7 Prerequisites: Magery 1, Flame Jet, Resist Fire" + }, + { + "Idkey": "210", + "Name": "Create Air", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "5 sec.#", + "Cost": "1", + "Skill": 15.0, + "Ref": "M23, B243", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Area", + "SpellCollege": "Air", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 1 Prerequisites: Purify Air or Seek Air" + }, + { + "Idkey": "197", + "Name": "Create Earth", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Perm.", + "Cost": "2/cu. yd.", + "Skill": 15.0, + "Ref": "M51, B246", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Earth", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 3 Prerequisites: Magery 1, Earth to Stone" + }, + { + "Idkey": "212", + "Name": "Create Fire", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "1 min.", + "Cost": "2/H", + "Skill": 15.0, + "Ref": "M72, B246", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Area", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 1 Prerequisites: Ignite Fire or Seek Fire" + }, + { + "Idkey": "219", + "Name": "Create Water", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Perm.", + "Cost": "2/gal.", + "Skill": 15.0, + "Ref": "M184, B253", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Water", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 2 Prerequisites: Purify Water" + }, + { + "Idkey": "198", + "Name": "Earth to Stone", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Perm.", + "Cost": "3/cu. yd.#", + "Skill": 15.0, + "Ref": "M51, B245", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Earth", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 2 Prerequisites: Magery 1, Shape Earth" + }, + { + "Idkey": "13354", + "Name": "Extinguish Fire", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 1.0, + "SpellResistedBy": "", + "Duration": "Perm.", + "Cost": "3", + "Skill": 14.0, + "Ref": "M72, B247", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Area", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 1 Prerequisites: Ignite Fire" + }, + { + "Idkey": "214", + "Name": "Fire Cloud", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "10 sec.", + "Cost": "1 to 5/S", + "Skill": 15.0, + "Ref": "M75", + "Casttime": "1 to 5 sec.", + "Maintain": "", + "SpellClass": "Area", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 7 Prerequisites: Magery 1, Shape Air, Fireball" + }, + { + "Idkey": "216", + "Name": "Fireball", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Instant", + "Cost": "1 to Magery#", + "Skill": 15.0, + "Ref": "M74, B247", + "Casttime": "1 to 3 sec.", + "Maintain": "", + "SpellClass": "Missile", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 3 Prerequisites: Magery 1, Create Fire, Shape Fire" + }, + { + "Idkey": "13353", + "Name": "Fireproof", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 1.0, + "SpellResistedBy": "", + "Duration": "1 day", + "Cost": "3#", + "Skill": 14.0, + "Ref": "M73", + "Casttime": "5 min.", + "Maintain": "", + "SpellClass": "Area", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 2 Prerequisites: Extinguish Fire" + }, + { + "Idkey": "13351", + "Name": "Flame Jet", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 1.0, + "SpellResistedBy": "", + "Duration": "1 sec.", + "Cost": "1 to 3/S", + "Skill": 14.0, + "Ref": "M73", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 3 Prerequisites: Create Fire, Shape Fire" + }, + { + "Idkey": "222", + "Name": "Ice Dagger", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Instant", + "Cost": "1 to Magery#", + "Skill": 15.0, + "Ref": "M188", + "Casttime": "1 to 3 sec.", + "Maintain": "", + "SpellClass": "Missile", + "SpellCollege": "Water", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 5 Prerequisites: Ice Sphere or Water Jet" + }, + { + "Idkey": "223", + "Name": "Ice Sphere", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Instant", + "Cost": "1 to Magery#", + "Skill": 15.0, + "Ref": "M186", + "Casttime": "1 to 3 sec.", + "Maintain": "", + "SpellClass": "Missile", + "SpellCollege": "Water", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 4 Prerequisites: Shape Water" + }, + { + "Idkey": "213", + "Name": "Ignite Fire", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "1 sec.", + "Cost": "1 to 4/S", + "Skill": 15.0, + "Ref": "M72, B246", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 0" + }, + { + "Idkey": "229", + "Name": "Itch", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "R-HT", + "Duration": "Scratch#", + "Cost": "2", + "Skill": 15.0, + "Ref": "M35, B244", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Body Control", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 0" + }, + { + "Idkey": "195", + "Name": "Lend Energy", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Perm.", + "Cost": "Varies", + "Skill": 15.0, + "Ref": "M89, B248", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Healing", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 0 Prerequisites: Magery 1 or Empathy" + }, + { + "Idkey": "230", + "Name": "Light", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "1 min.", + "Cost": "1/1", + "Skill": 15.0, + "Ref": "M110, B249", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Light & Darkness", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 0" + }, + { + "Idkey": "211", + "Name": "Purify Air", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Instant", + "Cost": "1", + "Skill": 15.0, + "Ref": "M23, B243", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Area", + "SpellCollege": "Air", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 0" + }, + { + "Idkey": "220", + "Name": "Purify Water", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Perm.", + "Cost": "1/gal.", + "Skill": 15.0, + "Ref": "M184, B253", + "Casttime": "5-10 sec/gal#", + "Maintain": "", + "SpellClass": "Special", + "SpellCollege": "Water", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 1 Prerequisites: Seek Water" + }, + { + "Idkey": "196", + "Name": "Recover Energy", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Special", + "Cost": "none", + "Skill": 15.0, + "Ref": "M89, B248", + "Casttime": "Special", + "Maintain": "", + "SpellClass": "Special", + "SpellCollege": "Healing", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 1 Prerequisites: Magery 1, Lend Energy" + }, + { + "Idkey": "13352", + "Name": "Resist Fire", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 1.0, + "SpellResistedBy": "", + "Duration": "1 min.", + "Cost": "2/1#", + "Skill": 14.0, + "Ref": "M74, B247", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 3 Prerequisites: Fireproof or Extinguish Fire, Cold" + }, + { + "Idkey": "218", + "Name": "Seek Air", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Instant", + "Cost": "1", + "Skill": 15.0, + "Ref": "M23", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Information", + "SpellCollege": "Air", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 0" + }, + { + "Idkey": "200", + "Name": "Seek Earth", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Instant", + "Cost": "3", + "Skill": 15.0, + "Ref": "M50, B245", + "Casttime": "10 sec.", + "Maintain": "", + "SpellClass": "Information", + "SpellCollege": "Earth", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 0" + }, + { + "Idkey": "221", + "Name": "Seek Water", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Instant", + "Cost": "2", + "Skill": 15.0, + "Ref": "M184, B253", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Information", + "SpellCollege": "Water", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 0" + }, + { + "Idkey": "215", + "Name": "Shape Air", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "1 min.", + "Cost": "1 to 10#", + "Skill": 15.0, + "Ref": "M24, B243", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Air", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 2 Prerequisites: Create Air" + }, + { + "Idkey": "199", + "Name": "Shape Earth", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "1 min.", + "Cost": "1/cu. yd./h", + "Skill": 15.0, + "Ref": "M50, B245", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Earth", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 1 Prerequisites: Seek Earth" + }, + { + "Idkey": "217", + "Name": "Shape Fire", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "1 min.", + "Cost": "2/H", + "Skill": 15.0, + "Ref": "M72, B246", + "Casttime": "1 sec.", + "Maintain": "", + "SpellClass": "Area", + "SpellCollege": "Fire", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 1 Prerequisites: Ignite Fire" + }, + { + "Idkey": "224", + "Name": "Shape Water", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "1 min.", + "Cost": "1/1#", + "Skill": 15.0, + "Ref": "M185, B253", + "Casttime": "2 sec.", + "Maintain": "", + "SpellClass": "Regular", + "SpellCollege": "Water", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 3 Prerequisites: Create Water" + }, + { + "Idkey": "201", + "Name": "Stone Missile", + "Difficulty": "H", + "SpellModifier": 0.0, + "Points": 2.0, + "SpellResistedBy": "", + "Duration": "Instant", + "Cost": "1 to Magery", + "Skill": 15.0, + "Ref": "M52", + "Casttime": "1 to 3 sec.", + "Maintain": "", + "SpellClass": "Missile", + "SpellCollege": "Earth", + "SpellCollegeSecondary": "", + "SpellModNotes": "", + "SpellNotes": "Prereq Count: 4 Prerequisites: Magery 1, Create Earth" + } + ] +} \ No newline at end of file diff --git a/GURPS/readme/assets/Rampage (NPC) export.json b/GURPS/readme/assets/Rampage (NPC) export.json index a705018441..33cdf18207 100644 --- a/GURPS/readme/assets/Rampage (NPC) export.json +++ b/GURPS/readme/assets/Rampage (NPC) export.json @@ -1,959 +1,947 @@ { - "CharacterName": "Rampage", - "Fullname": "Rampage (NPC)", - "Playername": "NPC", - "Nickname": "", - "Race": "Human", - "RaceRef": "", - "TemplateNames": "", - "Gender": "", - "Size": 0.0, - "ApplySizeModifier": false, - "Reactions": "+2 from 'Charisma 2'\nConditional:\n-2 from 'Reputation 2 (Gang Leader; 7 or less, +1, *1/3; Large class, +1, *1/2)'", - "CampaignTl": 8.0, - "TotalPoints": 150.0, - "Tl": 8.0, - "TlPts": 0.0, - "Status": "0", - "Wealth": "Comfortable", - "Income": 5200.0, - "CostOfLiving": 600.0, - "Stash": 5169.6, - "Age": "27", - "Height": "6'", - "Weight": 210.0, - "Appearance": 0.0, - "GeneralAppearance": "Short mohawk, painted face, likes to wear chains, like something out of Road Warrior.", - "StrengthMod": 1.0, - "StrengthPoints": 60.0, - "DexterityMod": 0.0, - "DexterityPoints": 40.0, - "IntelligenceMod": 0.0, - "IntelligencePoints": 0.0, - "HealthMod": 0.0, - "HealthPoints": 20.0, - "PerceptionMod": 0.0, - "PerceptionPoints": 10.0, - "VisionMod": 0.0, - "VisionPoints": 0.0, - "HearingMod": 0.0, - "HearingPoints": 0.0, - "TasteSmellMod": 0.0, - "TasteSmellPoints": 0.0, - "TouchMod": 0.0, - "TouchPoints": 0.0, - "WillpowerMod": 0.0, - "WillpowerPoints": 10.0, - "FearCheckMod": 2.0, - "FearCheckPoints": 0.0, - "StunCheckMod": 0.0, - "KnockdownCheckMod": 0.0, - "UnconsciousCheckMod": 1.0, - "UnconsciousCheckPoints": 0.0, - "DeathCheckMod": 1.0, - "DeathCheckPoints": 0.0, - "BasicSpeedMod": 0.0, - "BasicSpeedPoints": 0.0, - "BasicMoveMod": 0.0, - "BasicMovePoints": 0.0, - "EnhancedGroundMoveMod": 0.5, - "EnhancedGroundMovePoints": 0.0, - "DodgeMod": 2.0, - "LiftStMod": 7.0, - "LiftStPoints": 15.0, - "StrikingStMod": 4.0, - "StrikingStPoints": 0.0, - "HitPointsMod": 0.0, - "HitPointsPoints": 8.0, - "HitPoints": 21.0, - "FatiguePointsMod": 0.0, - "FatiguePointsPoints": 0.0, - "FatiguePoints": 12.0, - "FlightChecked": false, - "FlightPoints": 0.0, - "BasicAirMoveMod": 0.0, - "BasicAirMovePoints": 0.0, - "EnhancedAirLevel": 0.0, - "EnhancedAirMovePoints": 0.0, - "AmphibiousChecked": false, - "AmphibiousPoints": 0.0, - "BasicWaterMoveMod": 0.0, - "BasicWaterMovePoints": 0.0, - "EnhancedWaterLevel": 0.0, - "EnhancedWaterMovePoints": 0.0, - "SuperJumpEnteredLevel": 0.0, - "SuperJumpPoints": 0.0, - "SpellBonus": 0.0, - "CombatReflexes": true, - "RepeatingLanguages": [], - "RepeatingCultures": [ - { - "Idkey": "12982", - "Name": "European (Native)", - "Points": 0.0 - }, - { - "Idkey": "12983", - "Name": "Western", - "Points": 1.0 - } - ], - "RepeatingTraits": [ - { - "Idkey": "10717", - "Name": "Ambidexterity", - "TraitLevel": "1", - "Foa": "", - "Points": 5.0, - "Ref": "B39", - "Notes": "" - }, - { - "Idkey": "10800", - "Name": "Appearance", - "TraitLevel": "1", - "Foa": "", - "Points": 4.0, - "Ref": "B21", - "Notes": "\nAttractive" - }, - { - "Idkey": "10704", - "Name": "Body Control Talent", - "TraitLevel": "1", - "Foa": "", - "Points": 5.0, - "Ref": "P121,P167-169", - "Notes": "\nInnate Attack (Projectile), +0" - }, - { - "Idkey": "10799", - "Name": "Charisma", - "TraitLevel": "2", - "Foa": "", - "Points": 10.0, - "Ref": "B41", - "Notes": "" - }, - { - "Idkey": "10698", - "Name": "Combat Reflexes", - "TraitLevel": "1", - "Foa": "", - "Points": 14.0, - "Ref": "B43", - "Notes": "\nBiological, -10%" - }, - { - "Idkey": "12986", - "Name": "Contact (Rival Gang)", - "TraitLevel": "1", - "Foa": "9", - "Points": 1.0, - "Ref": "B44", - "Notes": "My notes here\nEffective Skill 12\nRival Gang\n9 or less, *1\nSomewhat Reliable, *1\nMy notes here\nUgly dude with twisted lips" - }, - { - "Idkey": "10720", - "Name": "Crossbow (Armor Piercing)", - "TraitLevel": "3", - "Foa": "", - "Points": 38.0, - "Ref": "B61, P53", - "Notes": "\nArmor Piercing\nArmor Divisor, 2, +50%\nGadget/Breakable: DR 3-5, -15%\nGadget/Breakable: Size -3 or -4, -15%\nGadget/Can Be Stolen: Must be forcefully removed, -10%\nInaccurate, -1, -5%\nIncreased Range, x2, +10%\nIncreased Range, 1/2D Range only, x5, +10%\nNo Signature, +20%\nRicochet, +10%" - }, - { - "Idkey": "10730", - "Name": "Crossbow (Explosive)", - "TraitLevel": "3", - "Foa": "", - "Points": 7.0, - "Ref": "B61, P53", - "Notes": "\nExplosive\nAlternative Attack, *1/5\nDouble Knockback, +20%\nExplosive, Damage / 2xYards, +100%\nGadget/Breakable: DR 3-5, -15%\nGadget/Breakable: Size -3 or -4, -15%\nGadget/Can Be Stolen: Must be forcefully removed, -10%\nInaccurate, -1, -5%\nIncreased Range, x2, +10%\nIncreased Range, 1/2D Range only, x10, +15%\nNo Signature, +20%" - }, - { - "Idkey": "10741", - "Name": "Crossbow (Smoke Arrow)", - "TraitLevel": "6", - "Foa": "", - "Points": 5.0, - "Ref": "B72, P64", - "Notes": "\nSmoke Arrow\nAlternative Ability, *1/5\nArea Effect, 4 yd, +50%\nGadget/Breakable: DR 3-5, -15%\nGadget/Breakable: Size -3 or -4, -15%\nGadget/Can Be Stolen: Must be forcefully removed, -10%\nInaccurate, -1, -5%\nIncreased Range, x2, +10%\nIncreased Range, 1/2D Range Only, x5, +10%\nNo Signature, +20%\nRanged, +50%" - }, - { - "Idkey": "10666", - "Name": "Damage Resistance", - "TraitLevel": "2", - "Foa": "", - "Points": 5.0, - "Ref": "B46, P45", - "Notes": "\nBiological, -10%\nTough Skin, -40%" - }, - { - "Idkey": "10700", - "Name": "Enhanced Dodge", - "TraitLevel": "1", - "Foa": "", - "Points": 14.0, - "Ref": "B51", - "Notes": "\nBiological, -10%" - }, - { - "Idkey": "10715", - "Name": "Enhanced Move (Ground)", - "TraitLevel": "1", - "Foa": "", - "Points": 9.0, - "Ref": "B52, P49", - "Notes": "\n#list(LevelName Step 0.5)\nGround\nBiological, -10%" - }, - { - "Idkey": "10702", - "Name": "Enhanced Muscle", - "TraitLevel": "4", - "Foa": "", - "Points": 29.0, - "Ref": "Bio213", - "Notes": "\nBiological, -10%" - }, - { - "Idkey": "10718", - "Name": "Extra Attack", - "TraitLevel": "1", - "Foa": "", - "Points": 23.0, - "Ref": "B54, P49", - "Notes": "\nBiological, -10%" - }, - { - "Idkey": "11893", - "Name": "Extra ST", - "TraitLevel": "1", - "Foa": "", - "Points": 10.0, - "Ref": "B14", - "Notes": "\nAffects ST, +0%\nSize, +0%\nThe Extra ST advantage allows you to take extra levels of the attribute which you can then apply enhancements and limitations to. The \"Affects displayed score\" modifier causes the Extra ST advantage to affect the displayed attribute score. If you don't wish this advantage to affect the displayed score remove that modifier." - }, - { - "Idkey": "10712", - "Name": "Fit", - "TraitLevel": "1", - "Foa": "", - "Points": 5.0, - "Ref": "B55", - "Notes": "" - }, - { - "Idkey": "11891", - "Name": "Lifting ST", - "TraitLevel": "3", - "Foa": "", - "Points": 9.0, - "Ref": "B65, P58", - "Notes": "\nSize, +0%" - }, - { - "Idkey": "10709", - "Name": "Protected Vision", - "TraitLevel": "1", - "Foa": "", - "Points": 5.0, - "Ref": "B78, P69", - "Notes": "\nBiological, -10%" - }, - { - "Idkey": "10714", - "Name": "Rapid Healing", - "TraitLevel": "1", - "Foa": "", - "Points": 5.0, - "Ref": "B79", - "Notes": "" - }, - { - "Idkey": "10711", - "Name": "Resilience", - "TraitLevel": "20", - "Foa": "", - "Points": 18.0, - "Ref": "", - "Notes": "\nBiological, -10%" - }, - { - "Idkey": "10705", - "Name": "Resistant (Metabolic Hazards)", - "TraitLevel": "4", - "Foa": "", - "Points": 9.0, - "Ref": "B80, P71", - "Notes": "\nVery Common\nMetabolic Hazards\nBiological, -10%\n+3, *1/3" - }, - { - "Idkey": "10835", - "Name": "Signature Gear (Advanced Body Armor)", - "TraitLevel": "1", - "Foa": "", - "Points": 1.0, - "Ref": "B85", - "Notes": "\n%SigGearAliasList%\nAdvanced Body Armor" - }, - { - "Idkey": "11890", - "Name": "Wealth", - "TraitLevel": "1", - "Foa": "", - "Points": 10.0, - "Ref": "B25", - "Notes": "\nComfortable" - } - ], - "RepeatingPerks": [ - { - "Idkey": "10756", - "Name": "Alcohol Tolerance", - "Foa": "", - "Points": 1.0, - "Ref": "B100, B100,PU2:13", - "Notes": "" - }, - { - "Idkey": "10757", - "Name": "Base (Bar)", - "Foa": "", - "Points": 1.0, - "Ref": "PU2:17", - "Notes": "\nBar" - }, - { - "Idkey": "10794", - "Name": "Teamwork (Concrete Savages)", - "Foa": "", - "Points": 1.0, - "Ref": "MA52, PU2:6", - "Notes": "\nConcrete Savages" - } - ], - "RepeatingQuirks": [ - { - "Idkey": "10774", - "Name": "Chauvinistic", - "ControlRating": "", - "Points": -1.0, - "Ref": "B164", - "Notes": "" - }, - { - "Idkey": "10773", - "Name": "wears chains", - "ControlRating": "", - "Points": -1.0, - "Ref": "", - "Notes": "" - } - ], - "RepeatingDisadvantages": [ - { - "Idkey": "10758", - "Name": "Bad Temper", - "TraitLevel": "1", - "ControlRating": "12", - "Points": -10.0, - "Ref": "B124", - "Notes": "\n12 or less, *1" - }, - { - "Idkey": "10769", - "Name": "Enemy (Police)", - "TraitLevel": "1", - "ControlRating": "", - "Points": -10.0, - "Ref": "B135", - "Notes": "\nSmall group (3-5 people)\nPolice\n9 or less, *1\nHunter, *1" - }, - { - "Idkey": "10760", - "Name": "Greed", - "TraitLevel": "1", - "ControlRating": "12", - "Points": -15.0, - "Ref": "B137", - "Notes": "\n12 or less, *1" - }, - { - "Idkey": "10762", - "Name": "Reputation (Gang Leader)", - "TraitLevel": "2", - "ControlRating": "", - "Points": -1.0, - "Ref": "B27", - "Notes": "\nGang Leader\n7 or less, *1/3\nLarge class, *1/2" - } - ], - "RepeatingRacial": [], - "RepeatingSkills": [ - { - "Idkey": "10784", - "Name": "Area Knowledge (local)", - "Tl": "", - "Base": "", - "Difficulty": "IQ/E", - "Bonus": 0.0, - "Points": 2.0, - "Skill": 11.0, - "Ref": "B176", - "SkillModNotes": "", - "Notes": "\nlocal" - }, - { - "Idkey": "10753", - "Name": "Brawling", - "Tl": "", - "Base": "", - "Difficulty": "DX/E", - "Bonus": 0.0, - "Points": 4.0, - "Skill": 14.0, - "Ref": "B182", - "SkillModNotes": "", - "Notes": "\nNotes: Calculated damage takes into account bonuses from Teeth, Weak Bite, Claws, and skill level. You may add the modifier \"Has Gauntlets/Brass Knuckles\" or \"Has Boots\" to apply the +1 damage to Punch or Kick, as appropriate." - }, - { - "Idkey": "10780", - "Name": "Carousing", - "Tl": "", - "Base": "", - "Difficulty": "HT/E", - "Bonus": 0.0, - "Points": 2.0, - "Skill": 13.0, - "Ref": "B183", - "SkillModNotes": "", - "Notes": "" - }, - { - "Idkey": "10776", - "Name": "Connoisseur (Music)", - "Tl": "", - "Base": "", - "Difficulty": "IQ/A", - "Bonus": 0.0, - "Points": 3.0, - "Skill": 11.0, - "Ref": "B185", - "SkillModNotes": "", - "Notes": "\nMusic" - }, - { - "Idkey": "10777", - "Name": "Dancing", - "Tl": "", - "Base": "", - "Difficulty": "DX/A", - "Bonus": 0.0, - "Points": 1.0, - "Skill": 11.0, - "Ref": "B187", - "SkillModNotes": "", - "Notes": "" - }, - { - "Idkey": "10781", - "Name": "Forced Entry", - "Tl": "", - "Base": "", - "Difficulty": "DX/E", - "Bonus": 0.0, - "Points": 2.0, - "Skill": 13.0, - "Ref": "B196", - "SkillModNotes": "", - "Notes": "" - }, - { - "Idkey": "10775", - "Name": "Guns (Pistol)", - "Tl": "8", - "Base": "", - "Difficulty": "DX/E", - "Bonus": 0.0, - "Points": 4.0, - "Skill": 14.0, - "Ref": "B198", - "SkillModNotes": "", - "Notes": "\nuns/TL8 (Pistol" - }, - { - "Idkey": "10752", - "Name": "Innate Attack (Projectile)", - "Tl": "", - "Base": "", - "Difficulty": "DX/E", - "Bonus": 1.0, - "Points": 12.0, - "Skill": 17.0, - "Ref": "B201", - "SkillModNotes": "+1 from 'Body Control Talent 1 (Innate Attack (Projectile), +0)'", - "Notes": "\nProjectile" - }, - { - "Idkey": "10782", - "Name": "Intimidation", - "Tl": "", - "Base": "", - "Difficulty": "Will/A", - "Bonus": 0.0, - "Points": 4.0, - "Skill": 13.0, - "Ref": "B202", - "SkillModNotes": "", - "Notes": "" - }, - { - "Idkey": "10798", - "Name": "Leadership", - "Tl": "", - "Base": "", - "Difficulty": "IQ/A", - "Bonus": 2.0, - "Points": 4.0, - "Skill": 13.0, - "Ref": "B204", - "SkillModNotes": "+2 from 'Charisma 2'", - "Notes": "" - }, - { - "Idkey": "10778", - "Name": "Musical Instrument (Guitar)", - "Tl": "", - "Base": "", - "Difficulty": "IQ/H", - "Bonus": 0.0, - "Points": 12.0, - "Skill": 12.0, - "Ref": "B211", - "SkillModNotes": "", - "Notes": "\nGuitar" - }, - { - "Idkey": "13357", - "Name": "Navigation (Land)", - "Tl": "8", - "Base": "", - "Difficulty": "IQ/A", - "Bonus": 0.0, - "Points": 2.0, - "Skill": 10.0, - "Ref": "B211", - "SkillModNotes": "", - "Notes": "\navigation/TL8 (Land" - }, - { - "Idkey": "13175", - "Name": "Shield (Force)", - "Tl": "", - "Base": "", - "Difficulty": "DX/E", - "Bonus": 0.0, - "Points": 2.0, - "Skill": 13.0, - "Ref": "B220", - "SkillModNotes": "", - "Notes": "\nForce" - }, - { - "Idkey": "10779", - "Name": "Singing", - "Tl": "", - "Base": "", - "Difficulty": "HT/E", - "Bonus": 0.0, - "Points": 2.0, - "Skill": 13.0, - "Ref": "B220", - "SkillModNotes": "", - "Notes": "" - }, - { - "Idkey": "10783", - "Name": "Streetwise", - "Tl": "", - "Base": "", - "Difficulty": "IQ/A", - "Bonus": 0.0, - "Points": 8.0, - "Skill": 12.0, - "Ref": "B223", - "SkillModNotes": "", - "Notes": "" - }, - { - "Idkey": "13174", - "Name": "Wrestling", - "Tl": "", - "Base": "", - "Difficulty": "DX/A", - "Bonus": 0.0, - "Points": 1.0, - "Skill": 11.0, - "Ref": "B228", - "SkillModNotes": "", - "Notes": "" - } - ], - "RepeatingTechniquesrevised": [ - { - "Idkey": "13172", - "Name": "Aggressive Parry (Brawling)", - "Parent": "Brawling", - "BaseLevel": "10", - "Default": -1.0, - "MaxModifier": 0.0, - "Difficulty": "Tech/H", - "SkillModifier": 0.0, - "Points": 2.0, - "Skill": 11.0, - "Ref": "MA65", - "SkillModNotes": "", - "Notes": "\nBrawling" - }, - { - "Idkey": "13173", - "Name": "Arm Lock (Wrestling)", - "Parent": "Wrestling", - "BaseLevel": "11", - "Default": 0.0, - "MaxModifier": 4.0, - "Difficulty": "Tech/A", - "SkillModifier": 0.0, - "Points": 2.0, - "Skill": 13.0, - "Ref": "MA65, B230", - "SkillModNotes": "", - "Notes": "\nWrestling" - } - ], - "RepeatingDefense": [ - { - "Idkey": "10704_mode_34", - "Name": "Body Control Talent (Power Dodge)", - "Type": "Power Dodge", - "Info": "", - "Skill": 9.0, - "SkillMod": 0.0, - "DefenseModReason": "", - "InfoDescription": "" - }, - { - "Idkey": "10704_mode_35", - "Name": "Body Control Talent (Power Block/Physical)", - "Type": "Power Block", - "Info": "", - "Skill": 9.0, - "SkillMod": 0.0, - "DefenseModReason": "", - "InfoDescription": "" - }, - { - "Idkey": "10704_mode_36", - "Name": "Body Control Talent (Power Block/Mental)", - "Type": "Power Block Mental", - "Info": "", - "Skill": 9.0, - "SkillMod": 0.0, - "DefenseModReason": "", - "InfoDescription": "" - }, - { - "Idkey": "10753_mode_88", - "Name": "Brawling (Punch)", - "Type": "Unarmed Parry", - "Info": "", - "Skill": 11.0, - "SkillMod": 0.0, - "DefenseModReason": "", - "InfoDescription": "" - }, - { - "Idkey": "10613_mode_19", - "Name": "Punch", - "Type": "Unarmed Parry", - "Info": "", - "Skill": 11.0, - "SkillMod": 0.0, - "DefenseModReason": "", - "InfoDescription": "" - }, - { - "Idkey": "13175_block", - "Name": "Shield (Force)", - "Type": "Block", - "Info": "", - "Skill": 10.0, - "SkillMod": 0.0, - "DefenseModReason": "", - "InfoDescription": "" - } - ], - "RepeatingMelee": [ - { - "Idkey": "13172_mode_87", - "Name": "Aggressive Parry (Brawling)", - "Damage": "2d6-2", - "Type": "cr", - "Reach": "C", - "Skill": 11.0, - "ReasonForMod": "", - "ArmorDivisor": 1.0, - "Notes": "" - }, - { - "Idkey": "10525_mode_1", - "Name": "Bite", - "Damage": "2d6+1", - "Type": "cr", - "Reach": "C", - "Skill": 14.0, - "ReasonForMod": "", - "ArmorDivisor": 1.0, - "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" - }, - { - "Idkey": "10753_mode_88", - "Name": "Brawling (Punch)", - "Damage": "2d6+1", - "Type": "cr", - "Reach": "C", - "Skill": 14.0, - "ReasonForMod": "", - "ArmorDivisor": 1.0, - "Notes": "" - }, - { - "Idkey": "10753_mode_89", - "Name": "Brawling (Bite)", - "Damage": "2d6+1", - "Type": "cr", - "Reach": "C", - "Skill": 14.0, - "ReasonForMod": "", - "ArmorDivisor": 1.0, - "Notes": "" - }, - { - "Idkey": "10753_mode_90", - "Name": "Brawling (Kick)", - "Damage": "2d6+2", - "Type": "cr", - "Reach": "C,1", - "Skill": 12.0, - "ReasonForMod": "", - "ArmorDivisor": 1.0, - "Notes": "{If you miss with a kick, roll vs. DX to avoid falling.}" - }, - { - "Idkey": "13176_mode_100", - "Name": "Force Shield (Bash)", - "Damage": "2d6", - "Type": "cr", - "Reach": "1", - "Skill": 13.0, - "ReasonForMod": "", - "ArmorDivisor": 1.0, - "Notes": "{Worn on the wrist, leaving the hand free.}" - }, - { - "Idkey": "13176_mode_101", - "Name": "Force Shield (Rush)", - "Damage": "slam+3", - "Type": "cr", - "Reach": "1", - "Skill": 13.0, - "ReasonForMod": "", - "ArmorDivisor": 1.0, - "Notes": "{Worn on the wrist, leaving the hand free.}" - }, - { - "Idkey": "10558_mode_12", - "Name": "Kick", - "Damage": "2d6+2", - "Type": "cr", - "Reach": "C,1", - "Skill": 12.0, - "ReasonForMod": "", - "ArmorDivisor": 1.0, - "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" - }, - { - "Idkey": "10613_mode_19", - "Name": "Punch", - "Damage": "2d6+1", - "Type": "cr", - "Reach": "C", - "Skill": 14.0, - "ReasonForMod": "", - "ArmorDivisor": 1.0, - "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" - } - ], - "RepeatingRanged": [ - { - "Idkey": "10720_mode_46", - "Name": "Crossbow (Armor Piercing) (Primary)", - "Damage": "3d6", - "Type": "imp", - "Acc": "2", - "Range": "100/200", - "Rof": "1", - "Shots": "", - "Bulk": "", - "Recoil": "1", - "Skill": 17.0, - "ReasonForMod": "", - "Malfunction": "", - "MalfunctionVerify": false, - "MalfunctionVeryReliable": false, - "ArmorDivisor": 2.0, - "Notes": "" - }, - { - "Idkey": "10730_mode_52", - "Name": "Crossbow (Explosive) (Primary)", - "Damage": "3d6", - "Type": "cr dkb ex/2", - "Acc": "2", - "Range": "200", - "Rof": "1", - "Shots": "n/a", - "Bulk": "", - "Recoil": "1", - "Skill": 17.0, - "ReasonForMod": "", - "Malfunction": "", - "MalfunctionVerify": false, - "MalfunctionVeryReliable": false, - "ArmorDivisor": 1.0, - "Notes": "" - }, - { - "Idkey": "10786_mode_102", - "Name": "Revolver, .357M", - "Damage": "3d6-1", - "Type": "pi", - "Acc": "2", - "Range": "185/2000", - "Rof": "3", - "Shots": "6(3i)", - "Bulk": "-2", - "Recoil": "3", - "Skill": 15.0, - "ReasonForMod": "", - "Malfunction": "17", - "MalfunctionVerify": false, - "MalfunctionVeryReliable": false, - "ArmorDivisor": 1.0, - "Notes": "" - } - ], - "RepeatingItem": [ - { - "Idkey": "10833", - "Name": "Advanced Body Armor", - "Tl": "8", - "LegalityClass": "2", - "Ref": "HT66", - "Count": 1.0, - "Cost": 4600.0, - "Weight": 17.0, - "Notes": "\nSignature Gear, +0\nTL:8 LC:2 DR:35/5* Location:torso Notes:[1] Concealable as or under clothing. [5] Use the lower DR versus crushing attacks only." - }, - { - "Idkey": "10790", - "Name": "Boots, Steel-Toed", - "Tl": "6", - "LegalityClass": "4", - "Ref": "HT68", - "Count": 1.0, - "Cost": 100.0, - "Weight": 4.0, - "Notes": "\nTL:6 LC:4 DR:6/2 Location:feet Notes:[1] Concealable as or under clothing. [2] Give +1 to kicking damage (p. B271). [4] Split DR: use the first, higher DR when - in the GM's opinion - the boot's steel toe box would protect (e. g. , dropping an item on the foot or crushing the toes in heavy machinery) or when an attack on the foot hits the toe (2/6 protection); use the second, lower DR against all other attacks." - }, - { - "Idkey": "13358", - "Name": "Compass", - "Tl": "6", - "LegalityClass": "", - "Ref": "B288", - "Count": 1.0, - "Cost": 50.0, - "Weight": 0.0, - "Notes": "\nTL:6 Notes: +1 to Navigation skill" - }, - { - "Idkey": "13176", - "Name": "Force Shield", - "Tl": "^", - "LegalityClass": "3", - "Ref": "B273, B287", - "Count": 1.0, - "Cost": 1500.0, - "Weight": 0.5, - "Notes": "\nTL:^ LC:3 DB:3 Dam:thr cr Reach:1 Parry:No ST:-- DR:100 HP:-- Skill:Shield (Force) Notes: [3,5] Also available as a buckler. You can ready a buckler in one turn and drop it as a free action, just like a weapon - but it always occupies one hand, and it does not allow a shield rush. Use Shield (Buckler) instead of regular shield skill. No effect on statistics. Worn on the wrist, leaving the hand free. DR is hardened (treat as Hardened enhancement, p. B47)." - }, - { - "Idkey": "13355", - "Name": "Holster, Belt", - "Tl": "5", - "LegalityClass": "", - "Ref": "B289", - "Count": 1.0, - "Cost": 1180.4, - "Weight": 7.62, - "Notes": "\nTL:5 Notes: Fits most pistols." - }, - { - "Idkey": "10788", - "Name": "Laser Sight", - "Tl": "8", - "LegalityClass": "", - "Ref": "B289", - "Count": 1.0, - "Cost": 100.0, - "Weight": 0.0, - "Notes": "\nTL:8 Notes: +1 to skill, see Laser Sights (p. B412)" - }, - { - "Idkey": "10792", - "Name": "Personal Basics", - "Tl": "0", - "LegalityClass": "", - "Ref": "B288", - "Count": 1.0, - "Cost": 5.0, - "Weight": 1.0, - "Notes": "\nTL:0 Notes: Minimum gear for camping: -2 to any Survival roll without it. Includes utensils, tinderbox or flint and steel, towel, etc., as TL permits." - }, - { - "Idkey": "10786", - "Name": "Revolver, .357M", - "Tl": "7", - "LegalityClass": "3", - "Ref": "B278", - "Count": 1.0, - "Cost": 1100.0, - "Weight": 3.6, - "Notes": "\nRugged, *2\nReceives Skill Bonus, +1, +0\nTL:7 LC:3 Damage:3d-1 pi Acc:2 Range:185/2000 RoF:3 Shots:6(3i) ST:10 Bulk:-2 Rcl:3 Skill:Guns (Pistol)" - }, - { - "Idkey": "13356", - "Name": "Revolver, .357M (Ammunition)", - "Tl": "7", - "LegalityClass": "3", - "Ref": "", - "Count": 12.0, - "Cost": 50.4, - "Weight": 2.52, - "Notes": "\nAmmunition" - } - ], - "RepeatingSpells": [] + "CharacterName": "Rampage", + "Fullname": "Rampage (NPC)", + "Playername": "NPC", + "Nickname": "", + "Race": "Human", + "RaceRef": "", + "TemplateNames": "", + "Gender": "", + "Size": 0.0, + "ApplySizeModifier": false, + "Reactions": "+2 from 'Charisma 2'\nConditional:\n-2 from 'Reputation 2 (Gang Leader; 7 or less, +1, *1/3; Large class, +1, *1/2)'", + "CampaignTl": 8.0, + "TotalPoints": 150.0, + "Tl": 8.0, + "TlPts": 0.0, + "Status": "0", + "Wealth": "Comfortable", + "Income": 5200.0, + "CostOfLiving": 600.0, + "Stash": 5169.6, + "Age": "27", + "Height": "6'", + "Weight": 210.0, + "Appearance": 0.0, + "GeneralAppearance": "Short mohawk, painted face, likes to wear chains, like something out of Road Warrior.", + "StrengthMod": 1.0, + "StrengthPoints": 60.0, + "DexterityMod": 0.0, + "DexterityPoints": 40.0, + "IntelligenceMod": 0.0, + "IntelligencePoints": 0.0, + "HealthMod": 0.0, + "HealthPoints": 20.0, + "PerceptionMod": 0.0, + "PerceptionPoints": 10.0, + "VisionMod": 0.0, + "VisionPoints": 0.0, + "HearingMod": 0.0, + "HearingPoints": 0.0, + "TasteSmellMod": 0.0, + "TasteSmellPoints": 0.0, + "TouchMod": 0.0, + "TouchPoints": 0.0, + "WillpowerMod": 0.0, + "WillpowerPoints": 10.0, + "FearCheckMod": 2.0, + "FearCheckPoints": 0.0, + "StunCheckMod": 0.0, + "KnockdownCheckMod": 0.0, + "UnconsciousCheckMod": 1.0, + "UnconsciousCheckPoints": 0.0, + "DeathCheckMod": 1.0, + "DeathCheckPoints": 0.0, + "BasicSpeedMod": 0.0, + "BasicSpeedPoints": 0.0, + "BasicMoveMod": 0.0, + "BasicMovePoints": 0.0, + "EnhancedGroundMoveMod": 0.5, + "EnhancedGroundMovePoints": 0.0, + "DodgeMod": 2.0, + "LiftStMod": 7.0, + "LiftStPoints": 15.0, + "StrikingStMod": 4.0, + "StrikingStPoints": 0.0, + "HitPointsMod": 0.0, + "HitPointsPoints": 8.0, + "HitPoints": 21.0, + "FatiguePointsMod": 0.0, + "FatiguePointsPoints": 0.0, + "FatiguePoints": 12.0, + "FlightChecked": false, + "FlightPoints": 0.0, + "BasicAirMoveMod": 0.0, + "BasicAirMovePoints": 0.0, + "EnhancedAirLevel": 0.0, + "EnhancedAirMovePoints": 0.0, + "AmphibiousChecked": false, + "AmphibiousPoints": 0.0, + "BasicWaterMoveMod": 0.0, + "BasicWaterMovePoints": 0.0, + "EnhancedWaterLevel": 0.0, + "EnhancedWaterMovePoints": 0.0, + "SuperJumpEnteredLevel": 0.0, + "SuperJumpPoints": 0.0, + "SpellBonus": 0.0, + "CombatReflexes": true, + "RepeatingLanguages": [], + "RepeatingCultures": [ + { + "Idkey": "12982", + "Name": "European (Native)", + "Points": 0.0 + }, + { + "Idkey": "12983", + "Name": "Western", + "Points": 1.0 + } + ], + "RepeatingTraits": [ + { + "Idkey": "10717", + "Name": "Ambidexterity", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B39", + "Notes": "" + }, + { + "Idkey": "10800", + "Name": "Appearance", + "TraitLevel": "1", + "Foa": "", + "Points": 4.0, + "Ref": "B21", + "Notes": "Attractive" + }, + { + "Idkey": "10704", + "Name": "Body Control Talent", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "P121,P167-169", + "Notes": "Innate Attack (Projectile), +0" + }, + { + "Idkey": "10799", + "Name": "Charisma", + "TraitLevel": "2", + "Foa": "", + "Points": 10.0, + "Ref": "B41", + "Notes": "" + }, + { + "Idkey": "10698", + "Name": "Combat Reflexes", + "TraitLevel": "1", + "Foa": "", + "Points": 14.0, + "Ref": "B43", + "Notes": "Biological, -10%" + }, + { + "Idkey": "12986", + "Name": "Contact (Rival Gang)", + "TraitLevel": "1", + "Foa": "9", + "Points": 1.0, + "Ref": "B44", + "Notes": "My notes here\nEffective Skill 12\nRival Gang\n9 or less, *1\nSomewhat Reliable, *1\nMy notes here\nUgly dude with twisted lips" + }, + { + "Idkey": "10720", + "Name": "Crossbow (Armor Piercing)", + "TraitLevel": "3", + "Foa": "", + "Points": 38.0, + "Ref": "B61, P53", + "Notes": "Armor Piercing\nArmor Divisor, 2, +50%\nGadget/Breakable: DR 3-5, -15%\nGadget/Breakable: Size -3 or -4, -15%\nGadget/Can Be Stolen: Must be forcefully removed, -10%\nInaccurate, -1, -5%\nIncreased Range, x2, +10%\nIncreased Range, 1/2D Range only, x5, +10%\nNo Signature, +20%\nRicochet, +10%" + }, + { + "Idkey": "10730", + "Name": "Crossbow (Explosive)", + "TraitLevel": "3", + "Foa": "", + "Points": 7.0, + "Ref": "B61, P53", + "Notes": "Explosive\nAlternative Attack, *1/5\nDouble Knockback, +20%\nExplosive, Damage / 2xYards, +100%\nGadget/Breakable: DR 3-5, -15%\nGadget/Breakable: Size -3 or -4, -15%\nGadget/Can Be Stolen: Must be forcefully removed, -10%\nInaccurate, -1, -5%\nIncreased Range, x2, +10%\nIncreased Range, 1/2D Range only, x10, +15%\nNo Signature, +20%" + }, + { + "Idkey": "10741", + "Name": "Crossbow (Smoke Arrow)", + "TraitLevel": "6", + "Foa": "", + "Points": 5.0, + "Ref": "B72, P64", + "Notes": "Smoke Arrow\nAlternative Ability, *1/5\nArea Effect, 4 yd, +50%\nGadget/Breakable: DR 3-5, -15%\nGadget/Breakable: Size -3 or -4, -15%\nGadget/Can Be Stolen: Must be forcefully removed, -10%\nInaccurate, -1, -5%\nIncreased Range, x2, +10%\nIncreased Range, 1/2D Range Only, x5, +10%\nNo Signature, +20%\nRanged, +50%" + }, + { + "Idkey": "10666", + "Name": "Damage Resistance", + "TraitLevel": "2", + "Foa": "", + "Points": 5.0, + "Ref": "B46, P45", + "Notes": "Biological, -10%\nTough Skin, -40%" + }, + { + "Idkey": "10700", + "Name": "Enhanced Dodge", + "TraitLevel": "1", + "Foa": "", + "Points": 14.0, + "Ref": "B51", + "Notes": "Biological, -10%" + }, + { + "Idkey": "10715", + "Name": "Enhanced Move (Ground)", + "TraitLevel": "1", + "Foa": "", + "Points": 9.0, + "Ref": "B52, P49", + "Notes": "#list(LevelName Step 0.5)\nGround\nBiological, -10%" + }, + { + "Idkey": "10702", + "Name": "Enhanced Muscle", + "TraitLevel": "4", + "Foa": "", + "Points": 29.0, + "Ref": "Bio213", + "Notes": "Biological, -10%" + }, + { + "Idkey": "10718", + "Name": "Extra Attack", + "TraitLevel": "1", + "Foa": "", + "Points": 23.0, + "Ref": "B54, P49", + "Notes": "Biological, -10%" + }, + { + "Idkey": "11893", + "Name": "Extra ST", + "TraitLevel": "1", + "Foa": "", + "Points": 10.0, + "Ref": "B14", + "Notes": "Affects ST, +0%\nSize, +0%\nThe Extra ST advantage allows you to take extra levels of the attribute which you can then apply enhancements and limitations to. The \"Affects displayed score\" modifier causes the Extra ST advantage to affect the displayed attribute score. If you don't wish this advantage to affect the displayed score remove that modifier." + }, + { + "Idkey": "10712", + "Name": "Fit", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B55", + "Notes": "" + }, + { + "Idkey": "11891", + "Name": "Lifting ST", + "TraitLevel": "3", + "Foa": "", + "Points": 9.0, + "Ref": "B65, P58", + "Notes": "Size, +0%" + }, + { + "Idkey": "10709", + "Name": "Protected Vision", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B78, P69", + "Notes": "Biological, -10%" + }, + { + "Idkey": "10714", + "Name": "Rapid Healing", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B79", + "Notes": "" + }, + { + "Idkey": "10711", + "Name": "Resilience", + "TraitLevel": "20", + "Foa": "", + "Points": 18.0, + "Ref": "", + "Notes": "Biological, -10%" + }, + { + "Idkey": "10705", + "Name": "Resistant (Metabolic Hazards)", + "TraitLevel": "4", + "Foa": "", + "Points": 9.0, + "Ref": "B80, P71", + "Notes": "Very Common\nMetabolic Hazards\nBiological, -10%\n+3, *1/3" + }, + { + "Idkey": "10835", + "Name": "Signature Gear (Advanced Body Armor)", + "TraitLevel": "1", + "Foa": "", + "Points": 1.0, + "Ref": "B85", + "Notes": "%SigGearAliasList%\nAdvanced Body Armor" + }, + { + "Idkey": "11890", + "Name": "Wealth", + "TraitLevel": "1", + "Foa": "", + "Points": 10.0, + "Ref": "B25", + "Notes": "Comfortable" + } + ], + "RepeatingPerks": [ + { + "Idkey": "10756", + "Name": "Alcohol Tolerance", + "Foa": "", + "Points": 1.0, + "Ref": "B100, B100,PU2:13", + "Notes": "" + }, + { + "Idkey": "10757", + "Name": "Base (Bar)", + "Foa": "", + "Points": 1.0, + "Ref": "PU2:17", + "Notes": "Bar" + }, + { + "Idkey": "10794", + "Name": "Teamwork (Concrete Savages)", + "Foa": "", + "Points": 1.0, + "Ref": "MA52, PU2:6", + "Notes": "Concrete Savages" + } + ], + "RepeatingQuirks": [ + { + "Idkey": "10774", + "Name": "Chauvinistic", + "ControlRating": "", + "Points": -1.0, + "Ref": "B164", + "Notes": "" + }, + { + "Idkey": "10773", + "Name": "wears chains", + "ControlRating": "", + "Points": -1.0, + "Ref": "", + "Notes": "" + } + ], + "RepeatingDisadvantages": [ + { + "Idkey": "10758", + "Name": "Bad Temper", + "TraitLevel": "1", + "ControlRating": "12", + "Points": -10.0, + "Ref": "B124", + "Notes": "12 or less, *1" + }, + { + "Idkey": "10769", + "Name": "Enemy (Police)", + "TraitLevel": "1", + "ControlRating": "", + "Points": -10.0, + "Ref": "B135", + "Notes": "Small group (3-5 people)\nPolice\n9 or less, *1\nHunter, *1" + }, + { + "Idkey": "10760", + "Name": "Greed", + "TraitLevel": "1", + "ControlRating": "12", + "Points": -15.0, + "Ref": "B137", + "Notes": "12 or less, *1" + }, + { + "Idkey": "10762", + "Name": "Reputation (Gang Leader)", + "TraitLevel": "2", + "ControlRating": "", + "Points": -1.0, + "Ref": "B27", + "Notes": "Gang Leader\n7 or less, *1/3\nLarge class, *1/2" + } + ], + "RepeatingRacial": [], + "RepeatingSkills": [ + { + "Idkey": "10784", + "Name": "Area Knowledge (local)", + "Tl": "", + "Base": "@{intelligence}", + "Difficulty": "E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 11.0, + "Ref": "B176", + "SkillModNotes": "", + "Notes": "local" + }, + { + "Idkey": "10753", + "Name": "Brawling", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "E", + "Bonus": 0.0, + "Points": 4.0, + "Skill": 14.0, + "Ref": "B182", + "SkillModNotes": "", + "Notes": "Notes: Calculated damage takes into account bonuses from Teeth, Weak Bite, Claws, and skill level. You may add the modifier \"Has Gauntlets/Brass Knuckles\" or \"Has Boots\" to apply the +1 damage to Punch or Kick, as appropriate." + }, + { + "Idkey": "10780", + "Name": "Carousing", + "Tl": "", + "Base": "@{health}", + "Difficulty": "E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "B183", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "10776", + "Name": "Connoisseur (Music)", + "Tl": "", + "Base": "@{intelligence}", + "Difficulty": "A", + "Bonus": 0.0, + "Points": 3.0, + "Skill": 11.0, + "Ref": "B185", + "SkillModNotes": "", + "Notes": "Music" + }, + { + "Idkey": "10777", + "Name": "Dancing", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "A", + "Bonus": 0.0, + "Points": 1.0, + "Skill": 11.0, + "Ref": "B187", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "10781", + "Name": "Forced Entry", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "B196", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "10775", + "Name": "Guns (Pistol)", + "Tl": "8", + "Base": "@{dexterity}", + "Difficulty": "E", + "Bonus": 0.0, + "Points": 4.0, + "Skill": 14.0, + "Ref": "B198", + "SkillModNotes": "", + "Notes": "uns/TL8 (Pistol" + }, + { + "Idkey": "10752", + "Name": "Innate Attack (Projectile)", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "E", + "Bonus": 1.0, + "Points": 12.0, + "Skill": 17.0, + "Ref": "B201", + "SkillModNotes": "+1 from 'Body Control Talent 1 (Innate Attack (Projectile), +0)'", + "Notes": "Projectile" + }, + { + "Idkey": "10782", + "Name": "Intimidation", + "Tl": "", + "Base": "10", + "Difficulty": "A", + "Bonus": 0.0, + "Points": 4.0, + "Skill": 13.0, + "Ref": "B202", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "10798", + "Name": "Leadership", + "Tl": "", + "Base": "@{intelligence}", + "Difficulty": "A", + "Bonus": 2.0, + "Points": 4.0, + "Skill": 13.0, + "Ref": "B204", + "SkillModNotes": "+2 from 'Charisma 2'", + "Notes": "" + }, + { + "Idkey": "10778", + "Name": "Musical Instrument (Guitar)", + "Tl": "", + "Base": "@{intelligence}", + "Difficulty": "H", + "Bonus": 0.0, + "Points": 12.0, + "Skill": 12.0, + "Ref": "B211", + "SkillModNotes": "", + "Notes": "Guitar" + }, + { + "Idkey": "13357", + "Name": "Navigation (Land)", + "Tl": "8", + "Base": "@{intelligence}", + "Difficulty": "A", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 10.0, + "Ref": "B211", + "SkillModNotes": "", + "Notes": "avigation/TL8 (Land" + }, + { + "Idkey": "13175", + "Name": "Shield (Force)", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "B220", + "SkillModNotes": "", + "Notes": "Force" + }, + { + "Idkey": "10779", + "Name": "Singing", + "Tl": "", + "Base": "@{health}", + "Difficulty": "E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "B220", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "10783", + "Name": "Streetwise", + "Tl": "", + "Base": "@{intelligence}", + "Difficulty": "A", + "Bonus": 0.0, + "Points": 8.0, + "Skill": 12.0, + "Ref": "B223", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "13174", + "Name": "Wrestling", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "A", + "Bonus": 0.0, + "Points": 1.0, + "Skill": 11.0, + "Ref": "B228", + "SkillModNotes": "", + "Notes": "" + } + ], + "RepeatingTechniquesrevised": [ + { + "Idkey": "13172", + "Name": "Aggressive Parry (Brawling)", + "Parent": "Brawling", + "BaseLevel": "10", + "Default": -1.0, + "MaxModifier": 0.0, + "Difficulty": "H", + "SkillModifier": 0.0, + "Points": 2.0, + "Skill": 11.0, + "Ref": "MA65", + "SkillModNotes": "", + "Notes": "Brawling" + }, + { + "Idkey": "13173", + "Name": "Arm Lock (Wrestling)", + "Parent": "Wrestling", + "BaseLevel": "11", + "Default": 0.0, + "MaxModifier": 4.0, + "Difficulty": "A", + "SkillModifier": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "MA65, B230", + "SkillModNotes": "", + "Notes": "Wrestling" + } + ], + "RepeatingDefense": [ + { + "Idkey": "10704_mode_207", + "Name": "Body Control Talent (Power Dodge)", + "Type": "Power Dodge", + "Info": "", + "Skill": 9.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "10704_mode_208", + "Name": "Body Control Talent (Power Block/Physical)", + "Type": "Power Block", + "Info": "", + "Skill": 9.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "10704_mode_209", + "Name": "Body Control Talent (Power Block/Mental)", + "Type": "Power Block Mental", + "Info": "", + "Skill": 9.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "10753_mode_289", + "Name": "Brawling (Punch)", + "Type": "Unarmed Parry", + "Info": "", + "Skill": 11.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "10613_mode_116", + "Name": "Punch", + "Type": "Unarmed Parry", + "Info": "", + "Skill": 11.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "13175_block", + "Name": "Shield (Force)", + "Type": "Block", + "Info": "", + "Skill": 10.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + } + ], + "RepeatingMelee": [ + { + "Idkey": "13172_mode_286", + "Name": "Aggressive Parry (Brawling)", + "Damage": "2d6-2", + "Type": "cr", + "Reach": "C", + "Skill": 11.0, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "10525_mode_12", + "Name": "Bite", + "Damage": "2d6+1", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + }, + { + "Idkey": "10753_mode_289", + "Name": "Brawling (Punch)", + "Damage": "2d6+1", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "10753_mode_290", + "Name": "Brawling (Bite)", + "Damage": "2d6+1", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "10753_mode_291", + "Name": "Brawling (Kick)", + "Damage": "2d6+2", + "Type": "cr", + "Reach": "C,1", + "Skill": 12.0, + "ArmorDivisor": 1.0, + "Notes": "{If you miss with a kick, roll vs. DX to avoid falling.}" + }, + { + "Idkey": "13176_mode_316", + "Name": "Force Shield (Bash)", + "Damage": "2d6", + "Type": "cr", + "Reach": "1", + "Skill": 13.0, + "ArmorDivisor": 1.0, + "Notes": "{Worn on the wrist, leaving the hand free.}" + }, + { + "Idkey": "13176_mode_317", + "Name": "Force Shield (Rush)", + "Damage": "slam+3", + "Type": "cr", + "Reach": "1", + "Skill": 13.0, + "ArmorDivisor": 1.0, + "Notes": "{Worn on the wrist, leaving the hand free.}" + }, + { + "Idkey": "10558_mode_53", + "Name": "Kick", + "Damage": "2d6+2", + "Type": "cr", + "Reach": "C,1", + "Skill": 12.0, + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + }, + { + "Idkey": "10613_mode_116", + "Name": "Punch", + "Damage": "2d6+1", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + } + ], + "RepeatingRanged": [ + { + "Idkey": "10720_mode_222", + "Name": "Crossbow (Armor Piercing) (Primary)", + "Damage": "3d6", + "Type": "imp", + "Acc": "2", + "Range": "100/200", + "Rof": "1", + "Shots": "", + "Bulk": "", + "Recoil": "1", + "Skill": 17.0, + "Malfunction": "", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 2.0, + "Notes": "" + }, + { + "Idkey": "10730_mode_228", + "Name": "Crossbow (Explosive) (Primary)", + "Damage": "3d6", + "Type": "cr dkb ex/2", + "Acc": "2", + "Range": "200", + "Rof": "1", + "Shots": "n/a", + "Bulk": "", + "Recoil": "1", + "Skill": 17.0, + "Malfunction": "", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "10786_mode_321", + "Name": "Revolver, .357M", + "Damage": "3d6-1", + "Type": "pi", + "Acc": "2", + "Range": "185/2000", + "Rof": "3", + "Shots": "6(3i)", + "Bulk": "-2", + "Recoil": "3", + "Skill": 15.0, + "Malfunction": "17", + "MalfunctionVerify": false, + "MalfunctionVeryReliable": false, + "ArmorDivisor": 1.0, + "Notes": "" + } + ], + "RepeatingItem": [ + { + "Idkey": "10833", + "Name": "Advanced Body Armor", + "Tl": "8", + "LegalityClass": "2", + "Ref": "HT66", + "Count": 1.0, + "Cost": 4600.0, + "Weight": 17.0, + "Notes": "Signature Gear, +0\nTL:8 LC:2 DR:35/5* Location:torso Notes:[1] Concealable as or under clothing. [5] Use the lower DR versus crushing attacks only." + }, + { + "Idkey": "10790", + "Name": "Boots, Steel-Toed", + "Tl": "6", + "LegalityClass": "4", + "Ref": "HT68", + "Count": 1.0, + "Cost": 100.0, + "Weight": 4.0, + "Notes": "TL:6 LC:4 DR:6/2 Location:feet Notes:[1] Concealable as or under clothing. [2] Give +1 to kicking damage (p. B271). [4] Split DR: use the first, higher DR when - in the GM's opinion - the boot's steel toe box would protect (e. g. , dropping an item on the foot or crushing the toes in heavy machinery) or when an attack on the foot hits the toe (2/6 protection); use the second, lower DR against all other attacks." + }, + { + "Idkey": "13358", + "Name": "Compass", + "Tl": "6", + "LegalityClass": "", + "Ref": "B288", + "Count": 1.0, + "Cost": 50.0, + "Weight": 0.0, + "Notes": "TL:6 Notes: +1 to Navigation skill" + }, + { + "Idkey": "13176", + "Name": "Force Shield", + "Tl": "^", + "LegalityClass": "3", + "Ref": "B273, B287", + "Count": 1.0, + "Cost": 1500.0, + "Weight": 0.5, + "Notes": "TL:^ LC:3 DB:3 Dam:thr cr Reach:1 Parry:No ST:-- DR:100 HP:-- Skill:Shield (Force) Notes: [3,5] Also available as a buckler. You can ready a buckler in one turn and drop it as a free action, just like a weapon - but it always occupies one hand, and it does not allow a shield rush. Use Shield (Buckler) instead of regular shield skill. No effect on statistics. Worn on the wrist, leaving the hand free. DR is hardened (treat as Hardened enhancement, p. B47)." + }, + { + "Idkey": "13355", + "Name": "Holster, Belt", + "Tl": "5", + "LegalityClass": "", + "Ref": "B289", + "Count": 1.0, + "Cost": 1180.4, + "Weight": 7.62, + "Notes": "TL:5 Notes: Fits most pistols." + }, + { + "Idkey": "10788", + "Name": "Laser Sight", + "Tl": "8", + "LegalityClass": "", + "Ref": "B289", + "Count": 1.0, + "Cost": 100.0, + "Weight": 0.0, + "Notes": "TL:8 Notes: +1 to skill, see Laser Sights (p. B412)" + }, + { + "Idkey": "10792", + "Name": "Personal Basics", + "Tl": "0", + "LegalityClass": "", + "Ref": "B288", + "Count": 1.0, + "Cost": 5.0, + "Weight": 1.0, + "Notes": "TL:0 Notes: Minimum gear for camping: -2 to any Survival roll without it. Includes utensils, tinderbox or flint and steel, towel, etc., as TL permits." + }, + { + "Idkey": "10786", + "Name": "Revolver, .357M", + "Tl": "7", + "LegalityClass": "3", + "Ref": "B278", + "Count": 1.0, + "Cost": 1100.0, + "Weight": 3.6, + "Notes": "Rugged, *2\nReceives Skill Bonus, +1, +0\nTL:7 LC:3 Damage:3d-1 pi Acc:2 Range:185/2000 RoF:3 Shots:6(3i) ST:10 Bulk:-2 Rcl:3 Skill:Guns (Pistol)" + }, + { + "Idkey": "13356", + "Name": "Revolver, .357M (Ammunition)", + "Tl": "7", + "LegalityClass": "3", + "Ref": "", + "Count": 12.0, + "Cost": 50.4, + "Weight": 2.52, + "Notes": "Ammunition" + } + ], + "RepeatingSpells": [] } \ No newline at end of file From 7eac1c435e37f0a5428fb0f2feaa745ae0ef9d9e Mon Sep 17 00:00:00 2001 From: Ken Date: Sat, 10 Sep 2022 23:48:48 -0700 Subject: [PATCH 03/12] update gurps tested racial traits --- GURPS/gurps.html | 2 - GURPS/readme/assets/gargoyle export.json | 508 +++++++++++++++++++++++ 2 files changed, 508 insertions(+), 2 deletions(-) create mode 100644 GURPS/readme/assets/gargoyle export.json diff --git a/GURPS/gurps.html b/GURPS/gurps.html index d7cf0af609..631b55ef88 100644 --- a/GURPS/gurps.html +++ b/GURPS/gurps.html @@ -34100,7 +34100,6 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm importRepeatingDisadvantages(character, uniqueKeys); - // TODO: test importRepeatingRacial(character, uniqueKeys); importRepeatingSkills(character, uniqueKeys); @@ -34442,7 +34441,6 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - // TODO: need test character importRepeatingRacial = (character, uniqueKeys) => { character.RepeatingRacial.forEach(trait => { diff --git a/GURPS/readme/assets/gargoyle export.json b/GURPS/readme/assets/gargoyle export.json new file mode 100644 index 0000000000..d488b473a3 --- /dev/null +++ b/GURPS/readme/assets/gargoyle export.json @@ -0,0 +1,508 @@ +{ + "CharacterName": "Gargoyle", + "Fullname": "Gargoyle (Test)", + "Playername": "Test", + "Nickname": "", + "Race": "Gargoyle", + "RaceRef": "", + "TemplateNames": "Gargoyle (Dungeon Fantasy)", + "Gender": "", + "Size": 0.0, + "ApplySizeModifier": false, + "Reactions": "Conditional:\n-1 from 'Callous' when past victim, or has Empathy\n-1 from 'Odious Racial Habit (Dirty)' when people notice your problem", + "CampaignTl": 3.0, + "TotalPoints": 150.0, + "Tl": 3.0, + "TlPts": 0.0, + "Status": "0", + "Wealth": "Average", + "Income": 700.0, + "CostOfLiving": 600.0, + "Stash": 180.0, + "Age": "14", + "Height": "5'6\"", + "Weight": 130.0, + "Appearance": 0.0, + "GeneralAppearance": "", + "StrengthMod": 0.0, + "StrengthPoints": 20.0, + "DexterityMod": 0.0, + "DexterityPoints": 60.0, + "IntelligenceMod": -1.0, + "IntelligencePoints": 0.0, + "HealthMod": 1.0, + "HealthPoints": 0.0, + "PerceptionMod": 0.0, + "PerceptionPoints": 10.0, + "VisionMod": 2.0, + "VisionPoints": 0.0, + "HearingMod": 2.0, + "HearingPoints": 0.0, + "TasteSmellMod": 0.0, + "TasteSmellPoints": 0.0, + "TouchMod": 0.0, + "TouchPoints": 0.0, + "WillpowerMod": 0.0, + "WillpowerPoints": 0.0, + "FearCheckMod": 0.0, + "FearCheckPoints": 0.0, + "StunCheckMod": 0.0, + "KnockdownCheckMod": 0.0, + "UnconsciousCheckMod": 0.0, + "UnconsciousCheckPoints": 0.0, + "DeathCheckMod": 0.0, + "DeathCheckPoints": 0.0, + "BasicSpeedMod": -0.25, + "BasicSpeedPoints": 5.0, + "BasicMoveMod": 0.0, + "BasicMovePoints": 5.0, + "EnhancedGroundMoveMod": 0.0, + "EnhancedGroundMovePoints": 0.0, + "DodgeMod": 0.0, + "LiftStMod": 0.0, + "LiftStPoints": 0.0, + "StrikingStMod": 0.0, + "StrikingStPoints": 0.0, + "HitPointsMod": 2.0, + "HitPointsPoints": 0.0, + "HitPoints": 14.0, + "FatiguePointsMod": 0.0, + "FatiguePointsPoints": 3.0, + "FatiguePoints": 12.0, + "FlightChecked": false, + "FlightPoints": 0.0, + "BasicAirMoveMod": 2.0, + "BasicAirMovePoints": 0.0, + "EnhancedAirLevel": 0.5, + "EnhancedAirMovePoints": 0.0, + "AmphibiousChecked": false, + "AmphibiousPoints": 0.0, + "BasicWaterMoveMod": 0.0, + "BasicWaterMovePoints": 0.0, + "EnhancedWaterLevel": 0.0, + "EnhancedWaterMovePoints": 0.0, + "SuperJumpEnteredLevel": 1.0, + "SuperJumpPoints": 0.0, + "SpellBonus": 0.0, + "CombatReflexes": false, + "RepeatingLanguages": [], + "RepeatingCultures": [ + { + "Idkey": "12362", + "Name": "Gargoyle (Native)", + "Points": 0.0 + } + ], + "RepeatingTraits": [ + { + "Idkey": "12371", + "Name": "Absolute Direction", + "TraitLevel": "1", + "Foa": "", + "Points": 5.0, + "Ref": "B34", + "Notes": "" + }, + { + "Idkey": "12363", + "Name": "Acute Hearing", + "TraitLevel": "2", + "Foa": "", + "Points": 4.0, + "Ref": "B35", + "Notes": "" + }, + { + "Idkey": "12364", + "Name": "Acute Vision", + "TraitLevel": "2", + "Foa": "", + "Points": 4.0, + "Ref": "B35", + "Notes": "" + }, + { + "Idkey": "12379", + "Name": "Enhanced Move (Air)", + "TraitLevel": "1", + "Foa": "", + "Points": 10.0, + "Ref": "B52", + "Notes": "#list(LevelName Step 0.5)\nAir" + }, + { + "Idkey": "12382", + "Name": "Extra Air Move", + "TraitLevel": "2", + "Foa": "", + "Points": 4.0, + "Ref": "B18", + "Notes": "Affects Air Move, +0%\nThe Extra Air Move advantage allows you to take extra levels of the attribute which you can then apply enhancements and limitations to. The \"Affects displayed score\" modifier causes the Extra Air Move advantage to affect the displayed attribute score. If you don't wish this advantage to affect the displayed score remove that modifier." + }, + { + "Idkey": "12372", + "Name": "Night Vision", + "TraitLevel": "3", + "Foa": "", + "Points": 3.0, + "Ref": "B71", + "Notes": "" + }, + { + "Idkey": "12378", + "Name": "Super Jump", + "TraitLevel": "1", + "Foa": "", + "Points": 10.0, + "Ref": "B89", + "Notes": "" + } + ], + "RepeatingPerks": [], + "RepeatingQuirks": [], + "RepeatingDisadvantages": [ + { + "Idkey": "12365", + "Name": "Callous", + "TraitLevel": "1", + "ControlRating": "", + "Points": -5.0, + "Ref": "B125", + "Notes": "" + } + ], + "RepeatingRacial": [ + { + "Idkey": "12346", + "Name": "Gargoyle (Dungeon Fantasy)", + "TraitLevel": "", + "ControlRating": "", + "Points": 0.0, + "Ref": "", + "Notes": "Dungeon Fantasy\nA gargoyle resembles nothing so much as an ugly stone man with wings." + }, + { + "Idkey": "12347", + "Name": "Stony", + "TraitLevel": "1", + "ControlRating": "", + "Points": 1.0, + "Ref": "", + "Notes": "" + }, + { + "Idkey": "12348", + "Name": "Claws (Blunt Claws)", + "TraitLevel": "1", + "ControlRating": "", + "Points": 3.0, + "Ref": "", + "Notes": "Blunt Claws" + }, + { + "Idkey": "12349", + "Name": "Gargoyle Flight", + "TraitLevel": "1", + "ControlRating": "", + "Points": 30.0, + "Ref": "", + "Notes": "Winged, -25%" + }, + { + "Idkey": "12351", + "Name": "Gargoyle Damage Resistance", + "TraitLevel": "2", + "ControlRating": "", + "Points": 10.0, + "Ref": "", + "Notes": "" + }, + { + "Idkey": "12352", + "Name": "Night Vision", + "TraitLevel": "5", + "ControlRating": "", + "Points": 5.0, + "Ref": "", + "Notes": "" + }, + { + "Idkey": "12353", + "Name": "Striker (Impaling; Gargoyle Tail)", + "TraitLevel": "1", + "ControlRating": "", + "Points": 5.0, + "Ref": "", + "Notes": "Impaling\nGargoyle Tail\nClumsy, -2, -40%" + }, + { + "Idkey": "12355", + "Name": "Appearance", + "TraitLevel": "2", + "ControlRating": "", + "Points": -8.0, + "Ref": "", + "Notes": "Ugly" + }, + { + "Idkey": "12356", + "Name": "Gluttony", + "TraitLevel": "1", + "ControlRating": "12", + "Points": -5.0, + "Ref": "", + "Notes": "12 or less, *1" + }, + { + "Idkey": "12358", + "Name": "Odious Racial Habit (Dirty)", + "TraitLevel": "1", + "ControlRating": "", + "Points": -5.0, + "Ref": "", + "Notes": "Dirty" + }, + { + "Idkey": "12359", + "Name": "Torso armor isn't interchangeable with human torso armor.", + "TraitLevel": "1", + "ControlRating": "", + "Points": 0.0, + "Ref": "", + "Notes": "" + } + ], + "RepeatingSkills": [ + { + "Idkey": "12366", + "Name": "Aerobatics", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "H", + "Bonus": 0.0, + "Points": 4.0, + "Skill": 13.0, + "Ref": "B174", + "SkillModNotes": "+0 from 'Absolute Direction'", + "Notes": "" + }, + { + "Idkey": "12369", + "Name": "Area Knowledge (local)", + "Tl": "", + "Base": "@{intelligence}", + "Difficulty": "E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 10.0, + "Ref": "B176", + "SkillModNotes": "", + "Notes": "local" + }, + { + "Idkey": "12377", + "Name": "Axe/Mace", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "A", + "Bonus": 0.0, + "Points": 1.0, + "Skill": 12.0, + "Ref": "B208", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "12373", + "Name": "Brawling", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "E", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 14.0, + "Ref": "B182", + "SkillModNotes": "", + "Notes": "Notes: Calculated damage takes into account bonuses from Teeth, Weak Bite, Claws, and skill level. You may add the modifier \"Has Gauntlets/Brass Knuckles\" or \"Has Boots\" to apply the +1 damage to Punch or Kick, as appropriate." + }, + { + "Idkey": "12374", + "Name": "Dropping", + "Tl": "", + "Base": "@{dexterity}", + "Difficulty": "A", + "Bonus": 0.0, + "Points": 2.0, + "Skill": 13.0, + "Ref": "B189", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "12367", + "Name": "Flight", + "Tl": "", + "Base": "@{health}", + "Difficulty": "A", + "Bonus": 0.0, + "Points": 8.0, + "Skill": 13.0, + "Ref": "B195", + "SkillModNotes": "", + "Notes": "" + }, + { + "Idkey": "12370", + "Name": "Navigation (Air)", + "Tl": "3", + "Base": "@{intelligence}", + "Difficulty": "A", + "Bonus": 3.0, + "Points": 4.0, + "Skill": 13.0, + "Ref": "B211", + "SkillModNotes": "+3 from 'Absolute Direction'", + "Notes": "avigation/TL3 (Air" + } + ], + "RepeatingTechniquesrevised": [], + "RepeatingDefense": [ + { + "Idkey": "12373_mode_538", + "Name": "Brawling (Punch)", + "Type": "Unarmed Parry", + "Info": "", + "Skill": 10.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "12376_mode_544", + "Name": "Knobbed Club (Swing)", + "Type": "Parry", + "Info": "", + "Skill": 9.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "12296_mode_503", + "Name": "Punch", + "Type": "Unarmed Parry", + "Info": "", + "Skill": 10.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + }, + { + "Idkey": "12353_mode_524", + "Name": "Striker (Impaling; Gargoyle Tail) ([Description])", + "Type": "Parry", + "Info": "", + "Skill": 9.0, + "SkillMod": 0.0, + "DefenseModReason": "", + "InfoDescription": "" + } + ], + "RepeatingMelee": [ + { + "Idkey": "12208_mode_485", + "Name": "Bite", + "Damage": "1d6-2", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + }, + { + "Idkey": "12373_mode_538", + "Name": "Brawling (Punch)", + "Damage": "1d6-1", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "12373_mode_539", + "Name": "Brawling (Bite)", + "Damage": "1d6-2", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "12373_mode_540", + "Name": "Brawling (Kick)", + "Damage": "1d6", + "Type": "cr", + "Reach": "C,1", + "Skill": 12.0, + "ArmorDivisor": 1.0, + "Notes": "{If you miss with a kick, roll vs. DX to avoid falling.}" + }, + { + "Idkey": "12241_mode_496", + "Name": "Kick", + "Damage": "1d6", + "Type": "cr", + "Reach": "C,1", + "Skill": 12.0, + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + }, + { + "Idkey": "12376_mode_544", + "Name": "Knobbed Club (Swing)", + "Damage": "1d6+3", + "Type": "cr", + "Reach": "1", + "Skill": 12.0, + "ArmorDivisor": 1.0, + "Notes": "" + }, + { + "Idkey": "12296_mode_503", + "Name": "Punch", + "Damage": "1d6-1", + "Type": "cr", + "Reach": "C", + "Skill": 14.0, + "ArmorDivisor": 1.0, + "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" + }, + { + "Idkey": "12353_mode_524", + "Name": "Striker (Impaling; Gargoyle Tail) ([Description])", + "Damage": "1d6", + "Type": "imp", + "Reach": "C", + "Skill": 12.0, + "ArmorDivisor": 1.0, + "Notes": "" + } + ], + "RepeatingRanged": [], + "RepeatingItem": [ + { + "Idkey": "12376", + "Name": "Knobbed Club", + "Tl": "0", + "LegalityClass": "4", + "Ref": "LT65", + "Count": 1.0, + "Cost": 20.0, + "Weight": 2.0, + "Notes": "TL:0 LC:4, Dam:sw+1 cr Reach:1 Parry:0 ST:8 Skill:Axe/Mace, DX-5, Flail-4, Two-Handed Axe/Mace-3" + } + ], + "RepeatingSpells": [] +} \ No newline at end of file From 01a66b56d5c15d61d12cd63da8859a6276b5c265 Mon Sep 17 00:00:00 2001 From: Ken Date: Sun, 11 Sep 2022 12:01:37 -0700 Subject: [PATCH 04/12] update gurps add styling when import button is clicked --- GURPS/gurps.css | 3 ++- GURPS/gurps.html | 46 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/GURPS/gurps.css b/GURPS/gurps.css index d10acdf6f9..c44f3e7e99 100644 --- a/GURPS/gurps.css +++ b/GURPS/gurps.css @@ -3178,7 +3178,8 @@ input[name="attr_toggle_melee_mod_tool"][value="1"] ~ .sheet-attack-modifiers-no width: 50px; } -.sheet-reset input[name="attr_resync_state"][value="clicked"] ~ button.sheet-reset { +.sheet-reset input[name="attr_resync_state"][value="clicked"] ~ button.sheet-reset, +.sheet-reset input[name="attr_import_json_state"][value="clicked"] ~ button.sheet-reset { background-color: gray; } diff --git a/GURPS/gurps.html b/GURPS/gurps.html index 631b55ef88..841e7603be 100644 --- a/GURPS/gurps.html +++ b/GURPS/gurps.html @@ -15575,10 +15575,12 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm
-

Import Tool [BETA]

+

Import Tool [DEPRACATED]

- Initial version is designed for a one time import. Future iterations will allow re-import and adding GURPS Character Sheet (GCS). + Initial version is designed for a one time import. + This import is being replaced by a generic json formatted import. + See the Import tab.

GCA4 Import

@@ -15615,7 +15617,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm
- +
@@ -15719,8 +15721,9 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm
-
- +
+ +
@@ -34032,19 +34035,34 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm // close roll modifiers, no updates on("clicked:import_json", (event) => { - setAttrs({ "import_json_message": "Processing..." }, null, () => { + let attribs = { + import_json_state: "clicked", + import_json_message: "Processing..." + }; - importCharacterJson(); + setAttrsAsync(attribs); + + importCharacterJson(); - }); }); - on("clicked:import_reset", (event) => { + resetImportJsonButtonSate = () => { + + setTimeout(() => { + + setAttrs({import_json_state: "normal"}); + + }, 2000); + + } + + on("clicked:import_json_reset", (event) => { setAttrs({ - "import_json_message": "Start Import", - "character_json_data": "" + import_json_state: "normal", + import_json_message: "Start Import", + character_json_data: "" }); }); @@ -34121,6 +34139,12 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm setAttrsAsync({combat_reflexes: applyCombatReflexes}); + setAttrs({ + import_json_state: "normal", + import_json_message: "Import has completed!", + character_json_data: "" + }); + } else { setAttrs({ "import_json_message": message }); From 99c118c7510ecc0b88ab7f9de6d209224fbc0fc2 Mon Sep 17 00:00:00 2001 From: Ken Date: Sun, 11 Sep 2022 15:18:57 -0700 Subject: [PATCH 05/12] update gurps add repeating languages and use let to define functions --- GURPS/gurps.html | 106 +++++++++++------- GURPS/readme/assets/Rampage (NPC) export.json | 63 ++++++++--- 2 files changed, 117 insertions(+), 52 deletions(-) diff --git a/GURPS/gurps.html b/GURPS/gurps.html index 841e7603be..b8ffa52436 100644 --- a/GURPS/gurps.html +++ b/GURPS/gurps.html @@ -19409,7 +19409,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm }); - updateRepeatingSkillValues = () => { + let updateRepeatingSkillValues = () => { let fieldValues = [ "repeating_skills_name", //for debugging @@ -19542,7 +19542,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm }); - updateRepeatingSpellValues = () => { + let updateRepeatingSpellValues = () => { let fieldValues = [ "repeating_spells_base", @@ -21681,7 +21681,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm * Function to make sure the repeating_ranged_{id}_mal_max_value is set * during a new version load or possible future reset button */ - setRangedMaxMalfunctionValues = () => { + let setRangedMaxMalfunctionValues = () => { getSectionIDs("repeating_ranged", (ids) => { @@ -33873,7 +33873,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm }); - resetResyncButtonSate = () => { + let resetResyncButtonSate = () => { setTimeout(() => { @@ -33887,7 +33887,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm * Loop through each skill, set sync field = 1 (true) * this forces the skill to recalculate the value. */ - resyncRepeatingSkills = () => { + let resyncRepeatingSkills = () => { getSectionIDs("repeating_skills", ids => { @@ -33920,7 +33920,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm * Loop through each technique, set sync field = 1 (true) * this forces the technique to recalculate the value. */ - resyncRepeatingTechniques = () => { + let resyncRepeatingTechniques = () => { getSectionIDs("repeating_techniquesrevised", ids => { @@ -33951,7 +33951,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm * Recalculate the weight and value of all items. * Should NOT be run silent, so the totals can be calculated */ - resyncRepeatingItems = () => { + let resyncRepeatingItems = () => { getSectionIDs("repeating_item", ids => { @@ -34004,7 +34004,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm * Loop through each spell, set sync field = 1 (true) * this forces the spell to recalculate the value. */ - resyncRepeatingSpells = () => { + let resyncRepeatingSpells = () => { getSectionIDs("repeating_spells", ids => { @@ -34047,16 +34047,6 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm }); - resetImportJsonButtonSate = () => { - - setTimeout(() => { - - setAttrs({import_json_state: "normal"}); - - }, 2000); - - } - on("clicked:import_json_reset", (event) => { setAttrs({ @@ -34067,7 +34057,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm }); - importCharacterJson = () => { + let importCharacterJson = () => { getAttrs(["character_json_data"], values => { @@ -34108,6 +34098,8 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm importAttributes(character); + importRepeatingLanguages(character, uniqueKeys); + importRepeatingCultures(character, uniqueKeys); importRepeatingTraits(character, uniqueKeys); @@ -34155,7 +34147,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - getUniqueKeysForCharacter = () => { + let getUniqueKeysForCharacter = () => { let uniqueKeys = {}; @@ -34167,7 +34159,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - getUniqueKeysByTableAsync = (table, uniqueKeys) => { + let getUniqueKeysByTableAsync = (table, uniqueKeys) => { getSectionIDsAsync(table, ids => { @@ -34218,7 +34210,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importAttributes = character => { + let importAttributes = character => { const applySizeModifier = character.ApplySizeModifier ? "1" : "0"; const flightChecked = character.FlightChecked ? "1" : "0"; @@ -34327,7 +34319,46 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingCultures = (character, uniqueKeys) => { + let importRepeatingLanguages = (character, uniqueKeys) => { + + character.RepeatingLanguages.forEach(language => { + + let attributes = {}; + + if (language.IsNative) { + + // use the non-repeating native language + attributes["native_language_idkey"] = language.Idkey; + + attributes["name_native_language"] = language.Name; + + attributes["native_language_spoken"] = parseInt(language.Spoken); + + attributes["native_language_written"] = parseInt(language.Written); + + } else { + + let rowId = generateOrGetRowId(uniqueKeys, language.Idkey); + + let baseFieldName = `repeating_languages_${rowId}`; + + attributes[`${baseFieldName}_idkey`] = language.Idkey; + + attributes[`${baseFieldName}_name`] = language.Name; + + attributes[`${baseFieldName}_spoken`] = parseInt(language.Spoken); + + attributes[`${baseFieldName}_written`] = parseInt(language.Written); + + } + + setAttrsAsync(attributes); + + }); + + } + + let importRepeatingCultures = (character, uniqueKeys) => { character.RepeatingCultures.forEach(culture => { @@ -34349,7 +34380,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingTraits = (character, uniqueKeys) => { + let importRepeatingTraits = (character, uniqueKeys) => { character.RepeatingTraits.forEach(trait => { @@ -34379,7 +34410,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingPerks = (character, uniqueKeys) => { + let importRepeatingPerks = (character, uniqueKeys) => { character.RepeatingPerks.forEach(trait => { @@ -34407,7 +34438,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingQuirks = (character, uniqueKeys) => { + let importRepeatingQuirks = (character, uniqueKeys) => { character.RepeatingQuirks.forEach(trait => { @@ -34435,7 +34466,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingDisadvantages = (character, uniqueKeys) => { + let importRepeatingDisadvantages = (character, uniqueKeys) => { character.RepeatingDisadvantages.forEach(trait => { @@ -34465,7 +34496,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingRacial = (character, uniqueKeys) => { + let importRepeatingRacial = (character, uniqueKeys) => { character.RepeatingRacial.forEach(trait => { @@ -34495,8 +34526,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - // TODO: Check for wildcard! - importRepeatingSkills = (character, uniqueKeys) => { + let importRepeatingSkills = (character, uniqueKeys) => { character.RepeatingSkills.forEach(skill => { @@ -34536,7 +34566,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm * Converts difficulty name to a number * TODO: checks for wildcard! */ - getSKillDifficultyValue = difficulty => { + let getSKillDifficultyValue = difficulty => { let difficultyValue = "-1"; @@ -34568,7 +34598,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingTechniquesrevised = (character, uniqueKeys) => { + let importRepeatingTechniquesrevised = (character, uniqueKeys) => { character.RepeatingTechniquesrevised.forEach(skill => { @@ -34608,7 +34638,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - getTechniqueDifficultyValue = difficulty => { + let getTechniqueDifficultyValue = difficulty => { let difficultyValue = "Average"; @@ -34628,7 +34658,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingDefense = (character, uniqueKeys) => { + let importRepeatingDefense = (character, uniqueKeys) => { character.RepeatingDefense.forEach(trait => { @@ -34660,7 +34690,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingMelee = (character, uniqueKeys) => { + let importRepeatingMelee = (character, uniqueKeys) => { character.RepeatingMelee.forEach(trait => { @@ -34692,7 +34722,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingRanged = (character, uniqueKeys) => { + let importRepeatingRanged = (character, uniqueKeys) => { character.RepeatingRanged.forEach(trait => { @@ -34744,7 +34774,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingItem = (character, uniqueKeys) => { + let importRepeatingItem = (character, uniqueKeys) => { character.RepeatingItem.forEach(trait => { @@ -34778,7 +34808,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - importRepeatingSpells = (character, uniqueKeys) => { + let importRepeatingSpells = (character, uniqueKeys) => { character.RepeatingSpells.forEach(skill => { diff --git a/GURPS/readme/assets/Rampage (NPC) export.json b/GURPS/readme/assets/Rampage (NPC) export.json index 33cdf18207..906d446a90 100644 --- a/GURPS/readme/assets/Rampage (NPC) export.json +++ b/GURPS/readme/assets/Rampage (NPC) export.json @@ -85,7 +85,29 @@ "SuperJumpPoints": 0.0, "SpellBonus": 0.0, "CombatReflexes": true, - "RepeatingLanguages": [], + "RepeatingLanguages": [ + { + "Idkey": "10663", + "Name": "English", + "Spoken": 0.0, + "Written": 0.0, + "IsNative": true + }, + { + "Idkey": "12985", + "Name": "French", + "Spoken": 2.0, + "Written": 1.0, + "IsNative": false + }, + { + "Idkey": "12984", + "Name": "German", + "Spoken": 2.0, + "Written": 2.0, + "IsNative": false + } + ], "RepeatingCultures": [ { "Idkey": "12982", @@ -586,6 +608,19 @@ "SkillModNotes": "", "Notes": "" }, + { + "Idkey": "13361", + "Name": "Thief!", + "Tl": "", + "Base": "@{intelligence}", + "Difficulty": "WC", + "Bonus": 0.0, + "Points": 24.0, + "Skill": 10.0, + "Ref": "SU37", + "SkillModNotes": "", + "Notes": "Replaces Climbing, Escape, Filch, Forced Entry, Pickpocket, and Stealth. Make an IQ-based roll for Electronics Operation (Security), Lockpicking, Traps, or Streetwise; for Shadowing to follow an intended victim; and for Merchant to sell stolen goods.\nReplaces Climbing, Escape, Filch, Forced Entry, Pickpocket, and Stealth. Make an IQ-based roll for Electronics Operation (Security), Lockpicking, Traps, or Streetwise; for Shadowing to follow an intended victim; and for Merchant to sell stolen goods.\nReplaces Climbing, Escape, Filch, Forced Entry, Pickpocket, and Stealth. Make an IQ-based roll for Electronics Operation (Security), Lockpicking, Traps, or Streetwise; for Shadowing to follow an intended victim; and for Merchant to sell stolen goods." + }, { "Idkey": "13174", "Name": "Wrestling", @@ -634,7 +669,7 @@ ], "RepeatingDefense": [ { - "Idkey": "10704_mode_207", + "Idkey": "10704_mode_208", "Name": "Body Control Talent (Power Dodge)", "Type": "Power Dodge", "Info": "", @@ -644,7 +679,7 @@ "InfoDescription": "" }, { - "Idkey": "10704_mode_208", + "Idkey": "10704_mode_209", "Name": "Body Control Talent (Power Block/Physical)", "Type": "Power Block", "Info": "", @@ -654,7 +689,7 @@ "InfoDescription": "" }, { - "Idkey": "10704_mode_209", + "Idkey": "10704_mode_210", "Name": "Body Control Talent (Power Block/Mental)", "Type": "Power Block Mental", "Info": "", @@ -664,7 +699,7 @@ "InfoDescription": "" }, { - "Idkey": "10753_mode_289", + "Idkey": "10753_mode_290", "Name": "Brawling (Punch)", "Type": "Unarmed Parry", "Info": "", @@ -696,7 +731,7 @@ ], "RepeatingMelee": [ { - "Idkey": "13172_mode_286", + "Idkey": "13172_mode_287", "Name": "Aggressive Parry (Brawling)", "Damage": "2d6-2", "Type": "cr", @@ -716,7 +751,7 @@ "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" }, { - "Idkey": "10753_mode_289", + "Idkey": "10753_mode_290", "Name": "Brawling (Punch)", "Damage": "2d6+1", "Type": "cr", @@ -726,7 +761,7 @@ "Notes": "" }, { - "Idkey": "10753_mode_290", + "Idkey": "10753_mode_291", "Name": "Brawling (Bite)", "Damage": "2d6+1", "Type": "cr", @@ -736,7 +771,7 @@ "Notes": "" }, { - "Idkey": "10753_mode_291", + "Idkey": "10753_mode_292", "Name": "Brawling (Kick)", "Damage": "2d6+2", "Type": "cr", @@ -746,7 +781,7 @@ "Notes": "{If you miss with a kick, roll vs. DX to avoid falling.}" }, { - "Idkey": "13176_mode_316", + "Idkey": "13176_mode_317", "Name": "Force Shield (Bash)", "Damage": "2d6", "Type": "cr", @@ -756,7 +791,7 @@ "Notes": "{Worn on the wrist, leaving the hand free.}" }, { - "Idkey": "13176_mode_317", + "Idkey": "13176_mode_318", "Name": "Force Shield (Rush)", "Damage": "slam+3", "Type": "cr", @@ -788,7 +823,7 @@ ], "RepeatingRanged": [ { - "Idkey": "10720_mode_222", + "Idkey": "10720_mode_223", "Name": "Crossbow (Armor Piercing) (Primary)", "Damage": "3d6", "Type": "imp", @@ -806,7 +841,7 @@ "Notes": "" }, { - "Idkey": "10730_mode_228", + "Idkey": "10730_mode_229", "Name": "Crossbow (Explosive) (Primary)", "Damage": "3d6", "Type": "cr dkb ex/2", @@ -824,7 +859,7 @@ "Notes": "" }, { - "Idkey": "10786_mode_321", + "Idkey": "10786_mode_322", "Name": "Revolver, .357M", "Damage": "3d6-1", "Type": "pi", From c7a551288b09ad395065e522a2d3d53fc85b6e6e Mon Sep 17 00:00:00 2001 From: Ken Date: Sun, 11 Sep 2022 19:52:45 -0700 Subject: [PATCH 06/12] update gurps refactor import to use async/await methods --- GURPS/gurps.html | 306 ++++++++++-------- .../assets/Artillery Mage (NPC) export.json | 58 ++-- GURPS/readme/assets/Rampage (NPC) export.json | 34 +- GURPS/readme/assets/gargoyle export.json | 34 +- 4 files changed, 241 insertions(+), 191 deletions(-) diff --git a/GURPS/gurps.html b/GURPS/gurps.html index b8ffa52436..2fd7e40b0d 100644 --- a/GURPS/gurps.html +++ b/GURPS/gurps.html @@ -18280,6 +18280,16 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm setActiveCharacterId(prevAcid); }); } + + /** + * Async foreach. + * see: https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404 + */ + async function asyncForEach(array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array); + } + } /*------------------*/ const styleCount = 9; // THIS NUMBER MUST BE EQUAL TO THE NUMBER OF COLOR SETTINGS @@ -34033,16 +34043,16 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } // close roll modifiers, no updates - on("clicked:import_json", (event) => { + on("clicked:import_json", async (event) => { let attribs = { import_json_state: "clicked", import_json_message: "Processing..." }; - setAttrsAsync(attribs); + await setAttrsAsync(attribs); - importCharacterJson(); + await importCharacterJson(); }); @@ -34057,160 +34067,178 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm }); - let importCharacterJson = () => { + let importCharacterJson = async () => { - getAttrs(["character_json_data"], values => { + let values = await getAttrsAsync(["character_json_data"]); - let data = String(values.character_json_data).trim(); + let data = String(values.character_json_data).trim(); - let success = true; - - let message = ""; + let success = true; - // schema file - let character; + let message = ""; - if (data) { + // schema file + let character; - try { + if (data) { - character = JSON.parse(data); - - } catch (ex) { - - success = false; - - message = "Invalid JSON Data. " + ex.message; + try { - } - } else { - + character = JSON.parse(data); + + } catch (ex) { + success = false; - message = "Please copy/paste JSON Data into text area."; + message = "Invalid JSON Data. " + ex.message; } + } else { - if (success) { + success = false; - // TODO: figure out async/await - let uniqueKeys = getUniqueKeysForCharacter(); + message = "Please copy/paste JSON Data into text area."; - importAttributes(character); + } - importRepeatingLanguages(character, uniqueKeys); + if (success) { - importRepeatingCultures(character, uniqueKeys); + // TODO: figure out async/await + let uniqueKeys = await getUniqueKeysForCharacter(); - importRepeatingTraits(character, uniqueKeys); + await importAttributes(character); - importRepeatingPerks(character, uniqueKeys); + await importRepeatingLanguages(character, uniqueKeys); - importRepeatingQuirks(character, uniqueKeys); + await importRepeatingCultures(character, uniqueKeys); - importRepeatingDisadvantages(character, uniqueKeys); + await importRepeatingTraits(character, uniqueKeys); - importRepeatingRacial(character, uniqueKeys); + await importRepeatingPerks(character, uniqueKeys); - importRepeatingSkills(character, uniqueKeys); + await importRepeatingQuirks(character, uniqueKeys); - importRepeatingTechniquesrevised(character, uniqueKeys); + await importRepeatingDisadvantages(character, uniqueKeys); - importRepeatingDefense(character, uniqueKeys); + await importRepeatingRacial(character, uniqueKeys); - importRepeatingMelee(character, uniqueKeys); + await importRepeatingSkills(character, uniqueKeys); - importRepeatingRanged(character, uniqueKeys); + await importRepeatingTechniquesrevised(character, uniqueKeys); - importRepeatingItem(character, uniqueKeys); + await importRepeatingDefense(character, uniqueKeys); - importRepeatingSpells(character, uniqueKeys); + await importRepeatingMelee(character, uniqueKeys); - // very last attribute to get updated - const applyCombatReflexes = character.CombatReflexes ? "1" : "0"; + await importRepeatingRanged(character, uniqueKeys); - setAttrsAsync({combat_reflexes: applyCombatReflexes}); + await importRepeatingItem(character, uniqueKeys); - setAttrs({ - import_json_state: "normal", - import_json_message: "Import has completed!", - character_json_data: "" - }); + await importRepeatingSpells(character, uniqueKeys); - } else { + // very last attribute to get updated + const applyCombatReflexes = character.CombatReflexes ? "1" : "0"; - setAttrs({ "import_json_message": message }); + await setAttrsAsync({combat_reflexes: applyCombatReflexes}); - } + setAttrs({ + import_json_state: "normal", + import_json_message: "Import has completed!", + character_json_data: "" + }); - }); + } else { + + setAttrs({ "import_json_message": message }); + + } } - let getUniqueKeysForCharacter = () => { + let getUniqueKeysForCharacter = async () => { let uniqueKeys = {}; - //getUniqueKeysByTableAsync("repeating_languages", uniqueKeys); + await getUniqueKeysByTableAsync("repeating_languages", uniqueKeys); - //getUniqueKeysByTableAsync("repeating_cultures", uniqueKeys); + await getUniqueKeysByTableAsync("repeating_cultures", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_traits", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_perks", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_quirks", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_disadvantages", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_racial", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_skills", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_techniquesrevised", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_defense", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_melee", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_ranged", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_item", uniqueKeys); + + await getUniqueKeysByTableAsync("repeating_spells", uniqueKeys); return uniqueKeys; } - let getUniqueKeysByTableAsync = (table, uniqueKeys) => { + let getUniqueKeysByTableAsync = async (table, uniqueKeys) => { - getSectionIDsAsync(table, ids => { + let ids = await getSectionIDsAsync(table); + + if (ids.length === 0) { + return; + } - if (ids.length === 0) { - callback(); - return; - } - - // get the idkey for each row. - let fields = []; - - for (let i = 0; i < ids.length; i++) { - - fields.push(`${table}_${ids[i]}_idkey`); - - } + // get the idkey for each row. + let fields = []; - getAttrsAsync(fields, values => { + for (let i = 0; i < ids.length; i++) { - // loop through each row - for (let key in values) { - - let idkey; + fields.push(`${table}_${ids[i]}_idkey`); - let rowId; + } - if (values.hasOwnProperty(key)) { + let values = await getAttrsAsync(fields); - idkey = values[key]; + // loop through each row + for (let key in values) { - // get row id from the key name - // example: repeating_melee_KEYHERE_idkey - rowId = getRowIdFromRowFieldKey(key, table); + let idkey; - if (idkey && rowId) { + let rowId; - // add new key/value pair! - uniqueKeys[idkey] = rowId; + if (values.hasOwnProperty(key)) { - } + idkey = values[key]; - } + // get row id from the key name + // example: repeating_melee_KEYHERE_idkey + rowId = getRowIdFromRowFieldKey(key, table); + + if (idkey && rowId) { + + // add new key/value pair! + uniqueKeys[idkey] = rowId; } - }); - }); + } + + } } - let importAttributes = character => { + let importAttributes = async (character) => { const applySizeModifier = character.ApplySizeModifier ? "1" : "0"; const flightChecked = character.FlightChecked ? "1" : "0"; @@ -34309,19 +34337,19 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm spell_bonus: parseInt(character.SpellBonus) }; - setAttrsAsync(baseAttributes); + await setAttrsAsync(baseAttributes); - setAttrsAsync(baseAttributeMods); + await setAttrsAsync(baseAttributeMods); - setAttrsAsync(secondaryAttributesPoints); + await setAttrsAsync(secondaryAttributesPoints); - setAttrsAsync(secondaryAttributesMods); + await setAttrsAsync(secondaryAttributesMods); } - let importRepeatingLanguages = (character, uniqueKeys) => { + let importRepeatingLanguages = async (character, uniqueKeys) => { - character.RepeatingLanguages.forEach(language => { + await asyncForEach(character.RepeatingLanguages, async (language) => { let attributes = {}; @@ -34352,16 +34380,16 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingCultures = (character, uniqueKeys) => { - - character.RepeatingCultures.forEach(culture => { + let importRepeatingCultures = async (character, uniqueKeys) => { + await asyncForEach(character.RepeatingCultures, async (culture) => { + let rowId = generateOrGetRowId(uniqueKeys, culture.Idkey); let baseFieldName = `repeating_cultures_${rowId}`; @@ -34374,15 +34402,15 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_points`] = parseInt(culture.Points); - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingTraits = (character, uniqueKeys) => { + let importRepeatingTraits = async (character, uniqueKeys) => { - character.RepeatingTraits.forEach(trait => { + await asyncForEach(character.RepeatingTraits, async (trait) => { let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); @@ -34404,15 +34432,15 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = trait.Notes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingPerks = (character, uniqueKeys) => { + let importRepeatingPerks = async (character, uniqueKeys) => { - character.RepeatingPerks.forEach(trait => { + await asyncForEach(character.RepeatingPerks, async (trait) => { let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); @@ -34432,15 +34460,15 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = trait.Notes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingQuirks = (character, uniqueKeys) => { + let importRepeatingQuirks = async (character, uniqueKeys) => { - character.RepeatingQuirks.forEach(trait => { + await asyncForEach(character.RepeatingQuirks, async (trait) => { let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); @@ -34460,15 +34488,15 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = trait.Notes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingDisadvantages = (character, uniqueKeys) => { + let importRepeatingDisadvantages = async (character, uniqueKeys) => { - character.RepeatingDisadvantages.forEach(trait => { + await asyncForEach(character.RepeatingDisadvantages, async(trait) => { let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); @@ -34490,15 +34518,15 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = trait.Notes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingRacial = (character, uniqueKeys) => { + let importRepeatingRacial = async (character, uniqueKeys) => { - character.RepeatingRacial.forEach(trait => { + await asyncForEach(character.RepeatingRacial, async (trait) => { let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); @@ -34520,15 +34548,15 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = trait.Notes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingSkills = (character, uniqueKeys) => { + let importRepeatingSkills = async (character, uniqueKeys) => { - character.RepeatingSkills.forEach(skill => { + await asyncForEach(character.RepeatingSkills, async (skill) => { let rowId = generateOrGetRowId(uniqueKeys, skill.Idkey); @@ -34556,7 +34584,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = skill.Notes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); @@ -34598,9 +34626,9 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - let importRepeatingTechniquesrevised = (character, uniqueKeys) => { + let importRepeatingTechniquesrevised = async (character, uniqueKeys) => { - character.RepeatingTechniquesrevised.forEach(skill => { + await asyncForEach(character.RepeatingTechniquesrevised, async (skill) => { let rowId = generateOrGetRowId(uniqueKeys, skill.Idkey); @@ -34632,7 +34660,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = skill.Notes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); @@ -34658,9 +34686,9 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } - let importRepeatingDefense = (character, uniqueKeys) => { + let importRepeatingDefense = async (character, uniqueKeys) => { - character.RepeatingDefense.forEach(trait => { + await asyncForEach(character.RepeatingDefense, async (trait) => { let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); @@ -34682,17 +34710,17 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_defense_mod_reason`] = trait.DefenseModReason; - attributes[`${baseFieldName}_info_description`] = parseInt(trait.InfoDescription); + attributes[`${baseFieldName}_info_description`] = trait.InfoDescription; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingMelee = (character, uniqueKeys) => { + let importRepeatingMelee = async (character, uniqueKeys) => { - character.RepeatingMelee.forEach(trait => { + await asyncForEach(character.RepeatingMelee, async (trait) => { let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); @@ -34716,15 +34744,15 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = trait.Notes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingRanged = (character, uniqueKeys) => { + let importRepeatingRanged = async (character, uniqueKeys) => { - character.RepeatingRanged.forEach(trait => { + await asyncForEach(character.RepeatingRanged, async (trait) => { let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); @@ -34768,15 +34796,15 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = trait.Notes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingItem = (character, uniqueKeys) => { + let importRepeatingItem = async (character, uniqueKeys) => { - character.RepeatingItem.forEach(trait => { + await asyncForEach(character.RepeatingItem, async (trait) => { let rowId = generateOrGetRowId(uniqueKeys, trait.Idkey); @@ -34802,15 +34830,15 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = trait.Notes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); } - let importRepeatingSpells = (character, uniqueKeys) => { + let importRepeatingSpells = async (character, uniqueKeys) => { - character.RepeatingSpells.forEach(skill => { + await asyncForEach(character.RepeatingSpells, async (skill) => { let rowId = generateOrGetRowId(uniqueKeys, skill.Idkey); @@ -34852,7 +34880,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_notes`] = skill.SpellNotes; - setAttrsAsync(attributes); + await setAttrsAsync(attributes); }); diff --git a/GURPS/readme/assets/Artillery Mage (NPC) export.json b/GURPS/readme/assets/Artillery Mage (NPC) export.json index 02f728ab93..c927e64e93 100644 --- a/GURPS/readme/assets/Artillery Mage (NPC) export.json +++ b/GURPS/readme/assets/Artillery Mage (NPC) export.json @@ -85,8 +85,22 @@ "SuperJumpPoints": 0.0, "SpellBonus": 3.0, "CombatReflexes": false, - "RepeatingLanguages": [], - "RepeatingCultures": [], + "RepeatingLanguages": [ + { + "Idkey": "13362", + "Name": "Common", + "Spoken": 0.0, + "Written": 0.0, + "IsNative": true + } + ], + "RepeatingCultures": [ + { + "Idkey": "13364", + "Name": "Western", + "Points": 1.0 + } + ], "RepeatingTraits": [ { "Idkey": "186", @@ -179,7 +193,7 @@ "RepeatingTechniquesrevised": [], "RepeatingDefense": [ { - "Idkey": "128_mode_20", + "Idkey": "128_unarmed_parry", "Name": "Punch", "Type": "Unarmed Parry", "Info": "", @@ -189,7 +203,7 @@ "InfoDescription": "" }, { - "Idkey": "189_mode_47", + "Idkey": "189_parry", "Name": "Quarterstaff (Staff Swing)", "Type": "Parry", "Info": "", @@ -199,7 +213,7 @@ "InfoDescription": "" }, { - "Idkey": "189_mode_48", + "Idkey": "189_parry", "Name": "Quarterstaff (Staff Thrust)", "Type": "Parry", "Info": "", @@ -209,7 +223,7 @@ "InfoDescription": "" }, { - "Idkey": "189_mode_49", + "Idkey": "189_parry", "Name": "Quarterstaff (2H Sword Swing)", "Type": "Parry", "Info": "", @@ -219,7 +233,7 @@ "InfoDescription": "" }, { - "Idkey": "189_mode_50", + "Idkey": "189_parry", "Name": "Quarterstaff (2H Sword Thrust)", "Type": "Parry", "Info": "", @@ -231,7 +245,7 @@ ], "RepeatingMelee": [ { - "Idkey": "226_mode_36", + "Idkey": "226_airjet_", "Name": "Air Jet", "Damage": "~2d6", "Type": "knock", @@ -241,7 +255,7 @@ "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" }, { - "Idkey": "14_mode_1", + "Idkey": "14_bite_bite", "Name": "Bite", "Damage": "1d6-3", "Type": "cr", @@ -251,7 +265,7 @@ "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" }, { - "Idkey": "13350_mode_37", + "Idkey": "13350_breathefire_", "Name": "Breathe Fire", "Damage": "~1d6+1", "Type": "burn", @@ -261,7 +275,7 @@ "Notes": "{~1-4 energy. Multiply spell effect based on enegy spent.}" }, { - "Idkey": "13351_mode_39", + "Idkey": "13351_flamejet_", "Name": "Flame Jet", "Damage": "~1d6", "Type": "burn", @@ -271,7 +285,7 @@ "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" }, { - "Idkey": "69_mode_13", + "Idkey": "69_kick_kick", "Name": "Kick", "Damage": "1d6-2", "Type": "cr", @@ -281,7 +295,7 @@ "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" }, { - "Idkey": "128_mode_20", + "Idkey": "128_punch_punch", "Name": "Punch", "Damage": "1d6-3", "Type": "cr", @@ -291,7 +305,7 @@ "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" }, { - "Idkey": "189_mode_47", + "Idkey": "189_quarterstaff_staffswing", "Name": "Quarterstaff (Staff Swing)", "Damage": "1d6+1", "Type": "cr", @@ -301,7 +315,7 @@ "Notes": "" }, { - "Idkey": "189_mode_48", + "Idkey": "189_quarterstaff_staffthrust", "Name": "Quarterstaff (Staff Thrust)", "Damage": "1d6", "Type": "cr", @@ -311,7 +325,7 @@ "Notes": "" }, { - "Idkey": "189_mode_49", + "Idkey": "189_quarterstaff_2hswordswing", "Name": "Quarterstaff (2H Sword Swing)", "Damage": "1d6+1", "Type": "cr", @@ -321,7 +335,7 @@ "Notes": "" }, { - "Idkey": "189_mode_50", + "Idkey": "189_quarterstaff_2hswordthrust", "Name": "Quarterstaff (2H Sword Thrust)", "Damage": "1d6-1", "Type": "cr", @@ -333,7 +347,7 @@ ], "RepeatingRanged": [ { - "Idkey": "216_mode_38", + "Idkey": "216_fireball_", "Name": "Fireball", "Damage": "~1d6", "Type": "burn", @@ -351,7 +365,7 @@ "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" }, { - "Idkey": "222_mode_40", + "Idkey": "222_icedagger_", "Name": "Ice Dagger", "Damage": "~1d6-1", "Type": "imp", @@ -369,7 +383,7 @@ "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" }, { - "Idkey": "223_mode_41", + "Idkey": "223_icesphere_", "Name": "Ice Sphere", "Damage": "~1d6", "Type": "cr", @@ -387,7 +401,7 @@ "Notes": "{~1-3 energy. Multiply spell effect based on enegy spent.}" }, { - "Idkey": "225_mode_45", + "Idkey": "225_pistolcrossbow_barbed-head", "Name": "Pistol Crossbow (ST 10) (Barbed-head)", "Damage": "1d6-4", "Type": "imp", @@ -405,7 +419,7 @@ "Notes": "{Requires two hands to ready, but only one hand to attack.}" }, { - "Idkey": "201_mode_42", + "Idkey": "201_stonemissile_", "Name": "Stone Missile", "Damage": "~1d6+1", "Type": "cr", diff --git a/GURPS/readme/assets/Rampage (NPC) export.json b/GURPS/readme/assets/Rampage (NPC) export.json index 906d446a90..a5c724aa1e 100644 --- a/GURPS/readme/assets/Rampage (NPC) export.json +++ b/GURPS/readme/assets/Rampage (NPC) export.json @@ -669,7 +669,7 @@ ], "RepeatingDefense": [ { - "Idkey": "10704_mode_208", + "Idkey": "10704_power_dodge", "Name": "Body Control Talent (Power Dodge)", "Type": "Power Dodge", "Info": "", @@ -679,7 +679,7 @@ "InfoDescription": "" }, { - "Idkey": "10704_mode_209", + "Idkey": "10704_power_block", "Name": "Body Control Talent (Power Block/Physical)", "Type": "Power Block", "Info": "", @@ -689,7 +689,7 @@ "InfoDescription": "" }, { - "Idkey": "10704_mode_210", + "Idkey": "10704_power_block_mental", "Name": "Body Control Talent (Power Block/Mental)", "Type": "Power Block Mental", "Info": "", @@ -699,7 +699,7 @@ "InfoDescription": "" }, { - "Idkey": "10753_mode_290", + "Idkey": "10753_unarmed_parry", "Name": "Brawling (Punch)", "Type": "Unarmed Parry", "Info": "", @@ -709,7 +709,7 @@ "InfoDescription": "" }, { - "Idkey": "10613_mode_116", + "Idkey": "10613_unarmed_parry", "Name": "Punch", "Type": "Unarmed Parry", "Info": "", @@ -731,7 +731,7 @@ ], "RepeatingMelee": [ { - "Idkey": "13172_mode_287", + "Idkey": "13172_aggressiveparry_", "Name": "Aggressive Parry (Brawling)", "Damage": "2d6-2", "Type": "cr", @@ -741,7 +741,7 @@ "Notes": "" }, { - "Idkey": "10525_mode_12", + "Idkey": "10525_bite_bite", "Name": "Bite", "Damage": "2d6+1", "Type": "cr", @@ -751,7 +751,7 @@ "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" }, { - "Idkey": "10753_mode_290", + "Idkey": "10753_brawling_punch", "Name": "Brawling (Punch)", "Damage": "2d6+1", "Type": "cr", @@ -761,7 +761,7 @@ "Notes": "" }, { - "Idkey": "10753_mode_291", + "Idkey": "10753_brawling_bite", "Name": "Brawling (Bite)", "Damage": "2d6+1", "Type": "cr", @@ -771,7 +771,7 @@ "Notes": "" }, { - "Idkey": "10753_mode_292", + "Idkey": "10753_brawling_kick", "Name": "Brawling (Kick)", "Damage": "2d6+2", "Type": "cr", @@ -781,7 +781,7 @@ "Notes": "{If you miss with a kick, roll vs. DX to avoid falling.}" }, { - "Idkey": "13176_mode_317", + "Idkey": "13176_forceshield_bash", "Name": "Force Shield (Bash)", "Damage": "2d6", "Type": "cr", @@ -791,7 +791,7 @@ "Notes": "{Worn on the wrist, leaving the hand free.}" }, { - "Idkey": "13176_mode_318", + "Idkey": "13176_forceshield_rush", "Name": "Force Shield (Rush)", "Damage": "slam+3", "Type": "cr", @@ -801,7 +801,7 @@ "Notes": "{Worn on the wrist, leaving the hand free.}" }, { - "Idkey": "10558_mode_53", + "Idkey": "10558_kick_kick", "Name": "Kick", "Damage": "2d6+2", "Type": "cr", @@ -811,7 +811,7 @@ "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" }, { - "Idkey": "10613_mode_116", + "Idkey": "10613_punch_punch", "Name": "Punch", "Damage": "2d6+1", "Type": "cr", @@ -823,7 +823,7 @@ ], "RepeatingRanged": [ { - "Idkey": "10720_mode_223", + "Idkey": "10720_crossbow_primary", "Name": "Crossbow (Armor Piercing) (Primary)", "Damage": "3d6", "Type": "imp", @@ -841,7 +841,7 @@ "Notes": "" }, { - "Idkey": "10730_mode_229", + "Idkey": "10730_crossbow_primary", "Name": "Crossbow (Explosive) (Primary)", "Damage": "3d6", "Type": "cr dkb ex/2", @@ -859,7 +859,7 @@ "Notes": "" }, { - "Idkey": "10786_mode_322", + "Idkey": "10786_revolver357m_", "Name": "Revolver, .357M", "Damage": "3d6-1", "Type": "pi", diff --git a/GURPS/readme/assets/gargoyle export.json b/GURPS/readme/assets/gargoyle export.json index d488b473a3..2e5634696a 100644 --- a/GURPS/readme/assets/gargoyle export.json +++ b/GURPS/readme/assets/gargoyle export.json @@ -85,7 +85,15 @@ "SuperJumpPoints": 0.0, "SpellBonus": 0.0, "CombatReflexes": false, - "RepeatingLanguages": [], + "RepeatingLanguages": [ + { + "Idkey": "12360", + "Name": "Common", + "Spoken": 0.0, + "Written": 0.0, + "IsNative": true + } + ], "RepeatingCultures": [ { "Idkey": "12362", @@ -368,7 +376,7 @@ "RepeatingTechniquesrevised": [], "RepeatingDefense": [ { - "Idkey": "12373_mode_538", + "Idkey": "12373_mode_219", "Name": "Brawling (Punch)", "Type": "Unarmed Parry", "Info": "", @@ -378,7 +386,7 @@ "InfoDescription": "" }, { - "Idkey": "12376_mode_544", + "Idkey": "12376_mode_228", "Name": "Knobbed Club (Swing)", "Type": "Parry", "Info": "", @@ -388,7 +396,7 @@ "InfoDescription": "" }, { - "Idkey": "12296_mode_503", + "Idkey": "12296_mode_117", "Name": "Punch", "Type": "Unarmed Parry", "Info": "", @@ -398,7 +406,7 @@ "InfoDescription": "" }, { - "Idkey": "12353_mode_524", + "Idkey": "12353_mode_195", "Name": "Striker (Impaling; Gargoyle Tail) ([Description])", "Type": "Parry", "Info": "", @@ -410,7 +418,7 @@ ], "RepeatingMelee": [ { - "Idkey": "12208_mode_485", + "Idkey": "12208_mode_12", "Name": "Bite", "Damage": "1d6-2", "Type": "cr", @@ -420,7 +428,7 @@ "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" }, { - "Idkey": "12373_mode_538", + "Idkey": "12373_mode_219", "Name": "Brawling (Punch)", "Damage": "1d6-1", "Type": "cr", @@ -430,7 +438,7 @@ "Notes": "" }, { - "Idkey": "12373_mode_539", + "Idkey": "12373_mode_220", "Name": "Brawling (Bite)", "Damage": "1d6-2", "Type": "cr", @@ -440,7 +448,7 @@ "Notes": "" }, { - "Idkey": "12373_mode_540", + "Idkey": "12373_mode_221", "Name": "Brawling (Kick)", "Damage": "1d6", "Type": "cr", @@ -450,7 +458,7 @@ "Notes": "{If you miss with a kick, roll vs. DX to avoid falling.}" }, { - "Idkey": "12241_mode_496", + "Idkey": "12241_mode_57", "Name": "Kick", "Damage": "1d6", "Type": "cr", @@ -460,7 +468,7 @@ "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" }, { - "Idkey": "12376_mode_544", + "Idkey": "12376_mode_228", "Name": "Knobbed Club (Swing)", "Damage": "1d6+3", "Type": "cr", @@ -470,7 +478,7 @@ "Notes": "" }, { - "Idkey": "12296_mode_503", + "Idkey": "12296_mode_117", "Name": "Punch", "Damage": "1d6-1", "Type": "cr", @@ -480,7 +488,7 @@ "Notes": "{Brawling (p. B182) increases all unarmed damage; Claws (p. B42) and Karate (p. B203) improve damage with punches and kicks (Claws don't affect damage with brass knuckles or boots); and Boxing (p. B182) improves punching damage.}" }, { - "Idkey": "12353_mode_524", + "Idkey": "12353_mode_195", "Name": "Striker (Impaling; Gargoyle Tail) ([Description])", "Damage": "1d6", "Type": "imp", From c530303f8cd6909c93c242ba5a8f62745eacbced Mon Sep 17 00:00:00 2001 From: Ken Date: Sun, 11 Sep 2022 20:11:12 -0700 Subject: [PATCH 07/12] update gurps add damage die macro --- GURPS/gurps.html | 200 ++++++++++++----------------------------------- 1 file changed, 49 insertions(+), 151 deletions(-) diff --git a/GURPS/gurps.html b/GURPS/gurps.html index 2fd7e40b0d..8a53f0554a 100644 --- a/GURPS/gurps.html +++ b/GURPS/gurps.html @@ -15676,12 +15676,14 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm

Import Tool

- Imports a file using json data based on a standard for use with GURPS Roll20 Charactersheet. - Exporter tools can be developed for a character generator int this format, instead of + Imports a file using data based on a standard json shema for use with the GURPS Roll20 Charactersheet. + Exporter tools can be developed for a character generator in this format, instead of creating a special import for each character generator.

- Initial version is designed for a one time import. Future iterations will allow re-import. + Initial version is designed to allow you to re-import your character. Be aware, this will overwrite general notes. + Future iterations will check for deleted items and remove them and import notes checkbox. This checkbox will + prevent overwriting any notes you may have written on the character sheet.

GCA5

@@ -29294,14 +29296,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm let uniqueKeys = {}; importCharacterSheetWithGCA(uniqueKeys, jsonData, importNotes); - - // uniqueKeys is passed by reference. Gets updated while reading each repeating table. - // getUniqueKeysForSheet(uniqueKeys, () => { - // - // importCharacterSheetWithGCA(uniqueKeys, jsonData, importNotes); - - // }); - + } else { @@ -29362,144 +29357,6 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm return true; } - /** - * Get all the unique keys and associated row ids. - * This allows us to update existing rows instead of inserting new ones - * - * @param {object} uniqueKeys Key values pairs for unique idkey and associated row id. Passed by reference - * @param {() => void} callback Function to run after we're done getting data - */ - function getUniqueKeysForSheet(uniqueKeys, callback) { - - // make sure we have a valid function - callback = callback || noop; - - // sorry about this - getUniqueKeysForTable("repeating_languages", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_cultures", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_traits", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_perks", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_quirks", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_disadvantages", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_racial", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_skills", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_techniquesrevised", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_defense", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_melee", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_ranged", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_item", uniqueKeys, () => { - - getUniqueKeysForTable("repeating_spells", uniqueKeys, () => { - - // finally return! Sorry1 - callback(); - - }); - - }); - - }); - - }); - - }); - - }); - - }); - - }); - - }); - - }); - - }); - - }); - - }); - - }); - - } - - /** - * Get unique idkey and associated row id for a table - * - * @param {string} table Name of repeating table - * @param {object} uniqueKeys Key values pairs for unique idkey and associated row id. Passed by reference - * @param {() => void} callback Function to run after we're done getting data - */ - function getUniqueKeysForTable(table, uniqueKeys, callback) { - - // make sure we have a valid function - callback = callback || noop; - - getSectionIDs(table, (ids) => { - - if (ids.length === 0) { - callback(); - return; - } - - // get the idkey for each row. - let fields = []; - - for (let i = 0; i < ids.length; i++) { - - fields.push(`${table}_${ids[i]}_idkey`); - - } - - getAttrs(fields, values => { - - // loop through each row - for (let key in values) { - - let idkey; - - let rowId; - - if (values.hasOwnProperty(key)) { - - idkey = values[key]; - - // get row id from the key name - // example: repeating_melee_KEYHERE_idkey - rowId = getRowIdFromRowFieldKey(key, table); - - if (idkey && rowId) { - - // add new key/value pair! - uniqueKeys[idkey] = rowId; - - } - - } - - } - - }); - - }); - - callback(); - - } - /** * Start processing GCA json data and update character sheet * @@ -34718,6 +34575,47 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm } + /** + * Will convert variable die rolls to Roll20 macro prompt + * if it starts with ~, then add macro to allow user to enter number of dice to roll + */ + let getDamageDieMacro = (damageDie) => { + + let dieRoll = damageDie; + + if (damageDie && damageDie.includes("~")) { + + // example: ~1d+1 + // remove ~ + damageDie = damageDie.replace("~", ""); + + // array = [1, +1] + let arrDamageDie = damageDie.split("d"); + + let baseDie = 1; + + let dieModifier = "0"; + + if (arrDamageDie.length === 1) { + + baseDie = arrDamageDie[0]; + + } else if (arrDamageDie.length === 2) { + + baseDie = arrDamageDie[0]; + + dieModifier = arrDamageDie[0]; + + } + + dieRoll = getNumberOfDicePrompt(baseDie, Number(dieModifier), 12); + + } + + return dieRoll; + + } + let importRepeatingMelee = async (character, uniqueKeys) => { await asyncForEach(character.RepeatingMelee, async (trait) => { @@ -34732,7 +34630,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_name`] = trait.Name; - attributes[`${baseFieldName}_damage`] = trait.Damage; + attributes[`${baseFieldName}_damage`] = getDamageDieMacro(trait.Damage); attributes[`${baseFieldName}_type`] = getDamageTypeFromGca(trait.Type); @@ -34768,7 +34666,7 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm attributes[`${baseFieldName}_name`] = trait.Name; - attributes[`${baseFieldName}_damage`] = trait.Damage; + attributes[`${baseFieldName}_damage`] = getDamageDieMacro(trait.Damage); attributes[`${baseFieldName}_type`] = getDamageTypeFromGca(trait.Type); From da1ee7a774544348ba85eea080f7a7295b58263c Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 16 Sep 2022 21:51:24 -0700 Subject: [PATCH 08/12] update gurps update tooltips with suggestions provided by Captain Joy --- GURPS/gurps.html | 30 ++++++++++++++++++++++++------ GURPS/translation.json | 8 ++++---- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/GURPS/gurps.html b/GURPS/gurps.html index 8a53f0554a..7d3d8c65af 100644 --- a/GURPS/gurps.html +++ b/GURPS/gurps.html @@ -4358,12 +4358,15 @@ - +
    -
  • Options tab. Sheet Options sub-tab. Updated Resync button to change colors when clicked. Thanks to Onyxring's Roll20Async functions!
  • +
  • Options -> Import subtab. This is a new feature with the ability to import GCA5 characters and can be used for importing GCS characters. +
      +
    • NOTE: The GCA4 Import has been depracted and will not be updated.
    • +
    +
  • - Repeating Skills, attribute drop-down. The character sheet uses an old method to link skills to an attribute. The old method might not trigger correctly - when an attribute like Dexterity is changed. Solved the issue by tricking the system into resyncing skills when an attribute is changed. + A few tooltip updates requested by Captain Joy.
@@ -14028,8 +14031,23 @@ Slam uses either DX, Brawling, or Sumo Wrestling. Note that the -4 to hit and ef

Version:

Pull Request:

+ +
    +
  • Options -> Import subtab. This is a new feature with the ability to import GCA5 characters and can be used for importing GCS characters. +
      +
    • NOTE: The GCA4 Import has been depracted and will not be updated.
    • +
    +
  • +
  • + A few tooltip updates requested by Captain Joy. +
  • +
+ +

Version: 2.8.4

+ +

Pull Request: 9/6/2022

  • Options tab. Sheet Options sub-tab. Updated Resync button to change colors when clicked. Thanks to Onyxring's Roll20Async functions!
  • @@ -17356,9 +17374,9 @@ Diffuse: Max 2HP (Exception: Area-effect, cone, and explosion attacks cause norm const noop = function () { }; // do nothing callback function. - const version = "2.8.4"; + const version = "2.9.0"; - const latestChangesDate = "9/6/2022"; + const latestChangesDate = "9/20/2022"; let modCascade = true; diff --git a/GURPS/translation.json b/GURPS/translation.json index 46c4e3a9e3..15f00509f9 100644 --- a/GURPS/translation.json +++ b/GURPS/translation.json @@ -436,14 +436,14 @@ "attribute-will": "Will", "attribute-will-tooltip": "Willpower
    Based on Intelligence
    5pts/level
    Unmodified: ", "attribute-fright": "Fright", - "attribute-fright-tooltip": "Fright Check (B360)
    Based on Willpower
    2pts/level
    Unmodified:
    See extensive list of Modifiers B360 & GURPS Horror p139-142.", + "attribute-fright-tooltip": "Fright Check (B360)
    Based on Willpower
    2pts/level
    Unmodified:
    See extensive list of Modifiers B360 & GURPS Horror p139-142.
    If manually creating and/or maintaining this sheet, Combat Reflexes adds +2 to Fright (Enter as a MOD with a value of 2)", "abbreviation-threshold": "Thresh", "attribute-fright-check-threshold-tooltip": "Fright Check Threshold - Uses Rule of 14 (B360). By default this value is 13.
    This means that a roll of 14 or more is automatically a failure.
    This Threshold can be modifier by the Perks of Brave (Dungeon Fantasy 11, p11) or Rule of 15
    (Power Ups 2, p13).
    Will and/or Fright plus bonuses (like Fearlessness or Combat Reflexes) must total 14+ for this
    to be useful, of course!
    Note: A Fright Check can be used for Awe and Confusion. (Powers p84 under Terror) and the Awe and
    Confusion Check Table for failures. (Powers p85).", "fright-check-label": "Fright Check", "attribute-unstun": "Unstun", "attribute-unstun-tooltip": "Recover from physical stun, based on Health.
    Roll at the end of your turn after Do Nothing ", "abbreviation-knock-down": "K Down", - "attribute-knock-down-tooltip": "Knockdown and Stunning check (B420), based on HT (Health).
    Roll immediately whenever the following happens:
    • You suffer a Major Wound (B420) - This is any single injury that inflicts a wound in excess of ½ your HP.
    • You suffer any Crippling Injury (B420-421).
    • Whenever you are struck in the Head (Skull, Face, or Eye) or Vitals for enough injury to cause a Shock (B419) penalty.
    Modifiers:
    • - 5 for a Major Wound (B420) to the Face or Vitals (or to the Groin on a humanoid male).
    • - 10 for a Major Wound (B420) to the Skull or Eye.
    ", + "attribute-knock-down-tooltip": "Knockdown and Stunning check (B420), based on HT (Health).
    Roll immediately whenever the following happens:
    • You suffer a Major Wound (B420) - This is any single injury that inflicts a wound in excess of ½ your HP.
    • You suffer any Crippling Injury (B420-421).
    • Whenever you are struck in the Head (Skull, Face, or Eye) or Vitals for enough injury to cause a Shock (B419) penalty.
    Modifiers:
    • - 5 for a Major Wound (B420) to the Face or Vitals (or to the Groin on a humanoid male).
    • - 10 for a Major Wound (B420) to the Skull or Eye.
    • If manually creating and/or maintaining this sheet, High Pain Threshold adds +3 to Knockdown (Enter as a MOD with a value of 3)
    ", "abbreviation-unconscious": "Unc.", "attribute-unconscious-check-tooltip": "Unconscious Check, based on Health
    If HP zero or less, roll per turn to take an Active Action.
    -1 per full multiple of HP below zero.
    Hard/Easy to Subdue: Gives +/- per level to Unconscious Check
    Fit +1 to Unc. Check . Very Fit +2 to Unc. Check", "abbreviation-death-check": "Death", @@ -887,7 +887,7 @@ "melee-attacks-label": "Melee Attacks", "attacks-label": "Attacks", "targets-label": "Targets", - "melee-attack-damage-tooltip": "For an Armor Divisor: A number in parenthesis after
    the damage - eg. (2) - is an armor divisor.
    Enter this number in the Damage Notes as AD(#) or as
    Armor Divisor(#).
    ex: indicates the attack causes an explosion.
    See B269. Enter in the Damage Notes", + "melee-attack-damage-tooltip": "For an Armor Divisor: A number in parenthesis after
    the damage - eg. (2) - is an armor divisor.
    Enter this number in the Damage Notes as AD(#) or as
    Armor Divisor(#).
    ex: indicates the attack causes an explosion.
    See B269. Enter in the Damage Notes
    Macros You can also use @{thrust} and @{swing} for Melee Damage value, which is based on the values entered on the General page. You can even add additional modifiers such as @{thrust}+3.", "damage-type-tooltip": "
    AbbrName
    aff Affliction
    burnBurning
    cor Corrosion
    cr Crushing
    cut Cutting
    fat Fatigue
    imp Impaling
    pi- Small Piercing
    pi Piercing
    pi+ Large Piercing
    pi++Huge Piercing
    specSpecial
    tox Toxic
    ", "reach-label": "Reach", "melee-reach-tooltip": "The distance in yards that the weapon can reach.
    C: this weapon can be used in close combat.
    *: the weapon is awkward, and requires a Ready
    maneuver to switch between different reaches.", @@ -930,7 +930,7 @@ "ranged-fail-notes-tooltip": "Any standard notes entered here will appear in the Roll Template in chat.
    Hint: Enter inline rolls for additional results.
    Example: Does an additional [[1d6]] fire damage.", "ranged-critical-fail-notes-tooltip": "Any standard notes entered here will appear in the Roll Template in chat.
    Hint: Enter inline rolls for additional results.
    Example: Does an additional [[1d6]] fire damage.", "ranged-attacks-label": "Ranged Attacks", - "ranged-damage-tooltip": "For an Armor Divisor: A number in parenthesis after
    the damage - eg. (2) - is an armor divisor.
    Enter this number in the Damage Notes as AD(#) or as
    Armor Divisor(#).
    ex: indicates the attack causes an explosion.
    [#d]: indicates the attack causes fragmentation.
    See B269. Enter in the Damage Notes", + "ranged-damage-tooltip": "For an Armor Divisor: A number in parenthesis after
    the damage - eg. (2) - is an armor divisor.
    Enter this number in the Damage Notes as AD(#) or as
    Armor Divisor(#).
    ex: indicates the attack causes an explosion.
    [#d]: indicates the attack causes fragmentation.
    See B269. Enter in the Damage Notes.
    Macros You can also use @{thrust} and @{swing} for Ranged Damage value, which is based on the values entered on the General page. You can even add additional modifiers such as @{thrust}+3.", "abbreviation-range-label": "RNG", "range-tooltip": "Range. See B269.", "shots-label": "Shots", From a068501e24e12fd5039c55ead706ca2df9d89520 Mon Sep 17 00:00:00 2001 From: Ken Date: Sun, 18 Sep 2022 11:07:32 -0700 Subject: [PATCH 09/12] update gurps highlight 1s and 6s for skill rolls. --- GURPS/gurps.html | 76 ++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/GURPS/gurps.html b/GURPS/gurps.html index 7d3d8c65af..a6ea09b25c 100644 --- a/GURPS/gurps.html +++ b/GURPS/gurps.html @@ -4368,6 +4368,9 @@
  • A few tooltip updates requested by Captain Joy.
  • +
  • + Skill Rolls. Rolls of 1 will be highleted Green, while rolls of 6 are highlighted Red. Requested by Tommi. +
@@ -4474,7 +4477,7 @@ Cost reduced by -10% (Max -80%) per SM+1 (B15)
-
@@ -4497,7 +4500,7 @@ Cost reduced by -10% (Max -80%) per SM+1 (B15)
-
@@ -4520,7 +4523,7 @@ Cost reduced by -10% (Max -80%) per SM+1 (B15)
-
@@ -4543,7 +4546,7 @@ Cost reduced by -10% (Max -80%) per SM+1 (B15)
-
@@ -4575,7 +4578,7 @@ Unmodified:
-
@@ -4602,7 +4605,7 @@ Unmodified:
-
@@ -4629,7 +4632,7 @@ Unmodified:
-
@@ -4656,7 +4659,7 @@ Unmodified:
-
@@ -4683,7 +4686,7 @@ Unmodified:
-
@@ -4710,7 +4713,7 @@ Unmodified:
-
@@ -4741,7 +4744,7 @@ See extensive list of Modifiers B360 & GURPS Horror p139-142.
-
@@ -4794,7 +4797,7 @@ Roll at the end of your turn after Do Nothing  
-
@@ -4829,7 +4832,7 @@ Roll -
@@ -4858,7 +4861,7 @@ Fit +1 to Unc. Check . Very Fit +2 to Unc. Check
-
@@ -4889,7 +4892,7 @@ Fit +1 to Death Check . Very Fit +2 to Death Check
-
@@ -7095,7 +7098,7 @@ PU2:126 = Power-Ups 2. Page 126
-
@@ -7242,7 +7245,7 @@ PU2:126 = Power-Ups 2. Page 126
-
@@ -7323,7 +7326,7 @@ PU2:126 = Power-Ups 2. Page 126
-
@@ -7420,7 +7423,7 @@ PU2:126 = Power-Ups 2. Page 126
-
@@ -7598,7 +7601,7 @@ PU2:126 = Power-Ups 2. Page 126
-
@@ -8233,7 +8236,7 @@ PU2:126 = Power-Ups 2. Page 126
-
@@ -8718,7 +8721,7 @@ PU2:126 = Power-Ups 2. Page 126
- +
@@ -9958,7 +9961,7 @@ visualize what it will look like in chat. -
@@ -10125,7 +10128,7 @@ visualize what it will look like in chat. -