Skip to content

Commit e692783

Browse files
committedJun 30, 2024
Update Earthdawn.js
Minor patch
1 parent d9e25aa commit e692783

File tree

1 file changed

+201
-91
lines changed
  • Earthdawn (FASA Official) character sheet companion/03.30

1 file changed

+201
-91
lines changed
 

‎Earthdawn (FASA Official) character sheet companion/03.30/Earthdawn.js

+201-91
Original file line numberDiff line numberDiff line change
@@ -1766,7 +1766,8 @@ Earthdawn.parseInt2 = function ( i, silent ) {
17661766
return x || 0;
17671767
*/
17681768
try {
1769-
if(( i === undefined ) || ( i === null ) || (i === "" )) return 0; // if it is an empty string, just quietly return a zero.
1769+
if(( i === undefined ) || ( i === null ) || (i === "" ) || (i === false)) return 0; // if it is an empty string, just quietly return a zero.
1770+
else if( i === true ) return 1;
17701771
let x = parseInt( i );
17711772
if( isNaN( x )) {
17721773
if( !silent )
@@ -1899,7 +1900,7 @@ Earthdawn.safeString = function( str ) {
18991900
// This checks for undefined, writes an error message, and substitutes a default value.
19001901
//
19011902
// Rats. Can't test for NaN here, because use same routine for string and numbers. But NaN fails as well.
1902-
Earthdawn.set = function( obj, type, val, dflt ) { // type is "current" or "max"
1903+
Earthdawn.set = function( obj, type, val, dflt ) { // type is often "current" or "max" for attributes, but could be name, bar3_value, bar3_max, or even status_xxx.
19031904
'use strict';
19041905
try {
19051906
// log( "set " + obj.get("name") + " val " + val);
@@ -3316,8 +3317,12 @@ Step/Action Dice Table
33163317
armortype;
33173318
ssa[ 1 ] = Earthdawn.safeString( ssa[ 1 ] ).toLowerCase();
33183319
switch ( ssa[ 1 ] ) {
3320+
case "sk": {
3321+
let cls = Earthdawn.getAttrBN( this.charID, pre + "Class", "General");
3322+
if( cls !== "General" )
3323+
this.misc[ "skillClass" ] = cls;
3324+
}
33193325
case "t":
3320-
case "sk":
33213326
case "skc":
33223327
case "nac": {
33233328
this.misc[ "result" ] = (this.misc[ "result" ] || 0) + this.getValue( pre + "Result-Mods");
@@ -3350,8 +3355,8 @@ Step/Action Dice Table
33503355
this.misc[ "Special" ] = special;
33513356
if( special.startsWith( "Recovery" )) {
33523357
this.bFlags |= Earthdawn.flags.Recovery;
3353-
if( special === "Recovery-Woodskin" )
3354-
this.misc[ "Recovery-Woodskin" ] = true;
3358+
if( special === "Recovery-WoodSkin" )
3359+
this.misc[ "Recovery-WoodSkin" ] = true;
33553360
if (Earthdawn.getAttrBN( this.charID, "NPC", "1") != Earthdawn.charType.mook) {
33563361
let aobj = Earthdawn.findOrMakeObj({ _type: 'attribute', _characterid: this.charID, name: "Recovery-Tests" }, 0, 2);
33573362
if( (aobj.get( "current" ) || 0) <= 0) {
@@ -3368,7 +3373,7 @@ Step/Action Dice Table
33683373

33693374
switch( special ) {
33703375
case "Recovery":
3371-
case "Recovery-Woodskin": this.misc[ "headcolor" ] = "recovery"; break;
3376+
case "Recovery-WoodSkin": this.misc[ "headcolor" ] = "recovery"; break;
33723377
case "Initiative": this.misc[ "headcolor" ] = "initrep"; break;
33733378
case "Knockdown": this.misc[ "headcolor" ] = "knockdown"; break;
33743379
default:
@@ -3911,7 +3916,7 @@ Step/Action Dice Table
39113916
// We have a request to display a menu in the chat window.
39123917
// attrib, damage, editspell2: (dur, MenuAddExtraThread, AddExtraThread, MenuRemoveExtraThread, RemoveExtraThread),
39133918
// fxSet: (sequnce of submenus), gmstate / gmspecial, grimoire, help, languages, link, linkAdd1, linkAdd2, linkRemove, linkRemoveHalf,
3914-
// oppmnvr, RolltypeEdit, skills, spells, stateEdit, status, talents.
3919+
// oppmnvr, RolltypeEdit, RolltypeMulti, skills, spells, stateEdit, status, talents.
39153920
this.ChatMenu = function( ssa ) {
39163921
'use strict';
39173922
let edParse = this;
@@ -4999,7 +5004,7 @@ Step/Action Dice Table
49995004
if( Array.isArray( v ) ) { // This is best practices for building Roll20 nested chat menu queries.
50005005
// The innermost query can be of the form ?{}. Inner queires must call Earthdawn.constant for pipe, comma, and braseClose.
50015006
str = "?{What do you want to do with array \'" + k + "\'|"
5002-
+ "Never mind, nothing|Delete|Add Elements, arrayAdd: "
5007+
+ "Delete|Add Elements, arrayAdd: "
50035008
+ "?{Add Where (F for first. L for last. or after a zero based index number)" + Earthdawn.constant( "braceClose", 2 ) + ": "
50045009
+ "?{Add What type of element"
50055010
+ Earthdawn.constant( "pipe", 2 ) + "Number" + Earthdawn.constant( "comma", 2 )
@@ -5013,7 +5018,7 @@ Step/Action Dice Table
50135018
+"|Set to Empty, change}";
50145019
tip = "This routine can not do anything with arrays yet except delete them, or set them to empty.";
50155020
} else {
5016-
str = "?{What do you want to do with object|Edit|Into object " + k + ",In|Delete|Never mind,nothing}";
5021+
str = "?{What do you want to do with object|Edit|Into object " + k + ",In|Delete}";
50175022
tip = "Make this object the current object, so that you can manipulate (edit or delete) its properties.";
50185023
}
50195024
break;
@@ -5121,6 +5126,47 @@ Step/Action Dice Table
51215126
log( ssa );
51225127
} } }
51235128
break; // end stateEdit
5129+
case "rolltypemulti": { // ssa[ 2 ] = state.Earthdawn.Rolltype.NPC, Others are ether exceptionIs or exceptionWouldBe entries.
5130+
//cdd
5131+
let except = ssa[ 2 ].endsWith( ".NPC" ) ? state.Earthdawn.Rolltype.NPC.Exceptions : state.Earthdawn.Rolltype.PC.Exceptions,
5132+
wkey, wname, dname,
5133+
s = "Do you want to: ";
5134+
for( let i = 3; i < ssa.length; ++i ) {
5135+
let tip;
5136+
switch( ssa[ i ].toLowerCase() ) {
5137+
case "skillexceptionis":
5138+
tip = "This display exception is setup by skill type: Knowledge or Artisan. Exceptions can also be setup by skill name.";
5139+
case "exceptionis":
5140+
if( tip === undefined ) tip = "This display exception is setup by skill name. They can also be setup by skill type: Knowledge or Artisan.";
5141+
wname = ssa[ ++i ];
5142+
if( wname in except ) {
5143+
dname = except[ wname ][ "name" ];
5144+
s += "Edit display exception for "
5145+
+ Earthdawn.makeButton( dname, "!Earthdawn~ ChatMenu: RolltypeEdit: " + ssa[ 2 ] + ": " + wname
5146+
+ ": ?{Edit display exception for '" + dname + "'|Change to Public, exceptionEdit: Public|Change to GM Only, exceptionEdit: GM Only"
5147+
+ "| Change to Player and GM, exceptionEdit: Player and GM|Delete exception, exceptionDelete}"
5148+
, tip, Earthdawn.Colors.action, Earthdawn.Colors.actionfg ) + ".";
5149+
} else
5150+
this.chat( "Earthdawn rolltypeMulti data mismatch Error. " + wname + " not found.", Earthdawn.whoFrom.apiWarning );
5151+
break;
5152+
case "skillexceptionwouldbe":
5153+
case "exceptionwouldbe":
5154+
tip = "You can setup rolltype exceptions for Knowledge and Artisan skills ether by name or type.";
5155+
wname = ssa[ ++i ];
5156+
s += "Create a display exception for "
5157+
+ Earthdawn.makeButton( wname, "!Earthdawn~ ChatMenu: RolltypeEdit: " + ssa[ 2 ] + ": " + wname
5158+
+ ": ?{Create a display exception for '" + wname
5159+
+ "'|Public, exceptionAdd: Public|GM Only, exceptionAdd: GM Only|Player and GM, exceptionAdd: Player and GM}"
5160+
, tip, Earthdawn.Colors.action, Earthdawn.Colors.actionfg ) + ".";
5161+
break;
5162+
default:
5163+
this.chat( "Earthdawn rolltypeMulti Error. Unknown command " + ssa[ i ], Earthdawn.whoFrom.apiWarning );
5164+
log( ssa );
5165+
} }
5166+
this.chat( s.trim(), Earthdawn.whoTo.player | Earthdawn.whoFrom.api | Earthdawn.whoFrom.noArchive, "gmStateEdit" );
5167+
5168+
// cdd
5169+
} break; // end RolltypeMulti
51245170
case "status": { // Called from a macro Token action. Visible when any character is selected.
51255171
let basic = true;
51265172

@@ -5675,8 +5721,8 @@ Step/Action Dice Table
56755721
currDmg += dmg;
56765722
if( bRecovery ) {
56775723
if( currDmg < 0 ) { // If all damage has been healed, we have to know whether this is a wood skin test or not, since those are handled differently.
5678-
if( "Recovery-Woodskin" in this.misc )
5679-
recMsg += " Wood Skin added " + (dmg * -1) + Earthdawn.addIcon( "damage", "l" ) + " Health. New damage value " + currDmg + ".";
5724+
if( "Recovery-WoodSkin" in this.misc )
5725+
recMsg += " Wood Skin added " + (dmg * -1) + Earthdawn.addIcon( "damagehealth", "l" ) + " Health. New damage value " + currDmg + ".";
56805726
else { // We know this is NOT woodskin and we have negative damage, have the leftover heal stun damage.
56815727
recMsg += " recovered " + ((dmg - currDmg) * -1) + Earthdawn.addIcon( "damage", "l" ) + " damage. New value 0.";
56825728
bStun = true;
@@ -5734,6 +5780,7 @@ Step/Action Dice Table
57345780
}
57355781
newMsg += ".<br>Takes wound " + currWound;
57365782
} // end wound
5783+
// cdd todo. If stun would have caused a wound, set harried until end of round.
57375784

57385785
if( currDmg >= Earthdawn.getAttrBN( this.charID, "Damage-Death-Rating", 25 )) {
57395786
newMsg += ".<br>Character is DEAD";
@@ -5748,8 +5795,10 @@ Step/Action Dice Table
57485795
newMsg += ". Need to make a Knockdown Test";
57495796
gmMsg += " TN " + ( dmg - WoundThreshold ) + "<br>" +
57505797
Earthdawn.makeButton( "Knockdown",
5751-
"!Earthdawn~ CharID:" + this.charID + "~ TargetNum: " + ( dmg - WoundThreshold )
5752-
+ ": Adjust-TN-Auto: Adjust-TN-Misc~ foreach~ modValue: ?{Modification|0} ~ K-ask: @{" + cname + "|KarmaGlobalMode}@{"
5798+
"!Earthdawn~ " + (( this.tokenInfo !== undefined && this.tokenInfo.tokenObj !== undefined)
5799+
? "setToken: " + this.tokenInfo.tokenObj.get( "id" ) : "charID: " + this.charID )
5800+
+ "~ TargetNum: " + ( dmg - WoundThreshold )
5801+
+ ": Adjust-TN-Auto: Adjust-TN-Misc~ modValue: ?{Modification|0} ~ K-ask: @{" + cname + "|KarmaGlobalMode}@{"
57535802
+ cname + "|Str-Karma-Ask}: @{" + getAttrByName( this.charID, "character_name") + "|DPGlobalMode}@{"
57545803
+ cname + "|Str-DP-Ask}~ Value: Knockdown: Adjust-All-Tests-Total: Defensive: Resistance~ Roll"
57555804
,"Make a standard Knockdown test.", Earthdawn.Colors.action, Earthdawn.Colors.actionfg );
@@ -5763,16 +5812,18 @@ Step/Action Dice Table
57635812
rid = Earthdawn.repeatSection( 2, att.get( "name") );
57645813
//log( "Talent Found " + pre + " " + name + " " + code +" " + rid + " " + cname);
57655814
gmMsg += Earthdawn.makeButton( name + " test",
5766-
"!Earthdawn~ CharID:" + po.charID + "~ TargetNum: " + ( dmg - WoundThreshold )
5767-
+ ": Adjust-TN-Auto: Adjust-TN-Misc~ foreach:sct:ust:c~ modValue: ?{Modification|0} ~ K-ask: @{" + cname + "|KarmaGlobalMode}@{"
5815+
"!Earthdawn~ " + (( po.tokenInfo !== undefined && po.tokenInfo.tokenObj !== undefined)
5816+
? "setToken: " + po.tokenInfo.tokenObj.get( "id" ) : "charID: " + po.charID )
5817+
+ "~ TargetNum: " + ( dmg - WoundThreshold )
5818+
+ ": Adjust-TN-Auto: Adjust-TN-Misc~ modValue: ?{Modification|0} ~ K-ask: @{" + cname + "|KarmaGlobalMode}@{"
57685819
+ cname + "|" + pre + "Karma-Ask}: @{" + cname + "|DPGlobalMode}@{"
57695820
+ cname + "|" + pre + "DP-Ask}~ Action: "+ code +":" + rid
57705821
,"Make a Knockdown test.", Earthdawn.Colors.action, Earthdawn.Colors.actionfg );
57715822
}
57725823
}); // End for each attribute.
57735824
} }
5774-
5775-
if(gmMsg && npc == Earthdawn.charType.pc){ //gm message is sent separately to GM for NPCs and appended for PCs
5825+
5826+
if(gmMsg && npc == Earthdawn.charType.pc) { //gm message is sent separately to GM for NPCs and appended for PCs
57765827
newMsg += gmMsg;
57775828
gmMsg = "";
57785829
}
@@ -6243,9 +6294,39 @@ log( cnt);
62436294

62446295

62456296

6297+
// ParseObj.findAllPagesAnyPlayterIsOn()
6298+
//
6299+
// Returns an array of pageIDs.
6300+
// if testOnline is false then list is of all pages, whether players are online or not. Otherwise it is only online players. Defaults to true.
6301+
this.findAllPagesAnyPlayterIsOn = function( testOnline ) {
6302+
'use strict';
6303+
try {
6304+
if( testOnline === undefined || testOnline ) testOnline = true; // testOnline defaults to true. Set to native boolean so don't have to convert each loop.
6305+
else testOnline = false;
6306+
let pgs = Campaign().get( "playerspecificpages" ), // object of pages that have players on them.
6307+
players = findObjs({ _type: "player", _online: true }), // array of online players.
6308+
ret = [ Campaign().get( "playerpageid" ) ]; // the all players page.
6309+
if( pgs )
6310+
Object.entries( pgs ).forEach(([key, val]) => {
6311+
if(( testOnline || ( key in players )) && ( !( key in ret))) // If page is not already in ret, and page is an online player, add it to the list.
6312+
ret.push( val );
6313+
});
6314+
players.forEach( function( item ) {
6315+
'use strict';
6316+
if( playerIsGM( item.get( "_id" )) && !ret.includes( item.get( "_lastpage" ))) // if player is gm and last page they visited is not already in ret, add it.
6317+
ret.push( item.get( "_lastpage" ));
6318+
});
6319+
return ret;
6320+
} catch(err) { Earthdawn.errorLog( "ED.findAllPagesAnyPlayterIsOn() error caught: " + err, this ); }
6321+
}; // End ParseObj.findAllPagesAnyPlayterIsOn
6322+
6323+
6324+
62466325
// ParseObj.FindPageOfPlayer()
62476326
//
62486327
// Returns pageID of page this player is on.
6328+
//
6329+
// Note that Jun 2024 I think the only routine that called this now calls findAllPagesAnyPlayerIsOn instead. So routine might be useless.
62496330
this.FindPageOfPlayer = function( playerID ) {
62506331
'use strict';
62516332
try {
@@ -6256,7 +6337,7 @@ log( cnt);
62566337
else // player is on the all players page.
62576338
ret = Campaign().get( "playerpageid" );
62586339
return ret;
6259-
} catch(err) { Earthdawn.errorLog( "ED.FindPageOfPlayer() error caught: " + err, playerID ); }
6340+
} catch(err) { Earthdawn.errorLog( "ED.FindPageOfPlayer() error caught: " + err, this ); }
62606341
}; // End ParseObj.FindPageOfPlayer
62616342

62626343

@@ -6269,18 +6350,18 @@ log( cnt);
62696350
let edParse = this;
62706351
try {
62716352
this.tokenIDs = [];
6272-
let bst = false, // Do we want all selected tokens?
6353+
let bst = false, // Do we want all selected tokens?
62736354
bsct = false, // Do we want all selected character tokens?
62746355
bust = false, // Do we want to look in unselected tokens if we can't find with the above?
62756356
binmt = false, // Do we want to ignore all selected tokens that do not match the character ID?
6276-
btuc = false, // Token Unique Character - Ignore all except the first token for each unique character.
6357+
btuc = false, // Token Unique Character - Ignore all except the first token for each unique character.
62776358
bc = false, // Do we want character (if found nothing else)?
6278-
flag = 0, // Instead of doing a ForEachToken loop: 1 - return a list of tokens.
6359+
flag = 0, // Instead of doing a ForEachToken loop: 1 - return a list of tokens.
62796360
mooks = false, // Do we want to ignore all selected non-mooks?
62806361
notMooks = false, // Do we want to ignore all selected mooks?
62816362
PCs = false, // Do we want to ignore all selected NPCs?
62826363
NPCs = false, // Do we want to ignore all selected PCs?
6283-
notPCs = false, // Do we want to ignore all selected non-PCs?
6364+
notPCs = false, // Do we want to ignore all selected non-PCs?
62846365
objarr = [];
62856366

62866367
for ( let i = 1; i < ssa.length; i++) {
@@ -6381,9 +6462,12 @@ log( cnt);
63816462
if( bust && ((objarr.length || 0) < 1 )) {
63826463
let CharObj = getObj("character", this.charID);
63836464
if ((typeof CharObj != 'undefined') && ( this.edClass.msg !== undefined )) {
6384-
let page = this.FindPageOfPlayer( this.edClass.msg.playerid );
6385-
let tkns = findObjs({ _pageid: page, _type: "graphic", _subtype: "token", represents: this.charID });
6386-
_.each( tkns, function (TokObj) { // Check all tokens on the page.
6465+
let pages = this.findAllPagesAnyPlayterIsOn(),
6466+
tkns = [];
6467+
pages.forEach(( page ) => {
6468+
tkns = _.union( tkns, findObjs({ _pageid: page, _type: "graphic", _subtype: "token", represents: this.charID }));
6469+
});
6470+
_.each( tkns, function( TokObj ) { // Check all tokens found
63876471
if( btuc && objarr.length > 0 )
63886472
return;
63896473
let TokenName = TokObj.get("name");
@@ -6422,7 +6506,7 @@ log( cnt);
64226506
edParse.tokenInfo = edpS1;
64236507
edParse.charID = edpS2;
64246508
return ret;
6425-
} else {
6509+
} else { // This is the more normal case. Call all the rest of the command line, with each token found.
64266510
let miscsave = _.clone( edParse.misc ); // Otherwise this gets passed by reference and all copies end up sharing the same object. So save a clone, and explicitly clone the clone back in.
64276511
this.indexToken = 0;
64286512
_.each( objarr, function ( obj ) {
@@ -7461,8 +7545,6 @@ Get these in pairs, char sheet attrib and token status, get them ORed, then figu
74617545
++fnd;
74627546
let itm = itma[ 1 ].replace( "\[", "").replace( "\]", "" ); // remove brackets from code.
74637547
if( itm !== "0^u" ) { // Unset with value 0 is already in array.
7464-
7465-
74667548
let kernals = itm.split( "^" ),
74677549
kb = kernals[ 1 ],
74687550
kb2 = kb;
@@ -7480,7 +7562,7 @@ Get these in pairs, char sheet attrib and token status, get them ORed, then figu
74807562
valid[ 0 ].attrib = kernals[ 0 ]; //If we are in this loop, i.e. there is a submenu, but it is not "0^u", we should update the default unset attrib
74817563
else
74827564
valid.push({ level: Earthdawn.parseInt2( kernals[ 0 ]), attrib: Earthdawn.parseInt2( kernals[ 0 ]), badge: kb2, marker: mark });
7483-
// log("test " + JSON.stringify(valid));
7565+
// log("test " + JSON.stringify(valid));
74847566
} } } }
74857567
if( !fnd ) { // A classic submenu was not found, so we seem to have a freeform numeric input.
74867568
valid.push({ level: 0, attrib: 0, badge: true, marker: mark });
@@ -7508,7 +7590,7 @@ Get these in pairs, char sheet attrib and token status, get them ORed, then figu
75087590
this.chat( "Earthdawn: Markerset Warning. Unable to parse " + JSON.stringify( mia[ i ] ), Earthdawn.whoFrom.apiWarning );
75097591
} // end make list of validValues and validBadges
75107592
valid = _.sortBy( valid, "level" );
7511-
//log( marker); log(mi); log( JSON.stringify( valid));
7593+
//log(mi); log( JSON.stringify( valid));
75127594

75137595
if( ssa.length > 1 ) { // This section sets level and adjust. See the declarations above and the comments at the top of the routine.
75147596
if( ssa.length > 2 ) {
@@ -7555,7 +7637,7 @@ Get these in pairs, char sheet attrib and token status, get them ORed, then figu
75557637
if( level > 0 && neg )
75567638
level *= -1;
75577639
// at this point level is -1111 for unset, 0 for set, or a badge between 1 and 9. Adjust might be set, which will modify these these.
7558-
7640+
//log("level " + level);
75597641

75607642
// Given a potential level value, see if it is one of the expected values. If so return that valid item.
75617643
// If not, find the closest one.
@@ -7623,7 +7705,6 @@ Get these in pairs, char sheet attrib and token status, get them ORed, then figu
76237705
else
76247706
setObj = findMenu( level );
76257707
}
7626-
//log( setObj);
76277708
if( !setObj ) {
76287709
this.chat( "Earthdawn: Markerset error. level is undefined.", Earthdawn.whoFrom.apiWarning );
76297710
return;
@@ -7633,13 +7714,15 @@ Get these in pairs, char sheet attrib and token status, get them ORed, then figu
76337714
//log( "level: " + level + " setObj: " + JSON.stringify( setObj ));
76347715
if( "marker" in setObj )
76357716
Earthdawn.set( this.tokenInfo.tokenObj, "status_" + setObj[ "marker" ], setObj.badge );
7717+
//log( "have set 'status_" + setObj[ "marker" ] + "' to " + setObj.badge );
76367718

76377719
// If this character has not already been done, also change the character sheet.
76387720
if( ssa[ 0 ] !== "sheetDirect" && !dupChar && ( attrib != undefined ) && !(mook && attrib === "condition-Health" )) {
7721+
//log("setting att. old is");
76397722
let attribute = Earthdawn.findOrMakeObj({ _type: 'attribute', _characterid: this.charID, name: attrib }, 0);
7723+
//log(attribute);
76407724
if( attribute[ "current" ] != setObj.attrib )
76417725
Earthdawn.setWithWorker( attribute, "current", setObj.attrib );
7642-
//log( "set attrib " + setObj.attrib);
76437726
} // End update the attribute.
76447727

76457728
// See if any other menu items share this attribute, and if so, unset those.
@@ -7663,6 +7746,7 @@ Get these in pairs, char sheet attrib and token status, get them ORed, then figu
76637746
else if( code === "defensive" )
76647747
this.MarkerSet( [ "m", "aggressive", "u" ] );
76657748
} } // End tokeninfo type is "Token"
7749+
//log("end MarkerSet");
76667750
} catch(err) { Earthdawn.errorLog( "ParseObj.MarkerSet() error caught: " + err, po ); }
76677751
} // End ParseObj.MarkerSet( ssa )
76687752

@@ -7783,15 +7867,15 @@ Get these in pairs, char sheet attrib and token status, get them ORed, then figu
77837867
case "newday": // Recovery tests and Karma reset. Some systems karma must be bought.
77847868
try {
77857869
let recov = Earthdawn.findOrMakeObj({ _type: 'attribute', _characterid: this.charID, name: "Recovery-Tests" });
7786-
let rt = (Earthdawn.parseInt2(recov.get( "max" )) || 2) + Earthdawn.parseInt2(Earthdawn.getAttrBN( this.charID, "Misc-NewDayRecoveryOffset", "0", true));
7870+
let rt = (Earthdawn.parseInt2(recov.get( "max" )) || 2) + Earthdawn.getAttrBN( this.charID, "Misc-NewDayRecoveryOffset", "0", true);
77877871
//log(rt);
77887872
Earthdawn.setWithWorker( recov, "current", rt.toString()); // set recovery tests available today to max.
7789-
7790-
// if( state.Earthdawn.gED && state.Earthdawn.edition == "4" ) {
77917873
let karmaObj = Earthdawn.findOrMakeObj({ _type: 'attribute', _characterid: this.charID, name: "Karma" }, 0),
7792-
kparam = ( ssa.length > 2 ) ? Earthdawn.parseInt2( ssa[ 2 ] ) : Earthdawn.getAttrBN( this.charID, "Misc-KarmaRitual", "-1", true), // V3.19 and later karmaritual is passed.
7874+
kparam = ( ssa.length > 2 ) ? ssa[ 2 ] : Earthdawn.getAttrBN( this.charID, "Misc-KarmaRitual", "-1"), // V3.19 and later karmaritual is passed.
7875+
dpparam = ( ssa.length > 3 ) ? ssa[ 3 ] : Earthdawn.getAttrBN( this.charID, "Misc-DPRitual", "-1"),
77937876
add;
7794-
switch ( kparam ) {
7877+
7878+
switch ( Earthdawn.parseInt2( kparam )) {
77957879
case -1: // set karma to it's max value
77967880
add = karmaObj.get( "max" );
77977881
break;
@@ -7822,30 +7906,32 @@ Get these in pairs, char sheet attrib and token status, get them ORed, then figu
78227906
} break;
78237907
default : // We were passed the number of karma to add.
78247908
if( isNaN( kparam ) || ( kparam < 0))
7825-
this.chat( "ED.funcMisc.NewDay Warning, invalid parameter " + kparam + ".", Earthdawn.whoTo.player | Earthdawn.whoFrom.api | Earthdawn.whoFrom.apiWarning)
7909+
this.chat( "ED.funcMisc.NewDay Warning, invalid karma parameter " + kparam + ".", Earthdawn.whoTo.player | Earthdawn.whoFrom.api | Earthdawn.whoFrom.apiWarning)
78267910
else
78277911
add = kparam;
78287912
};
78297913
let newKarma = Math.min( Earthdawn.parseInt2( karmaObj.get( "max" )), Earthdawn.parseInt2(karmaObj.get( "current" )) + Earthdawn.parseInt2( add ))
7830-
+ Earthdawn.parseInt2(Earthdawn.getAttrBN( this.charID, "Misc-NewDayKarmaOffset", "0", true));
7914+
+ Earthdawn.getAttrBN( this.charID, "Misc-NewDayKarmaOffset", "0", true);
78317915
Earthdawn.setWithWorker( karmaObj, "current", newKarma.toString());
7832-
this.chat( "New Day: Karma and Recovery tests reset.", this.WhoSendTo() | Earthdawn.whoFrom.character );
7833-
// } // Note: Don't set DP to max! that is not done on a mere new day.
7834-
// Note, we no longer need special code for older editions.
7835-
// else { // 1879, or ED edition other than 4th. Buy Karma.
7836-
// let newKarma = Earthdawn.getAttrBN( this.charID, "Karma_max", "0", true ) - Earthdawn.getAttrBN( this.charID, "Karma", "0", true );
7837-
// CDD ToDo This uses semi-obsolete code so needs to be rewritten once karma is moved to sheetworker, and hopefully the sheetworker will catch the karma changing.
7838-
/*
7839-
this.chat( Earthdawn.makeButton( "Buy Karma?", "!Earthdawn~ charID: " + this.charID + "~ Misc: Add: Karma: ?{How many Karma to buy|" + newKarma + "}"
7840-
+ "~ Record: ?{Posting Date|" + today.getFullYear() + "-" + (today.getMonth() +1) + "-" + today.getDate()
7841-
+ "}: : LP: ?{How many " + ( state.Earthdawn.gED ? "LP" : "AP" ) +" does that cost|" + newKarma * 10 + "}",
7842-
"Did you do a karma ritual and want to buy karma?", Earthdawn.Colors.param, Earthdawn.Colors.paramfg ),
7843-
Earthdawn.whoTo.player | Earthdawn.whoFrom.character | Earthdawn.whoFrom.noArchive );
7844-
*/
7845-
// this.chat( "New Day: " + Earthdawn.makeButton( "Buy Karma?", "!Earthdawn~ charID: " + this.charID + "~ Misc: Add: Karma: ?{How many Karma to buy|" + newKarma + "}",
7846-
// "Did you do a karma ritual and want to buy karma?", Earthdawn.Colors.param, Earthdawn.Colors.paramfg ),
7847-
// Earthdawn.whoTo.player | Earthdawn.whoFrom.character | Earthdawn.whoFrom.noArchive );
7848-
// }
7916+
7917+
add = 0;
7918+
switch ( Earthdawn.parseInt2( dpparam )) {
7919+
case -1: // set Add questor tier to their current devotion pool
7920+
add = Earthdawn.getAttrBN( this.charID, "IsQuestor", "0", true);
7921+
break;
7922+
default : // We were passed the number of karma to add.
7923+
if( isNaN( dpparam ) || ( dpparam < 0))
7924+
this.chat( "ED.funcMisc.NewDay Warning, invalid DP parameter " + dpparam + ".", Earthdawn.whoTo.player | Earthdawn.whoFrom.api | Earthdawn.whoFrom.apiWarning)
7925+
else
7926+
add = dpparam;
7927+
};
7928+
let added = "";
7929+
if( add > 0 ) {
7930+
let newDP = Math.min( Earthdawn.getAttrBN( this.charID, "DP_max", "0", true), Earthdawn.getAttrBN( this.charID, "DP", "0", true) + Earthdawn.parseInt2( add ));
7931+
Earthdawn.setWithWorker( karmaObj, "current", newDP.toString());
7932+
added = " " + add + " added to DP.";
7933+
}
7934+
this.chat( "New Day: Karma and Recovery tests reset." + added, this.WhoSendTo() | Earthdawn.whoFrom.character );
78497935
} catch(err) { Earthdawn.errorLog( "ED.funcMisc.NewDay error caught: " + err, po ); }
78507936
break;
78517937
case "resetchars": // reset all selected tokens to full health, karma, Recovery Tests, and no modifications or status markers.
@@ -8584,7 +8670,7 @@ log("Record Obsolete code. If you see this except on an 1879 sheet, please repor
85848670
else
85858671
po.edClass.countFail++;
85868672
if( po.misc[ "Special" ] === "Knockdown" ) {
8587-
// po.setWW( "condition-KnockedDown", "1" );
8673+
// po.setWW( "condition-KnockedDown", "1" ); // MarkerSet does this now.
85888674
po.MarkerSet( ["r", "knocked", "s"] );
85898675
po.misc[ "endNoteFail" ]="Character Knocked Down";
85908676
}
@@ -8857,30 +8943,43 @@ log("Record Obsolete code. If you see this except on an 1879 sheet, please repor
88578943
whoString = "public";
88588944
Earthdawn.errorLog( "ED.rollFormat invalid recipents value: " + recipients, po );
88598945
}
8860-
let k, bis = 0,
8861-
lt = "!Earthdawn~ ChatMenu: RolltypeEdit: state.Earthdawn.Rolltype." + (bpc ? "PC" : "NPC" ) + ": ";
8862-
if( "exceptionIs" in this.misc ) {
8863-
k = this.misc[ "exceptionIs" ];
8864-
let e = bpc ? state.Earthdawn.Rolltype.PC.Exceptions : state.Earthdawn.Rolltype.NPC.Exceptions;
8865-
if( k in e ) {
8866-
bis |= 0x01;
8867-
lt += this.misc[ "exceptionIs" ] + ": "
8868-
+"?{Edit display exception for '" + this.misc[ "exceptionIs" ][ "name" ]
8869-
+ "'|Never Mind, nothing|Change to Public, exceptionEdit: Public|Change to GM Only, exceptionEdit: GM Only"
8870-
+ "| Change to Player and GM, exceptionEdit: Player and GM|Delete exception, exceptionDelete}"
8871-
} else
8872-
edParse.chat( "Warning! Earthdawn internal data mismatch in rollFormat. key '" + k+ "' not found in exceptions.", Earthdawn.whoFrom.apiError);
8873-
} else if ( "exceptionWouldBe" in this.misc ) {
8874-
bis |= 0x02;
8875-
lt += this.misc[ "exceptionWouldBe" ][ "name" ] + ":?{Create a display exception for '" + this.misc[ "exceptionWouldBe" ][ "name" ]
8876-
+ "'|Never mind, nothing|Public, exceptionAdd: Public|GM Only, exceptionAdd: GM Only|Player and GM, exceptionAdd: Player and GM}";
8877-
}
8946+
let k, bis = 0, lt;
8947+
if(( "skillExceptionIs" in this.misc) || ( "skillExceptionWouldBe" in this.misc )) { // This is a knowledge or Artisan skill, which have special rolltype catagories. Send user to a special menu to ask which he wants. to set/edit.
8948+
bis |= 0x04;
8949+
lt = "!Earthdawn~ ChatMenu: RolltypeMulti: state.Earthdawn.Rolltype." + (bpc ? "PC" : "NPC" );
8950+
if( "skillExceptionIs" in this.misc )
8951+
lt += ": skillExceptionIs: " + this.misc[ "skillExceptionIs" ];
8952+
if( "skillExceptionWouldBe" in this.misc )
8953+
lt += ": skillExceptionWouldBe: " + this.misc[ "skillExceptionWouldBe" ];
8954+
if( "exceptionIs" in this.misc )
8955+
lt += ": exceptionIs: " + this.misc[ "exceptionIs" ];
8956+
if( "exceptionWouldBe" in this.misc )
8957+
lt += ": exceptionWouldBe: " + this.misc[ "exceptionWouldBe" ];
8958+
} else { // only one possible exception (talent name), not two (skill class).
8959+
lt = "!Earthdawn~ ChatMenu: RolltypeEdit: state.Earthdawn.Rolltype." + (bpc ? "PC" : "NPC" ) + ": ";
8960+
if( "exceptionIs" in this.misc ) {
8961+
k = this.misc[ "exceptionIs" ];
8962+
let e = bpc ? state.Earthdawn.Rolltype.PC.Exceptions : state.Earthdawn.Rolltype.NPC.Exceptions;
8963+
if( k in e ) {
8964+
bis |= 0x01;
8965+
lt += k + ": "
8966+
+"?{Edit display exception for '" + k
8967+
+ "'|Change to Public, exceptionEdit: Public|Change to GM Only, exceptionEdit: GM Only"
8968+
+ "| Change to Player and GM, exceptionEdit: Player and GM|Delete exception, exceptionDelete}"
8969+
} else
8970+
edParse.chat( "Warning! Earthdawn internal data mismatch in rollFormat. key '" + k+ "' not found in exceptions.", Earthdawn.whoFrom.apiError);
8971+
} else if ( "exceptionWouldBe" in this.misc ) {
8972+
bis |= 0x02;
8973+
lt += this.misc[ "exceptionWouldBe" ] + ":?{Create a display exception for '" + this.misc[ "exceptionWouldBe" ]
8974+
+ "'|Public, exceptionAdd: Public|GM Only, exceptionAdd: GM Only|Player and GM, exceptionAdd: Player and GM}";
8975+
} }
8976+
// cdd
8977+
// test for knowledge and/or artisan, and add a dropdown to change for all of those instead of name.
88788978
if( bis )
88798979
sectMain.append( "span", Earthdawn.makeButton(
88808980
Earthdawn.addIcon( whoString, "small" ), lt,
8881-
"This message is being sent to '" + whoString + (( "whoReason" in this.misc) ? "' due to " + this.misc[ "whoReason" ] : ""),
8882-
"white" ),
8883-
{ class: "sheet-rolltemplate-floatRight sheet-rolltemplate-RollTypeButton" });
8981+
"This message is being sent to '" + whoString + (( "whoReason" in this.misc) ? "' due to " + this.misc[ "whoReason" ] : ""), "white" ),
8982+
{ class: "sheet-rolltemplate-floatRight sheet-rolltemplate-RollTypeButton" });
88848983
else if( state.Earthdawn.Rolltype.Override )
88858984
sectMain.append( "span", Earthdawn.makeButton( " ! ", "!Earthdawn~ ChatMenu: RolltypeEdit: state.Earthdawn.Rolltype: : Display",
88868985
"Override is on and being sent to '" + state.Earthdawn.Rolltype.Override + "'" ),
@@ -8890,7 +8989,6 @@ log("Record Obsolete code. If you see this except on an 1879 sheet, please repor
88908989
+ this.misc[ "reason" ] + ((bsub || !sh ) ? "" : " -- " + new HtmlBuilder( "span", sh, { class: "sheet-rolltemplate-subheadertext" })), // Main Header
88918990
{class : ("sheet-rolltemplate-header" + (("headcolor" in this.misc) ?
88928991
" sheet-rolltemplate-header-" + Earthdawn.safeString( this.misc[ "headcolor" ] ).toLowerCase() : "" )) }); // The headers give the right colored thick line at bottom.
8893-
// log(sectMain);
88948992

88958993
if( bsub ) // This is a subheader. If it was short enough it would have been appended to the main header.
88968994
sectMain.append("", sh, { class: "sheet-rolltemplate-subheadertext"});
@@ -9247,7 +9345,6 @@ log("Record Obsolete code. If you see this except on an 1879 sheet, please repor
92479345
bodyMain.append( (( ++linenum % 2) ? ".odd" : ".even"), this.misc[ "endNoteFail" ]);
92489346
if( playerCard ) playerCardNix.push( bodyMain._children.length );
92499347
}
9250-
92519348
if(("cButtons" in this.misc) && this.misc[ "cButtons" ].length > 0) {
92529349
let tName;
92539350
for( let i = 0; i < this.misc[ "cButtons" ].length; ++i ) {
@@ -10727,8 +10824,8 @@ log("Record Obsolete code. If you see this except on an 1879 sheet, please repor
1072710824
T_Strain_max is set by the sheetworker and is used in a ~Strain: @{T_STrain_max}. It is either equal to T_Strain or to a query with T_Strain as default
1072810825
T_StrainAdvanced is a drop-down that right now is either "" (fixed strain) or "Ask". This will become much more complex in the future, especially for 1879.
1072910826
T_StrainAdvanced_max is the formula to be displayed to the user
10730-
Example Strains from ED and 1879:
10731-
Strain: 6
10827+
Example Strains from ED and 1879: (ones marked with * are currently supported. All others are not yet supported but will be in the future.
10828+
*Strain: 6
1073210829
Strain: 2 + target count
1073310830
Strain: 4 + TMD
1073410831
Strain: 4 + 1 per Spellcasting Test success
@@ -11536,23 +11633,36 @@ log("Record Obsolete code. If you see this except on an 1879 sheet, please repor
1153611633
this.misc[ "whoReason" ] = "Token is on the GM layer.";
1153711634
} else { // Token is not on gm layer. Check for exceptions, and then default.
1153811635
let bpc = (Earthdawn.getAttrBN( this.charID, "NPC", "1") == Earthdawn.charType.pc);
11636+
let except = bpc ? state.Earthdawn.Rolltype.PC.Exceptions : state.Earthdawn.Rolltype.NPC.Exceptions;
1153911637
let rn; // first, lets see if we can find a rolltype or a reason to check.
11638+
if( "skillClass" in this.misc ) { // check skill class first, but if there is a named exception, this class exception will be overriden.
11639+
let rnc = Earthdawn.matchString( this.misc[ "skillClass" ] ); // striped and lowercased
11640+
if( rnc in except ) {
11641+
rt = except[ rnc ][ "display" ];
11642+
this.misc[ "skillExceptionIs" ] = rnc;
11643+
this.misc[ "whoReason" ] = "an exception for " + this.misc[ "skillClass" ] + " skills.";
11644+
} else
11645+
this.misc[ "skillExceptionWouldBe" ] = this.misc[ "skillClass" ];
11646+
}
1154011647
if( "rollName" in this.misc )
1154111648
rn = this.misc[ "rollName" ];
1154211649
else if( "reason" in this.misc ) // Note that right now we are testing all reasons. We might have to narrow it down.
1154311650
rn = this.misc[ "reason" ];
1154411651
if( rn ) {
1154511652
let rnc = Earthdawn.matchString( rn ); // striped and lowercased
11546-
let except = bpc ? state.Earthdawn.Rolltype.PC.Exceptions : state.Earthdawn.Rolltype.NPC.Exceptions;
1154711653
if( rnc in except ) {
11548-
rt = except [ rnc ][ "display" ];
11654+
rt = except[ rnc ][ "display" ];
1154911655
this.misc[ "exceptionIs" ] = rnc;
1155011656
this.misc[ "whoReason" ] = "an exception for this name.";
11551-
} else { // no exception, use the default.
11552-
rt = bpc ? state.Earthdawn.Rolltype.PC.Default : state.Earthdawn.Rolltype.NPC.Default
11553-
this.misc[ "exceptionWouldBe" ] = { key: rnc, name: rn }
11554-
this.misc[ "whoReason" ] = "Default for " + (bpc ? "PCs." : "NPCs.");
11555-
} } } // end exceptions or default.
11657+
} else // no exception, use the default.
11658+
this.misc[ "exceptionWouldBe" ] = rn;
11659+
}
11660+
//cdd
11661+
if( rt === undefined ) {
11662+
rt = bpc ? state.Earthdawn.Rolltype.PC.Default : state.Earthdawn.Rolltype.NPC.Default
11663+
this.misc[ "whoReason" ] = "Default for " + (bpc ? "PCs." : "NPCs.");
11664+
}
11665+
} // end exceptions or default.
1155611666
} else if( state.Earthdawn.Rolltype.Override === "Sheet" ) { // use the old system where things are controled on a per talent basis by the player.
1155711667
if( "RollType" in this.misc ) // Option was "Ask" and we got an rolltype that way.
1155811668
rt = this.misc[ "RollType"]; // ?{Who should be able to see the results|Public, |Player & GM,pgm|GM Only,/w gm}
@@ -11579,7 +11689,7 @@ log("Record Obsolete code. If you see this except on an 1879 sheet, please repor
1157911689
ret = Earthdawn.whoTo.gm;
1158011690
else if(( r === "controlling only") || r.endsWith("plr" ))
1158111691
ret = Earthdawn.whoTo.player;
11582-
} }
11692+
} }
1158311693
} catch(err) { Earthdawn.errorLog( "ED.WhoSendTo() error caught: " + err, this ); }
1158411694
return ret;
1158511695
} // End ParseObj.WhoSendTo()

0 commit comments

Comments
 (0)
Please sign in to comment.