From 74cd4d59637389dba9d144a29f3e7c60eaaead41 Mon Sep 17 00:00:00 2001 From: Darth-John <77751557+Darth-John@users.noreply.github.com> Date: Wed, 29 Dec 2021 15:36:24 -0800 Subject: [PATCH] BESM4eExtras v1.4.0 Added support for range penalties on weapons when Range Enhancement is applied (Extras rulebook). Added support for weapons with Ammo Limiter. Added support for weapons with Autofire Enhancement. New UI additions for players to interact with Range, Ammo, and Autofire. --- BESM4eExtras/BESM4eExtras.css | 18 +- BESM4eExtras/BESM4eExtras.html | 402 ++++++++++++++++++++++++++++----- 2 files changed, 368 insertions(+), 52 deletions(-) diff --git a/BESM4eExtras/BESM4eExtras.css b/BESM4eExtras/BESM4eExtras.css index 2473b94c20..72cc595b86 100644 --- a/BESM4eExtras/BESM4eExtras.css +++ b/BESM4eExtras/BESM4eExtras.css @@ -1,5 +1,5 @@ /* === VERSION === */ -/* 1.3.2 */ +/* 1.4.0 */ /* === GENERAL === */ .charsheet { @@ -1506,6 +1506,7 @@ input.sheet-theme[value="1"]:checked ~ div > div > div > div > div > div > div > input.sheet-theme[value="1"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="1"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="1"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], +input.sheet-theme[value="1"]:checked ~ div > div > div > div > div > div > div > div > div > h4 > span > div > div > button[type="action"], input.sheet-theme[value="1"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="1"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="1"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"] @@ -1556,6 +1557,7 @@ input.sheet-theme[value="2"]:checked ~ div > div > div > div > div > div > div > input.sheet-theme[value="2"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="2"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="2"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], +input.sheet-theme[value="2"]:checked ~ div > div > div > div > div > div > div > div > div > h4 > span > div > div > button[type="action"], input.sheet-theme[value="2"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="2"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="2"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"] @@ -1606,6 +1608,7 @@ input.sheet-theme[value="3"]:checked ~ div > div > div > div > div > div > div > input.sheet-theme[value="3"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="3"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="3"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], +input.sheet-theme[value="3"]:checked ~ div > div > div > div > div > div > div > div > div > h4 > span > div > div > button[type="action"], input.sheet-theme[value="3"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="3"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="3"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"] @@ -1656,6 +1659,7 @@ input.sheet-theme[value="4"]:checked ~ div > div > div > div > div > div > div > input.sheet-theme[value="4"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="4"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="4"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], +input.sheet-theme[value="4"]:checked ~ div > div > div > div > div > div > div > div > div > h4 > span > div > div > button[type="action"], input.sheet-theme[value="4"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="4"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="4"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"] @@ -1706,6 +1710,7 @@ input.sheet-theme[value="5"]:checked ~ div > div > div > div > div > div > div > input.sheet-theme[value="5"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="5"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="5"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], +input.sheet-theme[value="5"]:checked ~ div > div > div > div > div > div > div > div > div > h4 > span > div > div > button[type="action"], input.sheet-theme[value="5"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="5"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="5"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"] @@ -1756,6 +1761,7 @@ input.sheet-theme[value="6"]:checked ~ div > div > div > div > div > div > div > input.sheet-theme[value="6"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="6"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="6"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], +input.sheet-theme[value="6"]:checked ~ div > div > div > div > div > div > div > div > div > h4 > span > div > div > button[type="action"], input.sheet-theme[value="6"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="6"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="6"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"] @@ -1806,6 +1812,7 @@ input.sheet-theme[value="7"]:checked ~ div > div > div > div > div > div > div > input.sheet-theme[value="7"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="7"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="7"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], +input.sheet-theme[value="7"]:checked ~ div > div > div > div > div > div > div > div > div > h4 > span > div > div > button[type="action"], input.sheet-theme[value="7"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="7"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="7"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"] @@ -1856,6 +1863,7 @@ input.sheet-theme[value="8"]:checked ~ div > div > div > div > div > div > div > input.sheet-theme[value="8"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="8"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="8"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], +input.sheet-theme[value="8"]:checked ~ div > div > div > div > div > div > div > div > div > h4 > span > div > div > button[type="action"], input.sheet-theme[value="8"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="8"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="8"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"] @@ -1906,6 +1914,7 @@ input.sheet-theme[value="9"]:checked ~ div > div > div > div > div > div > div > input.sheet-theme[value="9"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="9"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > button[type="action"], input.sheet-theme[value="9"]:checked ~ div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], +input.sheet-theme[value="9"]:checked ~ div > div > div > div > div > div > div > div > div > h4 > span > div > div > button[type="action"], input.sheet-theme[value="9"]:checked ~ div > div > div > div > div > div > h4 > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="9"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"], input.sheet-theme[value="9"]:checked ~ div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > button[type="action"] @@ -2339,6 +2348,13 @@ div.sheet-flex-container-right { align-content: space-between; } +div.sheet-flex-container-wrap { + display: flex; + + flex-flow: row wrap; + align-content: space-around; +} + div.sheet-flex-grow { flex-grow: 1; } diff --git a/BESM4eExtras/BESM4eExtras.html b/BESM4eExtras/BESM4eExtras.html index 3a13a05da2..0ebcc98266 100644 --- a/BESM4eExtras/BESM4eExtras.html +++ b/BESM4eExtras/BESM4eExtras.html @@ -30,7 +30,7 @@

Sheet Options

Sheet Version - +

Sheet Type @@ -544,7 +544,7 @@
- @@ -708,6 +708,96 @@

Actions by Initiative

+
+ +
+
+
+
+
+
+

+ +
+
Range +
+
+ +
+
+ +
+
+
+
+
+

+
+
+
+
+
+
+ +
+ +
+
+
+
+ +
+
+

+   +

+
+
+
+
+

+ +
+
Reloads
+
Capacity
+
+
+
+

+
+
+
+
+ +
+
+

+   +

+
+
+
+
+

+    Autofire Mode    + + +

+
+
+
+
+
+
+
Weapon Selection
@@ -3158,14 +3248,28 @@

+ +
+ +
+
+
+

+ Capacity +

@@ -3177,7 +3281,7 @@

Charges - +

@@ -5188,7 +5292,7 @@
-
+
@@ -5811,28 +5915,34 @@ {{/duration}} {{#range}}
Range
-
{{distance}} {{kilometers}}m
+
{{range}}
{{/range}} {{#autofire}}
-
Autofire - Attack
-
Number of Hits
-
-
-
>1-3
-
1
-
-
-
>4-6
-
2
-
-
-
>7-9
-
3
-
-
-
>10-12
-
4
+
Autofire
+ {{#rollTotal() roll 2}} +
hits: {{hits2}}/{{rof}}
+ {{/rollTotal() roll 2}} {{#rollTotal() roll 3}} +
hits: {{hits3}}/{{rof}}
+ {{/rollTotal() roll 3}} {{#rollTotal() roll 4}} +
hits: {{hits4}}/{{rof}}
+ {{/rollTotal() roll 4}} {{#rollTotal() roll 5}} +
hits: {{hits5}}/{{rof}}
+ {{/rollTotal() roll 5}} {{#rollTotal() roll 6}} +
hits: {{hits6}}/{{rof}}
+ {{/rollTotal() roll 6}} {{#rollTotal() roll 7}} +
hits: {{hits7}}/{{rof}}
+ {{/rollTotal() roll 7}} {{#rollTotal() roll 8}} +
hits: {{hits8}}/{{rof}}
+ {{/rollTotal() roll 8}} {{#rollTotal() roll 9}} +
hits: {{hits9}}/{{rof}}
+ {{/rollTotal() roll 9}} {{#rollTotal() roll 10}} +
hits: {{hits10}}/{{rof}}
+ {{/rollTotal() roll 10}} {{#rollTotal() roll 11}} +
hits: {{hits11}}/{{rof}}
+ {{/rollTotal() roll 11}} {{#rollTotal() roll 12}} +
hits: {{hits12}}/{{rof}}
+ {{/rollTotal() roll 12}}
{{/autofire}} {{#blight}}
@@ -6329,7 +6439,7 @@ const combattechniques_array = ['blackout', 'blindfighting', 'blindshooting', 'criticalstrike', 'enhancedknockback', 'extendedrange', 'farshot', 'lethalblow', 'multipletargets', 'perciseaim', 'rushattack', 'twoweapons']; const stats_array = ['static_stat_type_set', 'static_stat_temp_energy', 'static_stat_temp_health', 'stat_total_social', 'static_stat_total_shame', 'stat_total_sanity', 'static_stat_total_maddness', 'stat_total_energy', 'static_stat_total_fatigue', 'stat_total_health', 'static_stat_total_wounds', 'stat_total_shock', 'static_character_points_spent', 'bodystate', 'mindstate', 'soulstate', 'static_stat_base_body', 'static_stat_base_mind', 'static_stat_base_soul', 'stat_total_body', 'stat_total_mind', 'stat_total_soul', 'stat_total_acv', 'stat_total_dcv', 'stat_total_str', 'stat_total_cre', 'stat_total_com', 'stat_total_awa', 'stat_total_dex', 'stat_total_agi', 'stat_total_con', 'stat_total_int', 'stat_total_per', 'stat_total_rea', 'stat_total_wil', 'stat_total_cha', 'strstate', 'agistate', 'dexstate', 'constate', 'intstate', 'reastate', 'perstate', 'crestate', 'wilstate', 'chastate', 'awastate', 'comstate']; const rolls_array = ['static_roll_type_selection','static_button_personal_defense','static_button_movement_defense']; - const combat_stats_array = ['mainhand_state', 'offhand_state', 'mainhand_source', 'offhand_source', 'extraarms', 'extraarms_inuse', 'attrdb', 'static_button_targeted_damage', 'static_button_targeted_attack', 'static_button_targeted_defense', 'massivedamage_targeted', 'massivedamage', 'enemyattack', 'enemydefense']; + const combat_stats_array = ['static_weapon_autofire_selection','weapon_ammo_capacity','weapon_ammo_reloads','static_weapon_range_selection','mainhand_state', 'offhand_state', 'mainhand_source', 'offhand_source', 'extraarms', 'extraarms_inuse', 'attrdb', 'static_button_targeted_damage', 'static_button_targeted_attack', 'static_button_targeted_defense', 'massivedamage_targeted', 'massivedamage', 'enemyattack', 'enemydefense']; const size_template_values_array = ['size', 'height', 'mass', 'size_lift', 'size_strdmg', 'size_ar', 'size_extradmg', 'size_rnghitdef', 'size_rngspd']; const all_attributes_array = ['absorption','alternate form','alternate identity','armor','attack mastery','augmented','capacity','change state','cognition','combat technique','companion','connected','control environment','conversion','data access','defect','defense mastery','dimension walk','dynamic powers','elasticity','enemy attack','enemy defense','energized','exorcism','extra actions','extra arms','extra defenses','features','flight','forcefield','gear','ground speed','healing','heightened awareness','heightened senses','illusion','immovable','immunity','immutable','inspire','jumping','massive damage','melee attack','melee defense','merge','metamorphosis','mimic','mind control','mind shield','minions','mulligan','nullify','plant control','pocket dimension','portal','power flux','power variation','projection','ranged attack','ranged defense','regeneration','reincarnation','resilient','sensory block','shield','sixth sense','size change','skill','social mastery','spaceflight','special movement','summon creatures','supersense','superspeed','superstrength','swarm','telekinesis','telepathy','teleport','tough','transfer','transmute','tunneling','unaffected','unassailable','undetectable','unique attribute','unknown power','water speed','wealth','weapon']; const all_attributes_regex = /(absorption|alternate form|alternate identity|armor|attack mastery|augmented|capacity|change state|cognition|combat technique|companion|connected|control environment|conversion|data access|defect|defense mastery|dimension walk|dynamic powers|elasticity|enemy attack|enemy defense|energized|exorcism|extra actions|extra arms|extra defenses|features|flight|forcefield|gear|ground speed|healing|heightened awareness|heightened senses|illusion|immovable|immunity|immutable|inspire|jumping|massive damage|melee attack|melee defense|merge|metamorphosis|mimic|mind control|mind shield|minions|mulligan|nullify|plant control|pocket dimension|portal|power flux|power variation|projection|ranged attack|ranged defense|regeneration|reincarnation|resilient|sensory block|shield|sixth sense|size change|skill|social mastery|spaceflight|special movement|summon creatures|supersense|superspeed|superstrength|swarm|telekinesis|telepathy|teleport|tough|transfer|transmute|tunneling|unaffected|unassailable|undetectable|unique attribute|unknown power|water speed|wealth|weapon)/i; @@ -6531,12 +6641,15 @@ const attrs = [ `activate`, `ammo`, + `ammostate`, `armorlayer`, `attrdefecttoggle`, `attribute`, `attrsrc`, `augmentedstat`, `bonus`, + `capacity`, + `capacitystate`, `capacitytype`, `characteristic`, `charges`, @@ -10645,8 +10758,169 @@ return /(bite|disarm|grab|lock|pin|throw)/i.test(maneuver); } + function setRange(debug, attrdb, customization, selection, setObj) { + const result = getRange(debug, attrdb, customization, selection); + setObj.weapon_range_distance = result; + if(debug) { + console.log(`[setRange()] result = ${result}`); + } + } + + function getRangeRollmod(debug, selection) { + const result = selection == 3 ? -2 : + selection == 2 ? -1 : + 0; + if(debug) console.log(`[getRangeRollmod()] result = ${result}`); + return result; + } + + function getRangeDistance(debug, selection) { + console.log(`[getRangeDistance()] selection = ${selection}`); + const selectobj = { + 1:0.2, + 2:0.5, + 3:1 + }; + const result = selectobj[selection] || 0; + if(debug) console.log(`[getRangeDistance()] result = ${result}`); + return result; + } + + function getRange(debug, attrdb, customization, selection) { + console.log(`[getRange()] selection = ${selection}`); + const extended = + getSumOfActiveSubAttrRanks(attrdb, 'combattechnique', 'extendedrange') || + 0; + const rangeobj = { + 1:3, + 2:10, + 3:100, + 4:1000, + 5:10000, + 6:100000 + }; + const distance = + `${Math.round(((rangeobj[customization.rank] || + 0) * (extended + 1)) * getRangeDistance(debug, selection))}` || + "0"; + const length = distance.length; + const range = length > 3 ? + `${parseInt(distance)/1000} km` : + `${distance} m`; + if(debug) console.log(`[getRange()] range = ${range}`); + return range; + } + + function getAmmoMax(debug, rank) { + const result = rank == 4 ? 0 : 6 / rank; + if(debug) console.log(`[getAmmoMax()] result = ${result}`); + return result; + } + + function setWeaponReload(debug, attrdb, value, setObj) { + const debugtext = '[setWeaponReload()]'; + const rowID = value.active_weapon; + const weapon = _.find(attrdb.weapon, w => { + if (w.source == rowID) return true; + }); + const customization = _.find(weapon.customizations, c => { + if (c.name == 'ammo') return true; + }); + const ammo = getAmmoMax(debug, customization.rank); + const capacity = parseInt(value[`repeating_attr_${rowID}_capacity`]); + let ammostate = parseInt(value.weapon_ammo_reloads); + let capacitystate = parseInt(value.weapon_ammo_capacity); + const reloadammo = ammo => ammo > 0 ? ammostate -= 1 : ammostate; + const reloadcapacity = ammo => ammo > 0 ? capacitystate = capacity : capacitystate; + setObj.weapon_ammo_reloads = reloadammo(ammostate); + setObj.weapon_ammo_capacity = reloadcapacity(ammostate); + } + + function setWeaponAmmo(debug, attrdb, value, handsource, setObj) { + const debugtext = '[setWeaponAmmo()]'; + const state = setObj[`${handsource}_state`]; + const rowID = value[`${handsource}_source`]; + if (state) {//weapon armed, load ammo state + const weapon = _.find(attrdb.weapon, w => { + if (w.source == rowID) return true; + }); + const customization = _.find(weapon.customizations, c => { + if (c.name == 'ammo') return true; + }); + const ammo = isNaN(parseInt(value[`repeating_attr_${rowID}_ammostate`])) ? + getAmmoMax(debug, customization.rank) : parseInt(value[`repeating_attr_${rowID}_ammostate`]); + const capacity = isNaN(parseInt(value[`repeating_attr_${rowID}_capacitystate`])) ? + parseInt(value[`repeating_attr_${rowID}_capacity`]) : + parseInt(value[`repeating_attr_${rowID}_capacitystate`]); + setObj.weapon_ammo_reloads = ammo; + setObj.weapon_ammo_capacity = capacity; + if(debug){ + console.log(`${debugtext} ammo = ${ammo}`); + console.log(`${debugtext} capacity = ${capacity}`); + } + } else {//weapon unarmed, save ammo state + const ammostate = parseInt(value.weapon_ammo_reloads); + const capacitystate = parseInt(value.weapon_ammo_capacity); + setObj[`repeating_attr_${rowID}_ammostate`] = ammostate; + setObj[`repeating_attr_${rowID}_capacitystate`] = capacitystate; + if(debug){ + console.log(`${debugtext} ammostate = ${ammostate}`); + console.log(`${debugtext} capacitystate = ${capacitystate}`); + } + } + } + + function setActiveWeaponUI(debug, attrdb, value, setObj) { + //set defaults + setObj.weapon_range = 0; + setObj.weapon_ammo_autofire = 0; + setObj.weapon_ammo = 0; + setObj.weapon_autofire = 0; + const weapon = setObj.active_weapon; + if (weapon == '') return; + const weapondb = attrdb.weapon.find(o => { + if (o.source == weapon) return true; + }); + const customizations = weapondb.customizations; + //set default overrides + _.each(weapondb.customizations, customization => { + switch(customization.name){ + case 'ammo': + setObj.weapon_ammo_autofire = 1; + setObj.weapon_ammo = 1; + /* + const ammostate = parseInt(value[`repeating_attr_${weapon}_ammostate`]); + const ammo = isNaN(ammostate) ? + getAmmoMax(debug, customization.rank) : + ammostate; + const capacitystate = parseInt(value[`repeating_attr_${weapon}_capacitystate`]); + const capacity = isNaN(capacitystate) ? + parseInt(value[`repeating_attr_${weapon}_capacity`]) : + capacitystate; + setObj.weapon_ammo_reloads = ammo; + setObj.weapon_ammo_capacity = capacity; + */ + break; + case 'autofire': + setObj.weapon_ammo_autofire = 1; + setObj.weapon_autofire = 1 + break; + case 'range': + const selection = customization.rank > 2 ? + parseInt(setObj.static_weapon_range_selection) || + parseInt(value.static_weapon_range_selection) || + 1 : + 1; + setObj.weapon_range = customization.rank > 0 ? 1 : 0; + setRange(debug, attrdb, customization, selection, setObj); + break; + } + }) + } + function setCombatRoll(debug, value, attrdb, rowID, sourceAttr, setObj, invertState = false) { - const activeweapon = setObj.active_weapon; + const debugtext = '[setCombatRoll()]'; + const activeweapon = setObj.active_weapon === undefined ? rowID : setObj.active_weapon; const weapon = _.find(attrdb.weapon, o => { if (o.source == activeweapon) return o; }) || _.find(attrdb.swarm, o => { if (o.source == activeweapon) return o; }); @@ -10691,7 +10965,7 @@ const absorption2 = parseInt(value.protection_absorption2_ar) || 0; const conversion = parseInt(value.protection_conversion_ar) || 0; let maneuver = - setObj.static_activity_maneuver_name || value.static_activity_maneuver_name; + setObj.static_weapon_maneuver_name || value.static_weapon_maneuver_name; maneuver = `${maneuver.replace(/\s+/g, '')}`; const acv = @@ -10732,15 +11006,24 @@ result = `${result} {{title=Attack}} {{attack=1}} {{target_name=@{target|charactername}}} {{acv=${acv}}} {{damage_type=${damagetype}}} {{damage2=${Math.round(damage * 0.25)}}} {{damage3=${Math.round(damage * 0.35)}}} {{damage4=${Math.round(damage * 0.45)}}} {{damage5=${Math.round(damage * 0.55)}}} {{damage6=${Math.round(damage * 0.65)}}} {{damage7=${Math.round(damage * 0.75)}}} {{damage8=${Math.round(damage * 0.9)}}} {{damage9=${Math.round(damage * 1.05)}}} {{damage10=${Math.round(damage * 1.2)}}} {{damage11=${Math.round(damage * 1.35)}}} {{damage12=${Math.round(damage * 1.5)}}}`; if (isWeapon > 0){ _.each(weapon.customizations, customization => { + console.log(`${debugtext} customization:`); console.log(customization); switch (customization.name) { - case 'ammo': - const ammunition = parseInt(value[`repeating_attr_${rowID}_ammo`]) || 0; - result = `${result} {{${customization.name}=${customization.rank}}} {{ammunition=${ammunition}}}`; - break; case 'area': const radius = get1or3(customization.rank, 3) * (10 ** (Math.ceil((customization.rank) / 2))); result = `${result} {{${customization.name}=${customization.rank}}} {{radius=${radius}}}`; break; + case 'autofire': + const firemode = parseInt(setObj[`static_weapon_autofire_selection`]) || + parseInt(value[`static_weapon_autofire_selection`]); + const numhits = firemode == 1 ? + `{{hits2=1}} {{hits3=1}} {{hits4=1}} {{hits5=1}} {{hits6=1}} {{hits7=1}} {{hits8=1}} {{hits9=1}} {{hits10=1}} {{hits11=1}} {{hits12=1}}` : + firemode == 3 ? + `{{hits2=1}} {{hits3=1}} {{hits4=1}} {{hits5=1}} {{hits6=2}} {{hits7=2}} {{hits8=2}} {{hits9=2}} {{hits10=3}} {{hits11=3}} {{hits12=3}}` : + firemode == 6 ? + `{{hits2=1}} {{hits3=1}} {{hits4=1}} {{hits5=2}} {{hits6=2}} {{hits7=2}} {{hits8=3}} {{hits9=3}} {{hits10=4}} {{hits11=5}} {{hits12=6}}` : + ''; + result = `${result} {{${customization.name}=${customization.rank}}} {{rof=${firemode}}} ${numhits}`; + break; case 'backblast': const bystander = customization.rank > 1 ? 'User and bystanders' : customization.rank > 0 ? 'Bystanders only' : ''; @@ -10837,18 +11120,15 @@ result = `${result} {{${customization.name}=${customization.rank}}} {{fissure=${fissure}}}`; break; case 'range': - const extended = getSumOfActiveSubAttrRanks(attrdb, 'combattechnique', 'extendedrange') || 0; - const distanceobj = { - 1:3, - 2:10, - 3:100, - 4:1, - 5:10, - 6:100 - }; - const distance = distanceobj[customization.rank] * (extended + 1) || "0"; - const kilometers = customization.rank > 3 ? 'k' : ''; - result = `${result} {{${customization.name}=${customization.rank}}} {{distance=${distance}}} {{kilometers=${kilometers}}}`; + const selection = customization.rank > 2 ? + parseInt(setObj.static_weapon_range_selection) || + parseInt(value.static_weapon_range_selection) || + 1 : + 1; + setRange(debug, attrdb, customization, selection, setObj); + const range = setObj.weapon_range_distance; + rollmod = rollmod + getRangeRollmod(debug, selection); + result = `${result} {{${customization.name}=${customization.rank}}} {{range=${range}}}`; break; case 'stoppable': const stopdamage = parseInt(value[`repeating_attr_${rowID}_level`]) * 10; @@ -10881,7 +11161,6 @@ customization.rank > 0 ? 'Restore' : ''; result = `${result} {{${customization.name}=${customization.rank}}} {{stolenhealth=${stolenhealth}}}`; break; - case 'autofire': case 'contact': case 'contagious': case 'fieldless': @@ -11016,6 +11295,10 @@ } function disableActiveWeapon(debug, value, rowID, setObj) { + setObj.weapon_range = 0; + setObj.weapon_ammo_autofire = 0; + setObj.weapon_ammo = 0; + setObj.weapon_autofire = 0; const state = parseInt(setObj[`repeating_attr_${rowID}_activate`]) || parseInt(value[`repeating_attr_${rowID}_activate`]); const activeweapon = value.active_weapon; @@ -11060,14 +11343,16 @@ } function getHandSource(debug, rowID){ - const result = /(mainhand|offhand)/i.test(rowID) ? + const handsource = /(mainhand|offhand)/i.test(rowID) ? rowID : `repeating_extraarm_${rowID}`; + const handscheck = handsource.indexOf(',') > 0 ? handsource.split(',') : handsource; + const result = _.isArray(handscheck) ? handscheck[0] : handscheck; if(debug) console.log(`[getHandSource()] result = ${result}`); return result; } function setWeaponStates(debug, extraarmIDs, value, rowID, setObj) { - const armedID = setObj[`${rowID}_source`] || + const armedID = setObj[`${rowID}_source`] || value[`${rowID}_source`] || ''; const handsArray = buildHandsArray(debug, extraarmIDs); const handsStateArray = _.map(handsArray, hand => { @@ -11323,7 +11608,9 @@ function registerEvents() { const eventsToRegister = [ - "static_activity_maneuver_name", + "static_weapon_autofire_selection", + "static_weapon_range_selection", + "static_weapon_maneuver_name", "static_stat_type_set", "static_roll_type_selection", "static_stat_temp_health", @@ -11381,6 +11668,7 @@ "repeating_skilltemplate:addskill", "repeating_extraarm:armedstate", "repeating_skill", + "static_button_ammo_reload", "static_button_targeted_damage", "static_button_targeted_attack", "static_button_targeted_defense", @@ -11495,7 +11783,7 @@ getAttrsString = getAttrsString.concat(rolls_array); getAttrsString = getAttrsString.concat([ `theme`, - `static_activity_maneuver_name`, + `static_weapon_maneuver_name`, `active_weapon`, `static_attrgroup_selected_tab`, `static_skillgroup_selected_tab` @@ -11576,9 +11864,12 @@ if (!getIsLocked(debug, value, rowID, sourceAttr)) return; if (!getFluxGroupIsActive(debug, value, rowID)) return; const isActive = setButtonState(debug, value, source, rowID, sourceAttr, setObj); + const handsource = getHandSource(debug, value[`repeating_attr_${rowID}_source`]); + const handstate = parseInt(value[`${handsource}_state`]); setAttrEffects(debug, isActive, value, attrdb, extraarmIDs, attrIDs, sectionName, rowID, sourceAttr, setObj); setPoolCostIfGroupIsFlux(debug, isActive, attrIDs, value, rowID, setObj); setPoolCostIfGroupIsVariation(debug, isActive, attrIDs, value, rowID, setObj); + if (handstate) setWeaponAmmo(debug, attrdb, value, handsource, setObj); disableActiveWeapon(debug, value, rowID, setObj); setGroupDefectPointsOnActivation(debug, attrIDs, attrdb, value, sectionName, rowID, setObj); break; @@ -11634,7 +11925,9 @@ case `armedstate`: const handsource = getHandSource(debug, rowID); setWeaponStates(debug, extraarmIDs, value, handsource, setObj); - setActiveWeapon(debug, value, handsource, setObj); + setActiveWeapon(debug, value, handsource, setObj); + setActiveWeaponUI(debug, attrdb, value, setObj); + setWeaponAmmo(debug, attrdb, value, handsource, setObj); setCombatRoll(debug, value, attrdb, value[`${source}_source`], sourceAttr, setObj); break; } @@ -11662,9 +11955,11 @@ return; } else if (sourceType==`static`) { switch (sectionName) { - case `activity`: + case `weapon`: switch (rowID) { + case `autofire`: case `maneuver`: + case `range`: setCombatRoll(debug, value, attrdb, value.active_weapon, sourceAttr, setObj); break; } @@ -11726,11 +12021,16 @@ setButtonState(debug, value, source, rowID, sourceAttr, setObj); setDynamicRollValue(debug, eventInfo, value, attrdb, rowID, sourceAttr, setObj); } + if (rowID == 'ammo') { + setWeaponReload(debug, attrdb, value, setObj); + } setStatButtonStatsAndRolls(debug, eventInfo, value, rowID, sourceAttr, setObj); switch (`${sourceAttr}`) { case `armedstate`: setWeaponStates(debug, extraarmIDs, value, rowID, setObj); setActiveWeapon(debug, value, rowID, setObj); + setActiveWeaponUI(debug, attrdb, value, setObj); + setWeaponAmmo(debug, attrdb, value, rowID, setObj); setCombatRoll(debug, value, attrdb, value[`${rowID}_source`], sourceAttr, setObj); break; }