diff --git a/Shadowrun5th/Shadowrun5th.css b/Shadowrun5th/Shadowrun5th.css
index d82158691a..8501b2a56e 100644
--- a/Shadowrun5th/Shadowrun5th.css
+++ b/Shadowrun5th/Shadowrun5th.css
@@ -25,6 +25,7 @@ input[type=number]::-webkit-inner-spin-button {
.tabs {
display: flex;
+ flex-wrap: wrap;
justify-content: center;
align-content: stretch;
@@ -1814,8 +1815,22 @@ label.settings-checkbox {
text-align:center;
}
+.settings select,
+.settings input[type=number]
+{
+ vertical-align:top;
+ background-color:#444444;
+ color:inherit;
+ border:none;
+ box-shadow:none;
+ height:100%;
+ box-sizing:border-box;
+ margin:0px;
+ text-align:center;
+}
-.sheet-rolltemplate-reactdodge table,
+
+.sheet-rolltemplate-reactdefend table,
.sheet-rolltemplate-reactsoak table,
.sheet-rolltemplate-hitsToDrain table,
.sheet-rolltemplate-extendedRoll table,
@@ -1831,7 +1846,7 @@ label.settings-checkbox {
margin-right:5%;
}
-.sheet-rolltemplate-reactdodge img,
+.sheet-rolltemplate-reactdefend img,
.sheet-rolltemplate-reactsoak img,
.sheet-rolltemplate-hitsToDrain img,
.sheet-rolltemplate-extendedRoll img,
@@ -1843,7 +1858,7 @@ label.settings-checkbox {
height:3em;
}
-.sheet-rolltemplate-reactdodge table th,
+.sheet-rolltemplate-reactdefend table th,
.sheet-rolltemplate-reactsoak table th,
.sheet-rolltemplate-hitsToDrain table th,
.sheet-rolltemplate-extendedRoll table th,
@@ -1857,7 +1872,7 @@ label.settings-checkbox {
font-size:1em;
}
-.sheet-rolltemplate-reactdodge table .inlinerollresult,
+.sheet-rolltemplate-reactdefend table .inlinerollresult,
.sheet-rolltemplate-reactsoak table .inlinerollresult,
.sheet-rolltemplate-hitsToDrain table .inlinerollresult,
.sheet-rolltemplate-extendedRoll table .inlinerollresult,
@@ -1915,16 +1930,20 @@ label.settings-checkbox {
text-align:center;
}
+.sheet-rolltemplate-button-row {
+ display: flex;
+ margin-top: -3px;
+ justify-content: center;
+ align-content: center;
+}
.sheet-rolltemplate-button a[href^="~"]{
- width: 30%;
- margin-top: -10px;
- margin-left: 35%;
- margin-right: 35%;
text-align: center;
border-radius: 30px;
color: #eebb99;
background-color: black;
+ padding-left: 10px;
+ padding-right: 10px;
}
.sheet-rolltemplate-results-fail a[href^="~"],
diff --git a/Shadowrun5th/Shadowrun5th.html b/Shadowrun5th/Shadowrun5th.html
index 65e78a6857..20071be99d 100644
--- a/Shadowrun5th/Shadowrun5th.html
+++ b/Shadowrun5th/Shadowrun5th.html
@@ -13139,28 +13139,44 @@ Click again to switch to Manual and Remote">
-
Chummer Import
@@ -13388,7 +13404,10 @@ Click again to switch to Manual and Remote">
+
+
+
@@ -16909,16 +16928,121 @@ const rollDogableAttack = async (rollPart, dmgType) => {
);
}
-on('clicked:reactdodge', async (ev) => {
- await rollReactDodge(ev);
+on('clicked:reactdefend', async (ev) => {
+ await rollReactDefend(ev);
});
-const rollReactDodge = async (ev) => {
+const rollReactDefend = async (ev) => {
// The data we passed into the button will be stored in the originalRollId key
let attackRoll = rollEscape.unescape(ev.originalRollId);
let attrs = await asw.getAttrs(['gmroll','character_name','rea_total', 'int_total', 'avoid_total', 'avoid_bonus', 'edgeroll','edg_total','wound_total','sustainedspells','edgn','standardroll']);
- let rollBase = `${attrs.gmroll}&{template:reactdodge}{{nethits=[[0]]}}{{attackAp=[[0]]}}{{attackDamage=[[0]]}}{{attackDmgType=[[0]]}}{{passthrough=[[0]]}}{{name=${attrs.character_name}}}{{attacker_name=${attackRoll.attacker}}}{{rea=[[${attrs.rea_total}}]]}}{{int=[[${attrs.int_total}]]}}{{bonus=[[${attrs.avoid_bonus}]]}}{{mod=[[?{Situational Modifiers|0}]]}}{{edge=${attrs.edgeroll}}}{{edge_num=[[${attrs.edg_total}]]}}{{wounds_num=[[${attrs.wound_total}]]}}{{sustainedspells=[[${attrs.sustainedspells}*2]]}}{{result=[[(${attrs.avoid_total}+?{Situational Modifiers}-[[${attrs.wound_total}]]-[[${attrs.sustainedspells}*2]]+[[${attrs.edgn}*${attrs.edg_total}]])${attrs.standardroll}${attrs.edgeroll}]]}}`;
+ let rollBase = `${attrs.gmroll}&{template:reactdefend}{{defend=Defend}}{{nethits=[[0]]}}{{attackAp=[[0]]}}{{attackDamage=[[0]]}}{{attackDmgType=[[0]]}}{{passthrough=[[0]]}}{{name=${attrs.character_name}}}{{attacker_name=${attackRoll.attacker}}}{{rea=[[${attrs.rea_total}}]]}}{{int=[[${attrs.int_total}]]}}{{bonus=[[${attrs.avoid_bonus}]]}}{{mod=[[?{Situational Modifiers|0}]]}}{{edge=${attrs.edgeroll}}}{{edge_num=[[${attrs.edg_total}]]}}{{wounds_num=[[${attrs.wound_total}]]}}{{sustainedspells=[[${attrs.sustainedspells}*2]]}}{{result=[[(${attrs.avoid_total}+?{Situational Modifiers}-[[${attrs.wound_total}]]-[[${attrs.sustainedspells}*2]]+[[${attrs.edgn}*${attrs.edg_total}]])${attrs.standardroll}${attrs.edgeroll}]]}}`;
+ let defendRoll = await startRoll(rollBase);
+
+ let defendSuccesses = defendRoll.results.result.result;
+ let nethits = attackRoll.attackHits - defendSuccesses;
+ let attackDamage = attackRoll.attackDV + nethits;
+
+ let rollData = {
+ attackAp: attackRoll.attackAp,
+ attackDamage: attackDamage,
+ attackDmgType: attackRoll.attackDmgType,
+ }
+
+ finishRoll(defendRoll.rollId, {
+ nethits: nethits,
+ attackAp: attackRoll.attackAp,
+ attackDamage: attackDamage,
+ attackDmgType: attackRoll.attackDmgType,
+ passthrough: rollEscape.escape(rollData),
+ });
+}
+
+on('clicked:reactdodge', async (ev) => {
+ await rollReactDodge(ev);
+});
+const rollReactDodge = async (ev) => {
+ // The data we passed into the button will be stored in the originalRollId key
+ let attackRoll = rollEscape.unescape(ev.originalRollId);
+ let attrs = await asw.getAttrs(['gmroll','character_name','rea_total', 'int_total', 'avoid_total', 'avoid_bonus', 'edgeroll','edg_total','wound_total','sustainedspells','edgn','standardroll']);
+ let skill = await asw.getAttrs(['skillrating6', 'skillbonus6']);
+ let limit = await asw.getAttrs(['skilllimitbonus6', 'physical_total']);
+
+ let rollBase = `${attrs.gmroll}&{template:reactdefend}{{defend=Dodge}}{{nethits=[[0]]}}{{attackAp=[[0]]}}{{attackDamage=[[0]]}}{{attackDmgType=[[0]]}}{{passthrough=[[0]]}}{{name=${attrs.character_name}}}{{attacker_name=${attackRoll.attacker}}}{{rea=[[${attrs.rea_total}}]]}}{{int=[[${attrs.int_total}]]}}{{bonus=[[${attrs.avoid_bonus}]]}}{{skill=@{skillname6}}}{{skilldice=[[${skill.skillrating6}+${skill.skillbonus6}]]}}{{mod=[[?{Situational Modifiers|0}]]}}{{edge=${attrs.edgeroll}}}{{edge_num=[[${attrs.edg_total}]]}}{{limit=[[${limit.physical_total}+${limit.skilllimitbonus6}]]}}{{wounds_num=[[${attrs.wound_total}]]}}{{sustainedspells=[[${attrs.sustainedspells}*2]]}}{{result=[[(${attrs.avoid_total}+[[${skill.skillrating6}+${skill.skillbonus6}]]+?{Situational Modifiers}-[[${attrs.wound_total}]]-[[${attrs.sustainedspells}*2]]+[[${attrs.edgn}*${attrs.edg_total}]])${attrs.standardroll}${attrs.edgeroll}kh[[${limit.physical_total}+${limit.skilllimitbonus6}]] ]]}}{{description= -5 Initiative}}`;
+ console.log(rollBase);
+ let defendRoll = await startRoll(rollBase);
+
+ let defendSuccesses = defendRoll.results.result.result;
+ let nethits = attackRoll.attackHits - defendSuccesses;
+ let attackDamage = attackRoll.attackDV + nethits;
+
+ let rollData = {
+ attackAp: attackRoll.attackAp,
+ attackDamage: attackDamage,
+ attackDmgType: attackRoll.attackDmgType,
+ }
+
+ finishRoll(defendRoll.rollId, {
+ nethits: nethits,
+ attackAp: attackRoll.attackAp,
+ attackDamage: attackDamage,
+ attackDmgType: attackRoll.attackDmgType,
+ passthrough: rollEscape.escape(rollData),
+ });
+}
+
+on('clicked:reactparry', async (ev) => {
+ await rollReactParry(ev);
+});
+const rollReactParry = async (ev) => {
+ // The data we passed into the button will be stored in the originalRollId key
+ let attackRoll = rollEscape.unescape(ev.originalRollId);
+ let attrs = await asw.getAttrs(['gmroll','character_name','rea_total', 'int_total', 'avoid_total', 'avoid_bonus', 'edgeroll','edg_total','wound_total','sustainedspells','edgn','standardroll']);
+
+ let choosenSkill = await asw.getAttrs(['parrySkill']);
+ let skill = await asw.getAttrs(['skillname' + choosenSkill.parrySkill, 'skillrating' + choosenSkill.parrySkill, 'skillbonus' + choosenSkill.parrySkill]);
+ let limit = await asw.getAttrs(['parryAccuracy']);
+
+
+ let rollBase = `${attrs.gmroll}&{template:reactdefend}{{defend=Parry}}{{nethits=[[0]]}}{{attackAp=[[0]]}}{{attackDamage=[[0]]}}{{attackDmgType=[[0]]}}{{passthrough=[[0]]}}{{name=${attrs.character_name}}}{{attacker_name=${attackRoll.attacker}}}{{rea=[[${attrs.rea_total}}]]}}{{int=[[${attrs.int_total}]]}}{{bonus=[[${attrs.avoid_bonus}]]}}{{skill=${skill[Object.keys(skill)[0]]}}}{{skilldice=[[${skill[Object.keys(skill)[1]]}+${skill[Object.keys(skill)[2]]}]]}}{{mod=[[?{Situational Modifiers|0}]]}}{{edge=${attrs.edgeroll}}}{{edge_num=[[${attrs.edg_total}]]}}{{limit=[[${limit.parryAccuracy}]]}}{{wounds_num=[[${attrs.wound_total}]]}}{{sustainedspells=[[${attrs.sustainedspells}*2]]}}{{result=[[(${attrs.avoid_total}+[[${skill[Object.keys(skill)[1]]}+${skill[Object.keys(skill)[2]]}]]+?{Situational Modifiers}-[[${attrs.wound_total}]]-[[${attrs.sustainedspells}*2]]+[[${attrs.edgn}*${attrs.edg_total}]])${attrs.standardroll}${attrs.edgeroll}kh[[${limit.parryAccuracy}]] ]]}}{{description= -5 Initiative}}`;
+
+ if(limit.parryAccuracy == 0) {
+ rollBase += '{{configuration= Set Limit under Character -> Defense Settings}}'
+ }
+
+ let defendRoll = await startRoll(rollBase);
+
+ let defendSuccesses = defendRoll.results.result.result;
+ let nethits = attackRoll.attackHits - defendSuccesses;
+ let attackDamage = attackRoll.attackDV + nethits;
+
+ let rollData = {
+ attackAp: attackRoll.attackAp,
+ attackDamage: attackDamage,
+ attackDmgType: attackRoll.attackDmgType,
+ }
+
+ finishRoll(defendRoll.rollId, {
+ nethits: nethits,
+ attackAp: attackRoll.attackAp,
+ attackDamage: attackDamage,
+ attackDmgType: attackRoll.attackDmgType,
+ passthrough: rollEscape.escape(rollData),
+ });
+}
+
+on('clicked:reactblock', async (ev) => {
+ await rollReactBlock(ev);
+});
+const rollReactBlock = async (ev) => {
+ // The data we passed into the button will be stored in the originalRollId key
+ let attackRoll = rollEscape.unescape(ev.originalRollId);
+ let attrs = await asw.getAttrs(['gmroll','character_name','rea_total', 'int_total', 'avoid_total', 'avoid_bonus', 'edgeroll','edg_total','wound_total','sustainedspells','edgn','standardroll']);
+ let skill = await asw.getAttrs(['skillrating51', 'skillbonus51']);
+ let limit = await asw.getAttrs(['skilllimitbonus51', 'physical_total']);
+
+ let rollBase = `${attrs.gmroll}&{template:reactdefend}{{defend=Block}}{{nethits=[[0]]}}{{attackAp=[[0]]}}{{attackDamage=[[0]]}}{{attackDmgType=[[0]]}}{{passthrough=[[0]]}}{{name=${attrs.character_name}}}{{attacker_name=${attackRoll.attacker}}}{{rea=[[${attrs.rea_total}}]]}}{{int=[[${attrs.int_total}]]}}{{bonus=[[${attrs.avoid_bonus}]]}}{{skill=@{skillname51}}}{{skilldice=[[${skill.skillrating51}+${skill.skillbonus51}]]}}{{mod=[[?{Situational Modifiers|0}]]}}{{edge=${attrs.edgeroll}}}{{edge_num=[[${attrs.edg_total}]]}}{{limit=[[${limit.physical_total}+${limit.skilllimitbonus51}]]}}{{wounds_num=[[${attrs.wound_total}]]}}{{sustainedspells=[[${attrs.sustainedspells}*2]]}}{{result=[[(${attrs.avoid_total}+[[${skill.skillrating51}+${skill.skillbonus51}]]+?{Situational Modifiers}-[[${attrs.wound_total}]]-[[${attrs.sustainedspells}*2]]+[[${attrs.edgn}*${attrs.edg_total}]])${attrs.standardroll}${attrs.edgeroll}kh[[${limit.physical_total}+${limit.skilllimitbonus51}]] ]]}}{{description= -5 Initiative}}`;
let defendRoll = await startRoll(rollBase);
let defendSuccesses = defendRoll.results.result.result;
@@ -17946,9 +18070,21 @@ var TAS = TAS || (function(){
{{#rollGreater() result 0}}
{{#^rollTotal() computed::passthrough 0}}
-