Skip to content

Instantly share code, notes, and snippets.

@BaldarSilveraxe
Last active September 6, 2015 01:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BaldarSilveraxe/f50db7b37a434c59e55f to your computer and use it in GitHub Desktop.
Save BaldarSilveraxe/f50db7b37a434c59e55f to your computer and use it in GitHub Desktop.
AOEDrawer Roll20 API
/*global sendChat, createObj, getObj, toFront, toBack, state, _, log, on, filterObjs, setTimeout, playerIsGM*/
/*jslint white: true */
var AOEDrawer = AOEDrawer || (function(){
'use strict';
//breakcode = breakcode
var version = 0.81,
lastUpdate = 1440326236,
schemaVersion = 0.81,
//Default Settings
slideMenuDefaultOn = false,
strokeDefault = '#ff0000',
stroke = '#ff0000',
strokeWidth = 2,
controlWidth = 25,
ControlHeight = 25,
iconIndex = [],
keyIndex = [],
controlIndex = {},
menuIndex = {},
subMenuIndex = {},
//sliderIndex = {},
icons = [
{key: '000', url: 'https://s3.amazonaws.com/files.d20.io/images/11586803/h8osf5_LzhhLnd2b-xQ14w/thumb.png?1439740906'},
{key: '001', url: 'https://s3.amazonaws.com/files.d20.io/images/11599767/axQ_j6iVfMiyR-GH4XOICw/thumb.png?1439772721'},
{key: '002', url: 'https://s3.amazonaws.com/files.d20.io/images/11599764/Ypi69de9_TysWnzr0DCn6Q/thumb.png?1439772710'},
{key: '003', url: 'https://s3.amazonaws.com/files.d20.io/images/11695574/i9svmUrm5eFqVpKEKsRRDg/thumb.png?1440161024'},
{key: '004', url: 'https://s3.amazonaws.com/files.d20.io/images/11695573/MB1fcqoCGVYhQ3Z-I0UjRQ/thumb.png?1440161021'},
{key: '005', url: 'https://s3.amazonaws.com/files.d20.io/images/11655199/Gcr7m87Mt2AMOrhAUuF-uw/thumb.png?1440000088'},
{key: '006', url: 'https://s3.amazonaws.com/files.d20.io/images/11655198/IbMLzahdaGzmsZhm30g8BQ/thumb.png?1440000084'},
{key: '007', url: 'https://s3.amazonaws.com/files.d20.io/images/11695570/oMjSBI1TP8aakBdFhZb5kg/thumb.png?1440161017'},
{key: '008', url: 'https://s3.amazonaws.com/files.d20.io/images/11695569/eBn3dtLC2RLS6Mfvwji65A/thumb.png?1440161014'},
{key: '009', url: 'https://s3.amazonaws.com/files.d20.io/images/11759786/Iv3U3YdFpmRLc7xEm3HziQ/thumb.png?1440346196'},
{key: '010', url: 'https://s3.amazonaws.com/files.d20.io/images/11759790/JyH9Vush0peWGbFEci9kag/thumb.png?1440346201'}
],
objectNodeIc = 'https://s3.amazonaws.com/files.d20.io/images/11955642/VtboJWMnboar1U3Ytq23EQ/thumb.png?1441053682',
objectCenter = 'https://s3.amazonaws.com/files.d20.io/images/11955640/Hfb6XR-8jfJOry5i8d7j-Q/thumb.png?1441053678',
// ~~~> Cahnge Settings <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
changeSettings = (function(){
var toggleOnDefault = function() {
if( true === state.AOEdrawer.config.defaultOn ) {
state.AOEdrawer.config.defaultOn = false;
}else{
state.AOEdrawer.config.defaultOn = true;
}
},
getInput = function(input) {
switch(input){
case 'toggleOnDefault': toggleOnDefault(); break;
}
};
return {
Input: getInput
};
}()),
// ~~~> Cahnge Settings <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~> Chat Output <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
chatOutput = (function(){
var slideSwitch = function(href,onOff,options) {
var color = onOff ? '#393' : '#933',
float = onOff ? 'left' : 'right',
html = ''
+'<a href="'+href+'"style="display:block; width:2em;border:1px solid black; border-radius: 1em; padding: 1px;background-color: '
+color+';">'
+'<div style="width: 1em;height:1em;border:1px solid #333;border-radius:1em;background-color: white;float: '+float+';"> </div>'
+'<div style="clear:both;"></div></a>';
return html;
},
button = function(href,text,options) {
var html = ''
+ '<a href="'+href+'" style="background-color:#456ac7; -moz-border-radius:14px; -webkit-border-radius:14px;'
+ ' border-radius:14px; border:1px solid #194fab; display:inline-block; cursor:pointer; color:#ffffff; '
+ 'font-family:Arial; font-size:12px; padding:5px 10px; width: 150px; text-decoration:none;">'
+text+'</a>';
return html;
},
tableRowSwitch = function(value) {
var html = ''
+ '<tr style="border: 1px solid black;">'
+ '<td>' + value.text
+ '</td><td width="25">'
+ slideSwitch(value.command,value.onOff,value.options)
+ '</td></tr>';
return html;
},
tableRowButton = function(value) {
var html = ''
+ '<tr style="border: 1px solid black; text-align: center;">'
+ '<td colspan="2">'
+ button(value.command,value.text,value.options)
+ '</td></tr>';
return html;
},
help = function(toTarget) {
var content = toTarget + '<br><b>Beta Script. Read more here</b><br>'
+ '<table bgcolor="#FFFFFF">'
+ tableRowButton({
text: 'Main Menu.',
command: '!aoedrawer menu',
options: {}
})
+ '</table>';
sendChat('API', content);
},
menu = function(toTarget,gm) {
var content = toTarget + '<br>'
+ '<table bgcolor="#FFFFFF">';
if(gm){
content = content + tableRowSwitch({
text: state.AOEdrawer.config.defaultOn ? '<b>Drawing Control "Off" by default.</b>' : '<b>Drawing Control "On" by default.</b>',
command: '!aoedrawer toggleOnDefault',
onOff: state.AOEdrawer.config.defaultOn,
options: {}
});
}
content = content + tableRowButton({
text: 'Toggle On/Off for selected.',
command: '!aoedrawer toggleMenu',
options: {}
})
+ tableRowButton({
text: 'Help With this Script.',
command: '!aoedrawer help',
options: {}
})
+ '</table>';
sendChat('AOE Drawer', content);
},
getInput = function(input) {
var toTarget = '/w "' + (getObj('player', input.who) || {get: function() {return '';}}).get('displayname') + '" ';
switch(input.action){
case 'help': help(toTarget,input.gm); break;
case 'menu': menu(toTarget,input.gm); break;
}
};
return {
Input: getInput
};
}()),
// ~~~> Chat Output <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~> Place Spel Effect <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
placeEffect = (function(){
var checkAngle = function(ax,ay,bx,by) {
var ty = by - ay, tx = bx - ax, theta = Math.atan2(ty, tx);
theta *= 180 / Math.PI;
return theta + 180;
},
measurementValue = function (page,shape,distance1,distance2) {
var displayValue,w,h;
switch(shape){
case 'circle':
displayValue = (((distance1 / 2) / 70) * page.get('scale_number'));
displayValue = 'R:' + displayValue.toFixed(2) + ' ' + page.get('scale_units');
break;
case 'rectangle':
w = ((distance1 / 70) * page.get('scale_number')) * 2;
h = ((distance2 / 70) * page.get('scale_number')) * 2;
w = 'W:' + w.toFixed(1) + ' ' + page.get('scale_units');
h = 'H:' + h.toFixed(1) + ' ' + page.get('scale_units');
displayValue = w + ' ' + h;
break;
case 'cone':
displayValue = (((distance1) / 70) * page.get('scale_number'));
displayValue = 'L:' + displayValue.toFixed(2) + ' ' + page.get('scale_units') + ' ' + distance2 + '°';
break;
case 'ray':
displayValue = (((distance1) / 70) * page.get('scale_number'));
displayValue = 'L:' + displayValue.toFixed(2) + ' ' + page.get('scale_units');
break;
}
return displayValue;
},
lineDistance = function (point1, point2) {
return Math.sqrt( (point2.x - point1.x) * (point2.x - point1.x) + (point2.y - point1.y) * (point2.y - point1.y) );
},
createShape = function (value) { //(token,c,l,t,w,h,p)
var path = createObj('path', {
layer: 'objects',
pageid: value.token.get('_pageid'),
controlledby: value.controlledby,
left: value.left,
top: value.top,
width: value.width,
height: value.height,
path: value.path,
stroke: stroke,
stroke_width: strokeWidth,
rotation: value.rotation || 0
});
return path;
},
createControl = function (values) {
var control = createObj('graphic', {
imgsrc: objectNodeIc,
pageid: values.obj.get('pageid'),
layer: values.obj.get('layer'),
controlledby: 'NEW,' + values.controlList,
isdrawing: true,
width: controlWidth,
height: ControlHeight,
left: values.left,
top: values.top,
showname: true,
showplayers_name: true,
name: '',
lastmove: values.left + ',' + values.top,
tint_color: stroke,
light_hassight: true,
light_losangle: 0,
light_radius: 1
});
return control;
},
createCenter = function (values) {
var control = createObj('graphic', {
imgsrc: objectCenter,
pageid: values.obj.get('pageid'),
layer: values.obj.get('layer'),
controlledby: 'NEW,' + values.controlList,
isdrawing: true,
width: controlWidth,
height: ControlHeight,
left: values.obj.get('left') + values.offsetLeft,
top: values.obj.get('top') + values.offsetTop,
showname: true,
showplayers_name: true,
name: '',
lastmove: values.obj.get('left') + values.offsetLeft + ',' + values.obj.get('top') + values.offsetTop,
tint_color: stroke,
light_hassight: true,
light_losangle: 0,
light_radius: 1
});
return control;
},
getCircle = function (diameter) {
var pts = _.map([0,0.22382,0.5,0.77614,1],function(f){ return f*diameter; });
return {
path: '[["M",'+pts[0]+','+pts[2]+'],'+
'["C", '+pts[0]+', '+pts[1]+', '+pts[1]+', '+pts[0]+', '+pts[2]+', '+pts[0]+'],'+
'["C", '+pts[3]+', '+pts[0]+', '+pts[4]+', '+pts[1]+', '+pts[4]+', '+pts[2]+'],'+
'["C", '+pts[4]+', '+pts[3]+', '+pts[3]+', '+pts[4]+', '+pts[2]+', '+pts[4]+'],'+
'["C", '+pts[1]+', '+pts[4]+', '+pts[0]+', '+pts[3]+', '+pts[0]+', '+pts[2]+']]',
center: {x: pts[2], y: pts[2]},
box: {width: pts[4],height: pts[4]}
};
},
getSquare = function (w,h) {
return {
path: '[["M",'+ 0 +','+ 0 +'],'+
'["L", '+ w +', '+ 0 +'],'+
'["L", '+ w +', '+ h +'],'+
'["L", '+ 0 +', '+ h +'],'+
'["L", '+ 0 +', '+ 0 +']]',
center: {x: w/2, y: h/2},
box: {width: w, height: h}
};
},
rotate_point = function (pointX, pointY, originX, originY, angle) {
angle = angle * Math.PI / 180.0;
return {
x: Math.cos(angle) * (pointX-originX) - Math.sin(angle) * (pointY-originY) + originX,
y: Math.sin(angle) * (pointX-originX) + Math.cos(angle) * (pointY-originY) + originY
};
},
getCone = function (distance,angle,spin) {
var opposite = distance * Math.tan((angle / 2) * (Math.PI / 180)),
x0 = opposite, y0 = 0,
x1 = opposite * 2, y1 = distance,
x2 = 0, y2 = distance,
x3 = opposite, y3 = 0,
w = opposite * 2, h = distance,
spunPoints;
spunPoints = rotate_point(x0,y0,opposite,0, spin); x0 = spunPoints.x; y0 = spunPoints.y;
spunPoints = rotate_point(x1,y1,opposite,0, spin); x1 = spunPoints.x; y1 = spunPoints.y;
spunPoints = rotate_point(x2,y2,opposite,0, spin); x2 = spunPoints.x; y2 = spunPoints.y;
spunPoints = rotate_point(x3,y3,opposite,0, spin); x3 = spunPoints.x; y3 = spunPoints.y;
w = Math.max(x0,x1,x2,x3) - Math.min(x0,x1,x2,x3);
h = Math.max(y0,y1,y2,y3) - Math.min(y0,y1,y2,y3);
return {
path: '[["M",'+ x0 +','+ y0 +'],'+
'["L", '+ x1 +', '+ y1 +'],'+
'["L", '+ x2 +', '+ y2 +'],'+
'["L", '+ x3 +', '+ y3 +']]',
center: {x: Math.min(x0,x1,x2,x3) + (w/2) - x0, y: Math.min(y0,y1,y2,y3) + (h/2) - y0},
box: {width: w, height: h}
};
},
getRay = function (distance,spin) {
var x0 = 0, y0 = 0,
x1 = 0, y1 = distance,
w = strokeWidth, h = distance;
return {
path: '[["M",'+ x0 +','+ y0 +'],["L", '+ x1 +', '+ y1 +']]',
center: {x: strokeWidth / 2, y: distance / 2},
box: {width: w, height: h}
};
},
createNewShape = function (token,key,type) {
var controlList,page,shape,tokenOffsetLeft,tokenOffsetTop,contrlOffsetLeft,contrlOffsetTop,distance,control,measurement,playercolor;
if( undefined === token ) {return; }
page = getObj('page', token.get('pageid'));
if( undefined === page ) {return; }
controlList = getObj('character', token.get('represents'));
if( undefined !== controlList ) {controlList = controlList.get('controlledby'); }else{controlList = ''; }
playercolor = getObj('player', _.first(controlList.split(',')));
if( undefined !== playercolor ) {
stroke = playercolor.get('color');
}else{
stroke = strokeDefault;
}
switch(type){
case 'CircleToken': case 'CircleContr':
shape = getCircle(140);
break;
case 'RctnglToken': case 'RctnglContr': case 'SquareToken': case 'SquareContr':
shape = getSquare(140,140);
break;
case 'ConeslToken': case 'ConeslContr':
shape = getCone(140,30,0);
break;
case 'DthRayToken': case 'DthRayContr':
shape = getRay(140,0);
break;
}
tokenOffsetLeft = 70;
tokenOffsetTop = 70;
switch(type){
case 'CircleContr': case 'RctnglContr': case 'SquareContr': case 'ConeslContr': case 'DthRayContr':
token = createCenter({
obj: token,
offsetLeft: tokenOffsetLeft,
offsetTop: tokenOffsetTop,
controlList: controlList
});
break;
}
switch(type){
case 'CircleToken': case 'CircleContr':
contrlOffsetLeft = token.get('left');
contrlOffsetTop = token.get('top') - (shape.box.height / 2);
distance = lineDistance(
{x: contrlOffsetLeft, y: contrlOffsetTop},
{x: tokenOffsetLeft, y: tokenOffsetTop}
);
measurement = measurementValue(page,'circle',distance * 2);
break;
case 'RctnglToken': case 'RctnglContr': case 'SquareToken': case 'SquareContr':
contrlOffsetLeft = token.get('left') - (shape.box.width / 2);
contrlOffsetTop = token.get('top') + (shape.box.height / 2);
measurement = measurementValue(page,'rectangle',shape.box.width,shape.box.height);
break;
case 'ConeslToken': case 'ConeslContr':
contrlOffsetLeft = token.get('left');
contrlOffsetTop = token.get('top') + 140;
measurement = measurementValue(page,'cone',140,30);
break;
case 'DthRayToken': case 'DthRayContr':
contrlOffsetLeft = token.get('left');
contrlOffsetTop = token.get('top') + 140;
measurement = measurementValue(page,'ray',140);
break;
}
control = createControl({
obj: token,
left: contrlOffsetLeft,
top: contrlOffsetTop,
controlList: controlList
});
switch(type){
case 'CircleToken': case 'CircleContr':
case 'RctnglToken': case 'RctnglContr':
case 'SquareToken': case 'SquareContr':
control.set({
name: measurement
});
shape = createShape({
token: token,
controlledby: control.get('id') + ',' + token.get('id'),
left: token.get('left'),
top: token.get('top'),
width: shape.box.width,
height: shape.box.height,
path: shape.path
});
break;
case 'ConeslToken': case 'ConeslContr':
control.set({
name: measurement,
rotation: 30
});
shape = createShape({
token: token,
controlledby: control.get('id') + ',' + token.get('id'),
left: token.get('left') + shape.center.x,
top: token.get('top') + shape.center.y,
width: shape.box.width,
height: shape.box.height,
path: shape.path
});
break;
case 'DthRayToken': case 'DthRayContr':
control.set({
name: measurement
});
shape = createShape({
token: token,
controlledby: control.get('id') + ',' + token.get('id'),
left: token.get('left') + shape.center.x,
top: token.get('top') + shape.center.y,
width: shape.box.width,
height: shape.box.height,
path: shape.path
});
break;
}
state.AOEdrawer.pathData[control.get('id')] = {
type: type,
token: token.get('id'),
control: control.get('id'),
path: shape.get('id'),
color: stroke
};
//TEMP
state.AOEdrawer.preLeftTop[token.get('id')] = token.get('left') + ',' + token.get('top');
//TEMP
controlIndex[control.get('id')] = control.get('id');
controlIndex[shape.get('id')] = control.get('id');
state.AOEdrawer.controlPointMiddl[token.get('id')] = state.AOEdrawer.controlPointMiddl[token.get('id')] || {};
state.AOEdrawer.controlPointMiddl[token.get('id')][control.get('id')] = [control.get('id')];
setTimeout(function() {toBack(shape); }, 300);
},
updateShape = function(action,obj,key,type,centerMove) {
var token,control,shape,path,distance,page = getObj('page', obj.get('pageid')), measurement,spin,angle,lastx,lasty,controlList;
control = getObj('graphic', key.control);
if( undefined === control ) {return; }
token = getObj('graphic', key.token);
lastx = parseInt(state.AOEdrawer.preLeftTop[token.get('id')].split(',')[0]);
lasty = parseInt(state.AOEdrawer.preLeftTop[token.get('id')].split(',')[1]);
if( undefined === token ) {return; }
path = getObj('path', key.path);
if( undefined === path ) {return; }
stroke = path.get('stroke');
switch(type){
case 'ConeslToken': case 'ConeslContr':
spin = (Math.round(control.get('rotation')/5)*5)%360 + (control.get('rotation')<0 ? 360 : 0);
if( spin < 5 ){spin = 5; }
if( spin > 175 ){spin = 175; }
if( true === centerMove ){
control.set({
left: control.get('left') + token.get('left') - lastx,
top: control.get('top') + token.get('top') - lasty,
width: controlWidth,
height: ControlHeight,
rotation: spin
});
}else{
control.set({
left: control.get('left'),
top: control.get('top'),
width: controlWidth,
height: ControlHeight,
rotation: spin
});
}
break;
case 'DthRayToken': case 'DthRayContr':
if( true === centerMove ){
control.set({
left: control.get('left') + token.get('left') - lastx,
top: control.get('top') + token.get('top') - lasty,
width: controlWidth,
height: ControlHeight
});
}else{
control.set({
left: control.get('left'),
top: control.get('top'),
width: controlWidth,
height: ControlHeight
});
}
break;
case 'CircleToken':
case 'RctnglToken':
case 'SquareToken':
case 'CircleContr':
case 'RctnglContr':
case 'SquareContr':
control.set({
left: control.get('left') + token.get('left') - path.get('left'),
top: control.get('top') + token.get('top') - path.get('top'),
rotation: 0,
width: controlWidth,
height: ControlHeight
});
break;
}
switch(type){
case 'CircleToken': case 'CircleContr':
distance = lineDistance(
{x: control.get('left'), y: control.get('top')},
{x: token.get('left'), y: token.get('top')} );
measurement = measurementValue(page,'circle',distance * 2);
break;
case 'RctnglToken': case 'RctnglContr':
measurement = measurementValue(page,'rectangle',
Math.abs(control.get('left') - token.get('left')),
Math.abs(control.get('top') - token.get('top')) );
break;
case 'SquareToken': case 'SquareContr':
measurement = measurementValue(page,'rectangle',
Math.max(Math.abs(control.get('left') - token.get('left')),Math.abs(control.get('top') - token.get('top'))),
Math.max(Math.abs(control.get('left') - token.get('left')),Math.abs(control.get('top') - token.get('top'))) );
break;
case 'ConeslToken': case 'ConeslContr':
angle = checkAngle(token.get('left'),token.get('top'),control.get('left'),control.get('top'));
distance = lineDistance(
{x: control.get('left'), y: control.get('top')},
{x: token.get('left'), y: token.get('top')} );
measurement = measurementValue(page,'cone',distance,spin);
break;
case 'DthRayToken': case 'DthRayContr':
angle = checkAngle(token.get('left'),token.get('top'),control.get('left'),control.get('top'));
distance = lineDistance(
{x: control.get('left'), y: control.get('top')},
{x: token.get('left'), y: token.get('top')} );
measurement = measurementValue(page,'ray',distance);
break;
}
control.set('name', measurement);
delete controlIndex[path.get('id')];
path.remove();
switch(type){
case 'CircleToken': case 'CircleContr':
shape = getCircle(distance * 2);
break;
case 'RctnglToken': case 'RctnglContr':
shape = getSquare(Math.abs(control.get('left') - token.get('left')) * 2,
Math.abs(control.get('top') - token.get('top')) * 2 );
break;
case 'SquareToken': case 'SquareContr':
shape = getSquare(
Math.max(Math.abs(control.get('left') - token.get('left')) * 2,Math.abs(control.get('top') - token.get('top')) * 2),
Math.max(Math.abs(control.get('left') - token.get('left')) * 2,Math.abs(control.get('top') - token.get('top')) * 2) );
break;
case 'ConeslToken': case 'ConeslContr':
shape = getCone(distance,spin,angle + 90);
break;
case 'DthRayToken': case 'DthRayContr':
shape = getRay(distance,spin);
break;
}
switch(type){
case 'ConeslToken': case 'ConeslContr':
shape = createShape({
token: token,
controlledby: control.get('id') + ',' + token.get('id'),
left: token.get('left') + shape.center.x,
top: token.get('top') + shape.center.y,
width: shape.box.width,
height: shape.box.height,
path: shape.path
});
break;
case 'CircleToken': case 'CircleContr': case 'RctnglToken': case 'RctnglContr': case 'SquareToken': case 'SquareContr':
shape = createShape({
token: token,
controlledby: control.get('id') + ',' + token.get('id'),
left: token.get('left'),
top: token.get('top'),
width: shape.box.width,
height: shape.box.height,
path: shape.path
});
break;
case 'DthRayToken': case 'DthRayContr':
shape = createShape({
token: token,
controlledby: control.get('id') + ',' + token.get('id'),
left: ((token.get('left') + control.get('left'))/2),
top: ((token.get('top') + control.get('top'))/2),
width: shape.box.width,
height: shape.box.height,
path: shape.path,
rotation: angle + 90
});
break;
}
//TEMP
state.AOEdrawer.preLeftTop[token.get('id')] = token.get('left') + ',' + token.get('top');
//TEMP
controlIndex[shape.get('id')] = control.get('id');
state.AOEdrawer.pathData[control.get('id')].path = shape.get('id');
setTimeout(function() {toBack(shape); }, 300);
},
deleteShape = function(obj,key,type) {
var control = getObj('graphic', key.control),
token = getObj('graphic', key.token),
path = getObj('path', key.path);
if ( undefined !== control ) {
delete state.AOEdrawer.pathData[controlIndex[control.get('id')]];
delete controlIndex[control.get('id')]; control.remove();
}
if ( undefined !== path ) {
delete state.AOEdrawer.pathData[controlIndex[path.get('id')]];
delete controlIndex[path.get('id')]; path.remove();
}
switch(type){
case 'CircleContr': case 'RctnglContr': case 'SquareContr': case 'ConeslContr': case 'DthRayContr':
if ( undefined !== token ) {
delete state.AOEdrawer.controlPointMiddl[token.get('id')]; token.remove();
}
break;
default:
delete state.AOEdrawer.controlPointMiddl[token.get('id')][control.get('id')];
break;
}
delete controlIndex[control.get('id')];
},
getInput = function(value) {
switch(value.icon){
case '001': createNewShape(value.token,value.icon,'CircleToken'); break;
case '002': createNewShape(value.token,value.icon,'CircleContr'); break;
case '003': createNewShape(value.token,value.icon,'RctnglToken'); break;
case '004': createNewShape(value.token,value.icon,'RctnglContr'); break;
case '005': createNewShape(value.token,value.icon,'SquareToken'); break;
case '006': createNewShape(value.token,value.icon,'SquareContr'); break;
case '007': createNewShape(value.token,value.icon,'ConeslToken'); break;
case '008': createNewShape(value.token,value.icon,'ConeslContr'); break;
case '009': createNewShape(value.token,value.icon,'DthRayToken'); break;
case '010': createNewShape(value.token,value.icon,'DthRayContr'); break;
}
},
change = function(obj,centerMove) {
var data;
if ( undefined === controlIndex[obj.get('id')] ) {return; }
data = state.AOEdrawer.pathData[controlIndex[obj.get('id')]];
switch(data.type){
case 'CircleToken': updateShape('change',obj,data,'CircleToken',centerMove); break;
case 'CircleContr': updateShape('change',obj,data,'CircleContr',centerMove); break;
case 'RctnglToken': updateShape('change',obj,data,'RctnglToken',centerMove); break;
case 'RctnglContr': updateShape('change',obj,data,'RctnglContr',centerMove); break;
case 'SquareToken': updateShape('change',obj,data,'SquareToken',centerMove); break;
case 'SquareContr': updateShape('change',obj,data,'SquareContr',centerMove); break;
case 'ConeslToken': updateShape('change',obj,data,'ConeslToken',centerMove); break;
case 'ConeslContr': updateShape('change',obj,data,'ConeslContr',centerMove); break;
case 'DthRayToken': updateShape('change',obj,data,'DthRayToken',centerMove); break;
case 'DthRayContr': updateShape('change',obj,data,'DthRayContr',centerMove); break;
}
},
handleGraphicChangeLeftTopSpin = function(obj) {
var control,hasControl = false;
if( objectNodeIc === obj.get('imgsrc') ) {
change(obj,false);
setTimeout(function() {toFront(obj); }, 100);
return;
}
_.each(state.AOEdrawer.controlPointMiddl[obj.get('id')], function(cId) {
control = getObj('graphic', cId);
if ( undefined !== control ){
change(control,true);
hasControl = true;
setTimeout(function() {toFront(control); }, 100);
}
});
if ( true === hasControl ){
if( objectCenter === obj.get('imgsrc') ) {
obj.set({width: controlWidth, height: ControlHeight, rotation: 0 });
}
setTimeout(function() {toFront(obj); }, 100);
}
},
handlePathChange = function(obj) {
var control;
control = getObj('graphic', controlIndex[obj.get('id')]);
if ( undefined !== control ){change(control,false); }
},
detroy = function(obj) {
var data;
if ( undefined === controlIndex[obj.get('id')] ) {return; }
data = state.AOEdrawer.pathData[controlIndex[obj.get('id')]];
switch(data.type){
case 'CircleToken': deleteShape(obj,data,'CircleToken'); break;
case 'CircleContr': deleteShape(obj,data,'CircleContr'); break;
case 'RctnglToken': deleteShape(obj,data,'RctnglToken'); break;
case 'RctnglContr': deleteShape(obj,data,'RctnglContr'); break;
case 'SquareToken': deleteShape(obj,data,'SquareToken'); break;
case 'SquareContr': deleteShape(obj,data,'SquareContr'); break;
case 'ConeslToken': deleteShape(obj,data,'ConeslToken'); break;
case 'ConeslContr': deleteShape(obj,data,'ConeslContr'); break;
case 'DthRayToken': deleteShape(obj,data,'DthRayToken'); break;
case 'DthRayContr': deleteShape(obj,data,'DthRayContr'); break;
}
delete state.AOEdrawer.pathData[controlIndex[obj.get('id')]];
},
handleGraphicDestroy = function(obj) {
var control;
if( objectNodeIc === obj.get('imgsrc') ) {detroy(obj); }
_.each(state.AOEdrawer.controlPointMiddl[obj.get('id')], function(cId) {
control = getObj('graphic', cId);
if ( undefined !== control ){detroy(control); }
});
delete state.AOEdrawer.controlPointMiddl[obj.get('id')];
},
handleGraphicChange = function(obj) {
var controlledby = obj.get('controlledby').split(',');
if( 'NEW' === controlledby[0] ) {
controlledby.shift();
obj.set({
controlledby: controlledby.toString(),
left: obj.get('left') + 0.1
});
setTimeout(function() {toFront(obj); }, 100);
}
},
registerEventHandlers = function(){
on('change:graphic', handleGraphicChange );
on("change:graphic:lastmove", handleGraphicChangeLeftTopSpin);
on("change:graphic:rotation", handleGraphicChangeLeftTopSpin);
on("change:path", handlePathChange);
on("destroy:path", handlePathChange);
on('destroy:graphic', handleGraphicDestroy);
};
return {
RegisterEventHandlers: registerEventHandlers,
Input: getInput
};
}()),
// ~~~> Place Spel Effect <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~> Menu <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
menu = (function(){
var createNewMenuIcon = function(obj,character) {
var menuIcon = createObj('graphic', {
pageid: obj.get('pageid'),
imgsrc: keyIndex['000'],
left: obj.get('left') - (obj.get('width') / 2) + 10,
top: obj.get('top') + (obj.get('height') / 2) - 10,
width: controlWidth,
height: ControlHeight,
layer: obj.get('layer'),
isdrawing: true,
controlledby: 'NEW,' + character.get('controlledby'),
light_hassight: true,
light_losangle: 0,
light_radius: 1
});
state.AOEdrawer.preLeftTop[menuIcon.get('id')] = menuIcon.get('left') + ',' + menuIcon.get('top');
menuIndex[menuIcon.get('id')] = obj.get('id');
state.AOEdrawer.tokenMenu[obj.get('id')] = [menuIcon.get('id')];
setTimeout(function() {toFront(menuIcon); }, 300);
return menuIcon;
},
setMenuIcon = function(menuItem,obj) {
menuItem.set({
left: obj.get('left') - (obj.get('width') / 2) + 10,
top: obj.get('top') + (obj.get('height') / 2) - 10,
rotation: 0,
width: controlWidth,
height: ControlHeight,
layer: obj.get('layer')
});
state.AOEdrawer.preLeftTop[menuItem.get('id')] = menuItem.get('left') + ',' + menuItem.get('top');
setTimeout(function() {toFront(menuItem); }, 300);
},
createNewSubMenu = function(token,imgsrc,left,top,controlledby) {
var submenu = createObj('graphic', {
pageid: token.get('pageid'),
imgsrc: imgsrc,
left: token.get('left')+(token.get('width')/2) + left,
top: token.get('top')-(token.get('height')/2) + top,
width: controlWidth,
height: ControlHeight,
layer: token.get('layer'),
isdrawing: true,
controlledby: controlledby,
light_hassight: true,
light_losangle: 0,
light_radius: 1
});
setTimeout(function() {toFront(submenu); }, 300);
return submenu;
},
deleteSubMenu = function(token) {
if( undefined === state.AOEdrawer.tokenSubMenu[token.get('id')] ) {
return;
}
_.each(state.AOEdrawer.tokenSubMenu[token.get('id')], function(sm) {
if( undefined !== getObj('graphic', sm) ){
delete subMenuIndex[sm];
getObj('graphic', sm).remove();
}
});
delete state.AOEdrawer.tokenSubMenu[token.get('id')];
},
subMenu = function(token) {
var submenu, character = getObj('character', token.get('represents')),subMenuArray = [];
if( undefined === token) {
return;
}
if( undefined === character ) {
return;
}
character = 'NEW,' + character.get('controlledby');
submenu = createNewSubMenu(token,keyIndex['001'], 10,18,character);
subMenuArray.push(submenu.get('id')); subMenuIndex[submenu.get('id')] = token.get('id');
submenu = createNewSubMenu(token,keyIndex['002'], 10,48,character);
subMenuArray.push(submenu.get('id')); subMenuIndex[submenu.get('id')] = token.get('id');
submenu = createNewSubMenu(token,keyIndex['003'], 35,18,character);
subMenuArray.push(submenu.get('id')); subMenuIndex[submenu.get('id')] = token.get('id');
submenu = createNewSubMenu(token,keyIndex['004'], 35,48,character);
subMenuArray.push(submenu.get('id')); subMenuIndex[submenu.get('id')] = token.get('id');
submenu = createNewSubMenu(token,keyIndex['005'], 60,18,character);
subMenuArray.push(submenu.get('id')); subMenuIndex[submenu.get('id')] = token.get('id');
submenu = createNewSubMenu(token,keyIndex['006'], 60,48,character);
subMenuArray.push(submenu.get('id')); subMenuIndex[submenu.get('id')] = token.get('id');
submenu = createNewSubMenu(token,keyIndex['007'], 90,18,character);
subMenuArray.push(submenu.get('id')); subMenuIndex[submenu.get('id')] = token.get('id');
submenu = createNewSubMenu(token,keyIndex['008'], 90,47,character);
subMenuArray.push(submenu.get('id')); subMenuIndex[submenu.get('id')] = token.get('id');
submenu = createNewSubMenu(token,keyIndex['009'],110,18,character);
subMenuArray.push(submenu.get('id')); subMenuIndex[submenu.get('id')] = token.get('id');
submenu = createNewSubMenu(token,keyIndex['010'],110,48,character);
subMenuArray.push(submenu.get('id')); subMenuIndex[submenu.get('id')] = token.get('id');
state.AOEdrawer.tokenSubMenu[token.get('id')] = subMenuArray;
},
handleSubMenuDestroy = function(obj) {
var token,key;
key = iconIndex[obj.get('imgsrc')];
token = getObj('graphic', subMenuIndex[obj.get('id')]);
if( undefined !== token ) {
deleteSubMenu(token);
}
},
handleSubMenuChange = function(obj) {
var controlledby = obj.get('controlledby').split(','),token;
if( 'NEW' === controlledby[0] ) {
controlledby.shift();
obj.set('controlledby', controlledby.toString());
return;
}
token = getObj('graphic', subMenuIndex[obj.get('id')]);
if( undefined !== token ) {
deleteSubMenu(token);
}
placeEffect.Input({
token: token,
icon: iconIndex[obj.get('imgsrc')]
});
},
handleTokenChange = function(obj) {
var menuItem, character = getObj('character', obj.get('represents'));
menuItem = getObj('graphic', state.AOEdrawer.tokenMenu[obj.get('id')]);
if( undefined === menuItem ) {
delete state.AOEdrawer.tokenMenu[obj.get('id')];
delete state.AOEdrawer.preLeftTop[obj.get('id')];
delete menuIndex[obj.get('id')];
}else{
if ( menuItem.get('imgsrc') === keyIndex['000'] ){
setMenuIcon(menuItem,obj);
deleteSubMenu(obj);
}
return;
}
if( undefined !== menuItem ) {
return;
}
if ( undefined === character ) {
return;
}
createNewMenuIcon(obj,character);
deleteSubMenu(obj);
},
handleMenuChange = function(obj) {
var controlledby = obj.get('controlledby').split(','),token;
if( 'NEW' === controlledby[0] ) {
controlledby.shift();
obj.set('controlledby', controlledby.toString());
return;
}
//deltaX = Math.abs(state.AOEdrawer.preLeftTop[obj.get('id')].split(',')[0] - obj.get('left'));
//deltaY = Math.abs(state.AOEdrawer.preLeftTop[obj.get('id')].split(',')[1] - obj.get('top'));
token = getObj('graphic', menuIndex[obj.get('id')] );
if( undefined === token ) {
delete state.AOEdrawer.tokenMenu[menuIndex[obj.get('id')]];
delete menuIndex[obj.get('id')];
delete state.AOEdrawer.preLeftTop[obj.get('id')];
obj.remove();
return;
}
setMenuIcon(obj,token);
if( undefined !== state.AOEdrawer.tokenSubMenu[token.get('id')] ) {
deleteSubMenu(token);
}else{
//if( (deltaX > 20 || deltaY > 20) ) {
// return;
//}else{
// if( (deltaX > 0 && deltaY > 0) ) {
subMenu(token,obj);
// }
//}
}
},
handleMenuDestroy = function(obj) {
var token, character;
if ( undefined === menuIndex[obj.get('id')] ) {
return;
}
token = getObj('graphic', menuIndex[obj.get('id')]);
delete menuIndex[obj.get('id')];
delete state.AOEdrawer.preLeftTop[obj.get('id')];
if( undefined === token ) {
return;
}
delete state.AOEdrawer.tokenMenu[token.get('id')];
character = getObj('character', token.get('represents'));
if ( undefined === character ) {
return;
}
if( undefined === state.AOEdrawer.onForCharacter[token.get('represents')]
&& false === state.AOEdrawer.config.defaultOn ) {
return;
}
createNewMenuIcon(token,character);
deleteSubMenu(token);
},
handleTokenDestroy = function(obj) {
var menuIcon = getObj('graphic', state.AOEdrawer.tokenMenu[obj.get('id')]);
if( undefined !== menuIcon ){
delete menuIndex[menuIcon.get('id')];
delete state.AOEdrawer.preLeftTop[menuIcon.get('id')];
menuIcon.remove();
}
delete state.AOEdrawer.tokenMenu[obj.get('id')];
delete state.AOEdrawer.preLeftTop[obj.get('id')];
delete menuIndex[obj.get('id')];
deleteSubMenu(obj);
},
handleGraphicDestroy = function(obj) {
if( obj.get('imgsrc') === keyIndex['000'] ) {
handleMenuDestroy(obj);
return;
}
if( undefined !== iconIndex[obj.get('imgsrc')] ) {
handleSubMenuDestroy(obj);
}
if( undefined !== state.AOEdrawer.tokenMenu[obj.get('id')] ) {
handleTokenDestroy(obj);
return;
}
},
handleGraphicChange = function(obj) {
var character = getObj('character', obj.get('represents'));
if( obj.get('imgsrc') === keyIndex['000'] ) {
handleMenuChange(obj);
return;
}
if( undefined !== iconIndex[obj.get('imgsrc')] ) {
handleSubMenuChange(obj);
}
if ( undefined === character ) {
return;
}
if( undefined !== state.AOEdrawer.onForCharacter[character.get('id')] ) {
handleTokenChange(obj);
}
if( true === state.AOEdrawer.config.defaultOn ) {
handleTokenChange(obj);
}
},
toggleMenu = function(obj) {
var token = state.AOEdrawer.tokenMenu[obj.get('id')], character = getObj('character', obj.get('represents')), menuIcon;
if( undefined === token ) {
if ( undefined === character ) {
return;
}
state.AOEdrawer.onForCharacter[obj.get('represents')] = obj.get('represents');
createNewMenuIcon(obj,character);
}else{
menuIcon = getObj('graphic',state.AOEdrawer.tokenMenu[obj.get('id')] );
if( undefined !== menuIcon ){
delete menuIndex[menuIcon.get('id')];
delete state.AOEdrawer.preLeftTop[menuIcon.get('id')];
menuIcon.remove();
}
delete state.AOEdrawer.onForCharacter[obj.get('represents')];
delete state.AOEdrawer.tokenMenu[obj.get('id')];
}
},
getInput = function(input) {
switch(input.action){
case 'toggleMenu':
if( undefined !== input.selected ) {
toggleMenu(input.selected);
}
break;
}
},
registerEventHandlers = function(){
on('change:graphic', handleGraphicChange );
on('destroy:graphic', handleGraphicDestroy);
};
return {
RegisterEventHandlers: registerEventHandlers,
Input: getInput
};
}()),
// ~~~> Menu <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~> inputManagement <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Checked
inputManagement = (function() {
var handleInput = function (msg) {
var message = _.clone(msg);
if ( 'api' !== message.type || '!aoedrawer' !== message.content.split(/\s+/)[0] ) {
return;
}
switch(message.content.split(/\s+/)[1]) {
case 'menu':
chatOutput.Input({
action: 'menu',
who: message.playerid,
gm: playerIsGM(message.playerid)
});
break;
case 'toggleMenu':
if( getObj('graphic', (_.first(message.selected)||{_id:0})._id ) ) {
menu.Input({
action: 'toggleMenu',
selected: getObj('graphic', (_.first(message.selected)||{_id:0})._id )
});
}
break;
case 'toggleOnDefault':
changeSettings.Input('toggleOnDefault');
chatOutput.Input({
action: 'menu',
who: message.playerid,
gm: playerIsGM(message.playerid)
});
break;
//######################################REMOVE
//case 'state':
// SotSA.CheckState();
//break;
//######################################REMOVE
default:
chatOutput.Input({
action: 'help',
who: message.playerid,
gm: playerIsGM(message.playerid)
});
break;
}
},
registerEventHandlers = function(){
on('chat:message', handleInput);
};
return {
RegisterEventHandlers: registerEventHandlers
};
}()),
// ~~~> inputManagement <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~> On Start <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Checked
setup = (function() {
var onStart = function() {
if( ! _.has(state,'AOEdrawer' ) || state.AOEdrawer.version !== schemaVersion ) {
state.AOEdrawer = {
version: schemaVersion,
config: {
defaultOn: slideMenuDefaultOn
},
controlPointMiddl: {},
controlPointToken: {},
pathData: {},
charaterSettings: {},
tokenMenu: {},
tokenSubMenu: {},
onForCharacter: {},
preLeftTop: {}
};
log('AOEDrawer: Initialize State');
}else{
Object.keys(state.AOEdrawer.tokenMenu).forEach(function(key) {
if( undefined === getObj('graphic', key) ){
delete state.AOEdrawer.tokenMenu[key];
}
});
Object.keys(state.AOEdrawer.controlPointMiddl).forEach(function(key) {
Object.keys(state.AOEdrawer.controlPointMiddl[key]).forEach(function(subkey) {
if( undefined === getObj('graphic', subkey) ){
delete state.AOEdrawer.controlPointMiddl[key];
}
});
if( undefined === getObj('graphic', key) ){
delete state.AOEdrawer.controlPointMiddl[key];
}
});
Object.keys(state.AOEdrawer.pathData).forEach(function(key) {
if( undefined === getObj('graphic', key) ){
delete state.AOEdrawer.pathData[key];
}
});
Object.keys(state.AOEdrawer.tokenMenu).forEach(function(key) {
if( undefined === getObj('graphic', key) ){
delete state.AOEdrawer.tokenMenu[key];
}
});
Object.keys(state.AOEdrawer.preLeftTop).forEach(function(key) {
if( undefined === getObj('graphic', key) ){
delete state.AOEdrawer.preLeftTop[key];
}
});
}
_.each(icons, function(icon) {
iconIndex[icon.url] = icon.key;
keyIndex[icon.key] = icon.url;
});
Object.keys(state.AOEdrawer.pathData).forEach(function(key) {
controlIndex[state.AOEdrawer.pathData[key].control] = state.AOEdrawer.pathData[key].control;
controlIndex[state.AOEdrawer.pathData[key].path] = state.AOEdrawer.pathData[key].control;
});
Object.keys(state.AOEdrawer.tokenMenu).forEach(function(key) {
menuIndex[state.AOEdrawer.tokenMenu[key]] = key;
});
};
return {
Start: onStart
};
}()),
// ~~~> On Start <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~> Register <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Checked
registerEventHandlers = function() {
setup.Start();
menu.RegisterEventHandlers();
placeEffect.RegisterEventHandlers();
inputManagement.RegisterEventHandlers();
log('AOEDrawer ' + new Date(lastUpdate * 1000) + ' version: ' + version + ' Schema Version: ' + schemaVersion);
log('(!aoedrawer help)');
log('(!aoedrawer menu)');
};
// ~~~> Register <~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return {
RegisterEventHandlers: registerEventHandlers
};
}());
on('ready',function(){
'use strict';
AOEDrawer.RegisterEventHandlers();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment