I've not used Edge of the Empire, but on reading the call stack I think you need to add this at line 969:
if(!characterObj){
return;
}
I base this on the following:
- The crash occurs on line 981 of your script when characterObj.name is evaluated with characterObj === null. (Call stack lines 1 and 2)
- eote.updateAddAttribute() is being called by eote.process.suggestionDisplay() on line 1449 with eote.defaults.globalVars.GMObj (see below) as the character. (Call stack line 3)
- eote.process.suggestionDisplay() is being called in eote.process.setup() on line 1115 (Call stack line 4)
- eote.process.setup() is called in an on('chat:message',...) event on line 4132, in eote.events().
- eote.defaults.globalVars.GMObj is initialized to null (otherwise, line 981 would crash on undefined) on line 742
- eote.defaults.globalVars.GMObj is defined in eote.updateListeners() on line 963
- eote.updateListeners() is being called in eote.process.destiny() on line 1681
- eote.process.destiny() is being called in eote.process.setup() on line 1256 (141 lines after the above eote.process.suggestionDisplay() call that uses it.)
I don't know the specifics of this script, but it appears to me that a command which sets up suggestionDisplay (whatever that is) occurs before a command to set up Destiny (whatever that is), which leads to a crash based on the assumption that
GMObj is actually a character object and not
null.
On TokenLock:
This is the code that undoes changes to a token which is not the top of the initiative order:
handleMove = function(obj,prev) {
if(state.TokenLock.locked
&& 'token' === obj.get('subtype')
&& ( !state.TokenLock.config.allowMoveOnTurn || (( (JSON.parse(Campaign().get('turnorder'))||[{id:false}])[0].id) !== obj.id) )
&& ( obj.get('left') !== prev.left || obj.get('top') !== prev.top || obj.get('rotation') !== prev.rotation )
) {
if('' !== obj.get('controlledby')) {
obj.set({left: prev.left, top: prev.top, rotation: prev.rotation});
} else if('' !== obj.get('represents') ) {
var character = getObj('character',obj.get('represents'));
if( character && character.get('controlledby') ) {
obj.set({left: prev.left, top: prev.top, rotation: prev.rotation});
}
}
}
},
As you can see, all it ever changes is the left, top, or rotation of a token, which should have no effect on anything in EotE. The bolded line is the part that deals with the turn order, I'll break it out further as it's a bit compressed:
&& (
!state.TokenLock.config.allowMoveOnTurn || /* check if the setting is active (short circuits if it isn't) */
(
(
(
JSON.parse(Campaign().get('turnorder')) /* parses the current turn order into an array */
||
[{id:false}] /* on failed parse, provides an array with an unmatchable id */
)[0].id) !== obj.id /* checks to see if the current token is not the top of the turn */
)
)
I don't know how that would play with your slots system, but I speculate that players aren't moving "slots" around on the table, so wouldn't really activate this code in an unforeseen way, and it would, at worst, merely prevent players from moving "the token whose turn it is".