Skip to content

Commit 136a894

Browse files
authored
Merge branch 'Roll20:master' into master
2 parents 38b4a7a + 577a1a6 commit 136a894

File tree

22 files changed

+56730
-55
lines changed

22 files changed

+56730
-55
lines changed

AttackMaster/5.0.3/attackMaster.js

Lines changed: 8850 additions & 0 deletions
Large diffs are not rendered by default.

AttackMaster/attackMaster.js

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,16 @@ API_Meta.AttackMaster={offset:Number.MAX_SAFE_INTEGER,lineCount:-1};
109109
* parsing and enactment. Fix situational mod for save vs. dodgeable attack.
110110
* Fix changing ring table update.
111111
* v5.0.2 13/09/2025 Fixed assignment to a constant in buildRogueRoll().
112+
* v5.0.3 23/09/2025 Corrected Two Weapon Style Specialisation to not apply for ranged weapons. Added
113+
* --noWaitMsg command to suppress spurious Please Wait messages.
112114
*/
113115

114116
var attackMaster = (function() { // eslint-disable-line no-unused-vars
115117
'use strict';
116-
var version = '5.0.2',
118+
var version = '5.0.3',
117119
author = 'Richard @ Damery',
118120
pending = null;
119-
const lastUpdate = 1757793054;
121+
const lastUpdate = 1758783460;
120122

121123
/*
122124
* Define redirections for functions moved to the RPGMaster library
@@ -1107,7 +1109,7 @@ var attackMaster = (function() { // eslint-disable-line no-unused-vars
11071109
**/
11081110

11091111
var issueHandshakeQuery = function( api, cmd ) {
1110-
var handshake = '!'+api+' --hsq attk'+((cmd && cmd.length) ? ('|'+cmd) : '');
1112+
var handshake = '!'+api+' --noWaitMsg --hsq attk'+((cmd && cmd.length) ? ('|'+cmd) : '');
11111113
sendAPI(handshake);
11121114
if (_.isUndefined(apiCommands[api])) apiCommands[api] = {};
11131115
apiCommands[api].exists = false;
@@ -3003,17 +3005,17 @@ var attackMaster = (function() { // eslint-disable-line no-unused-vars
30033005
acValues.armour.magic = parseInt(acData.adj||0)!==0;
30043006
}
30053007
acValues = _.omit( acValues, function(item,iClass) {
3006-
let itemRules = item.data.rules.toLowerCase();
3008+
const itemRules = item.data.rules.toLowerCase().replace(/[_\s]/g, '').split('|').map(r => r.replace(/\-/g,(match,i,s)=>(i>0?'':match)));
30073009

3008-
if (itemClass === 'armour' && acValues.armour.magic && item.data.rules.includes('-magic')) {
3010+
if (itemClass === 'armour' && acValues.armour.magic && itemRules.includes('-magic')) {
30093011
armourMsg.push(item.name+' cannot be used alongside magical armour');
30103012
return true;
30113013
}
3012-
if (itemClass === 'armour' && (item.data.rules.includes('-'+itemSuperType) || (item.data.rules.includes('-acall') && !item.data.rules.includes('+'+itemSuperType)))) {
3014+
if (itemClass === 'armour' && (itemRules.includes('-'+itemSuperType) || (itemRules.includes('-acall') && !itemRules.includes('+'+itemSuperType)))) {
30133015
armourMsg.push(item.name+' cannot be used alongside '+acValues.armour.specs[4]);
30143016
return true;
30153017
}
3016-
if (item.data.rules.includes('-'+itemClass)) {
3018+
if (itemRules.includes('-'+itemClass)) {
30173019
armourMsg.push(item.name+' cannot be used alongside '+itemName);
30183020
return true;
30193021
}
@@ -3803,7 +3805,9 @@ var attackMaster = (function() { // eslint-disable-line no-unused-vars
38033805
magicDmgAdj = (parseInt(attrLookup( charCS, [fields.Magical_dmgAdj[0]+tokenID,fields.Magical_dmgAdj[1],undefined],null,null,null,null,false) || attrLookup( charCS, fields.Magical_dmgAdj )) || 0)
38043806
+ (parseInt(attrLookup( charCS, fields.Legacy_dmgAdj )) || 0),
38053807
primeWeapon = attrLookup( charCS, fields.Primary_weapon ) || 0,
3806-
twPen = Math.min(parseFloat(attrLookup( charCS, fields.TwoWeapStylePenalty ) || 9.9), classes.map(c => parseFloat(c.classData.twoWeapPen)).reduce((prev,cur) => (Math.min(prev,cur)))),
3808+
twPen = String(classes.map(c => parseFloat(c.classData.twoWeapPen)).reduce((prev,cur) => (Math.min(prev,cur)))), // Two Weapon Style Specialisation benefits do not apply to ranged weapons
3809+
// (Complete Fighters Handbook > Combat > Fighting Styles)
3810+
// twPen = String(Math.min(parseFloat(attrLookup( charCS, fields.TwoWeapStylePenalty ) || 9.9), classes.map(c => parseFloat(c.classData.twoWeapPen)).reduce((prev,cur) => (Math.min(prev,cur))))),
38073811
twoWeapPenalty = (ranger || primeWeapon < 1) ? 0 : (((rwIndex*2)+(fields.RW_table[1]==0?2:4)) == primeWeapon ? Math.floor(twPen) : Math.floor((10*twPen)%10)),
38083812
proficiency = dancing != 1 ? proficient( charCS, weaponName, rwType, rwSuperType ) : tableInfo.RANGED.tableLookup( fields.RW_dancingProf, rwIndex ),
38093813
race = raceMods( charCS, rwType, rwSuperType ),
@@ -8330,7 +8334,7 @@ var attackMaster = (function() { // eslint-disable-line no-unused-vars
83308334
var from = args[0] || '',
83318335
func = args[1] || '',
83328336
funcTrue = ['menu','other-menu','attk-hit','attk-roll','attk-target','weapon','dance','mod-weapon','quiet-modweap','ammo','setammo','checkac','save','help','check-db','debug'].includes(func.toLowerCase()),
8333-
cmd = '!'+from+' --hsr attk'+((func && func.length) ? ('|'+func+'|'+funcTrue) : '');
8337+
cmd = '!'+from+' --noWaitMsg --hsr attk'+((func && func.length) ? ('|'+func+'|'+funcTrue) : '');
83348338

83358339
sendAPI(cmd);
83368340
return;
@@ -8601,6 +8605,8 @@ var attackMaster = (function() { // eslint-disable-line no-unused-vars
86018605
// RED: v1.207 allow anyone to set debug and who to send debug messages to
86028606
doSetDebug(argString,senderId);
86038607
break;
8608+
case 'nowaitmsg':
8609+
break;
86048610
default:
86058611
showHelp();
86068612
sendFeedback('<span style="color: red;">Invalid command " <b>'+msg.content+'</b> "</span>',flags.feedbackName,flags.feedbackImg);
@@ -8648,7 +8654,7 @@ var attackMaster = (function() { // eslint-disable-line no-unused-vars
86488654
} else {
86498655
sendDebug('senderId is defined as ' + getObj('player',senderId).get('_displayname'));
86508656
};
8651-
if (!flags.noWaitMsg) sendWait(senderId,1,'attkMaster');
8657+
if (!flags.noWaitMsg && !args[0].toLowerCase().startsWith('nowaitmsg')) sendWait(senderId,1,'attkMaster');
86528658

86538659
_.each(args, function(e) {
86548660
setTimeout( doAttkCmd, (1*t++), e, selected, senderId, isGM );
@@ -8666,6 +8672,7 @@ var attackMaster = (function() { // eslint-disable-line no-unused-vars
86668672

86678673
var cmdMasterRegister = function() {
86688674
var cmd = fields.commandMaster
8675+
+ ' --noWaitMsg'
86698676
+ ' --register Attack_hit|Do an attack where Roll20 rolls the dice|attk|~~attk-hit|`{selected|token_id}'
86708677
+ ' --register Attack_roll|Do an attack where player rolls the dice|attk|~~attk-roll|`{selected|token_id}'
86718678
+ ' --register Attack_target|Do an attack with full target statistics (GM-only)|attk|~~attk-target|`{selected|token_id}'

AttackMaster/script.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"$schema": "https://github.com/DameryDad/roll20-api-scripts/blob/AttackMaster/AttackMaster/Script.json",
33
"name": "AttackMaster",
44
"script": "attackMaster.js",
5-
"version": "5.0.2",
6-
"previousversions": ["1.036","1.038","1.039","1.041","1.042","2.046","1.3.00","1.3.01","1.3.02","1.3.03","1.4.01","1.4.02","1.4.03","1.4.04","1.4.05","1.4.06","1.4.07","1.5.01","1.5.02","1.5.03","2.1.0","2.2.0","2.3.0","2.3.1","2.3.2","2.3.3","3.0.0","3.1.2","3.2.0","3.2.1","3.3.0","3.4.0","3.5.0","4.0.1","4.0.2","4.0.3","4.0.4","5.0.0","5.0.1"],
5+
"version": "5.0.3",
6+
"previousversions": ["1.036","1.038","1.039","1.041","1.042","2.046","1.3.00","1.3.01","1.3.02","1.3.03","1.4.01","1.4.02","1.4.03","1.4.04","1.4.05","1.4.06","1.4.07","1.5.01","1.5.02","1.5.03","2.1.0","2.2.0","2.3.0","2.3.1","2.3.2","2.3.3","3.0.0","3.1.2","3.2.0","3.2.1","3.3.0","3.4.0","3.5.0","4.0.1","4.0.2","4.0.3","4.0.4","5.0.0","5.0.1","5.0.2"],
77
"description": "AttackMaster API for AD&D 2E provides functions to manage weapons, armour & shields, including taking weapons in hand and using them to attack, ranged weapon range and ammo management; penalties & bonuses for non-proficiency, proficiency, specialisation & mastery; 1-handed, 2-handed or many-handed weapons, and multi-weapon attacks.\n[AttackMaster Documentation](https://wiki.roll20.net/Script:AttackMaster) \n\n### Related APIs\nThis API works best with the RPGMaster series of APIs\n[RPGMaster Documentation](https://wiki.roll20.net/RPGMaster) \n\n### Getting Started\n* After installation, add the commands `!attk --menu` and `!attk --other-menu` as Ability Macros on Character Sheets of Characters, NPCs & Monsters that will use the API, and tick 'Show as Token Action'. These menus will then be available to Players controlling those sheets and give access to all common commands used in game-play.",
88
"authors": "Richard E.",
99
"roll20userid": "6497708",

0 commit comments

Comments
 (0)