@@ -8396,7 +8492,7 @@
Help
- Character Sheet Version 1.1.05
+ Character Sheet Version 1.1.06
Diagnostics Attribute Lookup
@@ -9761,7 +9857,7 @@
});
});
- const buttonlist_sheettype = ["pc", "npc", "animal", "ship", "vehicle", "trade", "help"];
+ const buttonlist_sheettype = ["pc", "npc", "animal", "robot", "ship", "vehicle", "trade", "help"];
buttonlist_sheettype.forEach(button => {
on(`clicked:${button}`, function() {
setAttrs({
@@ -13101,6 +13197,57 @@
});
});
+ on("clicked:repeating_robotskills:robotskill", (info) => {
+
+ console.log("MgT2E: Robot skill: " + JSON.stringify(info))
+
+ const rowId = info.sourceAttribute.split('_')[2];
+ const skillName = "repeating_robotskills" + rowId + "_name";
+ const skillDM = "repeating_robotskills" + rowId + "_mod";
+
+ getAttrs([skillName, skillDM, "robot_name"], function(v) {
+ startRoll("@{whispertoggle}&{template:skill-attrib-alt} {{skill=" + v[skillName] + "}} {{character= " + v.robot_name + "}} @{ro_default_rolltype} + " + v[skillDM] + " ]]}} }}", (results) => {
+ finishRoll(results.rollId, {});
+ });
+ });
+ });
+
+ on("clicked:repeating_robotattacks:robotattack", (info) => {
+
+ console.log("MgT2E: Robot attack: " + JSON.stringify(info))
+
+ const rowId = info.sourceAttribute.split('_')[2];
+ const name = "repeating_robotattack" + rowId + "_name";
+ const attackMod = "repeating_robotattack" + rowId + "_attackmod";
+ const damage = "repeating_robotattack" + rowId + "_damage";
+
+ getAttrs([name, attackMod, damage, "robot_name"], function(v) {
+ console.log("- Attrs: " + JSON.stringify(v));
+
+ const wD = formatWeaponDamage(v[damage]);
+
+ startRoll("@{whispertoggle}&{template:combat-animal-alt} {{character=" + v.robot_name + "}} {{weapon=" + v[name] + "}} {{effect=[[0D6]]}} @{ro_default_rolltype_nodiff} + " + v[attackMod] + " @{ro_default_mod}]]}} {{damage=[[" + wD.weaponDamage + "]]}}", (results) => {
+ const toHit = results.results.roll.result;
+ var damage = results.results.damage.result;
+ //var effect = results.results.effect.result;
+ //if(toHit > 8 && !wD.isDestructive) {
+ // damage += (toHit - 8);
+ // effect = toHit - 8;
+ //}
+
+ finishRoll(
+ results.rollId,
+ {
+ roll: toHit,
+ damage: damage,
+ //effect: effect
+ }
+ );
+ });
+ });
+ });
+
+
on("clicked:vehicle-autopilot clicked:vehicle-navigation clicked:vehicle-sensors clicked:vehicle-camoflage clicked:vehicle-stealth", (info) => {
console.log("MgT2E: Vehicle skill roll: " + JSON.stringify(info))
@@ -14032,6 +14179,148 @@
setAttrs(attrs);
});
+ // Robot data
+ on('change:compendiumRobotData', function(info) {
+
+ console.log("MgT2E: compendiumRobotData: " + JSON.stringify(info));
+
+ // We may be coming in here from a blanking out of the compendium data
+ if(info.newValue === "__RESET__") {
+ console.log("Bailing from robot drop operation as this is a reset");
+ return;
+ }
+
+ // Grab the new value which is our stringified JSON
+ const compendiumData = JSON.parse(info.newValue);
+ console.log("MgT2E: compendiumRobotData: " + JSON.stringify(compendiumData, null, 4));
+
+ // Check the category
+ if(!checkCompendiumCategory(compendiumData, "Robots", "Robots")) {
+ return;
+ }
+
+ console.log("Robot attr setting");
+ let attrs = {compendiumRobotData: "__RESET__"};
+
+ /* Robot data takes the form:
+ {
+ "TL": "13",
+ "Cost": "Cr310000",
+ "Hits": "50",
+ "Name": "Angel of Mercy",
+ "Speed": "—",
+ "Skills": "Athletics (strength) 2, Medic 3, Melee 0, Recon 0, Science (biology) 2, Tactics (military) 1 ",
+ "Source": "custom",
+ "Traits": "Armour (+10, +10 vs. lasers), Flyer (high), Heightened Senses, Large (+2), IR/UV Vision, ",
+ "Attacks": "Static Axes x2 (4D+2, AP 8, Smasher)",
+ "Options": "Auditory Sensor (broad spectrum), Construction Equipment (small), Drone Interface, Environment Processor, Medical Chamber (50 Slots), Medikit (enhanced), Olfactory Sensor (advanced), PRIS Sensor, Reflec Armour, Storage Compartment (2 Slots refrigerated), Transceiver 500km (enhanced), Vacuum Environment Protection, Voder Speaker, Weapon Mounts (small) x2, Wireless Data Link ",
+ "Category": "Robots",
+ "Endurance": "36 (9) hours",
+ "Expansion": "38706",
+ "data-Name": "Angel of Mercy",
+ "Locomotion": "Grav",
+ "Programming": "Advanced (INT 9)",
+ "Manipulators": "2x (STR 12 DEX 8), 2x (STR 6 DEX 9)",
+ "data-description": "RH",
+ "blobs": {},
+ "expansion": 38706
+ }
+ */
+
+ attrs.robot_name = compendiumData["data-Name"];
+ attrs.character_name = compendiumData["data-Name"];
+ attrs.robot_hits = compendiumData["Hits"];
+ attrs.robot_speed = compendiumData["Speed"];
+ attrs.robot_manipulators = compendiumData["Manipulators"];
+ attrs.robot_endurance = compendiumData["Endurance"];
+ attrs.robot_programming = compendiumData["Programming"];
+ attrs.robot_options = compendiumData["Options"];
+ attrs.robot_locomotion = compendiumData["Locomotion"];
+
+ console.log("- Processing robot skills: " + compendiumData["Skills"]);
+
+ // Process skills (repeating)
+ removeRepeatingRows("repeating_robotskills");
+ // Bit hacky but sometimes we have 'Athletics (endurance)+2' so want to space out the mod for parsing
+ let skills = compendiumData["Skills"].replace(")+", ") +").replace(")-", ") -").split(",");
+ console.log("- Skills- " + skills);
+ skills.forEach((skill, index) => {
+ console.log("- Skill: " + skill);
+ let skillRec = skill.trim().split(" ");
+ let mod = skillRec.pop().replace("+", "");
+ let skillName = skillRec.join(" ");
+
+ let slotId = generateRowID();
+ attrs["repeating_robotskills_" + slotId + "_name"] = skillName;
+ attrs["repeating_robotskills_" + slotId + "_mod"] = mod;
+ });
+
+ // Process attacks (repeating)
+ removeRepeatingRows("repeating_robotattacks");
+
+ if(compendiumData["Attacks"] !== "None" && compendiumData["Attacks"] !== "-") {
+
+ // Need to tidy up the atack data as comes in the form: Laser Rifle (5D+3, Zero-G), Claws (1D+2 ) OR
+ // Crush (3D) or Claw (2D), Submachinegun (3D, Auto 3) etc.
+ // So we split on closing '),' then have to trim and reformat
+ let attacks = compendiumData["Attacks"].split("),");
+ console.log("- Attacks: " + attacks);
+
+ // Process attacks if set, may be set to empty space, dash or long dash e.g., - or —
+ if(attacks.length > 1) {
+ attacks.forEach((attack, index) => {
+
+ // Need to trim and format
+ attack = attack.trim().replaceAll(" )", ")");
+ console.log("- Attack: " + attack);
+
+ // So need to extract damage as first term after bracket
+ let damage = attack.replace(/.*\(/, "").replace(/,.*/, "");
+ // With a single term like Crush (3D) we need to remove last bracket
+ damage = damage.replace(")", "");
+
+ let attackRec = attack.trim().split(" ");
+ let attackName = attackRec.join(" ");
+ // Because we've split on ,) we need to add the bracket back in for any attacks that don't have it
+ if(!attackName.endsWith(")")) {
+ attackName += ")";
+ }
+
+ let slotId = generateRowID();
+ attrs["repeating_robotattacks_" + slotId + "_name"] = attackName;
+ if(damage.includes("DD")) {
+ attrs["repeating_robotattacks_" + slotId + "_damage"] = damage;
+ }
+ else {
+ attrs["repeating_robotattacks_" + slotId + "_damage"] = damage.replace("D", "D6");
+ }
+ });
+ }
+ }
+
+ // Process Traits (repeating)
+ removeRepeatingRows("repeating_robottraits");
+
+ let traits = compendiumData["Traits"].split(",");
+ traits.forEach((trait, index) => {
+ let traitRec = trait.trim();
+ let mod = "";
+ let traitArr = traitRec.split(" ");
+ if(traitRec.endsWith(")")) {
+ // Has a modifier
+ mod = traitArr.pop().replace(")", "").replace("(", "");
+ }
+ let traitName = traitArr.join(" ");
+
+ let slotId = generateRowID();
+ attrs["repeating_robottraits_" + slotId + "_robottraits-trait"] = traitName;
+ attrs["repeating_robottraits_" + slotId + "_robottraits-mod"] = mod;
+ });
+
+ // Finally set our attributes
+ setAttrs(attrs);
+ });
+
on("sheet:compendium-drop", (e) => {
console.log("compendium-drop: " + JSON.stringify(e));
@@ -14099,5 +14388,7 @@
}
});
});
+
+
\ No newline at end of file
diff --git a/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.png b/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.png
index 5793a085f4..44f7055457 100644
Binary files a/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.png and b/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.png differ
diff --git a/Mongoose Traveller 2e Official/README.md b/Mongoose Traveller 2e Official/README.md
index f41c1b229e..0939bc0910 100644
--- a/Mongoose Traveller 2e Official/README.md
+++ b/Mongoose Traveller 2e Official/README.md
@@ -108,6 +108,8 @@ This is the Official Mongoose Traveller 2nd Edition Character Sheet
- Updated translation key for personal Armour for translations
- Allow custom characteristics to be dragged to macro bar
+### Version 1.1.06
+- Added Robot tab to character sheet
