mirror of
https://github.com/Nighthawk42/roll20-character-sheets.git
synced 2026-08-30 11:42:29 +00:00
Created roll buttons for the Attack section of the character sheet. Any existing characters will need to be updated manually for the roll buttons to work.
983 lines
34 KiB
HTML
983 lines
34 KiB
HTML
<!-- Sheet Workers -->
|
||
<script type="text/worker">
|
||
|
||
/* ---- BEGIN: TheAaronSheet.js ---- */
|
||
// Github: https://github.com/shdwjk/TheAaronSheet/blob/master/TheAaronSheet.js
|
||
// By: The Aaron, Arcane Scriptomancer
|
||
// Contact: https://app.roll20.net/users/104025/the-aaron
|
||
|
||
var TAS = TAS || (function(){
|
||
'use strict';
|
||
|
||
var version = '0.2.1',
|
||
lastUpdate = 1453794214,
|
||
|
||
loggingSettings = {
|
||
debug: {
|
||
key: 'debug',
|
||
title: 'DEBUG',
|
||
color: {
|
||
bgLabel: '#7732A2',
|
||
label: '#F2EF40',
|
||
bgText: '#FFFEB7',
|
||
text: '#7732A2'
|
||
}
|
||
},
|
||
error: {
|
||
key: 'error',
|
||
title: 'Error',
|
||
color: {
|
||
bgLabel: '#C11713',
|
||
label: 'white',
|
||
bgText: '#C11713',
|
||
text: 'white'
|
||
}
|
||
},
|
||
warn: {
|
||
key: 'warn',
|
||
title: 'Warning',
|
||
color: {
|
||
bgLabel: '#F29140',
|
||
label: 'white',
|
||
bgText: '#FFD8B7',
|
||
text: 'black'
|
||
}
|
||
},
|
||
info: {
|
||
key: 'info',
|
||
title: 'Info',
|
||
color: {
|
||
bgLabel: '#413FA9',
|
||
label: 'white',
|
||
bgText: '#B3B2EB',
|
||
text: 'black'
|
||
}
|
||
},
|
||
notice: {
|
||
key: 'notice',
|
||
title: 'Notice',
|
||
color: {
|
||
bgLabel: '#33C133',
|
||
label: 'white',
|
||
bgText: '#ADF1AD',
|
||
text: 'black'
|
||
}
|
||
},
|
||
log: {
|
||
key: 'log',
|
||
title: 'Log',
|
||
color: {
|
||
bgLabel: '#f2f240',
|
||
label: 'black',
|
||
bgText: '#ffff90',
|
||
text: 'black'
|
||
}
|
||
},
|
||
callstack: {
|
||
key: 'TAS',
|
||
title: 'function',
|
||
color: {
|
||
bgLabel: '#413FA9',
|
||
label: 'white',
|
||
bgText: '#B3B2EB',
|
||
text: 'black'
|
||
}
|
||
},
|
||
callstack_async: {
|
||
key: 'TAS',
|
||
title: 'ASYNC CALL',
|
||
color: {
|
||
bgLabel: '#413FA9',
|
||
label: 'white',
|
||
bgText: '#413FA9',
|
||
text: 'white'
|
||
}
|
||
},
|
||
TAS: {
|
||
key: 'TAS',
|
||
title: 'TAS',
|
||
color: {
|
||
bgLabel: 'grey',
|
||
label: 'black;background:linear-gradient(#304352,#d7d2cc,#d7d2cc,#d7d2cc,#304352)',
|
||
bgText: 'grey',
|
||
text: 'black;background:linear-gradient(#304352,#d7d2cc,#d7d2cc,#d7d2cc,#304352)'
|
||
}
|
||
}
|
||
},
|
||
|
||
|
||
config = {
|
||
debugMode: false,
|
||
logging: {
|
||
log: true,
|
||
notice: true,
|
||
info: true,
|
||
warn: true,
|
||
error: true,
|
||
debug: false
|
||
}
|
||
},
|
||
|
||
callstackRegistry = [],
|
||
queuedUpdates = {}, //< Used for delaying saves till the last momment.
|
||
|
||
complexType = function(o){
|
||
switch(typeof o){
|
||
case 'string':
|
||
return 'string';
|
||
case 'boolean':
|
||
return 'boolean';
|
||
case 'number':
|
||
return (_.isNaN(o) ? 'NaN' : (o.toString().match(/\./) ? 'decimal' : 'integer'));
|
||
case 'function':
|
||
return 'function: '+(o.name ? o.name+'()' : '(anonymous)');
|
||
case 'object':
|
||
return (_.isArray(o) ? 'array' : (_.isArguments(o) ? 'arguments' : ( _.isNull(o) ? 'null' : 'object')));
|
||
default:
|
||
return typeof o;
|
||
}
|
||
},
|
||
|
||
dataLogger = function(primaryLogger,secondaryLogger,data){
|
||
_.each(data,function(m){
|
||
var type = complexType(m);
|
||
switch(type){
|
||
case 'string':
|
||
primaryLogger(m);
|
||
break;
|
||
case 'undefined':
|
||
case 'null':
|
||
case 'NaN':
|
||
primaryLogger('['+type+']');
|
||
break;
|
||
case 'number':
|
||
case 'not a number':
|
||
case 'integer':
|
||
case 'decimal':
|
||
case 'boolean':
|
||
primaryLogger('['+type+']: '+m);
|
||
break;
|
||
default:
|
||
primaryLogger('['+type+']:=========================================');
|
||
secondaryLogger(m);
|
||
primaryLogger('=========================================================');
|
||
break;
|
||
}
|
||
});
|
||
},
|
||
|
||
|
||
colorLog = function(options){
|
||
var coloredLoggerFunction,
|
||
key = options.key,
|
||
label = options.title || 'TAS',
|
||
lBGColor = (options.color && options.color.bgLabel) || 'blue',
|
||
lTxtColor = (options.color && options.color.label) || 'white',
|
||
mBGColor = (options.color && options.color.bgText) || 'blue',
|
||
mTxtColor = (options.color && options.color.text) || 'white';
|
||
|
||
coloredLoggerFunction = function(message){
|
||
console.log(
|
||
'%c '+label+': %c '+message,
|
||
'background-color: '+lBGColor+';color: '+lTxtColor+'; font-weight:bold;',
|
||
'background-color: '+mBGColor+';color: '+mTxtColor+';'
|
||
);
|
||
};
|
||
return function(){
|
||
if('TAS'===key || config.logging[key]){
|
||
dataLogger(coloredLoggerFunction,function(m){console.log(m);},_.toArray(arguments));
|
||
}
|
||
};
|
||
},
|
||
|
||
logDebug = colorLog(loggingSettings.debug),
|
||
logError = colorLog(loggingSettings.error),
|
||
logWarn = colorLog(loggingSettings.warn),
|
||
logInfo = colorLog(loggingSettings.info),
|
||
logNotice = colorLog(loggingSettings.notice),
|
||
logLog = colorLog(loggingSettings.log),
|
||
log = colorLog(loggingSettings.TAS),
|
||
logCS = colorLog(loggingSettings.callstack),
|
||
logCSA = colorLog(loggingSettings.callstack_async),
|
||
|
||
registerCallstack = function(callstack,label){
|
||
var idx=_.findIndex(callstackRegistry,function(o){
|
||
return (_.difference(o.stack,callstack).length === _.difference(callstack,o.stack).length)
|
||
&& _.difference(o.stack,callstack).length === 0
|
||
&& o.label === label;
|
||
});
|
||
if(-1 === idx){
|
||
idx=callstackRegistry.length;
|
||
callstackRegistry.push({
|
||
stack: callstack,
|
||
label: label
|
||
});
|
||
}
|
||
return idx;
|
||
},
|
||
|
||
setConfigOption = function(options){
|
||
var newconf =_.defaults(options,config);
|
||
newconf.logging=_.defaults(
|
||
(options && options.logging)||{},
|
||
config.logging
|
||
);
|
||
config=newconf;
|
||
},
|
||
|
||
debugMode = function(){
|
||
config.logging.debug=true;
|
||
config.debugMode = true;
|
||
},
|
||
|
||
getCallstack = function(){
|
||
var e = new Error('dummy'),
|
||
stack = _.map(_.rest(e.stack.replace(/^[^\(]+?[\n$]/gm, '')
|
||
.replace(/^\s+at\s+/gm, '')
|
||
.replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@')
|
||
.split('\n')),function(l){
|
||
return l.replace(/\s+.*$/,'');
|
||
});
|
||
return stack;
|
||
},
|
||
logCallstackSub = function(cs){
|
||
var matches, csa;
|
||
_.find(cs,function(line){
|
||
matches = line.match(/TAS_CALLSTACK_(\d+)/);
|
||
if(matches){
|
||
csa=callstackRegistry[matches[1]];
|
||
logCSA( '===================='+(csa.label ? '> '+csa.label+' <' : '')+'====================');
|
||
logCallstackSub(csa.stack);
|
||
return true;
|
||
}
|
||
logCS(line);
|
||
return false;
|
||
});
|
||
},
|
||
logCallstack = function(){
|
||
var cs;
|
||
if(config.debugMode){
|
||
cs = getCallstack();
|
||
cs.shift();
|
||
log('==============================> CALLSTACK <==============================');
|
||
logCallstackSub(cs);
|
||
log('=========================================================================');
|
||
}
|
||
},
|
||
|
||
|
||
wrapCallback = function (label, callback,context){
|
||
var callstack;
|
||
if('function' === typeof label){
|
||
context=callback;
|
||
callback=label;
|
||
label=undefined;
|
||
}
|
||
if(!config.debugMode){
|
||
return (function(cb,ctx){
|
||
return function(){
|
||
cb.apply(ctx||{},arguments);
|
||
};
|
||
}(callback,context));
|
||
}
|
||
|
||
callstack = getCallstack();
|
||
callstack.shift();
|
||
|
||
return (function(cb,ctx,cs,lbl){
|
||
var ctxref=registerCallstack(cs,lbl);
|
||
return new Function('cb','ctx','TASlog',
|
||
"return function TAS_CALLSTACK_"+ctxref+"(){"+
|
||
"TASlog('Entering: '+(cb.name||'(anonymous function)'));"+
|
||
"cb.apply(ctx||{},arguments);"+
|
||
"TASlog('Exiting: '+(cb.name||'(anonymous function)'));"+
|
||
"};")(cb,ctx,log);
|
||
}(callback,context,callstack,label));
|
||
},
|
||
|
||
|
||
prepareUpdate = function( attribute, value ){
|
||
queuedUpdates[attribute]=value;
|
||
},
|
||
|
||
applyQueuedUpdates = function() {
|
||
setAttrs(queuedUpdates);
|
||
queuedUpdates = {};
|
||
},
|
||
|
||
namesFromArgs = function(args,base){
|
||
return _.chain(args)
|
||
.reduce(function(memo,attr){
|
||
if('string' === typeof attr) {
|
||
memo.push(attr);
|
||
} else if(_.isArray(args) || _.isArguments(args)){
|
||
memo = namesFromArgs(attr,memo);
|
||
}
|
||
return memo;
|
||
},(_.isArray(base) && base) || [])
|
||
.uniq()
|
||
.value();
|
||
},
|
||
|
||
addId = function(obj,value){
|
||
Object.defineProperty(obj,'id',{
|
||
value: value,
|
||
writeable: false,
|
||
enumerable: false
|
||
});
|
||
},
|
||
|
||
addProp = function(obj,prop,value,fullname){
|
||
(function(){
|
||
var pname=(_.contains(['S','F','I','D'],prop) ? '_'+prop : prop),
|
||
full_pname = fullname || prop,
|
||
pvalue=value;
|
||
|
||
_.each(['S','I','F'],function(p){
|
||
if( !_.has(obj,p)){
|
||
Object.defineProperty(obj, p, {
|
||
value: {},
|
||
enumerable: false,
|
||
readonly: true
|
||
});
|
||
}
|
||
});
|
||
if( !_.has(obj,'D')){
|
||
Object.defineProperty(obj, 'D', {
|
||
value: _.reduce(_.range(10),function(m,d){
|
||
Object.defineProperty(m, d, {
|
||
value: {},
|
||
enumerable: true,
|
||
readonly: true
|
||
});
|
||
return m;
|
||
},{}),
|
||
enumerable: false,
|
||
readonly: true
|
||
});
|
||
}
|
||
|
||
|
||
// Raw value
|
||
Object.defineProperty(obj, pname, {
|
||
enumerable: true,
|
||
set: function(v){
|
||
pvalue=v;
|
||
prepareUpdate(full_pname,v);
|
||
},
|
||
get: function(){
|
||
return pvalue;
|
||
}
|
||
});
|
||
|
||
// string value
|
||
Object.defineProperty(obj.S, pname, {
|
||
enumerable: true,
|
||
set: function(v){
|
||
var val=v.toString();
|
||
pvalue=val;
|
||
prepareUpdate(full_pname,val);
|
||
},
|
||
get: function(){
|
||
return pvalue.toString();
|
||
}
|
||
});
|
||
|
||
// int value
|
||
Object.defineProperty(obj.I, pname, {
|
||
enumerable: true,
|
||
set: function(v){
|
||
var val=parseInt(v,10) || 0;
|
||
pvalue=val;
|
||
prepareUpdate(full_pname,val);
|
||
},
|
||
get: function(){
|
||
return parseInt(pvalue,10) || 0;
|
||
}
|
||
});
|
||
|
||
// float value
|
||
Object.defineProperty(obj.F, pname, {
|
||
enumerable: true,
|
||
set: function(v){
|
||
var val=parseFloat(v) || 0;
|
||
pvalue=val;
|
||
prepareUpdate(full_pname,val);
|
||
},
|
||
get: function(){
|
||
return parseFloat(pvalue) || 0;
|
||
}
|
||
});
|
||
_.each(_.range(10),function(d){
|
||
Object.defineProperty(obj.D[d], pname, {
|
||
enumerable: true,
|
||
set: function(v){
|
||
var val=(parseFloat(v) || 0).toFixed(d);
|
||
pvalue=val;
|
||
prepareUpdate(full_pname,val);
|
||
},
|
||
get: function(){
|
||
return (parseFloat(pvalue) || 0).toFixed(d);
|
||
}
|
||
});
|
||
});
|
||
|
||
}());
|
||
},
|
||
|
||
repeating = function( section ) {
|
||
return (function(s){
|
||
var sectionName = s,
|
||
attrNames = [],
|
||
fieldNames = [],
|
||
operations = [],
|
||
after = [],
|
||
|
||
repAttrs = function TAS_Repeating_Attrs(){
|
||
attrNames = namesFromArgs(arguments,attrNames);
|
||
return this;
|
||
},
|
||
repFields = function TAS_Repeating_Fields(){
|
||
fieldNames = namesFromArgs(arguments,fieldNames);
|
||
return this;
|
||
},
|
||
repReduce = function TAS_Repeating_Reduce(func, initial, final, context) {
|
||
operations.push({
|
||
type: 'reduce',
|
||
func: (func && _.isFunction(func) && func) || _.noop,
|
||
memo: (_.isUndefined(initial) && 0) || initial,
|
||
final: (final && _.isFunction(final) && final) || _.noop,
|
||
context: context || {}
|
||
});
|
||
return this;
|
||
},
|
||
repMap = function TAS_Repeating_Map(func, final, context) {
|
||
operations.push({
|
||
type: 'map',
|
||
func: (func && _.isFunction(func) && func) || _.noop,
|
||
final: (final && _.isFunction(final) && final) || _.noop,
|
||
context: context || {}
|
||
});
|
||
return this;
|
||
},
|
||
repEach = function TAS_Repeating_Each(func, final, context) {
|
||
operations.push({
|
||
type: 'each',
|
||
func: (func && _.isFunction(func) && func) || _.noop,
|
||
final: (final && _.isFunction(final) && final) || _.noop,
|
||
context: context || {}
|
||
});
|
||
return this;
|
||
},
|
||
repTap = function TAS_Repeating_Tap(final, context) {
|
||
operations.push({
|
||
type: 'tap',
|
||
final: (final && _.isFunction(final) && final) || _.noop,
|
||
context: context || {}
|
||
});
|
||
return this;
|
||
},
|
||
repAfter = function TAS_Repeating_After(callback,context) {
|
||
after.push({
|
||
callback: (callback && _.isFunction(callback) && callback) || _.noop,
|
||
context: context || {}
|
||
});
|
||
return this;
|
||
},
|
||
repExecute = function TAS_Repeating_Execute(callback,context){
|
||
var rowSet = {},
|
||
attrSet = {},
|
||
fieldIds = [],
|
||
fullFieldNames = [];
|
||
|
||
repAfter(callback,context);
|
||
|
||
// call each operation per row.
|
||
// call each operation's final
|
||
getSectionIDs("repeating_"+sectionName,function(ids){
|
||
fieldIds = ids;
|
||
fullFieldNames = _.reduce(fieldIds,function(memo,id){
|
||
return memo.concat(_.map(fieldNames,function(name){
|
||
return 'repeating_'+sectionName+'_'+id+'_'+name;
|
||
}));
|
||
},[]);
|
||
getAttrs( _.uniq(attrNames.concat(fullFieldNames)), function(values){
|
||
_.each(attrNames,function(aname){
|
||
if(values.hasOwnProperty(aname)){
|
||
addProp(attrSet,aname,values[aname]);
|
||
}
|
||
});
|
||
|
||
rowSet = _.reduce(fieldIds,function(memo,id){
|
||
var r={};
|
||
addId(r,id);
|
||
_.each(fieldNames,function(name){
|
||
var fn = 'repeating_'+sectionName+'_'+id+'_'+name;
|
||
addProp(r,name,values[fn],fn);
|
||
});
|
||
|
||
memo[id]=r;
|
||
|
||
return memo;
|
||
},{});
|
||
|
||
_.each(operations,function(op){
|
||
var res;
|
||
switch(op.type){
|
||
case 'tap':
|
||
_.bind(op.final,op.context,rowSet,attrSet)();
|
||
break;
|
||
|
||
case 'each':
|
||
_.each(rowSet,function(r){
|
||
_.bind(op.func,op.context,r,attrSet,r.id,rowSet)();
|
||
});
|
||
_.bind(op.final,op.context,rowSet,attrSet)();
|
||
break;
|
||
|
||
case 'map':
|
||
res = _.map(rowSet,function(r){
|
||
return _.bind(op.func,op.context,r,attrSet,r.id,rowSet)();
|
||
});
|
||
_.bind(op.final,op.context,res,rowSet,attrSet)();
|
||
break;
|
||
|
||
case 'reduce':
|
||
res = op.memo;
|
||
_.each(rowSet,function(r){
|
||
res = _.bind(op.func,op.context,res,r,attrSet,r.id,rowSet)();
|
||
});
|
||
_.bind(op.final,op.context,res,rowSet,attrSet)();
|
||
break;
|
||
}
|
||
});
|
||
|
||
// finalize attrs
|
||
applyQueuedUpdates();
|
||
_.each(after,function(op){
|
||
_.bind(op.callback,op.context)();
|
||
});
|
||
});
|
||
});
|
||
};
|
||
|
||
return {
|
||
attrs: repAttrs,
|
||
attr: repAttrs,
|
||
|
||
column: repFields,
|
||
columns: repFields,
|
||
field: repFields,
|
||
fields: repFields,
|
||
|
||
reduce: repReduce,
|
||
inject: repReduce,
|
||
foldl: repReduce,
|
||
|
||
map: repMap,
|
||
collect: repMap,
|
||
|
||
each: repEach,
|
||
forEach: repEach,
|
||
|
||
tap: repTap,
|
||
'do': repTap,
|
||
|
||
after: repAfter,
|
||
last: repAfter,
|
||
done: repAfter,
|
||
|
||
execute: repExecute,
|
||
go: repExecute,
|
||
run: repExecute
|
||
};
|
||
}(section));
|
||
},
|
||
|
||
|
||
repeatingSimpleSum = function(section, field, destination){
|
||
repeating(section)
|
||
.attr(destination)
|
||
.field(field)
|
||
.reduce(function(m,r){
|
||
return m + (r.F[field]);
|
||
},0,function(t,r,a){
|
||
a[destination]=t;
|
||
})
|
||
.execute();
|
||
};
|
||
|
||
console.log('%c•.¸¸.•*´¨`*•.¸¸.•*´¨`*•.¸ The Aaron Sheet v'+version+' ¸.•*´¨`*•.¸¸.•*´¨`*•.¸¸.•','background: linear-gradient(to right,green,white,white,green); color:black;text-shadow: 0 0 8px white;');
|
||
console.log('%c•.¸¸.•*´¨`*•.¸¸.•*´¨`*•.¸ Last update: '+(new Date(lastUpdate*1000))+' ¸.•*´¨`*•.¸¸.•*´¨`*•.¸¸.•','background: linear-gradient(to right,green,white,white,green); color:black;text-shadow: 0 0 8px white;');
|
||
|
||
|
||
return {
|
||
/* Repeating Sections */
|
||
repeatingSimpleSum: repeatingSimpleSum,
|
||
repeating: repeating,
|
||
|
||
/* Configuration */
|
||
config: setConfigOption,
|
||
|
||
/* Debugging */
|
||
callback: wrapCallback,
|
||
callstack: logCallstack,
|
||
debugMode: debugMode,
|
||
_fn: wrapCallback,
|
||
|
||
/* Logging */
|
||
debug: logDebug,
|
||
error: logError,
|
||
warn: logWarn,
|
||
info: logInfo,
|
||
notice: logNotice,
|
||
log: logLog
|
||
};
|
||
}());
|
||
|
||
/* ---- END: TheAaronSheet.js ---- */
|
||
|
||
/* ---- START: ordinalInWord ---- */
|
||
function ordinalInWord( cardinal ) {
|
||
'use strict';
|
||
var ordinals = [ 'Zeroth ', 'First ', 'Second ', 'Third ', 'Fourth ', 'Fifth ', 'Sixth ', 'Seventh ', 'Eighth ', 'Ninth ', 'Tenth ', 'Eleventh ', 'Twelfth ', 'Thirteenth ', 'Fourteenth ', 'Fifteenth ', 'Sixteenth ','Seventeenth ', 'Eighteenth ', 'Nineteenth ', 'Twentieth ' ];
|
||
var tens = {
|
||
20: 'Twenty',
|
||
30: 'Thirty',
|
||
40: 'Forty' /* and so on up to 90 */
|
||
};
|
||
var ordinalTens = {
|
||
30: 'Thirtieth',
|
||
40: 'Fortieth',
|
||
50: 'Fiftieth' /* and so on */
|
||
};
|
||
|
||
if( cardinal <= 20 ) {
|
||
return ordinals[ cardinal ];
|
||
}
|
||
|
||
if( cardinal % 10 === 0 ) {
|
||
return ordinalTens[ cardinal ];
|
||
}
|
||
|
||
return tens[ cardinal - ( cardinal % 10 ) ] + ordinals[ cardinal % 10 ];
|
||
}
|
||
/* ---- END: ordinalInWord ---- */
|
||
|
||
/* ---- START: Build Dice Roll for OVA Template ---- */
|
||
on("sheet:opened change:numdicetoroll", function () {
|
||
'use strict';
|
||
getAttrs(["numdicetoroll"], function (value) {
|
||
console.log("Number of Dice to Roll: " + value.numdicetoroll);
|
||
var dice = parseInt(value.numdicetoroll);
|
||
console.log("Number of Dice Type = " + typeof dice);
|
||
var newFormula = " ";
|
||
var newOrd;
|
||
var i = 0;
|
||
for (i = 1; i <= dice; i += 1) {
|
||
console.log("i = " + i);
|
||
newOrd = ordinalInWord(i);
|
||
newFormula += "{{" + newOrd + "Die=[[1d6]]}} ";
|
||
console.log("Roll Formula = " + newFormula);
|
||
}
|
||
setAttrs({rollformula: newFormula});
|
||
});
|
||
});
|
||
//End Rank
|
||
|
||
/* ---- START: Build Dice Roll for OVA Template ATK Repeating Section ----*/
|
||
//First ATK Field (non-repeating)
|
||
on("sheet:opened change:roll1", function () {
|
||
'use strict';
|
||
getAttrs(["roll1"], function (value) {
|
||
console.log("Number of Dice to Roll: " + value.roll1);
|
||
var dice = parseInt(value.roll1);
|
||
console.log("Number of Dice Type = " + typeof dice);
|
||
var newFormula = " ";
|
||
var i = 0;
|
||
for (i = 1; i <= dice; i += 1) {
|
||
console.log("i = " + i);
|
||
newFormula += "[[1d6]] ";
|
||
console.log("Roll Formula = " + newFormula);
|
||
}
|
||
setAttrs({atk1: newFormula});
|
||
});
|
||
});
|
||
|
||
//Other ATK Fields (repeating section)
|
||
on("change:repeating_attacks:roll2", function (eventInfo) {
|
||
'use strict';
|
||
getAttrs(["repeating_attacks_roll2","repeating_attacks_atk"], function (value) {
|
||
console.log("Number of Dice to Roll: " + value.repeating_attacks_roll2);
|
||
var dice = parseInt(value.repeating_attacks_roll2);
|
||
var newFormula = " ";
|
||
var i = 0;
|
||
for (i = 1; i <= dice; i += 1) {
|
||
console.log("i = " + i);
|
||
newFormula += "[[1d6]] ";
|
||
console.log("Roll Formula = " + newFormula);
|
||
}
|
||
setAttrs({repeating_attacks_atk: newFormula});
|
||
});
|
||
});
|
||
|
||
/* ---- END: Build Dice Roll for OVA Template ---- */
|
||
|
||
</script>
|
||
<!-- End Sheet Workers -->
|
||
<div style='width:810px; background-color: white;'>
|
||
<div class='sheet-row' style='padding-left: 75px; width: 733px; background-color: white; margin-bottom: 15px;'><!--Header-->
|
||
<div class='sheet-col'>
|
||
<!--<img src="http://www.geeksville.us/roll20/OVALogo.png">-->
|
||
<img src="http://i.imgur.com/IDEiHQ2.png">
|
||
</div>
|
||
|
||
<div class='sheet-col sheet-red' style='padding-top: 5px; padding-left: 25px; padding-right: 38px; margin-top: 25px; margin-left: -25px; z-index: -1;'>
|
||
<input class='sheet-name' type="text" name="attr_character_name" title="@{character_name}" />
|
||
<input class='sheet-name' type="text" name="attr_player_name" title="@{player_name}" /><br />
|
||
<div class='sheet-names' style='width: 232px;'>Character Name</div>
|
||
<div class='sheet-names'>Player Name</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!--Character Sheet data -->
|
||
<div class='sheet-row' style='width: 800px; margin-top: -45px;'>
|
||
<span style="margin-left: 300px; font-weight: bold;">Number of Dice to roll:</span>
|
||
<input type="number" name="attr_numdicetoroll" value=1 style='border: 1px solid #801421; background-color: #eee2e2; color: black; text-align: center;' />
|
||
<input type="text" name="attr_rollformula" style="display: none;" value="{{Die one=[[1d6]]}}" />
|
||
<button class="sheet-templatebutton" type='roll' name='roll_Generic-Roll' title="@{Generic-Roll}" value='&{template:ova} {{name=@{character_name}}} @{rollformula}'></button>
|
||
<!--<button class="sheet-initiativebutton" type='roll' name='roll_initiative' title="@{initiative}" value='/roll @{numdicetoroll}d6 &{tracker}'>Initiative</button>-->
|
||
<span style="margin-left: 100px;"> </span>
|
||
<input type="radio" class="sheet-tab sheet-tab1" name="attr_core-tab" value="1" title="Stats & Abilities" checked="checked"/>
|
||
<span class="sheet-tab sheet-tab1">Stats</span>
|
||
<input type="radio" class="sheet-tab sheet-tab2" name="attr_core-tab" value="2" title="Background & Notes" />
|
||
<span class="sheet-tab sheet-tab2">Misc</span>
|
||
<div class='sheet-shim' style='width:790px; height: 100%;'> </div>
|
||
<div class='sheet-section-core'>
|
||
<div class='sheet-row' style='width: 100%;'>
|
||
<div class='sheet-3colrow sheet-pink' style='width: 94%; border-top-right-radius: 5px; border-bottom-right-radius: 5px; padding-bottom: 5px;'>
|
||
<div class='sheet-col sheet-pink' style="width: 80px; margin-right: -5px;"> </div>
|
||
<div class='sheet-col sheet-pink' style='width: 320px; margin-right: 5px;'>
|
||
<h4>Abilities</h4>
|
||
<fieldset class="repeating_abilities" style='background-color: #eee2e2;'>
|
||
<input class="sheet-mod" type="text" name="attr_abilitymod" title="@{repeating_abilities_#_abilitymod}" />
|
||
<input class="sheet-ability" type="text" name="attr_ability" title="@{repeating_abilities_#_ability}" />
|
||
</fieldset>
|
||
</div>
|
||
|
||
<div class='sheet-col sheet-pink' style='width: 320px; margin-left: -10px; padding-left: 15px; border-top-right-radius: 10px; border-bottom-right-radius: 10px;'>
|
||
<h4>Weaknesses</h4>
|
||
<fieldset class="repeating_weaknesses" style='background-color: #eee2e2;'>
|
||
<input class="sheet-mod" type="text" name="attr_weaknessmod" title="@{repeating_abilities_#_weaknessmod}" />
|
||
<input class="sheet-ability" type="text" name="attr_weakness" title="@{repeating_abilities_#_weakness}" />
|
||
</fieldset>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- Release Notes Info for New Buttons -->
|
||
<input type='checkbox' class='sheet-Dismiss' style='display: none;' name='attr_dismissRN' value='1' />
|
||
<div class='sheet-row sheet-CSRelease' style='width: 100%; padding-top: 5px; padding-bottom: 5px;'>
|
||
<div class='sheet-col' style='width: 80px;'> </div>
|
||
<div class='sheet-col' style='width: 240px; text-align: right;'>Combat Stats Release Notes</div>
|
||
<div class='sheet-col' style='width: 400px;'>
|
||
<input type='checkbox' class='sheet-releasenotes' name='attr_releasenotes' value='1' checked /><span class='sheet-releasenotes'></span>
|
||
<div class='sheet-row sheet-releasenotes' style='width: 100%; padding: 0px; margin: 0px'>
|
||
<input type='checkbox' class='sheet-Dismiss' name='attr_dismissRN' value='1' /><span class='sheet-Dismiss'> Dismiss</span>
|
||
|
||
<p>
|
||
In order to get the Combat Stats roll buttons to work for existing characters with existing Stats, each stat will need to be changed so the sheet worker gets triggered. To accomplish this, you will need to change the number in each of the Roll boxes to a different number and hit enter, then you'll need to change it back and hit enter a second time. After that, each roll button should work. You should not need to do this when creating a new a character, nor when adding a new Combat Stat.<br /><br />
|
||
To hide this message, simply click on the downward pointing triangle above this message.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- End Release Notes Info for New Buttons -->
|
||
<div class='sheet-row' style='width: 100%; padding-top: 25px;'>
|
||
<div class='sheet-row' style='width: 100%;'>
|
||
<div class='sheet-col' style='width:80px; margin-right: -5px;'> </div>
|
||
<div class='sheet-col sheet-pink' style='width: 240px; font-weight: bold; border-radius: 5px; padding: 5px; padding-right: 0px; margin-right: -5px;'>
|
||
COMBAT NOTES <br />
|
||
<div class='sheet-row' style='border: none; border-radius: 5px; background-color: white; color: black; font-size:.75em;'>
|
||
<textarea name='attr_combatnotes' style='border-radius: 5px; height: 420px;'></textarea><br />
|
||
<span style="color:#eee2e2; text-transform: uppercase; font-size: 1.5em;"> Damage, Complications, Etc.</span>
|
||
</div>
|
||
</div>
|
||
<div class='sheet-col sheet-red' style='width: 400px; padding: 5px; border-radius: 10px; font-weight: bold; font-size: 2em; margin-top: -10px;'>
|
||
Combat Stats<br />
|
||
<div class='sheet-row sheet-combatstatsmain'>
|
||
<div class='sheet-row' style='width: 100%; padding: 5px; vertical-align: top;'>
|
||
<div class='sheet-combatstat' style='width:198px; text-align: left; height: 85px;'>
|
||
<input type='text' name='attr_mode1' placeholder="Attack" style="width:146px; border: none; color: #801421; font-weight: bold; margin: 0px; padding: 0px;" /><button class="sheet-templatebutton" type='roll' name='roll_attack-roll1' title="@{attack-roll}" value='@{bv1}'></button><button class="sheet-GM-button" type='roll' name='roll_attack-roll1' title="@{attack-roll}" value='/w gm @{bv1}'></button><br />
|
||
<textarea name="attr_modedesc1" placeholder="description" class="sheet-combattext"></textarea>
|
||
<input type='text' style='display:none;' name='attr_bv1' value='&{template:ova} {{name=@{character_name}}} {{attack=@{mode1}}} {{ATK (@{roll1})=@{atk1}}} {{DX=@{dx1}}} {{END=@{end1}}} {{desc=@{modedesc1}}}' />
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:50px; margin-left: -7px; vertical-align: top; height: 85px;'>
|
||
ROLL
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_roll1" /><br />
|
||
<input type="text" name='attr_atk1' style='display:none;' />
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:45px; margin-left: -7px; height: 85px;'>
|
||
DX
|
||
<input type="number" class="sheet-combatnum" style="width:43px; height: 70px;" name="attr_dx1" />
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:50px; margin-left: -7px; border-right: none; height: 85px;'>
|
||
END
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_end1" />
|
||
</div>
|
||
</div>
|
||
<fieldset class="repeating_attacks" style='font-size: 1em;'>
|
||
<div class='sheet-row' style='width: 100%; padding: 5px; padding-top: 0px; vertical-align: top; margin-top: -5px;'>
|
||
<div class='sheet-combatstat' style='width:198px; text-align: left; height: 85px;'>
|
||
<input type='text' name='attr_mode' placeholder="Attack" style="width:146px; border: none; color: #801421; font-weight: bold; margin: 0px; padding: 0px;" /><button class="sheet-templatebutton" type='roll' name='roll_attack-roll' title="@{attack-roll}" value='@{bv}'></button><button class="sheet-GM-button" type='roll' name='roll_attack-roll1' title="@{attack-roll}" value='/w gm @{bv}'></button><br />
|
||
<!--<span style="color: black;">Affinity: </span><input type="text" name="attr_affinity2" style="width:150px; border: none; color: black;"/><br />-->
|
||
<textarea name="attr_modedesc2" placeholder="description" class="sheet-combattext"></textarea>
|
||
<input type='text' style='display:none;' name='attr_bv' value='&{template:ova} {{name=@{character_name}}} {{attack=@{mode}}} {{ATK (@{roll2})=@{atk}}} {{DX=@{dx2}}} {{END=@{end2}}} {{desc=@{modedesc2}}}' />
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:50px; margin-left: -7px; vertical-align: top; height: 85px;'>
|
||
ROLL
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_roll2" /><br />
|
||
<input type="text" name='attr_atk' style='display:none;' />
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:45px; margin-left: -7px; height: 85px;'>
|
||
DX
|
||
<input type="number" class="sheet-combatnum" style="width:43px; height: 70px;" name="attr_dx2" />
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:50px; margin-left: -7px; border-right: none; height: 85px;'>
|
||
END
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_end2" />
|
||
</div>
|
||
</div>
|
||
</fieldset>
|
||
<!--
|
||
<div class='sheet-row' style='width: 100%; padding: 5px; padding-top: 0px; vertical-align: top; margin-top: -5px;'>
|
||
<div class='sheet-combatstat' style='width:198px; text-align: left; height: 85px;'>
|
||
Mode 3: <input type='text' name='attr_mode3' style="width:145px; border: none; color: #801421;" /><br />
|
||
<span style="color: black;">Affinity: </span><input type="text" name="attr_affinity3" style="width:150px; border: none; color: black;"/><br />
|
||
<textarea name="attr_modedesc3" placeholder="description" class="sheet-combattext"></textarea>
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:50px; margin-left: -7px; vertical-align: top; height: 85px;'>
|
||
ROLL
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_roll3" /><br />
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:45px; margin-left: -7px; height: 85px;'>
|
||
DX
|
||
<input type="number" class="sheet-combatnum" style="width:43px; height: 70px;" name="attr_dx3" />
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:50px; margin-left: -7px; border-right: none; height: 85px;'>
|
||
END
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_end3" />
|
||
</div>
|
||
</div>
|
||
<div class='sheet-row' style='width: 100%; padding: 5px; padding-top: 0px; vertical-align: top; margin-top: -5px;'>
|
||
<div class='sheet-combatstat' style='width:198px; text-align: left; height: 85px;'>
|
||
Mode 4: <input type='text' name='attr_mode4' style="width:145px; border: none; color: #801421;" /><br />
|
||
<span style="color: black;">Affinity: </span><input type="text" name="attr_affinity4" style="width:150px; border: none; color: black;"/><br />
|
||
<textarea name="attr_modedesc4" placeholder="description" class="sheet-combattext"></textarea>
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:50px; margin-left: -7px; vertical-align: top; height: 85px;'>
|
||
ROLL
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_roll4" /><br />
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:45px; margin-left: -7px; height: 85px;'>
|
||
DX
|
||
<input type="number" class="sheet-combatnum" style="width:43px; height: 70px;" name="attr_dx4" />
|
||
</div>
|
||
<div class='sheet-combatstat' style='width:50px; margin-left: -7px; border-right: none; height: 85px;'>
|
||
END
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_end4" />
|
||
</div>
|
||
</div>
|
||
-->
|
||
<div class='sheet-row' style='width:100%; margin-top: -6px; border-top: 1px solid #801421;'>
|
||
<div class='sheet-col' style='width: 25%; color: #801421; margin: 0px; text-align: center; font-size: .5em;'>
|
||
DEFENSE<br />
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_defense" />
|
||
</div>
|
||
<div class='sheet-col' style='width: 25%; color: #801421; margin: 0px; text-align: center; font-size: .5em;'>
|
||
HEALTH<br />
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_health" />
|
||
</div>
|
||
<div class='sheet-col' style='width: 25%; color: #801421; margin: 0px; text-align: center; font-size: .5em;'>
|
||
ENDURANCE<br />
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px;' name="attr_endurance" />
|
||
</div>
|
||
<div class='sheet-col sheet-red' style='width: 17%; margin: 0px; text-align: center; font-size: .5em; margin-left: 10px;'>
|
||
TV<br />
|
||
<input type="number" class="sheet-combatnum" style='width: 47px; height: 70px; background-color: #801421; color:white;' name="attr_threatvalue" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class='sheet-col sheet-pink' style='width: 50px; height: 475px; font-weight: bold; padding: 5px; padding-right: 2px; margin-left: -3px;'>
|
||
<!--
|
||
<div class='sheet-rotate'>
|
||
Character Record
|
||
</div>
|
||
-->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class='sheet-section-misc sheet-pink' style='padding-bottom: 5px;'>
|
||
<div class='sheet-shim' style='width: 100%; height: 15px;'> </div>
|
||
<div class='sheet-col sheet-notes' style='width:97%; margin: 10px; border-radius: 5px;'>
|
||
Background<br />
|
||
<textarea name='attr_background'></textarea>
|
||
</div>
|
||
|
||
<div class='sheet-shim' style='width: 100%; height: 15px;'> </div>
|
||
|
||
<div class='sheet-2colrow sheet-pink' style="width: 100%;">
|
||
<div class='sheet-col sheet-notes' style='width:46%; margin: 10px; border-radius: 5px;'>
|
||
Appearance <br />
|
||
<textarea name='attr_appearance'></textarea>
|
||
</div>
|
||
<div class='sheet-col sheet-notes' style='width:47%; margin: 10px; margin-right: 5px; border-radius: 5px;'>
|
||
Personality <br />
|
||
<textarea name='attr_personality'></textarea>
|
||
</div>
|
||
</div>
|
||
|
||
<div class='sheet-row sheet-notes' style='width:97%; margin: 10px; margin-right: 5px; border-radius: 5px; padding-bottom: 5px;'>
|
||
Other Notes <br />
|
||
<textarea name='attr_othernotes'></textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!--End Character Sheet data -->
|
||
|
||
<!-- Roll Template Section -->
|
||
|
||
<rolltemplate class="sheet-rolltemplate-ova">
|
||
<!--<h2 class="sheet-caption">{{name}}</h2>-->
|
||
<div class="sheet-rtcard">
|
||
<table>
|
||
{{#name}}
|
||
<caption>{{name}}</caption>
|
||
{{/name}}
|
||
{{#attack}}
|
||
<tbody>
|
||
<tr class="sheet-rth">
|
||
<th colspan="2">{{attack}}</th>
|
||
</tr>
|
||
|
||
{{/attack}}
|
||
{{#allprops() attack desc}}
|
||
<tr>
|
||
<td class="sheet-rresults">{{key}}</td>
|
||
<td class="sheet-rollresults" style='text-align: right;'>{{value}}</td>
|
||
</tr>
|
||
{{/allprops() attack desc}}
|
||
{{#desc}}
|
||
<tr>
|
||
<td colspan=2 class="sheet-rollresults">{{desc}}</td>
|
||
</tr>
|
||
{{/desc}}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</rolltemplate>
|
||
|
||
</div> |