diff --git a/js/rpg_core/Graphics.js b/js/rpg_core/Graphics.js
index 93a252a0..8b20562e 100644
--- a/js/rpg_core/Graphics.js
+++ b/js/rpg_core/Graphics.js
@@ -11,6 +11,9 @@ function Graphics() {
Graphics._cssFontLoading = document.fonts && document.fonts.ready && document.fonts.ready.then;
Graphics._fontLoaded = null;
Graphics._videoVolume = 1;
+Graphics._showErrorDetailEnabled = false;
+Graphics._progressEnabled = false;
+Graphics._errorMessage = "";
/**
* Initializes the graphics system.
@@ -411,24 +414,46 @@ Graphics.printError = function(name, message) {
this._clearUpperCanvas();
};
-/**
- * Shows the stacktrace of error.
- *
- * @static
- * @method printStackTrace
- */
-Graphics.printStackTrace = function(stack) {
- if (this._errorPrinter) {
- stack = (stack || '')
- .replace(/file:.*js\//g, '')
- .replace(/http:.*js\//g, '')
- .replace(/https:.*js\//g, '')
- .replace(/chrome-extension:.*js\//g, '')
- .replace(/\n/g, '
');
- this._makeStackTrace(decodeURIComponent(stack));
+Graphics._makeErrorStackLog =function(e){
+ if(e.stack){
+ var log = e.stack.replace(/file:.*js\//g, '')
+ .replace(/http:.*js\//g, '')
+ .replace(/https:.*js\//g, '')
+ .replace(/chrome-extension:.*js\//g, '')
+ .replace(/\n/g, '
');
+ return log;
+ }
+ return '';
+};
+Graphics._makeEventInfo = function(e){
+ if(e.rpgmvErrorLog){
+ return e.rpgmvErrorLog.createErrorHTML();
}
+ return "";
};
+Graphics.createErrorHTML = function(error){
+ return this._makeEventInfo(error)+ this._makeErrorStackLog(error);
+};
+
+Graphics.setErrorDetailEnabled =function(state){
+ this._showErrorDetailEnabled = !!state;
+};
+
+Graphics.printErrorDetail =function(e){
+ if ( this._showErrorDetailEnabled && this._errorPrinter){
+ var html = this.createErrorHTML(e);
+ var detail = document.createElement('div');
+ var style = detail.style;
+ style.color = 'white';
+ style.textAlign = 'left';
+ style.fontSize = '18px';
+ detail.innerHTML = html + '
' ;
+ this._errorPrinter.appendChild(detail);
+ }
+};
+
+
/**
* Sets the error message.
*
diff --git a/js/rpg_managers/SceneManager.js b/js/rpg_managers/SceneManager.js
index d4c8d804..6815cda1 100644
--- a/js/rpg_managers/SceneManager.js
+++ b/js/rpg_managers/SceneManager.js
@@ -197,11 +197,18 @@ SceneManager.onKeyDown = function(event) {
}
};
+SceneManager.showErrorLog = function(e){
+ console.error(e.stack);
+ if(e.rpgmvErrorLog){
+ console.error(e.rpgmvErrorLog.createConsoleMessage() );
+ }
+};
+
SceneManager.catchException = function(e) {
if (e instanceof Error) {
Graphics.printError(e.name, e.message);
- Graphics.printStackTrace(e.stack);
- console.error(e.stack);
+ Graphics.printErrorDetail(e);
+ this.showErrorLog(e);
} else {
Graphics.printError('UnknownError', e);
}
diff --git a/js/rpg_objects/Game_Character.js b/js/rpg_objects/Game_Character.js
index 85bfed0d..67718352 100644
--- a/js/rpg_objects/Game_Character.js
+++ b/js/rpg_objects/Game_Character.js
@@ -80,6 +80,7 @@ Game_Character.prototype.restoreMoveRoute = function() {
this._moveRoute = this._originalMoveRoute;
this._moveRouteIndex = this._originalMoveRouteIndex;
this._originalMoveRoute = null;
+ this._moveRouteLog = null;
};
Game_Character.prototype.isMoveRouteForcing = function() {
@@ -262,10 +263,28 @@ Game_Character.prototype.processMoveCommand = function(command) {
AudioManager.playSe(params[0]);
break;
case gc.ROUTE_SCRIPT:
- eval(params[0]);
+ this.evalRouteScript(params[0]);
break;
}
};
+Game_Character.prototype.evalRouteScript = function(script){
+ var gc = Game_Character;
+ try {
+ eval(script);
+ } catch (error) {
+
+ if(this._moveRouteLog){
+ this._moveRouteLog.setMoveRouteIndex(this._moveRouteIndex);
+ this._moveRouteLog.addLog('target:'+this.debugName());
+ this._moveRouteLog.addLog("script:"+script);
+ this.saveErrorCode(error);
+ }
+ throw(error);
+ }
+};
+Game_Character.prototype.saveErrorCode =function(exeption){
+ exeption.rpgmvErrorLog = this._moveRouteLog;
+};
Game_Character.prototype.deltaXFrom = function(x) {
return $gameMap.deltaX(this.x, x);
diff --git a/js/rpg_objects/Game_CharacterBase.js b/js/rpg_objects/Game_CharacterBase.js
index a3cda3b9..84211be4 100644
--- a/js/rpg_objects/Game_CharacterBase.js
+++ b/js/rpg_objects/Game_CharacterBase.js
@@ -48,6 +48,7 @@ Game_CharacterBase.prototype.initMembers = function() {
this._jumpCount = 0;
this._jumpPeak = 0;
this._movementSuccess = true;
+ this._moveRouteLog =null;
};
Game_CharacterBase.prototype.pos = function(x, y) {
@@ -588,3 +589,11 @@ Game_CharacterBase.prototype.endAnimation = function() {
Game_CharacterBase.prototype.endBalloon = function() {
this._balloonPlaying = false;
};
+
+Game_CharacterBase.prototype.setMoveRouteLog = function(callLog){
+ this._moveRouteLog = callLog;
+};
+Game_CharacterBase.prototype.debugName = function(){
+ return "CharacterBase";
+};
+
diff --git a/js/rpg_objects/Game_CommonEvent.js b/js/rpg_objects/Game_CommonEvent.js
index 5a9a707c..044de620 100644
--- a/js/rpg_objects/Game_CommonEvent.js
+++ b/js/rpg_objects/Game_CommonEvent.js
@@ -36,10 +36,14 @@ Game_CommonEvent.prototype.isActive = function() {
return event.trigger === 2 && $gameSwitches.value(event.switchId);
};
+Game_CommonEvent.prototype.setupEvent = function(){
+ this._interpreter.setup(this.list());
+ this._interpreter.setEventCallLog(new Game_LogCommonEvent(this._commonEventId));
+};
Game_CommonEvent.prototype.update = function() {
if (this._interpreter) {
if (!this._interpreter.isRunning()) {
- this._interpreter.setup(this.list());
+ this.setupEvent();
}
this._interpreter.update();
}
diff --git a/js/rpg_objects/Game_Event.js b/js/rpg_objects/Game_Event.js
index e1924ba7..597f49e1 100644
--- a/js/rpg_objects/Game_Event.js
+++ b/js/rpg_objects/Game_Event.js
@@ -48,6 +48,22 @@ Game_Event.prototype.list = function() {
return this.page().list;
};
+Game_Event.prototype.debugName = function(){
+ var event = this.event();
+ if(event){
+ return "MapEvent:"+ this._eventId +"("+ event.name+")";
+ }
+ return "";
+};
+
+Game_Event.prototype.createLogClass = function(){
+ return new Game_LogMapEvent(
+ this._mapId,
+ this._eventId,
+ this._pageIndex
+ );
+};
+
Game_Event.prototype.isCollidedWithCharacters = function(x, y) {
return (Game_Character.prototype.isCollidedWithCharacters.call(this, x, y) ||
this.isCollidedWithPlayerCharacters(x, y));
@@ -280,6 +296,12 @@ Game_Event.prototype.setupPageSettings = function() {
this.setThrough(page.through);
this.setMoveRoute(page.moveRoute);
this._moveType = page.moveType;
+
+ if(this._moveType === 3){
+ var log =new Game_LogMoveRoute(this.createLogClass());
+ this.setMoveRouteLog( log);
+ }
+
this._trigger = page.trigger;
if (this._trigger === 4) {
this._interpreter = new Game_Interpreter();
@@ -287,7 +309,6 @@ Game_Event.prototype.setupPageSettings = function() {
this._interpreter = null;
}
};
-
Game_Event.prototype.isOriginalPattern = function() {
return this.pattern() === this._originalPattern;
};
@@ -322,6 +343,7 @@ Game_Event.prototype.updateParallel = function() {
if (this._interpreter) {
if (!this._interpreter.isRunning()) {
this._interpreter.setup(this.list(), this._eventId);
+ this._interpreter.setEventCallLog(this.createLogClass());
}
this._interpreter.update();
}
diff --git a/js/rpg_objects/Game_Follower.js b/js/rpg_objects/Game_Follower.js
index d27a87f2..53108218 100644
--- a/js/rpg_objects/Game_Follower.js
+++ b/js/rpg_objects/Game_Follower.js
@@ -55,3 +55,8 @@ Game_Follower.prototype.chaseCharacter = function(character) {
}
this.setMoveSpeed($gamePlayer.realMoveSpeed());
};
+
+Game_Follower.prototype.debugName = function(){
+ return "follower[" + this._memberIndex+"]";
+};
+
diff --git a/js/rpg_objects/Game_Interpreter.js b/js/rpg_objects/Game_Interpreter.js
index 56b36b83..0d825aea 100644
--- a/js/rpg_objects/Game_Interpreter.js
+++ b/js/rpg_objects/Game_Interpreter.js
@@ -34,6 +34,7 @@ Game_Interpreter.prototype.clear = function() {
this._comments = '';
this._character = null;
this._childInterpreter = null;
+ this._callLog = null;
};
Game_Interpreter.prototype.setup = function(list, eventId) {
@@ -44,6 +45,10 @@ Game_Interpreter.prototype.setup = function(list, eventId) {
Game_Interpreter.requestImages(list);
};
+Game_Interpreter.prototype.setEventCallLog = function(callLog){
+ this._callLog = callLog;
+};
+
Game_Interpreter.prototype.eventId = function() {
return this._eventId;
};
@@ -55,6 +60,7 @@ Game_Interpreter.prototype.isOnCurrentMap = function() {
Game_Interpreter.prototype.setupReservedCommonEvent = function() {
if ($gameTemp.isCommonEventReserved()) {
this.setup($gameTemp.reservedCommonEvent().list);
+ this.setEventCallLog(new Game_LogCommonEvent($gameTemp._commonEventId) );
$gameTemp.clearCommonEvent();
return true;
} else {
@@ -543,7 +549,7 @@ Game_Interpreter.prototype.command111 = function() {
result = Input.isPressed(this._params[1]);
break;
case 12: // Script
- result = !!eval(this._params[1]);
+ result = !!this.evalScript(this._params[1]);
break;
case 13: // Vehicle
result = ($gamePlayer.vehicle() === $gameMap.vehicle(this._params[1]));
@@ -605,10 +611,13 @@ Game_Interpreter.prototype.command115 = function() {
// Common Event
Game_Interpreter.prototype.command117 = function() {
- var commonEvent = $dataCommonEvents[this._params[0]];
+ var commonEventId =this._params[0];
+ var commonEvent = $dataCommonEvents[commonEventId];
if (commonEvent) {
var eventId = this.isOnCurrentMap() ? this._eventId : 0;
this.setupChild(commonEvent.list, eventId);
+ this._childInterpreter.setEventCallLog(new Game_LogCommonEvent(commonEventId));
+
}
return true;
};
@@ -680,7 +689,7 @@ Game_Interpreter.prototype.command122 = function() {
value = this.gameDataOperand(this._params[4], this._params[5], this._params[6]);
break;
case 4: // Script
- value = eval(this._params[4]);
+ value = this.evalScript(this._params[4]);
break;
}
for (var i = this._params[0]; i <= this._params[1]; i++) {
@@ -689,6 +698,20 @@ Game_Interpreter.prototype.command122 = function() {
return true;
};
+Game_Interpreter.prototype.evalScript = function(script){
+ try {
+ return eval(script);
+ } catch (error) {
+ if(this._callLog){
+ this._callLog.addLog(this.errorCode(this._index));
+ this._callLog.addLog("ScriptError");
+ this._callLog.addLog(script);
+ this.saveErrorCode(error);
+ }
+ throw(error);
+ }
+};
+
Game_Interpreter.prototype.gameDataOperand = function(type, param1, param2) {
switch (type) {
case 0: // Item
@@ -1027,6 +1050,9 @@ Game_Interpreter.prototype.command205 = function() {
if (this._params[1].wait) {
this.setWaitMode('route');
}
+ var log =new Game_LogMoveRoute(this._callLog);
+ log.setEventCommandLine(this._index);
+ this._character.setMoveRouteLog(log);
}
return true;
};
@@ -1732,11 +1758,16 @@ Game_Interpreter.prototype.command354 = function() {
// Script
Game_Interpreter.prototype.command355 = function() {
var script = this.currentCommand().parameters[0] + '\n';
- while (this.nextEventCode() === 655) {
- this._index++;
- script += this.currentCommand().parameters[0] + '\n';
+ var index =this._index+1;
+
+ var eventCode = this._list[index];
+ while(eventCode && eventCode.code ===655){
+ script += eventCode.parameters[0]+"\n";
+ ++index;
+ eventCode = this._list[index];
}
- eval(script);
+ this.evalScript(script);
+ this._index = index-1;
return true;
};
@@ -1744,13 +1775,63 @@ Game_Interpreter.prototype.command355 = function() {
Game_Interpreter.prototype.command356 = function() {
var args = this._params[0].split(" ");
var command = args.shift();
- this.pluginCommand(command, args);
+ try {
+ this.pluginCommand(command, args);
+ } catch (error) {
+ if(this._callLog){
+ this._callLog.addLog(this.errorCode(this._index));
+ this._callLog.addLog("command:"+command);
+ this._callLog.addLog("args:"+args);
+ this.saveErrorCode(error);
+ }
+ throw(error);
+ }
return true;
};
Game_Interpreter.prototype.pluginCommand = function(command, args) {
// to be overridden by plugins
};
+Game_Interpreter.codeName = function(code){
+
+
+ switch (code) {
+ case 111:
+ return "Conditional Branch";
+ case 122:
+ return "Control Variables";
+ case 355:
+ return "Script";
+ case 356:
+ return "Plugin Command";
+ }
+ return "";
+};
+Game_Interpreter.prototype.errorCode = function(errorLine){
+ var data= this._list[errorLine];
+ var lineText = "line:"+(errorLine+1);
+ if(!data){
+ return lineText +" Out of Code range"
+ }
+
+ if(data.code ===355){
+ for(var i = errorLine+1; i< this._list.length;++i){
+ var scriptData = this._list[i];
+ if(scriptData && scriptData.code !==655){
+ if( errorLine < (i-1) ){
+ lineText +="-"+i;
+ }
+ break;
+ }
+ }
+ }
+ return lineText + " " + Game_Interpreter.codeName(data.code);
+};
+
+Game_Interpreter.prototype.saveErrorCode =function(exeption){
+ exeption.rpgmvErrorLog = this._callLog;
+};
+
Game_Interpreter.requestImagesByPluginCommand = function(command,args){
};
diff --git a/js/rpg_objects/Game_Log.js b/js/rpg_objects/Game_Log.js
new file mode 100644
index 00000000..47526eee
--- /dev/null
+++ b/js/rpg_objects/Game_Log.js
@@ -0,0 +1,190 @@
+function Game_LogBase(){
+ this.initialize.apply(this,arguments);
+}
+
+Game_LogBase.prototype.initialize = function(){
+ this._additionalLog =[];
+};
+
+Game_LogBase.prototype.createMessage = function(){
+ return 'unknown error';
+};
+
+Game_LogBase.prototype.createErrorHTML = function(){
+ var addError = this.createAdditionalError('
');
+ return this.createMessage() +addError+ '