=begin Output ErrorLog(for VX Ace) ver 1.0.0.0 by Han-Nama http://www.tktkgame.com/ ■ Outline ・ The various output that might help debug log at the end of an error. ・ Log is output as "error_log{date}.txt" in the game folder. ■ How to use ・ More copies on the [Main] to open the script editor ・ If you no longer need the log output, etc. for each item removed when the public ■ Revision History ver 1.0.0.0 (2012/02/27) Published. =end module TKG;end module TKG::ErrorLog # Whether to print a list of switches OUTPUT_SWITCHES = false # Whether to print the list of variables OUTPUT_VARIABLES = false end module TKG::ErrorLog REGEX_BT = /^\{(\d+)\}\:(\d+)/ @error_events = [] @error_script = "" @indent = " " module_function def set_error_script(code) @error_script = code end def set_error_event(map_id, event_id, commonevent_id, troop_page) if commonevent_id > 0 @error_events.push "CommonEvent: #{commonevent_id}" elsif troop_page > 0 @error_events.push "TroopEvent: #{troop_page} page" else @error_events.push "MapEvent: #{map_id}:#{event_id}" end end # Replace the section name, the name of the script def replace_section_name(message) message.sub(REGEX_BT) {|item| section = $RGSS_SCRIPTS[$1.to_i] if section.nil? item else "\"#{section[1]}\"(#{$2})" end } end def error_script_info return "" if @error_script == "" info = "\n■ ScriptCode\n" script_lines = @error_script.gsub("\r","").split("\n") script_lines.each_with_index do |code, index| info += @indent + sprintf("% 2d: %s\n", index + 1,code) end info += "\n" return info end def switches_log return "" unless OUTPUT_SWITCHES log = "■ Switches List\n" $data_system.switches.each_with_index do |name,index| next if index == 0 sw = $game_switches[index] log += @indent + sprintf("\[%04d:%s\] :\t%s\n", index, name, sw.to_s) end log += "\n" return log end def variables_log return "" unless OUTPUT_VARIABLES log = "■ Variavles List\n" $data_system.variables.each_with_index do |name,index| next if index == 0 var = $game_variables[index] log += @indent + sprintf("\[var%04d:%s\] :\t%s\n", index, name, var.to_s) end log += "\n" return log end # Battler Status def battler_info(battler, depth=0) tab = @indent * depth msg = "" msg += tab + sprintf("HP: %d / %d\n",battler.hp, battler.mhp) msg += tab + sprintf("MP: %d / %d\n",battler.mp, battler.mmp) msg += tab + sprintf("TP: %d / %d\n",battler.tp, battler.max_tp) msg += tab + "States: [#{battler.instance_variable_get(:@states).join(",")}]\n" return msg end # Battler Actions def battler_actions(battler, depth=0) msg = "" tab = @indent * depth battler.actions.each_with_index do |action, i| msg += tab + "Action#{i+1}:\n" case action.item when RPG::Skill # Skill msg += tab + @indent + sprintf("Action: Skill: [%03d:%s]\n",action.item.id,action.item.name) when 2 # Item msg += tab + sprintf("Action: Item: [%03d:%s]\n",action.item.id,action.item.name) end msg += tab + @indent + "TargetIndex: #{action.target_index.to_s}\n" msg += tab + @indent + "Forced?: #{action.forcing}\n" end return msg end # Actor Info def actor_info(actor, index=0, depth=0, with_battle_info=false) tab = @indent * depth if actor.dead? info = " :Dead" else info = "" end msg = tab + sprintf("%03d: [%03d: %s]%s\n",index,actor.id, actor.name, info) msg += battler_info(actor, depth + 1) msg += battler_actions(actor, depth + 1) if with_battle_info return msg end # Enemy Info def enemy_info(enemy, index=0, depth=0) tab = @indent * depth if enemy.hidden? info = " :Hidden" elsif enemy.dead? info = " :Dead" else info = "" end msg = tab + sprintf("%02d: [%03d:%s]%s\n",index,enemy.enemy_id, enemy.name, info) msg += battler_info(enemy, depth + 1) msg += battler_actions(enemy, depth + 1) return msg end # Battle Info def battle_info return "" unless SceneManager.scene.is_a?(Scene_Battle) active_battler = SceneManager.scene.instance_variable_get(:@subject) msg = "■ Battle:\n" msg += @indent + "Troop:#{sprintf("[%03d: %s]",$game_troop.troop.id,$game_troop.troop.name)}\n" msg += @indent + "Turn: #{$game_troop.turn_count}\n" if active_battler.is_a?(Game_Battler) msg += @indent + "ActiveBattler: #{active_battler.name}\n" end msg += @indent + "Actors:\n" $game_party.members.each_with_index do |actor, index| msg += actor_info(actor,index+1, 2, true) end msg += @indent + "Enemies:\n" $game_troop.members.each_with_index do |enemy,index| msg += enemy_info(enemy,index+1,2) end msg += @indent + "\n" return msg end def event_backlog return '' if @error_events.size == 0 msg = "■ EventBacklog:\n" @error_events.each do |error_event| msg += @indent + error_event + "\n" end return msg end # Map Info def map_info msg = "■ Map:\n" msg += @indent + "MAP_ID: #{$game_map.map_id.to_s}\n" msg += @indent + "Player: [#{$game_player.x}, #{$game_player.y}]\n" msg += @indent + "Events:\n" $game_map.events.each do |eid, ge| ev = ge.instance_variable_get(:@event) page = ge.instance_variable_get(:@page) msg += @indent * 2 + sprintf("[%03d:%s](%d,%d):\n", eid, ev.name, ge.x,ge.y) # draw PageNO if page page_no = ev.pages.index(page) + 1 else page_no = 0 end msg += @indent * 3 + "Page: #{page_no}\n" # draw SelfSwitches msg += @indent * 3 + "SelfSW: [" ['A','B','C','D'].each do |alpha| key = [$game_map.map_id, eid, alpha] msg += " #{alpha}:" + ($game_self_switches[key] ? 'ON' : 'OFF') end msg += " ]\n" end return msg end # Saved to a file the error log def save(filename=nil, exception=$!) if filename.nil? filename = "error_log" + Time.now.strftime("%Y%m%d") + ".txt" end msg = "◆ #{Time.now.strftime('%Y-%m-%dT%H:%M:%S')}\n" msg += "■ Error Type :\n" msg += @indent + "#{exception.class.to_s}\n" msg += "\n" if exception.message msg += "■ Message :\n" msg += @indent + "#{self.replace_section_name(exception.message)}\n" msg += "\n" end @error_events.each do |error_event| msg += error_event + "\n" end msg += self.event_backlog() msg += "\n" msg += self.error_script_info() if exception.backtrace.size > 0 msg += "■ Backtrace :\n" exception.backtrace.map do |bt| msg += @indent + "#{self.replace_section_name(bt)}\n" end msg += "\n" end if SceneManager.scene.is_a?(Scene_Battle) msg += self.battle_info msg += "\n" elsif $game_map msg += "■ Party\n" msg += @indent + "Members:------\n" $game_party.members.each_with_index do |actor, index| msg += actor_info(actor,index+1, 1) end msg += @indent + "------:Members\n" msg += "\n" msg += self.map_info msg += "\n" end sw_log = self.switches_log var_log = self.variables_log open(filename,"w") do |log| log.print msg log.print sw_log log.print var_log end end end module TKG::ErrorLog::Extend_Interpreter attr_accessor :troop_page attr_accessor :commonevent_id def eval(*args) begin super rescue TKG::ErrorLog.set_error_script(args[0]) raise end end def clear @troop_page = 0 @commonevent_id = 0 super end def run begin result = super rescue TKG::ErrorLog.set_error_event(@map_id, @event_id, @commonevent_id, @troop_page) raise end return result end end module TKG::ErrorLog::Extend_GameTroop def conditions_met?(page) result = super(page) if result @interpreter.troop_page = $game_troop.troop.pages.index(page) + 1 end return result end end class Game_Interpreter unless private_method_defined?('_tkg_debuglog__initialize') alias _tkg_debuglog__initialize initialize end def initialize(*args) _tkg_debuglog__initialize(*args) self.extend TKG::ErrorLog::Extend_Interpreter end end class Game_Troop unless private_method_defined?('_tkg_debuglog__initialize') alias _tkg_debuglog__initialize initialize end def initialize(*args) _tkg_debuglog__initialize(*args) self.extend TKG::ErrorLog::Extend_GameTroop end end class RPG::CommonEvent def list _list = @list if trigger != 2 command = RPG::EventCommand.new(355,0,["@commonevent_id = #{@id}"]) _list.unshift(command) end return _list end end module SceneManager unless respond_to?('_debug__run') class << self alias _tkg_debug__run run end end def self.run begin _tkg_debug__run rescue TKG::ErrorLog.save() raise end end end