diff --git a/BattleTech-A-Time-of-War/.gitignore b/BattleTech-A-Time-of-War/.gitignore
index dd1bed072a..13cd983a9c 100644
--- a/BattleTech-A-Time-of-War/.gitignore
+++ b/BattleTech-A-Time-of-War/.gitignore
@@ -1,3 +1,4 @@
node_modules/
coverage/
-.idea
\ No newline at end of file
+.idea
+output/
\ No newline at end of file
diff --git a/BattleTech-A-Time-of-War/BattleTech-A-Time-of-War.html b/BattleTech-A-Time-of-War/BattleTech-A-Time-of-War.html
index 73183a99c4..3addec12d8 100644
--- a/BattleTech-A-Time-of-War/BattleTech-A-Time-of-War.html
+++ b/BattleTech-A-Time-of-War/BattleTech-A-Time-of-War.html
@@ -762,120 +762,122 @@
diff --git a/BattleTech-A-Time-of-War/README.md b/BattleTech-A-Time-of-War/README.md
new file mode 100644
index 0000000000..b8ac3330a4
--- /dev/null
+++ b/BattleTech-A-Time-of-War/README.md
@@ -0,0 +1,18 @@
+# BattleTech - A Time of War Character Sheet
+
+## Development Notes
+
+The character sheet for BattleTech - A Time of War is not as straightforward as other character sheets. However, it is hopefully easier to develop.
+
+Since the majority of IDEs recognise a file based on its file extension, having the sheet worker JavaScript in the same HTML file as the character sheet results in the IDE not being able to give you any help with your JavaScript code. To rectify this problem, the sheet worker code has been pulled out into multiple separate JavaScript files. The main file is the [sheet-worker.js](https://github.com/Roll20/roll20-character-sheets/blob/master/BattleTech-A-Time-of-War/development/src/sheet-worker.js) file, with other separate files for the different pieces of functionality. All changes to the sheet worker code should be made to these files.
+
+Once your changes have been made, there are two steps you need to do before committing. You'll need a few programs as well.
+
+1. [npm](https://www.npmjs.com/get-npm)
+2. [Python](https://www.python.org/downloads/)
+
+Once npm is installed, run `npm -i` in the development directory to install the libraries needed.
+
+After making your code changes:
+1. Run `npm test` in the development directory to automatically run the unit tests. If any of the tests fail, check your changes; you must have made a mistake in your code.
+2. Run `python3 main.py` in the pre-commit-script directory. This will combine all the JavaScript into a single file, then insert the JavaScript into the character sheet HTML file.
\ No newline at end of file
diff --git a/BattleTech-A-Time-of-War/development/package-lock.json b/BattleTech-A-Time-of-War/development/package-lock.json
index 7570baad87..4a0cbc1746 100644
--- a/BattleTech-A-Time-of-War/development/package-lock.json
+++ b/BattleTech-A-Time-of-War/development/package-lock.json
@@ -1571,6 +1571,35 @@
}
}
},
+ "@rollup/plugin-babel": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.2.tgz",
+ "integrity": "sha512-MjmH7GvFT4TW8xFdIeFS3wqIX646y5tACdxkTO+khbHvS3ZcVJL6vkAHLw2wqPmkhwCfWHoNsp15VYNwW6JEJA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.10.4",
+ "@rollup/pluginutils": "^3.1.0"
+ }
+ },
+ "@rollup/pluginutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
+ "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
+ "dev": true,
+ "requires": {
+ "@types/estree": "0.0.39",
+ "estree-walker": "^1.0.1",
+ "picomatch": "^2.2.2"
+ },
+ "dependencies": {
+ "estree-walker": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
+ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
+ "dev": true
+ }
+ }
+ },
"@sinonjs/commons": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz",
@@ -1630,6 +1659,12 @@
"@babel/types": "^7.3.0"
}
},
+ "@types/estree": {
+ "version": "0.0.39",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
+ "dev": true
+ },
"@types/graceful-fs": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz",
@@ -1887,12 +1922,6 @@
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
"dev": true
},
- "babel": {
- "version": "6.23.0",
- "resolved": "https://registry.npmjs.org/babel/-/babel-6.23.0.tgz",
- "integrity": "sha1-0NHn2APpdHZb7qMjLU4VPA77kPQ=",
- "dev": true
- },
"babel-jest": {
"version": "26.6.3",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz",
@@ -1973,6 +2002,15 @@
"babel-preset-current-node-syntax": "^1.0.0"
}
},
+ "babelrc-rollup": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/babelrc-rollup/-/babelrc-rollup-3.0.0.tgz",
+ "integrity": "sha1-/Ozb4+tkAM9OdpIzwXhqL6/otWw=",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.1.7"
+ }
+ },
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -2905,6 +2943,12 @@
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true
},
+ "estree-walker": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
+ "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
+ "dev": true
+ },
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@@ -5474,6 +5518,43 @@
"glob": "^7.1.3"
}
},
+ "rollup": {
+ "version": "2.35.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.35.1.tgz",
+ "integrity": "sha512-q5KxEyWpprAIcainhVy6HfRttD9kutQpHbeqDTWnqAFNJotiojetK6uqmcydNMymBEtC4I8bCYR+J3mTMqeaUA==",
+ "dev": true,
+ "requires": {
+ "fsevents": "~2.1.2"
+ },
+ "dependencies": {
+ "fsevents": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "rollup-plugin-babel": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.4.0.tgz",
+ "integrity": "sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.0.0",
+ "rollup-pluginutils": "^2.8.1"
+ }
+ },
+ "rollup-pluginutils": {
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
+ "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
+ "dev": true,
+ "requires": {
+ "estree-walker": "^0.6.1"
+ }
+ },
"rsvp": {
"version": "4.8.5",
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
diff --git a/BattleTech-A-Time-of-War/development/package.json b/BattleTech-A-Time-of-War/development/package.json
index 31eaaf2811..8211335f4e 100644
--- a/BattleTech-A-Time-of-War/development/package.json
+++ b/BattleTech-A-Time-of-War/development/package.json
@@ -2,10 +2,11 @@
"name": "battletech-a-time-of-war",
"version": "1.0.0",
"description": "Character sheet for Roll20 for the A Time of War TTRPG system.",
- "main": "index.js",
+ "main": "sheet-worker.js",
"type": "module",
"scripts": {
- "test": "jest --silent --coverage"
+ "test": "jest --silent --coverage",
+ "compile": "npx rollup src/sheet-worker.js --file output/sheet-worker.js --format cjs"
},
"author": "",
"license": "ISC",
@@ -14,7 +15,10 @@
"@babel/core": "^7.12.9",
"@babel/polyfill": "^7.12.1",
"@babel/preset-env": "^7.12.7",
+ "@rollup/plugin-babel": "^5.2.2",
+ "babelrc-rollup": "^3.0.0",
"eslint": "^7.15.0",
- "jest": "^26.6.3"
+ "jest": "^26.6.3",
+ "rollup": "^2.35.1"
}
}
diff --git a/BattleTech-A-Time-of-War/development/src/sheet-worker.js b/BattleTech-A-Time-of-War/development/src/sheet-worker.js
index 342ad7f119..d37ba416ce 100644
--- a/BattleTech-A-Time-of-War/development/src/sheet-worker.js
+++ b/BattleTech-A-Time-of-War/development/src/sheet-worker.js
@@ -1,14 +1,17 @@
import {
- STRENGTH_LINK,
- BODY_LINK,
- REFLEX_LINK,
- DEXTERITY_LINK,
- INTELLIGENCE_LINK,
- WILL_LINK,
- CHARISMA_LINK,
calculateAbilityScore,
linkedAttributeDisplayNames
-} from './domain/attribute'
+} from './attributes'
+import {
+ calculateSkillLevel,
+ getSkill,
+ getSkillDisplayName
+} from './skills'
+import {
+ skillsList,
+ tieredSkillsBasic,
+ tieredSkills
+} from './domain/skills/skills-list'
const sheetOpened = () => {
sheetMigration()
@@ -56,15 +59,6 @@ const skillXPChanged = ({
id,
newValue
}) => {
- const tieredSkills = [
- "art",
- "computers",
- "interest",
- "martial",
- "melee",
- "prestidigitation",
- ]
-
// When the sheet is opened, or data migrations are run, the skills are retrieved via ID, and thus must have their
// ID included in the attribute name when setting attributes.
const skillId = id !== undefined ? id + "_" : ""
@@ -114,628 +108,6 @@ on("change:repeating_skills:skill_xp", skillXPChanged)
// recalculate all skills when learning speed modifier changes
on("change:learning_speed", recalculateSkills)
-const calculateSkillLevel = (skillXP, learningSpeedModifier) => {
- skillXP = Number(skillXP)
- learningSpeedModifier = Number(learningSpeedModifier)
-
- if (skillXP < 30 + learningSpeedModifier * 3) {
- return 0
- }
-
- if (skillXP >= 570 + learningSpeedModifier * 57) {
- return 10
- }
-
- let currentSkillXP = skillXP - (20 + learningSpeedModifier * 2)
-
- for (let i = 1; i < 11; i++) {
- if (currentSkillXP < i * (10 + learningSpeedModifier)) {
- return i - 1
- }
-
- currentSkillXP -= i * (10 + learningSpeedModifier)
- }
-
- console.error("should never hit this line, this means the skill XP is not less than level 1, not greater than level 10, but also not within a level range.")
- return undefined
-}
-
-const getSkillDisplayName = (skill, skillDisplayNameKey, subSkill) => {
- if (skill.subSkills === true) {
- return skill.displayName[skillDisplayNameKey] + "/" + subSkill
- }
-
- if (typeof subSkill === "string" && subSkill != "") {
- return skill.displayName[skillDisplayNameKey] + " (" + subSkill + ")"
- }
-
- return skill.displayName[skillDisplayNameKey]
-}
-
-const skillsList = {
- "acrobatics": {
- "linkedAttributes": [REFLEX_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "acrobatics_free_fall": "Acrobatics/Free-Fall",
- "acrobatics_gymnastics": "Acrobatics/Gymnastics",
- },
- },
- "acting": {
- "linkedAttributes": [CHARISMA_LINK, ],
- "targetNumber": 8,
- "complexity": "CB",
- "subSkills": false,
- "displayName": {
- "acting": "Acting",
- },
- },
- "administration": {
- "linkedAttributes": [INTELLIGENCE_LINK, WILL_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "administration": "Administration",
- },
- },
- "animal": {
- "linkedAttributes": [WILL_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "animal_handling_herding": "Animal Handling/Herding",
- "animal_handling_riding": "Animal Handling/Riding",
- "animal_handling_training": "Animal Handling/Training",
- },
- },
- "appraisal": {
- "linkedAttributes": [INTELLIGENCE_LINK, ],
- "targetNumber": 8,
- "complexity": "CB",
- "subSkills": false,
- "displayName": {
- "appraisal": "Appraisal",
- },
- },
- "archery": {
- "linkedAttributes": [DEXTERITY_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "archery": "Archery",
- },
- },
- "artillery": {
- "linkedAttributes": [INTELLIGENCE_LINK, WILL_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "artillery": "Artillery",
- },
- },
- "career": {
- "linkedAttributes": [INTELLIGENCE_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": true,
- "displayName": {
- "career": "Career",
- },
- },
- "climbing": {
- "linkedAttributes": [DEXTERITY_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "climbing": "Climbing",
- },
- },
- "communications": {
- "linkedAttributes": [INTELLIGENCE_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "communications_black_box": "Communications/Black Box",
- "communications_conventional_em": "Communications/Conventional (EM)",
- "communications_hyperpulse_generator": "Communications/Hyperpulse Generator",
- },
- },
- "cryptography": {
- "linkedAttributes": [INTELLIGENCE_LINK, WILL_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "cryptography": "Cryptography",
- },
- },
- "demolitions": {
- "linkedAttributes": [DEXTERITY_LINK, INTELLIGENCE_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "demolitions": "Demolitions",
- },
- },
- "disguise": {
- "linkedAttributes": [CHARISMA_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "disguise": "Disguise",
- },
- },
- "driving": {
- "linkedAttributes": [REFLEX_LINK, DEXTERITY_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "driving_ground_vehicles": "Driving/Ground Vehicles",
- "driving_rail_vehicles": "Driving/Rail Vehicles",
- "driving_sea_vehicles": "Driving/Sea Vehicles",
- },
- },
- "escape": {
- "linkedAttributes": [STRENGTH_LINK, DEXTERITY_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "escape_artist": "Escape Artist",
- },
- },
- "forgery": {
- "linkedAttributes": [DEXTERITY_LINK, INTELLIGENCE_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "forgery": "Forgery",
- },
- },
- "gunnery": {
- "linkedAttributes": [REFLEX_LINK, DEXTERITY_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "gunnery_aerospace": "Gunnery/Aerospace",
- "gunnery_air_vehicle": "Gunnery/Air Vehicle",
- "gunnery_battlesuit": "Gunnery/Battlesuit",
- "gunnery_ground_vehicle": "Gunnery/Ground Vehicle",
- "gunnery_mech": "Gunnery/'Mech",
- "gunnery_protomech": "Gunnery/ProtoMech",
- "gunnery_sea_vehicle": "Gunnery/Sea Vehicle",
- "gunnery_spacecraft": "Gunnery/Spacecraft",
- "gunnery_turret": "Gunnery/Turret",
- },
- },
- "interrogation": {
- "linkedAttributes": [WILL_LINK, CHARISMA_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "interrogation": "Interrogation",
- },
- },
- "investigation": {
- "linkedAttributes": [INTELLIGENCE_LINK, WILL_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "investigation": "Investigation",
- },
- },
- "language": {
- "linkedAttributes": [INTELLIGENCE_LINK, CHARISMA_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": true,
- "displayName": {
- "language": "Language",
- },
- },
- "leadership": {
- "linkedAttributes": [WILL_LINK, CHARISMA_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "leadership": "Leadership",
- },
- },
- "medtech": {
- "linkedAttributes": [INTELLIGENCE_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "medtech_general": "MedTech/General",
- "medtech_veterinary": "MedTech/Veterinary",
- },
- },
- "navigation": {
- "linkedAttributes": [INTELLIGENCE_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "navigation_air": "Navigation/Air",
- "navigation_ground": "Navigation/Ground",
- "navigation_kf_jump": "Navigation/K-F Jump",
- "navigation_sea": "Navigation/Sea",
- "navigation_space": "Navigation/Space",
- },
- },
- "negotiation": {
- "linkedAttributes": [CHARISMA_LINK, ],
- "targetNumber": 8,
- "complexity": "CB",
- "subSkills": false,
- "displayName": {
- "negotiation": "Negotiation",
- },
- },
- "perception": {
- "linkedAttributes": [INTELLIGENCE_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "perception": "Perception",
- },
- },
- "piloting": {
- "linkedAttributes": [REFLEX_LINK, DEXTERITY_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "piloting_aerospace": "Piloting/Aerospace",
- "piloting_air_vehicle": "Piloting/Air Vehicle",
- "piloting_battlesuit": "Piloting/Battlesuit",
- "piloting_ground_vehicle": "Piloting/Ground Vehicle",
- "piloting_mech": "Piloting/'Mech",
- "piloting_protomech": "Piloting/ProtoMech",
- "piloting_rail_vehicle": "Piloting/Rail Vehicle",
- "piloting_sea_vehicle": "Piloting/Sea Vehicle",
- "piloting_spacecraft": "Piloting/Spacecraft",
- },
- },
- "protocol": {
- "linkedAttributes": [WILL_LINK, CHARISMA_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": true,
- "displayName": {
- "protocol": "Protocol",
- },
- },
- "running": {
- "linkedAttributes": [REFLEX_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "running": "Running",
- },
- },
- "science": {
- "linkedAttributes": [INTELLIGENCE_LINK, WILL_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": true,
- "displayName": {
- "science": "Science",
- },
- },
- "security": {
- "linkedAttributes": [DEXTERITY_LINK, INTELLIGENCE_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "security_systems_electronic": "Security Systems/Electronic",
- "security_systems_mechanical": "Security Systems/Mechanical",
- },
- },
- "sensor": {
- "linkedAttributes": [INTELLIGENCE_LINK, WILL_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "sensor_operations": "Sensor Operations",
- },
- },
- "small": {
- "linkedAttributes": [DEXTERITY_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "small_arms": "Small Arms",
- },
- },
- "stealth": {
- "linkedAttributes": [REFLEX_LINK, INTELLIGENCE_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "stealth": "Stealth",
- },
- },
- "strategy": {
- "linkedAttributes": [INTELLIGENCE_LINK, WILL_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "strategy": "Strategy",
- },
- },
- "streetwise": {
- "linkedAttributes": [CHARISMA_LINK, ],
- "targetNumber": 8,
- "complexity": "CB",
- "subSkills": true,
- "displayName": {
- "streetwise": "Streetwise",
- },
- },
- "support": {
- "linkedAttributes": [DEXTERITY_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "support_weapons": "Support Weapons",
- },
- },
- "surgery": {
- "linkedAttributes": [DEXTERITY_LINK, INTELLIGENCE_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "surgery_general": "Surgery/General",
- "surgery_veterinary": "Surgery/Veterinary",
- },
- },
- "survival": {
- "linkedAttributes": [BODY_LINK, INTELLIGENCE_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": true,
- "displayName": {
- "survival": "Survival",
- },
- },
- "swimming": {
- "linkedAttributes": [STRENGTH_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "swimming": "Swimming",
- },
- },
- "tactics": {
- "linkedAttributes": [INTELLIGENCE_LINK, WILL_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "tactics_air": "Tactics/Air",
- "tactics_infantry": "Tactics/Infantry",
- "tactics_land": "Tactics/Land",
- "tactics_sea": "Tactics/Sea",
- "tactics_space": "Tactics/Space",
- },
- },
- "technician": {
- "linkedAttributes": [DEXTERITY_LINK, INTELLIGENCE_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "technician_aeronautics": "Technician/Aeronautics",
- "technician_cybernetics": "Technician/Cybernetics",
- "technician_electronic": "Technician/Electronic",
- "technician_jets": "Technician/Jets",
- "technician_mechanical": "Technician/Mechanical",
- "technician_myomer": "Technician/Myomer",
- "technician_nuclear": "Technician/Nuclear",
- "technician_weapons": "Technician/Weapons",
- },
- },
- "thrown": {
- "linkedAttributes": [DEXTERITY_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "thrown_weapons_blades": "Thrown Weapons/Blades",
- "thrown_weapons_blunt_weapons": "Thrown Weapons/Blunt Weapons",
- },
- },
- "tracking": {
- "linkedAttributes": [INTELLIGENCE_LINK, WILL_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "tracking_urban": "Tracking/Urban",
- "tracking_wilds": "Tracking/Wilds",
- },
- },
- "training": {
- "linkedAttributes": [INTELLIGENCE_LINK, CHARISMA_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "training": "Training",
- },
- },
- "zero": {
- "linkedAttributes": [REFLEX_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "zero_g_operations": "Zero-G Operations",
- },
- },
-}
-
-const tieredSkillsBasic = {
- "art": {
- "linkedAttributes": [DEXTERITY_LINK, ],
- "targetNumber": 8,
- "complexity": "CB",
- "subSkills": true,
- "displayName": {
- "art": "Art",
- },
- },
- "computers": {
- "linkedAttributes": [INTELLIGENCE_LINK, ],
- "targetNumber": 8,
- "complexity": "CB",
- "subSkills": false,
- "displayName": {
- "computers": "Computers",
- },
- },
- "interest": {
- "linkedAttributes": [INTELLIGENCE_LINK, ],
- "targetNumber": 8,
- "complexity": "CB",
- "subSkills": true,
- "displayName": {
- "interest": "Interest",
- },
- },
- "martial": {
- "linkedAttributes": [REFLEX_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "martial_arts": "Martial Arts",
- },
- },
- "melee": {
- "linkedAttributes": [DEXTERITY_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "melee_weapons": "Melee Weapons",
- },
- },
- "prestidigitation": {
- "linkedAttributes": [DEXTERITY_LINK, ],
- "targetNumber": 7,
- "complexity": "SB",
- "subSkills": false,
- "displayName": {
- "prestidigitation_pick_pocket": "Prestidigitation/Pick Pocket",
- "prestidigitation_quickdraw": "Prestidigitation/Quickdraw",
- "prestidigitation_sleight_of_hand": "Prestidigitation/Sleight of Hand",
- },
- },
-}
-
-const tieredSkillsAdvanced = {
- "art": {
- "linkedAttributes": [DEXTERITY_LINK, INTELLIGENCE_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": true,
- "displayName": {
- "art": "Art",
- },
- },
- "computers": {
- "linkedAttributes": [DEXTERITY_LINK, INTELLIGENCE_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": false,
- "displayName": {
- "computers": "Computers",
- },
- },
- "interest": {
- "linkedAttributes": [INTELLIGENCE_LINK, WILL_LINK, ],
- "targetNumber": 9,
- "complexity": "CA",
- "subSkills": true,
- "displayName": {
- "interest": "Interest",
- },
- },
- "martial": {
- "linkedAttributes": [REFLEX_LINK, DEXTERITY_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "martial_arts": "Martial Arts",
- },
- },
- "melee": {
- "linkedAttributes": [REFLEX_LINK, DEXTERITY_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "melee_weapons": "Melee Weapons",
- },
- },
- "prestidigitation": {
- "linkedAttributes": [REFLEX_LINK, DEXTERITY_LINK, ],
- "targetNumber": 8,
- "complexity": "SA",
- "subSkills": false,
- "displayName": {
- "prestidigitation_pick_pocket": "Prestidigitation/Pick Pocket",
- "prestidigitation_quickdraw": "Prestidigitation/Quickdraw",
- "prestidigitation_sleight_of_hand": "Prestidigitation/Sleight of Hand",
- },
- },
-}
-
-const getSkill = (skillName, skillLevel, tieredSkill) => {
- skillName = String(skillName)
- skillLevel = Number(skillLevel)
-
- if (tieredSkill) {
- if (skillLevel <= 3) {
- return tieredSkillsBasic[skillName]
- } else {
- return tieredSkillsAdvanced[skillName]
- }
- } else {
- return skillsList[skillName]
- }
-}
-
const sheetMigration = () => {
console.log("Running sheet data migration")
@@ -918,9 +290,4 @@ const migrateFrom2To3 = () => {
})
})
})
-}
-
-// exports for testing
-// export {
-// calculateLinkedAttributeValue
-// }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/BattleTech-A-Time-of-War/development/src/skills.js b/BattleTech-A-Time-of-War/development/src/skills.js
index d36f914bae..876e19b393 100644
--- a/BattleTech-A-Time-of-War/development/src/skills.js
+++ b/BattleTech-A-Time-of-War/development/src/skills.js
@@ -8,76 +8,52 @@ import {
tieredSkillsAdvanced
} from './domain/skills/skills-list'
-// const recalculateSkills = () => {
-// getSectionIDs("skills", ids =>
-// ids.forEach(
-// id => getAttrs(["repeating_skills_" + id + "_skill_xp", ],
-// values =>
-// skillXPChanged({
-// newValue: values["repeating_skills_" + id + "_skill_xp"],
-// id,
-// })
-// )
-// )
-// )
-// }
+const skillXPChanged = ({
+ id,
+ newValue
+}) => {
+ // When the sheet is opened, or data migrations are run, the skills are retrieved via ID, and thus must have their
+ // ID included in the attribute name when setting attributes.
+ const skillId = id !== undefined ? id + "_" : ""
-// on("change:repeating_skills:skill change:repeating_skills:sub_skill", _ => {
-// getAttrs(["repeating_skills_skill_xp", ], ({
-// repeating_skills_skill_xp
-// }) => {
-// skillXPChanged({
-// newValue: repeating_skills_skill_xp,
-// })
-// })
-// })
+ const skill = "repeating_skills_" + skillId + "skill"
+ const skillLevel = "repeating_skills_" + skillId + "skill_level"
+ const subSkillAttrName = "repeating_skills_" + skillId + "sub_skill"
-// const skillXPChanged = ({
-// id,
-// newValue
-// }) => {
-// // When the sheet is opened, or data migrations are run, the skills are retrieved via ID, and thus must have their
-// // ID included in the attribute name when setting attributes.
-// const skillId = id !== undefined ? id + "_" : ""
+ getAttrs([skill, subSkillAttrName, "learning_speed", ], values => {
+ const skillName = values[skill]
+ const skillNameLookupKey = skillName.split("_")[0]
+ const subSkill = values[subSkillAttrName]
-// const skill = "repeating_skills_" + skillId + "skill"
-// const skillLevel = "repeating_skills_" + skillId + "skill_level"
-// const subSkillAttrName = "repeating_skills_" + skillId + "sub_skill"
+ let skillAttributesToSet = {}
-// getAttrs([skill, subSkillAttrName, "learning_speed", ], values => {
-// const skillName = values[skill]
-// const skillNameLookupKey = skillName.split("_")[0]
-// const subSkill = values[subSkillAttrName]
+ skillAttributesToSet[skillLevel] = calculateSkillLevel(Number(newValue), values.learning_speed)
-// let skillAttributesToSet = {}
+ const skillData = getSkill(
+ skillNameLookupKey,
+ skillAttributesToSet[skillLevel],
+ tieredSkills.includes(skillNameLookupKey)
+ )
-// skillAttributesToSet[skillLevel] = calculateSkillLevel(Number(newValue), values.learning_speed)
+ skillAttributesToSet["repeating_skills_" + skillId + "skill_tnc"] = skillData.targetNumber + "/" + skillData.complexity
+ skillAttributesToSet["repeating_skills_" + skillId + "target_number"] = skillData.targetNumber
-// const skillData = getSkill(
-// skillNameLookupKey,
-// skillAttributesToSet[skillLevel],
-// tieredSkills.includes(skillNameLookupKey)
-// )
+ getAttrs(skillData.linkedAttributes, values => {
+ skillAttributesToSet["repeating_skills_" + skillId + "skill_modifier"] = Object.values(values)
+ .reduce((total, num) => Number(total) + Number(num)) + Number(skillAttributesToSet[skillLevel])
-// skillAttributesToSet["repeating_skills_" + skillId + "skill_tnc"] = skillData.targetNumber + "/" + skillData.complexity
-// skillAttributesToSet["repeating_skills_" + skillId + "target_number"] = skillData.targetNumber
+ skillAttributesToSet["repeating_skills_" + skillId + "skill_linked_attributes"] = skillData.linkedAttributes
+ .map(linkAtr => linkedAttributeDisplayNames[linkAtr] + " (" + values[linkAtr] + ")")
+ .join(" + ")
-// getAttrs(skillData.linkedAttributes, values => {
-// skillAttributesToSet["repeating_skills_" + skillId + "skill_modifier"] = Object.values(values)
-// .reduce((total, num) => Number(total) + Number(num)) + Number(skillAttributesToSet[skillLevel])
+ skillAttributesToSet["repeating_skills_" + skillId + "skill_roll_value"] =
+ getSkillDisplayName(skillData, skillName, subSkill) + " Skill Check:\n" +
+ "Margin of Success: [[2d6 + @{skill_modifier}[MOD] - @{target_number}[TN]]]"
-// skillAttributesToSet["repeating_skills_" + skillId + "skill_linked_attributes"] = skillData.linkedAttributes
-// .map(linkAtr => linkedAttributeDisplayNames[linkAtr] + " (" + values[linkAtr] + ")")
-// .join(" + ")
-
-// skillAttributesToSet["repeating_skills_" + skillId + "skill_roll_value"] =
-// getSkillDisplayName(skillData, skillName, subSkill) + " Skill Check:\n" +
-// "Margin of Success: [[2d6 + @{skill_modifier}[MOD] - @{target_number}[TN]]]"
-
-// setAttrs(skillAttributesToSet, {}, () => {})
-// })
-// })
-// }
+ setAttrs(skillAttributesToSet, {}, () => {})
+ })
+ })
+}
export const calculateSkillLevel = (skillXP, learningSpeedModifier) => {
const learningSpeedPercentageModifier = 1 + 0.2 * learningSpeedModifier
diff --git a/BattleTech-A-Time-of-War/pre-commit-script/main.py b/BattleTech-A-Time-of-War/pre-commit-script/main.py
index b568ecd147..80564782cf 100644
--- a/BattleTech-A-Time-of-War/pre-commit-script/main.py
+++ b/BattleTech-A-Time-of-War/pre-commit-script/main.py
@@ -1,7 +1,10 @@
+import os
from typing import List
def main():
+ os.system("npm --prefix ../development/ run compile")
+
output: List[str] = []
with open('../BattleTech-A-Time-of-War.html', 'r') as character_sheet:
@@ -10,7 +13,7 @@ def main():
if line == '\n")