设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索

关于一些脚本报错(已解决)

查看数: 565 | 评论数: 9 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2026-4-16 17:39

正文摘要:

本帖最后由 duanyanchujing 于 2026-4-21 16:16 编辑 如题,出现这个报错一般是什么问题呢? 以下是使用老鹰的对话框扩展脚本的提示: 这两个报错长得很像(但是看不懂),不知道问题出在哪里,诚心发问orz ...

回复

duanyanchujing 发表于 2026-4-18 19:01:39
!!谢谢各位,果然是脚本互相冲突了!!
我一个个排查,删除了一个单独的“选项合并”脚本就没问题了!!
两个脚本都能用了,感谢各位orz
风吹处阴凉 发表于 2026-4-17 23:46:23
RGSS特有的抓瞎报错
百里_飞柳 发表于 2026-4-17 17:53:38
我的对话框是因为读取旧存档,导致那个变量为nil然后报错

可能这个weather脚本也是这个原因?
喵呜喵5 发表于 2026-4-17 16:03:53
那就先开个新工程,只插入这俩脚本看会不会报错
duanyanchujing 发表于 2026-4-17 15:20:08
喵呜喵5 发表于 2026-4-17 13:51
一般是脚本冲突,你搜下你有没有其他脚本里也有 class Game_System
有的话把这两个脚本的位置往下放到哪些 ...

这两个脚本都放在最下面,它们俩下面只有main了,还是一样的报错
喵呜喵5 发表于 2026-4-17 13:51:19
一般是脚本冲突,你搜下你有没有其他脚本里也有 class Game_System
有的话把这两个脚本的位置往下放到哪些脚本下面试试
duanyanchujing 发表于 2026-4-17 12:58:51
附一下MOG的天气脚本:
RUBY 代码复制
  1. #==============================================================================
  2. # +++ MOG - 天气效果 EX (v2.3) +++
  3. #==============================================================================
  4. # By Moghunter
  5. # [url]http://www.atelier-rgss.com/[/url]
  6. #==============================================================================
  7. # 更加丰富的天气效果.
  8. #==============================================================================
  9. # 全部图片需放在文件夹:
  10. #
  11. # GRAPHICS/WEATHER/
  12. #
  13. #==============================================================================
  14. # 使用方法
  15. #
  16. # 使用以下脚本来改变天气.*(事件)
  17. #
  18. # weather(类型, 强度, 图片文件名)
  19. #
  20. # 类型 - 天气的类型. (从 0 到 6)
  21. # 强度 - 即画面中的粒子数. (从 1 到 10)
  22. # 图片文件名 - 图片的文件名.
  23. #
  24. # 例子:
  25. #
  26. # weather(0, 5, "Leaf")
  27. #
  28. #==============================================================================
  29. # 天气类型:
  30. #
  31. # 0 - (雨)  
  32. # 1 - (风)
  33. # 2 - (雾)  
  34. # 3 - (光升起)
  35. # 4 - (雪)
  36. # 5 - (萤火虫)
  37. # 6 - (随机)
  38. #
  39. #==============================================================================
  40. # 注意
  41. #
  42. # 为了防止卡顿最好不要使用太大的图片,如果一定要大图的话,最好减小一些天气的
  43. # 强度。
  44. #
  45. #==============================================================================
  46. #==============================================================================
  47. # 天气复原的脚本:
  48. #
  49. # weather_stop
  50. #==============================================================================
  51. # 在战斗以后天气复原的脚本:
  52. #
  53. # weather_stop_b
  54. #
  55. #==============================================================================
  56. # 要停止使用当前使用之前特性的天气的脚本(?):
  57. #
  58. # weather_restore
  59. #==============================================================================
  60. # 在你使用新天气之前,如果你想要当前天气的特性以后可以被读取,就使用以下脚本:
  61. #
  62. # weather_store                     =>存储
  63. # weather_restore_store             =>读取
  64. #
  65. #==============================================================================
  66.  
  67. #==============================================================================
  68. # ● Histórico (Version History)
  69. #==============================================================================
  70. # v 2.3 - Compatibilidade com MOG Battle Camera.
  71. # v 2.2 - Adicionado o comando parar o clima após a batalha.
  72. # v 2.1 - Melhoria na posição das partículas durante as transições
  73. #         de scenes.
  74. # v 2.0 - Correção do bug do Crash aleatório.
  75. #==============================================================================
  76. module MOG_WEATHER_EX
  77.   #天气效果的Z坐标.
  78.   WEATHER_SCREEN_Z = 50
  79.   #默认天气强度.
  80.   WEATHER_POWER_EFIC = 1
  81.   #是否将天气应用于战斗画面.
  82.   WEATHER_BATTLE = true
  83. end
  84.  
  85. $imported = {} if $imported.nil?
  86. $imported[:mog_weather_ex] = true
  87.  
  88. #==============================================================================
  89. # ■ Cache
  90. #==============================================================================
  91. module Cache
  92.  
  93.   #--------------------------------------------------------------------------
  94.   # ● Weather
  95.   #--------------------------------------------------------------------------
  96.   def self.weather(filename)
  97.       load_bitmap("Graphics/Weather/", filename)
  98.   end
  99.  
  100. end
  101.  
  102. #==============================================================================
  103. # ■ Game System
  104. #==============================================================================
  105. class Game_System
  106.  
  107.   attr_accessor :weather
  108.   attr_accessor :weather_restore
  109.   attr_accessor :weather_record_set
  110.   attr_accessor :weather_temp
  111.  
  112.   #--------------------------------------------------------------------------
  113.   # ● Initialize
  114.   #--------------------------------------------------------------------------  
  115.   alias weather_ex_initialize initialize  
  116.   def initialize
  117.       @weather = [-1,0,""]
  118.       @weather_restore = [-1,0,""]
  119.       @weather_temp = [-1,0,""]
  120.       @weather_record_set = [-1,0,""]
  121.       weather_ex_initialize
  122.   end  
  123.  
  124. end  
  125.  
  126. #==============================================================================
  127. # ■ Game Temp
  128. #==============================================================================
  129. class Game_Temp
  130.  
  131.   attr_accessor :weather_ex_set
  132.   attr_accessor :weather_fade
  133.   attr_accessor :weather_rf_time
  134.   attr_accessor :weather_fstop
  135.  
  136.   #--------------------------------------------------------------------------
  137.   # ● Initialize
  138.   #--------------------------------------------------------------------------  
  139.   alias mog_weather_ex_temp_initialize initialize
  140.   def initialize
  141.       @weather_ex_set = []
  142.       @weather_fade = false
  143.       @weather_rf_time = 0
  144.       @weather_fstop = false
  145.       mog_weather_ex_temp_initialize
  146.   end  
  147.  
  148. end
  149.  
  150. #==============================================================================
  151. # ■ Game Interpreter
  152. #==============================================================================
  153. class Game_Interpreter
  154.  
  155.   #--------------------------------------------------------------------------
  156.   # ● Weather
  157.   #--------------------------------------------------------------------------   
  158.   def weather(type = -1, power = 0, image = "")
  159.       $game_temp.weather_fade = false
  160.       $game_temp.weather_rf_time = 0
  161.       $game_system.weather.clear
  162.       $game_system.weather = [type,power,image]
  163.   end
  164.  
  165.   #--------------------------------------------------------------------------
  166.   # ● Weather Stop
  167.   #--------------------------------------------------------------------------     
  168.   def weather_stop
  169.       $game_temp.weather_fade = false
  170.       $game_system.weather.clear
  171.       $game_system.weather = [-1,0,""]
  172.       $game_system.weather_restore  = [-1,0,""]
  173.       $game_system.weather_temp = [-1,0,""]      
  174.   end
  175.  
  176.   #--------------------------------------------------------------------------
  177.   # ● Weather Restore
  178.   #--------------------------------------------------------------------------      
  179.   def weather_restore
  180.       $game_temp.weather_fade = false
  181.       if $game_system.weather[0] != -1
  182.          w = $game_system.weather
  183.          $game_system.weather_restore = [w[0],w[1],w[2]]
  184.          $game_system.weather.clear
  185.          $game_system.weather = [-1,0,""]
  186.          return
  187.       end
  188.       w = $game_system.weather_restore
  189.       weather(w[0],w[1],w[2])
  190.   end
  191.  
  192.   #--------------------------------------------------------------------------
  193.   # ● Weather Fade
  194.   #--------------------------------------------------------------------------         
  195.   def weather_fade(value)
  196.       $game_temp.weather_fade = value
  197.   end
  198.  
  199.   #--------------------------------------------------------------------------
  200.   # ● Weather Store
  201.   #--------------------------------------------------------------------------           
  202.   def weather_store
  203.       w = $game_system.weather
  204.       $game_system.weather_record_set = [w[0],w[1],w[2]]
  205.   end  
  206.  
  207.   #--------------------------------------------------------------------------
  208.   # ● Weather Restore Store
  209.   #--------------------------------------------------------------------------           
  210.   def weather_restore_store
  211.       w = $game_system.weather_record_set
  212.       weather(w[0],w[1],w[2])      
  213.   end   
  214.  
  215.   #--------------------------------------------------------------------------
  216.   # ● Weather Stop B
  217.   #--------------------------------------------------------------------------           
  218.   def weather_stop_b
  219.       $game_temp.weather_fstop = true
  220.   end
  221.  
  222. end  
  223.  
  224. #==============================================================================
  225. # ** Spriteset_Map
  226. #==============================================================================
  227. class Spriteset_Map
  228.  
  229.   #--------------------------------------------------------------------------
  230.   # * Create Viewport
  231.   #--------------------------------------------------------------------------
  232.   alias mog_weather_ex_create_viewports create_viewports
  233.   def create_viewports
  234.       create_viewport_weather
  235.       mog_weather_ex_create_viewports      
  236.   end
  237.  
  238.   #--------------------------------------------------------------------------
  239.   # * Create Viewport Weather
  240.   #--------------------------------------------------------------------------
  241.   def create_viewport_weather
  242.       return if @viewport_weather != nil
  243.       @viewport_weather = Viewport.new
  244.       @viewport_weather.z = MOG_WEATHER_EX::WEATHER_SCREEN_Z
  245.       @viewport_weather.ox = ($game_map.display_x * 32)
  246.       @viewport_weather.oy = ($game_map.display_y * 32)
  247.   end
  248.  
  249.   #--------------------------------------------------------------------------
  250.   # * Dispose Viewports
  251.   #--------------------------------------------------------------------------
  252.   alias mog_weather_ex_dispose_viewports dispose_viewports
  253.   def dispose_viewports      
  254.       mog_weather_ex_dispose_viewports
  255.       dispose_viewport_weather
  256.   end
  257.  
  258.   #--------------------------------------------------------------------------
  259.   # * Dispose Viewport Weather
  260.   #--------------------------------------------------------------------------
  261.   def dispose_viewport_weather
  262.       return if @viewport_weather == nil
  263.       @viewport_weather.dispose   
  264.   end
  265.  
  266.   #--------------------------------------------------------------------------
  267.   # * Update Viewports
  268.   #--------------------------------------------------------------------------
  269.   alias mog_weather_ex_update_viewports update_viewports
  270.   def update_viewports
  271.       mog_weather_ex_update_viewports
  272.       update_viewport_weather
  273.   end
  274.  
  275.   #--------------------------------------------------------------------------
  276.   # * Update Viewports Weather
  277.   #--------------------------------------------------------------------------
  278.   def update_viewport_weather
  279.       return if @viewport_weather == nil
  280.       @viewport_weather.ox = ($game_map.display_x * 32)
  281.       @viewport_weather.oy = ($game_map.display_y * 32)
  282.   end     
  283.  
  284. end
  285.  
  286. #==============================================================================
  287. # ** Spriteset_Battle
  288. #==============================================================================
  289. class Spriteset_Battle
  290.  
  291.   #--------------------------------------------------------------------------
  292.   # * Create Viewport
  293.   #--------------------------------------------------------------------------
  294.   alias mog_weather_ex_create_viewports_battle create_viewports
  295.   def create_viewports
  296.       mog_weather_ex_create_viewports_battle
  297.       create_viewport_weather   
  298.   end
  299.  
  300.   #--------------------------------------------------------------------------
  301.   # * Create Viewport Weather
  302.   #--------------------------------------------------------------------------
  303.   def create_viewport_weather
  304.       return if @viewport_weather != nil
  305.       @viewport_weather = Viewport.new
  306.       @viewport_weather.z = MOG_WEATHER_EX::WEATHER_SCREEN_Z
  307.   end
  308.  
  309.   #--------------------------------------------------------------------------
  310.   # * Dispose Viewports
  311.   #--------------------------------------------------------------------------
  312.   alias mog_weather_ex_dispose_viewports_battle dispose_viewports
  313.   def dispose_viewports      
  314.       mog_weather_ex_dispose_viewports_battle
  315.       dispose_viewport_weather
  316.   end
  317.  
  318.   #--------------------------------------------------------------------------
  319.   # * Dispose Viewport Weather
  320.   #--------------------------------------------------------------------------
  321.   def dispose_viewport_weather
  322.       return if @viewport_weather == nil
  323.       @viewport_weather.dispose   
  324.   end
  325.  
  326.   #--------------------------------------------------------------------------
  327.   # * Update Viewports
  328.   #--------------------------------------------------------------------------
  329.   alias mog_weather_ex_update_viewports_battle update_viewports
  330.   def update_viewports
  331.       mog_weather_ex_update_viewports_battle
  332.       update_viewport_weather        
  333.   end  
  334.  
  335.   #--------------------------------------------------------------------------
  336.   # * Update Viewports Weather
  337.   #--------------------------------------------------------------------------
  338.   def update_viewport_weather
  339.       return if @viewport_weather == nil
  340.       if $imported[:mog_battle_camera]
  341.          @viewport_weather.ox = $game_temp.viewport_oxy[0]
  342.          @viewport_weather.oy = $game_temp.viewport_oxy[1]
  343.       end   
  344.   end   
  345.  
  346. end
  347.  
  348. #==============================================================================
  349. # ■ Weather_EX
  350. #==============================================================================
  351. class Weather_EX
  352.  
  353.   #--------------------------------------------------------------------------
  354.   # ● Initialize
  355.   #--------------------------------------------------------------------------  
  356.   def initialize(viewport = nil ,type = 0, image_name = "",index = 0,nx,ny)
  357.       @wp = Sprite.new
  358.       @wp.bitmap = Cache.weather(image_name.to_s)
  359.       @wp.opacity = 0
  360.       @wp.viewport = viewport
  361.       @cw = @wp.bitmap.width
  362.       @cwm = (@cw / 2) + @cw
  363.       @ch = @wp.bitmap.height
  364.       @chm = (@ch / 2) + @ch
  365.       @range_x = [-@cwm,Graphics.width + @cwm]
  366.       @range_y = [-@chm,Graphics.height + @chm]
  367.       @angle_speed = 0
  368.       @x_speed = 0
  369.       @y_speed = 0
  370.       @zoom_speed = 0
  371.       @opacity_speed = 0
  372.       @type = type
  373.       @index = index
  374.       @nx = 0
  375.       @nx_old = 0
  376.       @ny = 0
  377.       @ny_old = 0      
  378.       @old_nx = nx
  379.       @old_ny = ny
  380.       type_setup(nx,ny)
  381.   end
  382.  
  383.   #--------------------------------------------------------------------------
  384.   # ● x
  385.   #--------------------------------------------------------------------------      
  386.   def x
  387.       @wp.x
  388.   end
  389.  
  390.   #--------------------------------------------------------------------------
  391.   # ● y
  392.   #--------------------------------------------------------------------------      
  393.   def y
  394.       @wp.y
  395.   end
  396.  
  397.   #--------------------------------------------------------------------------
  398.   # ● Opacity
  399.   #--------------------------------------------------------------------------      
  400.   def opacity
  401.       @wp.opacity
  402.   end
  403.  
  404.   #--------------------------------------------------------------------------
  405.   # ● Angle
  406.   #--------------------------------------------------------------------------      
  407.   def angle
  408.       @wp.angle
  409.   end
  410.  
  411.   #--------------------------------------------------------------------------
  412.   # ● Zoom X
  413.   #--------------------------------------------------------------------------      
  414.   def zoom_x
  415.       @wp.zoom_x
  416.   end  
  417.  
  418.   #--------------------------------------------------------------------------
  419.   # ● Dispose Weather
  420.   #--------------------------------------------------------------------------      
  421.   def dispose_weather
  422.       return if @wp == nil
  423.       @wp.bitmap.dispose
  424.       @wp.dispose
  425.       @wp = nil
  426.   end
  427.  
  428.   #--------------------------------------------------------------------------
  429.   # ● Pre Values
  430.   #--------------------------------------------------------------------------   
  431.   def pre_values(index)
  432.       return if  $game_temp.weather_ex_set[index] == nil
  433.       @wp.x = $game_temp.weather_ex_set[index][0]
  434.       @wp.y = $game_temp.weather_ex_set[index][1]
  435.       @wp.opacity = 1#$game_temp.weather_ex_set[index][2]
  436.       @wp.angle = $game_temp.weather_ex_set[index][3]
  437.       @wp.zoom_x = $game_temp.weather_ex_set[index][4]
  438.       @wp.zoom_y = $game_temp.weather_ex_set[index][4]
  439.       $game_temp.weather_ex_set[index].clear
  440.       $game_temp.weather_ex_set[index] = nil
  441.   end  
  442.  
  443.   #--------------------------------------------------------------------------
  444.   # ● Type Setup
  445.   #--------------------------------------------------------------------------      
  446.   def type_setup(nx = 0, ny = 0)
  447.       @cw2 = [@range_x[1] + nx, @range_x[0] + nx]
  448.       @ch2 = [@range_y[1] + ny, @range_y[0] + ny]
  449.       check_weather_type
  450.       pre_values(@index)
  451.       @opacity_speed = -1 if $game_temp.weather_fade
  452.   end
  453.  
  454.   #--------------------------------------------------------------------------
  455.   # ● Update
  456.   #--------------------------------------------------------------------------   
  457.   def update_weather(nx = 0, ny = 0)
  458.       @wp.x += @x_speed
  459.       @wp.y += @y_speed
  460.       @wp.opacity += @opacity_speed
  461.       @wp.angle += @angle_speed
  462.       @wp.zoom_x += @zoom_speed
  463.       @wp.zoom_y += @zoom_speed
  464.       check_loop_map(nx,ny)
  465.       type_setup(nx,ny) if can_reset_setup?
  466.   end  
  467.  
  468.   #--------------------------------------------------------------------------
  469.   # ● Check Loop Map
  470.   #--------------------------------------------------------------------------        
  471.   def check_loop_map(nx,ny)
  472.       if (@old_nx - nx).abs > 32
  473.          @cw2 = [@range_x[1] + nx, @range_x[0] + nx]
  474.          @wp.x += nx
  475.          @wp.x -= @old_nx if nx == 0
  476.       end   
  477.       if (@old_ny - ny).abs > 32
  478.          @ch2 = [@range_y[1] + ny, @range_y[0] + ny]
  479.          @wp.y += ny
  480.          @wp.y -= @old_ny if ny == 0
  481.       end         
  482.       @old_nx = nx
  483.       @old_ny = ny   
  484.   end  
  485.  
  486.   #--------------------------------------------------------------------------
  487.   # ● Can Reset Setup
  488.   #--------------------------------------------------------------------------      
  489.   def can_reset_setup?
  490.       return true if @wp.x > @cw2[0] or @wp.x <  @cw2[1]
  491.       return true if @wp.y > @ch2[0]  or @wp.y < @ch2[1]
  492.       return true if @wp.opacity == 0
  493.       return true if @wp.zoom_x > 2.0 or @wp.zoom_x < 0.5
  494.       return false
  495.   end
  496.  
  497. #--------------------------------------------------------------------------
  498. # ● Check Weather Type
  499. #--------------------------------------------------------------------------                        
  500. def check_weather_type
  501.      case @type
  502.          when 0;   rain
  503.          when 1;   wind   
  504.          when 2;   fog
  505.          when 3;   light
  506.          when 4;   snow
  507.          when 5;   spark
  508.          when 6;   random                  
  509.       end
  510. end
  511.  
  512. #--------------------------------------------------------------------------
  513. # ● Snow
  514. #--------------------------------------------------------------------------                          
  515. def snow
  516.      @wp.angle = rand(360)
  517.      @wp.x = rand(@cw2[0])
  518.      @wp.y = rand(@ch2[0])
  519.      @wp.opacity = 1
  520.      @wp.zoom_x = (rand(100) + 50) / 100.0
  521.      @wp.zoom_y = @wp.zoom_x
  522.      @y_speed = [[rand(5), 1].max, 5].min
  523.      @opacity_speed = 5
  524.      @angle_speed = rand(3)
  525. end   
  526.  
  527. #--------------------------------------------------------------------------
  528. # ● Spark
  529. #--------------------------------------------------------------------------                           
  530. def spark
  531.      @wp.angle = rand(360)
  532.      @wp.x = rand(@cw2[0])
  533.      @wp.y = rand(@ch2[0])
  534.      @wp.opacity = 1
  535.      @wp.zoom_x = (rand(100) + 100) / 100.0
  536.      @wp.zoom_y = @wp.zoom_x
  537.      @wp.blend_type = 1     
  538.      @opacity_speed = 10
  539.      @zoom_speed = -0.01
  540. end
  541.  
  542. #--------------------------------------------------------------------------
  543. # ● Rain
  544. #--------------------------------------------------------------------------                          
  545. def rain
  546.      @wp.x = rand(@cw2[0])      
  547.      if @start == nil
  548.         @wp.y = rand(@ch2[0])
  549.         @start = true
  550.      else
  551.         @wp.y = @ch2[1]        
  552.      end   
  553.      @wp.opacity = 1
  554.      @wp.zoom_y = (rand(50) + 100) / 100.0
  555.      @wp.zoom_x = (rand(25) + 100) / 100.0
  556.      @y_speed = [[rand(10) + 10, 10].max, 20].min
  557.      @opacity_speed = 10
  558. end   
  559.  
  560. #--------------------------------------------------------------------------
  561. # ● Fog
  562. #--------------------------------------------------------------------------                           
  563. def fog
  564.      rand_angle = rand(2)
  565.      @wp.angle = rand_angle == 1 ? 180 : 0
  566.      @wp.x = rand(@cw2[0])
  567.      @wp.y = rand(@ch2[0])
  568.      @wp.opacity = 1
  569.      @wp.zoom_x = (rand(100) + 50) / 100.0
  570.      @wp.zoom_y = @wp.zoom_x
  571.      @x_speed = [[rand(10), 1].max, 10].min
  572.      @opacity_speed = 10
  573. end
  574.  
  575. #--------------------------------------------------------------------------
  576. # ● Light
  577. #--------------------------------------------------------------------------                           
  578. def light
  579.      @wp.angle = rand(360)
  580.      @wp.x = rand(@cw2[0])
  581.      @wp.y = rand(@ch2[0])
  582.      @wp.opacity = 1
  583.      @wp.zoom_x = (rand(100) + 50) / 100.0
  584.      @wp.zoom_y = @wp.zoom_x
  585.      @wp.blend_type = 1
  586.      @angle_speed = [[rand(3), 1].max, 3].min
  587.      @y_speed = -[[rand(10), 1].max, 10].min
  588.      @opacity_speed = 2
  589. end
  590.  
  591. #--------------------------------------------------------------------------
  592. # ● Wind
  593. #--------------------------------------------------------------------------                          
  594. def wind
  595.      @wp.angle = rand(360)
  596.      @wp.x = rand(@cw2[0])
  597.      @wp.y = rand(@ch2[0])
  598.      @wp.opacity = 1
  599.      @wp.zoom_x = (rand(100) + 50) / 100.0
  600.      @wp.zoom_y = @wp.zoom_x
  601.      @x_speed = [[rand(10), 1].max, 10].min
  602.      @y_speed = [[rand(10), 1].max, 10].min
  603.      @opacity_speed = 10
  604. end   
  605.  
  606. #--------------------------------------------------------------------------
  607. # ● Random
  608. #--------------------------------------------------------------------------                          
  609. def random
  610.      @wp.angle = rand(360)
  611.      @wp.x = rand(@cw2[0])
  612.      @wp.y = rand(@ch2[0])
  613.      @wp.opacity = 1
  614.      @wp.zoom_x = (rand(100) + 50) / 100.0
  615.      @wp.zoom_y = @wp.zoom_x
  616.      x_s = [[rand(10), 1].max, 10].min
  617.      y_s = [[rand(10), 1].max, 10].min
  618.      rand_x = rand(2)
  619.      rand_y = rand(2)
  620.      @x_speed = rand_x == 1 ? x_s : -x_s
  621.      @y_speed = rand_y == 1 ? y_s : -y_s      
  622.      @opacity_speed = 10
  623. end   
  624.  
  625. end
  626.  
  627. #==============================================================================
  628. # ■ Module Weather EX
  629. #==============================================================================
  630. module Module_Weather_EX
  631.  
  632. #--------------------------------------------------------------------------
  633. # ● Create Weather EX
  634. #--------------------------------------------------------------------------                  
  635.   def create_weather_ex
  636.       dispose_weather_ex
  637.       create_weather_sprite     
  638.   end
  639.  
  640. #--------------------------------------------------------------------------
  641. # ● Dispose Wheater EX
  642. #--------------------------------------------------------------------------                     
  643.   def dispose_weather_ex
  644.       dispose_weather_ex_sprite
  645.   end
  646.  
  647. #--------------------------------------------------------------------------
  648. # ● Create Weather Sprite
  649. #--------------------------------------------------------------------------                       
  650.   def create_weather_sprite
  651.       dispose_weather_ex_sprite
  652.       @old_weather = $game_system.weather
  653.       return if $game_system.weather == [] or $game_system.weather[0] == -1
  654.       @weather_ex = []
  655.       @weather_oxy = [$game_map.display_x * 32,
  656.                       $game_map.display_y * 32]      
  657.       index = 0
  658.       power_efic = MOG_WEATHER_EX::WEATHER_POWER_EFIC
  659.       power_efic = 1 if power_efic < 1
  660.       power = [[$game_system.weather[1] * power_efic, power_efic].max, 999].min
  661.       for i in 0...power
  662.           @weather_ex.push(Weather_EX.new(@viewport_weather,$game_system.weather[0],$game_system.weather[2],index, @viewport1.ox, @viewport1.oy))
  663.           index += 1
  664.       end            
  665.   end
  666.  
  667. #--------------------------------------------------------------------------
  668. # ● Dispose Weather EX
  669. #--------------------------------------------------------------------------                  
  670.   def dispose_weather_ex_sprite
  671.       return if @weather_ex == nil
  672.       index = 0
  673.       for i in @weather_ex
  674.           $game_temp.weather_ex_set[index] = [] if $game_temp.weather_ex_set[index] == nil
  675.           $game_temp.weather_ex_set[index].push(i.x,i.y,i.opacity,i.angle,i.zoom_x)
  676.           i.dispose_weather
  677.           index += 1
  678.       end
  679.       @weather_ex.each {|sprite| sprite.dispose_weather}  
  680.       @weather_ex = nil
  681.   end
  682.  
  683. #--------------------------------------------------------------------------
  684. # ● Dispose Refresh
  685. #--------------------------------------------------------------------------                    
  686.   def dispose_refresh
  687.       $game_temp.weather_ex_set.clear
  688.       return if @weather_ex == nil
  689.       @weather_ex.each {|sprite| sprite.dispose_weather}
  690.       @weather_ex = nil
  691.   end  
  692.  
  693. #--------------------------------------------------------------------------
  694. # ● Update Weather EX
  695. #--------------------------------------------------------------------------                  
  696.   def update_weather_ex
  697.       $game_temp.weather_rf_time -= 1 if $game_temp.weather_rf_time > 0
  698.       refresh_weather_ex if $game_temp.weather_rf_time == 0
  699.       return if @weather_ex == nil
  700.       @weather_ex.each {|sprite| sprite.update_weather(@viewport_weather.ox,@viewport_weather.oy)}
  701.   end
  702.  
  703. #--------------------------------------------------------------------------
  704. # ● Refresh Weather EX
  705. #--------------------------------------------------------------------------                     
  706.   def refresh_weather_ex
  707.       return if @old_weather == nil
  708.       return if @old_weather == $game_system.weather
  709.       dispose_refresh      
  710.       create_weather_sprite
  711.   end  
  712.  
  713. end  
  714.  
  715. #==============================================================================
  716. # ■ Spriteset Map
  717. #==============================================================================
  718. class Spriteset_Map
  719.    include Module_Weather_EX  
  720.  
  721. #--------------------------------------------------------------------------
  722. # ● Initialize
  723. #--------------------------------------------------------------------------                  
  724.   alias mog_weather_ex_initialize initialize
  725.   def initialize
  726.       dispose_weather_ex   
  727.       mog_weather_ex_initialize
  728.       create_weather_ex
  729.   end
  730.  
  731. #--------------------------------------------------------------------------
  732. # ● Dispose
  733. #--------------------------------------------------------------------------                  
  734.   alias mog_weather_ex_dispose dispose
  735.   def dispose
  736.       dispose_weather_ex   
  737.       mog_weather_ex_dispose
  738.   end  
  739.  
  740. #--------------------------------------------------------------------------
  741. # ● Update
  742. #--------------------------------------------------------------------------                  
  743.   alias mog_weather_ex_update update
  744.   def update
  745.       mog_weather_ex_update
  746.       update_weather_ex
  747.   end  
  748.  
  749. end
  750.  
  751. if MOG_WEATHER_EX::WEATHER_BATTLE
  752. #==============================================================================
  753. # ■ Spriteset Battle
  754. #==============================================================================
  755. class Spriteset_Battle
  756.  
  757.    include Module_Weather_EX  
  758.  
  759. #--------------------------------------------------------------------------
  760. # ● Initialize
  761. #--------------------------------------------------------------------------                  
  762.   alias mog_weather_ex_initialize initialize
  763.   def initialize
  764.       dispose_weather_ex   
  765.       mog_weather_ex_initialize
  766.       create_weather_ex
  767.   end
  768.  
  769. #--------------------------------------------------------------------------
  770. # ● Dispose
  771. #--------------------------------------------------------------------------                  
  772.   alias mog_weather_ex_dispose dispose
  773.   def dispose
  774.       mog_weather_ex_dispose
  775.       dispose_weather_ex
  776.   end  
  777.  
  778. #--------------------------------------------------------------------------
  779. # ● Update
  780. #--------------------------------------------------------------------------                  
  781.   alias mog_weather_ex_update update
  782.   def update
  783.       mog_weather_ex_update
  784.       update_weather_ex
  785.   end   
  786.  
  787. end
  788.  
  789. end
  790.  
  791. #=============================================================================
  792. # ■ Scene Base
  793. #=============================================================================
  794. class Scene_Base
  795.  
  796.   #--------------------------------------------------------------------------
  797.   # ● Weather Recover Data
  798.   #--------------------------------------------------------------------------  
  799.   def weather_recover_data
  800.       if $game_system.weather.empty? or
  801.           $game_system.weather[0] == -1
  802.           if !$game_system.weather_restore.empty? and
  803.              $game_system.weather_restore[0] != -1
  804.              v = $game_system.weather_restore
  805.              $game_system.weather = [v[0],v[1],v[2]]
  806.           end
  807.       end         
  808.   end
  809.  
  810.   #--------------------------------------------------------------------------
  811.   # ● Weather Restore
  812.   #--------------------------------------------------------------------------      
  813.   def weather_recover_scene
  814.       return if $game_system.weather_temp.empty?
  815.       return if $game_system.weather_temp[0] == -1
  816.       w = $game_system.weather_temp
  817.       $game_system.weather = [w[0],w[1],w[2]]
  818.       $game_system.weather_temp.clear
  819.       $game_system.weather_temp = [-1,0,""]
  820.   end  
  821.  
  822.   #--------------------------------------------------------------------------
  823.   # ● Main
  824.   #--------------------------------------------------------------------------         
  825.   alias mog_weather_ex_main main
  826.   def main
  827.       dispose_weather_ex_base
  828.       weather_recover_scene if can_recover_weather_scene?
  829.       mog_weather_ex_main
  830.   end   
  831.  
  832.   #--------------------------------------------------------------------------
  833.   # ● Can Recover Weather Scene
  834.   #--------------------------------------------------------------------------         
  835.   def can_recover_weather_scene?
  836.       return true if SceneManager.scene_is?(Scene_Map)
  837.       return true if SceneManager.scene_is?(Scene_Battle)
  838.       return false
  839.   end  
  840.  
  841.   #--------------------------------------------------------------------------
  842.   # ● terminate
  843.   #--------------------------------------------------------------------------         
  844.   alias mog_weather_ex_terminate_base terminate
  845.   def terminate
  846.       mog_weather_ex_terminate_base
  847.       dispose_weather_ex_base      
  848.   end  
  849.  
  850.   #--------------------------------------------------------------------------
  851.   # ● Dispose Weather EX Base
  852.   #--------------------------------------------------------------------------           
  853.   def dispose_weather_ex_base
  854.       return if @spriteset == nil
  855.       @spriteset.dispose_weather_ex rescue nil
  856.   end        
  857.  
  858. end
  859.  
  860. #=============================================================================
  861. # ■ Sprite Battle
  862. #=============================================================================
  863. class Spriteset_Battle  
  864.  
  865.   #--------------------------------------------------------------------------
  866.   # ● Dispose
  867.   #--------------------------------------------------------------------------           
  868.   alias mog_weather_ex_aft_dispose dispose
  869.   def dispose
  870.       force_stop_weather_ex_after_battle
  871.       mog_weather_ex_aft_dispose
  872.   end
  873.  
  874.   #--------------------------------------------------------------------------
  875.   # ● Force Stop Weather EX After
  876.   #--------------------------------------------------------------------------           
  877.   def force_stop_weather_ex_after_battle
  878.       return if !$game_temp.weather_fstop
  879.       $game_temp.weather_fstop = false
  880.       $game_temp.weather_fade = false
  881.       $game_system.weather.clear
  882.       $game_system.weather = [-1,0,""]
  883.       $game_system.weather_restore  = [-1,0,""]
  884.       $game_system.weather_temp = [-1,0,""]      
  885.   end
  886.  
  887.  
  888. end
  889.  
  890. #=============================================================================
  891. # ■ Scene Load
  892. #=============================================================================
  893. class Scene_Load < Scene_File
  894.  
  895.   #--------------------------------------------------------------------------
  896.   # ● On Load Success
  897.   #--------------------------------------------------------------------------
  898.   alias mog_weather_ex_on_load_success on_load_success
  899.   def on_load_success
  900.       mog_weather_ex_on_load_success
  901.       weather_recover_data
  902.   end
  903. end
  904.  
  905. #=============================================================================
  906. # ■ Scene Manager
  907. #=============================================================================
  908. class << SceneManager
  909.  
  910.   #--------------------------------------------------------------------------
  911.   # ● Call
  912.   #--------------------------------------------------------------------------         
  913.   alias mog_weather_ex_call call
  914.   def call(scene_class)
  915.       weather_dispose
  916.       mog_weather_ex_call(scene_class)
  917.   end
  918.  
  919.   #--------------------------------------------------------------------------
  920.   # ● Weather Restore
  921.   #--------------------------------------------------------------------------      
  922.   def weather_dispose
  923.       return if $game_system.weather.empty?
  924.       return if $game_system.weather[0] == -1
  925.       w = $game_system.weather
  926.       $game_system.weather_temp = [w[0],w[1],w[2]]
  927.       $game_system.weather.clear
  928.       $game_system.weather = [-1,0,""]
  929.   end   
  930.  
  931. end
duanyanchujing 发表于 2026-4-17 12:57:35
百里_飞柳 发表于 2026-4-16 22:20
额,光看错误提示是无法知道具体为啥报错的,还需要原本的脚本

我的对话框现在更新到 2.2.6 了,所以我也 ...

好像是个比较旧的版本……但我想着如果两个不同的脚本都出现同样的报错,会不会是其他地方存在什么问题?
这个是我用的对话框扩展:
RUBY 代码复制
  1. #=============================================================================
  2. # ■ 对话框扩展 by 老鹰([url]https://github.com/OneEyedEagle/EAGLE-RGSS3[/url])
  3. #=============================================================================
  4. $imported ||= {}
  5. $imported["EAGLE-MessageEX"] = "1.10.1"
  6. #=============================================================================
  7. # - 2023.7.14.21 新增\env在对话框关闭时自动重置为默认环境
  8. #=============================================================================
  9. # 【兼容模式】
  10. # - 本模式用于与其他对话框兼容,确保其他对话框正常使用,同时可以用本对话框及扩展
  11. #
  12. #     若此常量被设为 true,则本对话框不再覆盖其他对话框:
  13. #        而在事件脚本中调用 $game_message.eagle_message = true 后,
  14. #         本对话框将被激活,变更为正在使用的对话框;
  15. #        调用 $game_message.eagle_message = false 则可切回之前的原有对话框。
  16. #
  17. #     若此常量被设为 false,则本对话框将完全替代默认对话框。
  18. #
  19. # - 由于对话框存在动态的开启关闭特效,若对话框切换后,旧对话框仍然显示在地图上,
  20. #   则请在切换对话框的事件脚本前后添加【等待10帧】,来保证旧对话框有时间顺利完成关闭。
  21. #
  22. EAGLE_MSG_EX_COMPAT_MODE = false
  23.  
  24. module MESSAGE_EX
  25. #=============================================================================
  26. # ● 什么是转义符?
  27. #=============================================================================
  28. # - 鼠标放置于编辑器对话框中停留一段时间,即可看到默认支持的转义符及其作用
  29. #     如 \| 代表文本显示到该位置时,将等待 1s
  30. #     如 \c[5] 代表之后的文本将使用 5 号颜色进行绘制
  31. #
  32. # - 转义符即为特别约定的、能够起到特殊功能的文本,
  33. #     在对话框中,我们约定转义符均以 \ 符号为开头,之后接其他符号、字母、数字,
  34. #     并且一般情况下转义符自身不会被绘制、显示
  35.  
  36. #=============================================================================
  37. # ● 什么是扩展转义符?
  38. #=============================================================================
  39. # - 本插件对默认的转义符进行了扩展,
  40. #   我们约定在对话框中编写 \code[param] 类型的文本,即可执行 code 对应的功能,
  41. #   而 param 为特殊格式的字符串,本插件中命名其为“变量参数字符串”,
  42. #   它将被作为调用 code 功能所需的自定义设置传入
  43. #
  44. # - code “指令名”解析:
  45. #     下述列举出的各类转义符(英文、数字的组合)
  46. #
  47. # - param “变量参数字符串”解析:
  48. #    · 由 变量名(字母组合)+ 参数值(整数或nil(用$符号代表传入的为nil))重复构成
  49. #       - 字符串中可以增加无意义的空格,用于在视觉上区分不同变量
  50. #       - 字符串中 变量名 和 参数值 之间可以添加 = 符号,增强阅读性
  51. #    · 当传入 无变量名 的 参数值 时,将存入其【默认】变量
  52. #    · 对于没有传入值的 变量 ,将读取上一次设置所存储的值
  53. #    · 带有【重置】的变量,将在每一次设置转义符时,重置为脚本中的预设值
  54. #
  55. # - 示例:
  56. #    某个转义符的帮助:
  57. #      \foo[param] → 执行某个功能
  58. #         变量名称 a → 【默认】设置某个功能
  59. #         变量名称 b → 设置某个功能
  60. #         变量名称 c → 设置某个功能
  61. #
  62. #    在对话中编写:
  63. #      对话文本\foo[1 b=-1 tc=0 d$],其他对话文本
  64. #
  65. #    实际产生的效果:
  66. #    → 调用 foo 的功能,同时给它的所有变量传入预设值
  67. #      再给 a 变量传入值 1,b 变量传入值 -1,tc 变量传入值 0,d 变量传入值 nil
  68. #      (转义符的帮助中并没有写 tc 和 d 两个变量,
  69. #         但是这样传入并不会出错,也不会产生任何其他影响)
  70. #
  71. # - 注意:
  72. #    · 若没有明确说明,则转义符\code[param]不会被绘制、显示
  73. #    · “指令名”和“变量参数字符串”的大小写差异不会造成影响
  74. #    · 转义符会在对话文本逐字显示到它时生效
  75. #        但若有【预先】,则会在绘制开始前生效(绘制中途不会再次生效)
  76. #        但若有【结尾】,则会在全部文字绘制完成后生效
  77.  
  78. #=============================================================================
  79. # ● 扩展转义符列表
  80. #=============================================================================
  81. # 【索引】
  82. #    此处放置转义符及其一句话简介,可通过搜索转义符进行快速定位
  83. #
  84. # (文本替换类)
  85. #    \conv   自定义的文本替换
  86. #    \rb     利用Ruby脚本获取替换文本
  87. #    \info   显示数据库指定对象的图标和名称
  88. #    \nl     换行符
  89. #
  90. # (绘制类)
  91. #    \pic    绘制图片
  92. #
  93. # (控制类)
  94. #    \font   文字绘制的基本设置,包括文字大小、加粗、阴影、边框、发光、底纹等
  95. #    \win    对话框的基本设置,包括对话框皮肤背景、位置、大小、文字显示等
  96. #    \move   对话框的动态移动
  97. #    \auto   自动对话的设置
  98. #    \pop    气泡对话框的基本设置,包括显示位置、大小、指示箭头等
  99. #    \face   脸图的动态设置,包括脸图当前显示索引、循环等
  100. #    \facep  脸图的预先设置,包括脸图位置、移入移出方式等
  101. #    \facem  脸图的实时动作,包括跳跃、移动等
  102. #    \name   姓名框的预先设置,包括姓名文本、姓名框位置、大小等
  103. #    \pause  等待按键时的帧动画设置,包括帧动画类型、显示位置等
  104. #    \shake  控制对话框的震动
  105. #    \wait   直接等待
  106. #    \ins    对话框立即完全显示
  107. #    \hold   保留当前对话框,直到下一个不包含该转义符的对话框关闭
  108. #    \close  当前对话框必定处理关闭
  109. #    \next   当前对话框不关闭,下一次的显示文本在该对话框内继续显示
  110. #    \clc    向上移出隐藏全部文字,在新一行里继续绘制之后的文字
  111. #
  112. # (文字特效类)
  113. #    \cin    文字移入
  114. #    \cout   文字移出
  115. #    \uout   文字消散移出
  116. #    \csin   文字正弦扭曲
  117. #    \cwave  文字上下浮动
  118. #    \cswing 文字左右摇摆
  119. #    \czoom  文字缩放
  120. #    \cshake 文字抖动
  121. #    \cshake2 文字抖动(高频率版本)
  122. #    \cflash 文字闪烁
  123. #    \cmirror 文字镜像
  124. #    \cu     文字间歇消散
  125. #    \ctog   文字间歇切换
  126. #    \cneon  文字霓虹灯变色
  127. #    \cmc    文字叠加
  128. #    \cjump  文字跳跃
  129. #    \cfk    文字明灭闪烁
  130. #
  131. # (变量环境)
  132. #    \env    保存、读取应用指定的变量环境,方便进行不同对话框设置之间的切换
  133. #    \temp   对话框关闭时,将对话框重置为开启前的环境
  134. #
  135. # (高级)
  136. #    \func   设置一些进阶功能
  137. #    \eval   在对话中途,执行Ruby脚本
  138. #    \set    设置文字分组
  139. #    \setm   对指定文字分组进行处理
  140. #
  141. # (扩展)
  142. #    \cg     渐变色绘制
  143.  
  144. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  145. # ○ 文本替换类
  146. #     此类别的转义符将在绘制开始前,进行一次对应文本的替换
  147. #     将按照下面的排列顺序(从上往下)进行替换,因此请注意相互之间的嵌套层级
  148. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  149. #----------------------------------------------------------------------------
  150. #  \conv[string] 或 \M[string]
  151. #----------------------------------------------------------------------------
  152. # 【功能】
  153. #    整个转义符将被替换成 CONVERT_ESCAPE 中所设置的 string 所对应的文本
  154. #
  155. # 【参数】
  156. #    string → 在CONVERT_ESCAPE哈希表中的键值(若不存在,则返回空字符串)
  157. #
  158. # 【常量设置:文本替换】
  159. # (由于解析问题,字符串中请将 "\" 替换成 "\\")
  160. # (如果目标转义符是用 <> 代替 [],如姓名框中的名称,
  161. #    则需将姓名框中名称中的 "\" 替换成 "\e")
  162. CONVERT_ESCAPE = {
  163. # String => String,
  164.   "底部" => "\\win[ali0dw1dh1o2do-2dx0dy-60]\\pause[do0o4]\\temp",
  165.   "顶部" => "\\win[ali0dw1dh1o8do-8dx0dy60]\\pause[do0o4]\\temp",
  166. }
  167. # (之后的常量也推荐用这种方式进行新增/覆盖)
  168. # (也可以在新脚本页中新增 module MESSAGE_EX 和 end ,并在其中添加常量设置)
  169. CONVERT_ESCAPE["系统"] = "\\win[ali1dw1dh1o5do-5dx0dy0]\\pause[do2o5]\\temp"
  170. #
  171. # 【示例】
  172. #   - 脚本常量
  173. CONVERT_ESCAPE["测试用"] = "这是一句测试语句。"
  174. #   - 对话编写
  175. #       测试对话为 \conv[测试用]。
  176. #    或 测试对话为 \M[测试用]。
  177. #   - 实际对话
  178. #       测试对话为 这是一句测试语句。
  179. #
  180. #----------------------------------------------------------------------------
  181. #  \rb{string}
  182. #----------------------------------------------------------------------------
  183. # 【功能】
  184. #    整个转义符将被替换成 eval(string) 的执行结果(强制转化为文本)
  185. #
  186. # 【参数】
  187. #    string → Ruby脚本语句,可以用 ; 分隔多句,不可含有花括号
  188. #
  189. # 【注意】
  190. #   该转义符使用花括号,同时 string 中不可以出现花括号
  191. #   可用 s 代替 $game_switches ,用 v 代替 $game_variables
  192. #   可用 event 代表执行当前对话框的事件(Game_Event对象)
  193. #
  194. # 【示例】
  195. #   - 对话编写(1号变量值为1,2号变量值为2)
  196. #       这是一句测试用对话,都已经说了\rb{v[1]+v[2]}次了!
  197. #   - 实际对话
  198. #       这是一句测试用对话,都已经说了3次了!
  199. #
  200. #----------------------------------------------------------------------------
  201. #  \info[type+id,n]
  202. #----------------------------------------------------------------------------
  203. # 【功能】
  204. #    整个转义符将被替换成指定数据库对象的 图标+名称 的文本
  205. #
  206. # 【参数】
  207. #    type → 数据库对象的类型(s代表技能,i代表物品,w代表武器,a代表防具)
  208. #      id → 数据库对象的序号
  209. #      n  → 绘制类型(可省略,0默认绘制图标+名称,1仅绘制图标,2仅绘制名称)
  210. #
  211. # 【注意】
  212. #    加号只是表示由两个必须的参数构成,实际编写时不要写 + 符号!
  213. #
  214. # 【示例】
  215. #   - 对话编写
  216. #       1号物品是\info[i1],2号武器的名称是\info[w2,2]
  217. #   - 实际对话
  218. #       1号物品是【图标】恢复剂,2号武器的名称是战斧
  219. #
  220. #----------------------------------------------------------------------------
  221. #  \nl
  222. #----------------------------------------------------------------------------
  223. # 【功能】
  224. #    将被替换成换行转义符 \n(效果等同编辑器中的手动回车)
  225. #
  226. # 【注意】
  227. #    由于编辑器自身限制,部分文本框无法识别输入的\n,因此添加了该转义符,
  228. #    实际上并没有什么用处
  229. #
  230.  
  231. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  232. # ○ 绘制类
  233. #     此类别的转义符将被视为绘制内容,与通常文字一样占用绘制空间
  234. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  235. #----------------------------------------------------------------------------
  236. #  \pic[filename|param]
  237. #----------------------------------------------------------------------------
  238. # 【功能】
  239. #    在当前位置绘制指定名称的图片
  240. #
  241. # 【参数】
  242. #    filename → 图片的名称,可省略后缀名
  243. #     (图片存放于 Grphics/Pictures 目录下)
  244. #    param → 变量参数字符串,可省略不写
  245. # (变量一览)
  246. #      w → 指定绘制图片的宽度(默认与原图一致,若不同则利用stretch_blt进行缩放)
  247. #      h → 指定绘制图片的高度
  248. #    opa → 【默认】指定绘制图片的不透明度(默认255)
  249. #
  250. # 【示例】
  251. #   - 对话编写
  252. #       这是测试对话\pic[猫猫快乐]
  253. #   - 实际对话
  254. #      (在转义符所在位置绘制目录下文件名为 猫猫快乐 的图片,显示宽高不变)
  255. # 【示例】
  256. #   - 对话编写
  257. #       这是测试对话\pic[猫猫疑惑|w=50 h=50]
  258. #   - 实际对话
  259. #      (在转义符所在位置绘制目录下文件名为 猫猫疑惑 的图片,且宽度高度固定为50)
  260. #
  261.  
  262. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  263. # ○ 控制类
  264. #     此类别的转义符将对各类功能进行设置、调用
  265. #      对于带有“是否”描述的变量,数字0代表 false,正数(推荐数字1)代表 true
  266. #      对于未说明 nil 效果的变量,请尽量不要传入 nil(传入符号$代表传入nil)
  267. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  268. #----------------------------------------------------------------------------
  269. #  \c[id]
  270. #----------------------------------------------------------------------------
  271. # 【功能】
  272. #    变更之后的文字绘制颜色(扩展了默认的\c[id]转义符)
  273. #
  274. # 【参数】
  275. #    id → 可传入 TEXT_COLORS 常量中所设置的字符串,将匹配其对应的颜色
  276. #            如 \c[pink] 将使用 "pink" 所对应的 Color 作为文字颜色
  277. #         若匹配失败,将执行 id.to_i 转为数字,使用默认的索引颜色
  278. #       (若传入 -1,则重置为 DEFAULT_COLOR_INDEX ,同时不透明度重置为 255)
  279. #
  280. # 【常量设置:每次开启对话框时,文字颜色重置为该索引颜色】
  281. DEFAULT_COLOR_INDEX = 0
  282. #
  283. # 【常量设置:标识符映射到Color】
  284. TEXT_COLORS = {
  285.   "pink" => Color.new(255, 187, 217),
  286. }
  287. #
  288. # 【示例】
  289. #   - 脚本常量
  290. TEXT_COLORS["gold"] = Color.new(255,215,0)
  291. #   - 对话编写
  292. #       这是\c[gold]测试\c[0]对话。
  293. #   - 实际对话
  294. #      (“测试”文字将变成设置的gold对应颜色)
  295. #
  296. #----------------------------------------------------------------------------
  297. #  \font[param]
  298. #----------------------------------------------------------------------------
  299. # 【功能】
  300. #    设置文字的绘制参数
  301. #
  302. # 【参数】
  303. #    param → 变量参数字符串
  304. # (变量一览)
  305. #    name → 字体名称的索引(在INDEX_TO_FONT中设置)(若为nil,则与默认一致)
  306. #    size → 【默认】字体大小
  307. #    c → 文字颜色的索引号(与 \c 一致)
  308. #       (若传入 -1,则重置为 DEFAULT_COLOR_INDEX ,同时不透明度重置为 255)
  309. #    ca → 文字的不透明度(0~255)
  310. #    i → 是否斜体(font.italic)
  311. #    b → 是否加粗(font.bold)
  312. #    s → 是否添加阴影(font.shadow)
  313. #    o → 是否添加边框(font.outline)
  314. #    or/og/ob/oa → 设置边框颜色RGBA(0~255)
  315. #    p → 底部花纹的类型(0不绘制,1边框,2实心方框)
  316. #    pc → 底部花纹的颜色索引号(具体查看 Windowskin 右下角,同默认\c[id]颜色)
  317. #    l → 是否绘制外发光(若开启,则强制关闭阴影和边框)
  318. #    lc → 外发光的颜色索引号
  319. #    lp → 外发光的强度
  320. #    d → 是否绘制删除线
  321. #    dc → 删除线的颜色索引号
  322. #    u → 是否绘制下划线
  323. #    uc → 下划线的颜色索引号
  324. #    k → 是否生成文字破碎效果(参考:[url]http://www.whiteflute.org/wfrgss/[/url])
  325. #    kv → 单个像素的破碎概率(百分数,数字越大,文字破碎效果越明显)
  326. #
  327. # 【常量设置:参数预设值】
  328. FONT_PARAMS_INIT = {
  329. # \font[]
  330.   :name => nil,
  331.   :size => nil, # 字体大小
  332.   :ca => 255, # 不透明度
  333.   :i => nil, # 斜体绘制
  334.   :b => nil, # 加粗绘制
  335.   :s => nil, # 阴影
  336.   :o => nil, # 描边
  337.   :or => nil,
  338.   :og => nil,
  339.   :ob => nil,
  340.   :oa => nil,
  341.   :p => 0, # 底纹
  342.   :pc => 0, # 底纹颜色index
  343.   :l => 0, # 外发光
  344.   :lc => 0, # 外发光颜色index
  345.   :lp => 2, # 外发光强度
  346.   :d => 0, # 删除线
  347.   :dc => 0, # 删除线颜色index
  348.   :u => 0, # 下划线
  349.   :uc => 0, # 下划线颜色index
  350.   :k => 0, # 文字破碎
  351.   :kv => 50, # 像素破碎概率
  352. }
  353. #
  354. # 【常量设置:序号映射到字体名称】
  355. INDEX_TO_FONT = {
  356. # 数字 => 字体名称字符串
  357.   1 => "黑体",
  358. }
  359. #
  360. # 【示例】
  361. #   - 对话编写
  362. #       这是\font[d=1]测试\font[d=0]对话。
  363. #   - 实际对话
  364. #      (“测试”文字将绘制删除线)
  365. #
  366. #----------------------------------------------------------------------------
  367. #  \win[param]
  368. #----------------------------------------------------------------------------
  369. # 【功能】
  370. #    对话框窗口的各类设置
  371. #
  372. # 【参数】
  373. #    param → 变量参数字符串
  374. # (变量一览)
  375. #  (窗口属性相关)
  376. #    z → 对话框的z值(仅正整数有效)(默认取va里的200)
  377. #    skin → 对话框所用windowskin的index(按常量设置进行 index → skin名称 映射)
  378. #    bg → 对话框背景图片的index(按常量设置进行 index → 图片名称 映射)
  379. #        (只有当 事件指令-显示文字-窗口背景 为 普通窗口 时,才生效)
  380. #        (若图片读取成功,将不再显示窗口皮肤;若读取失败,仍绘制窗口皮肤)
  381. #    bgo → 对话框背景图片与对话框的对齐原点(对应九宫格小键盘)
  382. #        (默认背景图片的左上角与对话框左上角对齐,值为7)
  383. #
  384. #  (窗口位置相关)
  385. #    o → 【默认】对话框的显示原点的类型(对应九宫格小键盘)(默认左上角7)
  386. #    x/y → 对话框显示原点在屏幕上的坐标(默认nil,取va设置,对话框位于底部)
  387. #    do → 将屏幕进行九宫格划分,对话框显示原点在屏幕上的位置类型(覆盖x/y)
  388. #        (参考九宫格小键盘,有效值为-1~-9,-1在屏幕左下角,-5在屏幕中心点)
  389. #    dx/dy → x、y坐标的增加量(默认0)
  390. #    fix → 是否修正对话框位置(保证对话框完整显示在屏幕内)
  391. #
  392. #  (窗口大小相关)
  393. #    w → 窗口内容的宽度(不含边框)(默认0不设置)(优先级高于dw和fw)
  394. #    dw → 窗口内容宽度是否随文字绘制而动态变化(默认0,不动态变化)
  395. #    fw → 窗口内容宽度是否设置为全部文字绘制完成时的宽度(优先级高于dw)
  396. #    wmin/wmax → 窗口内容宽度的最小最大值(启用dw/fw时生效)(默认0不设置)
  397. #    h → 窗口内容的高度(不含边框)(默认0不设置)(优先级高于dh和fh)
  398. #       (若小于对话框的 line_height 方法值,则识别为行数,乘以行高,作为高度值)
  399. #    dh → 窗口内容高度是否随文字绘制而动态变化(默认0,不动态变化)
  400. #    fh → 窗口内容高度是否指定为全部文字绘制完成时的高度(优先级高于dh)
  401. #    hmin/hmax → 窗口内容高度的最小最大值(启用dh/fh时生效)(若小于行高,则为行数)
  402. #
  403. #  (文本显示相关)
  404. #    se → 启用的打字音类型index(默认0,按常量设置进行 index → 声效SE设置 映射)
  405. #    ali → 文本的对齐方式(0左对齐,1居中对齐,2右对齐;默认0)
  406. #    ck → 增加的字符间距值(默认0)
  407. #    lh → 设置基础行高 line_height 值(若为nil则取当前字号)
  408. #    ld → 增加的行间距值(默认0)(每一行的行高将取该行的最大高度)
  409. #    cwi → 单个文字绘制完成后的等待帧数(最小值0)
  410. #    cwo → 单个文字移出开始后的等待帧数(最小值0)
  411. #    cor → 全部文字移出的顺序类型(0正序,1逆序,2乱序,默认0)
  412. #    cfast → 是否允许按键快进(默认1,可以按键快进)
  413. #    cdx/cdy/cdw/cdh → 文本绘制区域与窗口padding左侧/上侧/右侧/下侧的间距(默认0)
  414. #
  415. # 【常量设置:参数预设值】
  416. WIN_PARAMS_INIT = {
  417. # \win[]
  418.   # (窗口属性相关)
  419.   :z => 200,
  420.   :skin => 0, # 对话框所用windowskin的类型
  421.   :bg => nil, # 对话框背景所用图片(覆盖窗口皮肤)
  422.   :bgo => 7,  # 对话框背景图片与对话框的对齐原点
  423.   # (窗口位置相关)
  424.   :o => 7, # 原点位置类型 默认为7左上角
  425.   :x => nil, # 原点坐标xy
  426.   :y => nil,
  427.   :do => 0, # 相较于屏幕的九宫格位置(覆盖x/y的设置)
  428.   :dx => 0, # 坐标偏移值xy
  429.   :dy => 0,
  430.   :fix => 1, # 是否进行位置修正,防止对话框跑出屏幕
  431.   # (窗口大小相关)
  432.   :w => 0,
  433.   :h => 0,
  434.   :dw => 0, # 若为1,则代表宽度会依据文字动态调整
  435.   :fw => 0, # 若为1,则窗口打开时即为文字绘制完成时所需宽度值
  436.   :wmin => 0, # 设置宽度的上下限(当dw==1时生效)
  437.   :wmax => 0, # (有脸图时宽度会自动增加脸图宽度)
  438.   :dh => 0, # 若为1,则代表高度会依据文字动态调整
  439.   :fh => 0, # 若为1,则窗口打开时即为文字绘制完成时所需高度值
  440.   :hmin => 0, # 设置高度的上下限(当dh==1时生效)
  441.   :hmax => 0,
  442.   # (文本显示相关)
  443.   :se => 0, # 打字音类型序号(默认0,无声效)
  444.   :ali => 0, # 设置文本对齐方式
  445.   :ck => 0, # 增加的字符间距值
  446.   :lh => nil, # 基础行高(若为nil,则取当前文字大小)
  447.   :ld => 4, # 增加的行间距值
  448.   :cwi => 2, # 单个文字绘制后的等待帧数(最小值0)
  449.   :cwo => 0, # 单个文字开始移出后的等待帧数(最小值0)
  450.   :cor => 0, # 全部文字移出的顺序类型
  451.   :cfast => 1, # 是否允许快进
  452.   :cdx => 0, # 文本左侧与窗口padding的间距
  453.   :cdy => 0, # 文本上边距
  454.   :cdw => 0, # 文本右边距
  455.   :cdh => 0, # 文本下边距
  456. }
  457. #
  458. # 【常量设置:序号映射到windowskin文件名】
  459. #  (其中 index 必须为整数)
  460. #  (窗口皮肤图片存储于 Graphics/System 目录下)
  461. INDEX_TO_WINDOWSKIN = {
  462. # 数字 => 皮肤文件名(可省略后缀)
  463.   0 => "Window", # 默认所用皮肤名称
  464. }
  465. #
  466. # 【常量设置:序号映射到窗口背景图片文件名】
  467. # (图片的左上角会与对话框的左上角对齐)
  468. # (其中 index 必须为整数)
  469. # (图片存储于 Graphics/System 目录下)
  470. INDEX_TO_WINDOW_BG = {
  471. # 数字 => "背景图片名称"
  472. }
  473. #
  474. # 【常量设置:序号映射到打字音效】
  475. # (音效文件存储于 Audio/SE 目录下)
  476. INDEX_TO_SE = {
  477. # 数字 => SE文件名, 音量, 音调
  478.   0 => ["", 80, 100], # 默认设置,不推荐修改
  479.   1 => ["Cursor1", 40, 150],
  480. }
  481. #
  482. # 【示例】
  483. #   - 对话编写
  484. #       \win[o5 do-5 dw1dh1]这是测试对话。
  485. #   - 实际对话
  486. #      (对话框显示在屏幕中心,且随着文字显示而动态扩展)
  487. # 【示例】
  488. #   - 对话编写
  489. #       \win[o=2 do=-2 dy=-20 fw1fh1]这是测试对话,看看到底怎么样。
  490. #   - 实际对话
  491. #      (对话框显示在屏幕底部,且依据文字动态变更宽高)
  492. #
  493. #----------------------------------------------------------------------------
  494. #  \move[param]
  495. #----------------------------------------------------------------------------
  496. # 【功能】
  497. #    动态移动对话框位置,并等待移动结束
  498. #
  499. # 【注意】
  500. #    若设置了 win 转义符的 do 参数,则该移动无效
  501. #    若设置了 pop 转义符,则该移动无效
  502. #
  503. # 【参数】
  504. #    param → 变量参数字符串
  505. # (变量一览)
  506. #    t → 移动所需的总共帧数(默认20帧)
  507. #    x → 直接指定移动的目的地x(若为0,则重置为win转义符中的x,或RGSS中初始位置0)
  508. #    y → 直接指定移动的目的地y(若为0,则重置为win转义符中的y,或RGSS中初始位置底部)
  509. #    dx → 在当前位置基础上,水平移动的距离(正数为向右,负数为向左)
  510. #    dy → 在当前位置基础上,竖直移动的距离(正数为向下,负数为向上)
  511. #
  512. # 【示例】
  513. #   - 对话编写
  514. #       这是测试对话,\move[dx=40 dy=30]看看到底怎么样。
  515. #   - 实际对话
  516. #      (在显示完“这是测试对话,”后,对话框将向下移动40,向下移动30的距离,
  517. #        然后继续显示剩余的文字)
  518. #
  519. #----------------------------------------------------------------------------
  520. #  \auto[t]
  521. #----------------------------------------------------------------------------
  522. # 【功能】
  523. #    等待按键时,设置文本自动继续
  524. #
  525. # 【参数】
  526. #    t → 在t帧后自动结束按键等待,并继续事件处理(默认nil,不自动继续)
  527. #
  528. # 【常量设置:参数预设值】
  529. # 当未调用 \auto[t] 进行设置,或其值为 nil 时,读取此处的值
  530. WIN_AUTO_T = nil
  531. #
  532. # 【常量设置:提示文本】
  533. # 自动播放的UI中显示的文本
  534. WIN_AUTO_TEXT = "自动播放"
  535. #
  536. # 【常量设置:UI的宽高】
  537. WIN_AUTO_W = 100
  538. WIN_AUTO_H = 40
  539. #
  540. # 【常量设置:UI的原点】
  541. # 九宫格小键盘,如 5 代表中点为原点,9 代表右上角为原点
  542. WIN_AUTO_O  = 9
  543. #
  544. # 【常量设置:UI的位置】
  545. # 九宫格小键盘,如 3 代表绑定到对话框的右下角,5 代表绑定到对话框的中心
  546. #  -2 代表绑定到屏幕的底部中点,-9 代表绑定到屏幕的右上角
  547. WIN_AUTO_DO = -9
  548. #
  549. # 【常量设置:UI的坐标偏移值】
  550. WIN_AUTO_DX = 0
  551. WIN_AUTO_DY = 0
  552. #
  553. # 【示例】
  554. #   - 对话编写
  555. #       这是测试对话,看看到底怎么样。\auto[60]
  556. #   - 实际对话
  557. #      (在显示完成后,等待1s后自动关闭当前对话框,继续之后的事件指令)
  558. #
  559. #----------------------------------------------------------------------------
  560. #  \pop[param] 【预先】
  561. #----------------------------------------------------------------------------
  562. # 【功能】
  563. #    气泡类型对话框的各类设置
  564. #
  565. # 【参数】
  566. #    param → 变量参数字符串
  567. # (变量一览)
  568. #  (窗口属性相关)
  569. #    skin → pop状态下对话框所用皮肤的index(按常量设置进行 index → skin名称 映射)
  570. #         (默认nil,取win转义符中的skin变量的值)
  571. #
  572. #  (窗口位置相关)
  573. #    id → 【重置】【默认】所绑定对象的id
  574. #     【地图】设置 0 取执行当前对话框的事件的id
  575. #              正数id 取当前地图id号的事件,目标事件不存在则取当前事件
  576. #              负数id 取队列中数据库id号的角色,目标角色不在队伍中则取队首角色
  577. #     【战斗】设置 正数id 取敌群中index序号为id的敌人,目标敌人不存在则pop无效
  578. #              负数id 取我方参战角色中数据库id号的角色,目标角色不存在则pop无效
  579. #    mx/my → 【重置】绑定到地图的 (mx, my) 处(同编辑器坐标)(格子中心为显示原点)
  580. #           (当未设置id时,该变量设置才生效)
  581. #    do → 对话框相对于绑定对象的位置类型(默认8,即对话框原点位于目标的顶部中间)
  582. #         (参考九宫格小键盘,1代表目标左下角,5代表目标中心,9代表目标右上角)
  583. #    o → 对话框原点的类型
  584. #         (若为nil,则为 10-do,即当do为8时,对话框原点为底部中点2)
  585. #    d → 对话框原点远离绑定对象中心点的像素值(默认0)
  586. #         (用于设置对话框与绑定对象的距离,将按do自动决定xy如何增减)
  587. #    dx/dy → x、y方向上的像素增量(默认0)
  588. #    fix → 是否进行位置修正(保证pop对话框完整显示在屏幕内)
  589. #
  590. #  (窗口大小相关)(与win中相同,均覆盖win中的对应设置)
  591. #    w → pop对话框的内容固定宽度(默认0不设置)(优先级高于dw/fw)
  592. #    h → pop对话框的内容固定高度
  593. #       (若小于对话框的 line_height 方法值,则识别为行数,乘以行高,作为高度值)
  594. #    dw → 是否随文字绘制而动态变更pop对话框的内容宽度
  595. #    fw → 是否指定为全部文字绘制完成时的所需宽度(覆盖dw)
  596. #    dh → 是否随文字绘制而动态变更pop对话框的内容高度
  597. #    fh → 是否指定为全部文字绘制完成时的所需高度(覆盖dh)
  598. #
  599. #  (Tag精灵相关)
  600. #    tag → 所用的tag箭头图片的index(按常量设置进行 index → tag名称 映射)
  601. #    td → 设置tag与所绑定对象的中心的远离偏移值(按pop的do自动设置xy)(默认0)
  602. #
  603. # 【常量设置:参数预设值】
  604. POP_PARAMS_INIT = {
  605. # \pop[]
  606.   :skin => nil, # pop模式下所用skin类型
  607.   :do => 8, # 对话框相对于绑定对象的位置(九宫格小键盘)
  608.   :o => nil, # 对话框显示原点,若为nil,则取 10 - :do
  609.   :d => 0, # 指定原点远离事件格子中心的偏移量
  610.   :dx => 0,  # 指定x、y方向上的偏移量
  611.   :dy => 0,
  612.   :fix => 0, # 是否进行位置修正
  613.   :w => 0, # 指定固定的宽度和高度(优先级高于win_params)
  614.   :h => 0,
  615.   :dw => 0, # 若为1,则代表宽度会依据文字动态调整
  616.   :fw => 1, # 若为1,则窗口打开时将预绘制成文字区域最终大小
  617.   :dh => 0, # 若为1,则代表高度会依据文字动态调整
  618.   :fh => 1, # 若为1,则窗口打开时将预绘制成文字区域最终大小
  619.   :tag => 1, # tag所用文件名index(0时表示不启用)
  620.   :td => 3, # tag与绑定事件格子中心位置的远离值
  621. }
  622. #
  623. # 【常量设置:序号映射到Tag】
  624. # (其中 index 为正整数;为 0 时代表不启用tag)
  625. # (图片存储于 Graphics/System 目录下)
  626. # 【Tag图片解析】任意大小,3帧×3帧规格
  627. #    7 8 9
  628. #    4 5 6  ← pop对话框的原点位置类型 与 对应所用的tag位图区域
  629. #    1 2 3
  630. # (比如 pop对话框的原点类型为 2 时,tag显示在对话框底部中央,图像使用2号区域)
  631. # 【注意】tag的存在不会使pop对话框产生额外偏移,请利用pop参数d/dx/dy自行移动
  632. INDEX_TO_WINDOWTAG = {
  633.   1 => "Window_Tag", # 默认所用tag名称
  634. }
  635. #
  636. # 【常量设置:窗口皮肤绑定Tag】
  637. # (当使用的窗口皮肤在此处有设置时,将必定使用此处对应设置的Tag)
  638. WINDOWSKIN_TO_WINDOWTAG = {
  639.   -1 => 1,
  640. }
  641. #
  642. # 【示例】
  643. #   - 对话编写
  644. #       \pop[-1]这是测试对话。
  645. #   - 实际对话
  646. #      (在玩家头顶显示气泡对话框)
  647. #
  648. #----------------------------------------------------------------------------
  649. #  \face[param]
  650. #----------------------------------------------------------------------------
  651. # 【功能】
  652. #    脸图的动态设置
  653. #
  654. # 【注意】
  655. #    本对话框对显示脸图进行了规格扩展:
  656. #      当脸图文件名包含 _数字1x数字2 时(其中为字母x),
  657. #      将定义该脸图文件的规格为 行数(数字1)x列数(数字2)(默认2行x4列)
  658. #    如:ace_actor.png → 该脸图规格为 2行4列,含有8张脸图,与默认一致
  659. #    如:ace_actor_1x1.png → 该脸图规格为 1行1列,含有1张脸图,只有index为0时生效
  660. #    如:ace_actor_1x4.png → 该脸图规格为 1行4列,含有4张脸图
  661. #
  662. # 【参数】
  663. #    param → 变量参数字符串
  664. # (变量一览)
  665. #    i → 【重置】【默认】脸图文件不改变,切换所显示脸图的序号index
  666. #    ls/le → 【重置】定义脸图自动循环播放的开始index/结束index(-1时不启用自动播放)
  667. #    lt → 自动循环播放时,每两帧之间的等待间隔帧数
  668. #    lw → 自动循环播放时,每一次loop结束时的等待帧数(nil代表不再循环)
  669. #
  670. #
  671. # 【高级】
  672. #  - 本对话框的宽高可以动态变化,脸图不影响对话框高度,
  673. #      也因此本对话框允许脸图超出范围,这样方便显示更大规格的脸图(立绘)。
  674. #    但一般大家都使用默认 96x96 规格的脸图,且默认的脸图恰好显示在默认对话框内,
  675. #      此时如果不把脸图包裹住的话比较难看,因此增加该项设置:
  676. #      开启时,当使用默认规格脸图,将强制对话框内容高度大于等于脸图高度
  677. FORCE_WIN_H_BIGGER_THAN_DEFAULT_FACE = true
  678. #
  679. # 【常量设置:参数预设值】
  680. FACE_PARAMS_INIT = {
  681. # \face[]
  682.   :lt => 30, # 循环时,每两帧之间的间隔
  683.   :lw => 60, # 循环后,等待帧数
  684. # \facep[]
  685.   :dir => 0, # 脸图显示方向 1为右侧
  686.   :m => 0, # 脸图镜像显示
  687.   :it => 15, # 脸图移入所需帧数
  688.   :ot => 10, # 脸图移出所需帧数
  689.   :dx => 0, # 脸图x方向的偏移增量
  690.   :dy => 0, # 脸图y方向的偏移增量
  691.   :dw => 8, # 脸图显示宽度的补足量
  692.   :z => 1, # 脸图z值增量
  693. }
  694. #
  695. # 【示例】
  696. #   - 对话编写
  697. #       这是测试对话。\facep[dir1]\face[2]\facem[jump]
  698. #   - 实际对话
  699. #      (脸图显示到右侧,在对话最后切换成第1行第3列的脸图,且跳跃一次)
  700. #
  701. #----------------------------------------------------------------------------
  702. #  \facep[param] 【预先】
  703. #----------------------------------------------------------------------------
  704. # 【功能】
  705. #    脸图的预先设置
  706. #
  707. # 【参数】
  708. #    param → 变量参数字符串
  709. # (变量一览)
  710. #    dir → 【默认】脸图的显示位置(0左侧,1右侧;默认0)
  711. #    m → 是否镜像显示脸图(默认0,不开启镜像)
  712. #    it → 脸图淡入时所用帧数
  713. #    ot → 脸图淡出时所用帧数
  714. #    dx → 脸图在x方向上的偏移增量(默认0)
  715. #    dy → 脸图在y方向上的偏移增量(默认0)
  716. #    dw → 当嵌入对话框内时,脸图宽度的补足增量(默认0)
  717. #    z → 脸图的z值增量(默认1,在对话框上面)
  718. #        (当传入 -1 时将显示在对话框下面,此时脸图不占用对话框宽度)
  719. #
  720. #----------------------------------------------------------------------------
  721. #  \facem[str|param]
  722. #----------------------------------------------------------------------------
  723. # 【功能】
  724. #    脸图的实时动作设置
  725. #
  726. # 【参数】
  727. #    str → 脸图动作的字符串
  728. #    param → 脸图动作的变量参数字符串,可省略
  729. #
  730. # (脸图动作一览)
  731. #    in → 脸图移入(无参数)
  732. #    out → 脸图移出(无参数)
  733. #    jump → 脸图进行一次短暂跳跃(无参数)
  734. #      使用示例: \facem[jump] 脸图小幅度跳跃一次
  735. #    move → 脸图移动到指定位置
  736. #      (变量一览)
  737. #           x/y → 直接指定移动的目的地(以脸图移入后的位置为原点)
  738. #         dx/dy → 指定在当前位置基础上的移动增量
  739. #             t → 移动所需的时间(三次立方平滑)
  740. #     使用示例: \facem[move|dx=50] 脸图朝右侧移动50像素
  741. #
  742. # 【注意】
  743. #   - 脸图动作期间,对话框不会暂停绘制,请自行调用 wait 转义符进行等待。
  744. #   - 若在执行动作时,又呼叫了新的动作,
  745. #      则在当前动作执行完成后,只会继续执行最后传入的一个动作。
  746. #
  747. #----------------------------------------------------------------------------
  748. #  \name[param] 【预先】
  749. #----------------------------------------------------------------------------
  750. # 【功能】
  751. #    姓名框的设置
  752. #
  753. # 【注意】
  754. #  - param 中用 | 分隔 姓名字符串(其中转义符用<>代替[])与 变量参数字符串
  755. #    (若无变量参数的设置,可省略 | 符号)
  756. #  - 若存在多个 \name ,只会取最后一个成功设置的姓名,但变量参数会依次生效覆盖
  757. #
  758. # 【参数】
  759. #    param → 变量参数字符串
  760. # (变量一览)
  761. #    o → 姓名框的显示原点(对应九宫格小键盘)(默认7,姓名框左上角为显示原点)
  762. #    do → 基于对话框的九宫格位置,姓名框的显示原点的实际位置
  763. #       (默认7,位于对话框左上角7)(0时为嵌入对话框中,且o自动设为7)
  764. #    dx/dy → 姓名框x、y坐标的额外偏移量
  765. #    opa → 姓名框背景的不透明度(默认255)(文字的不透明度锁定为255)
  766. #    skin → 姓名框所用皮肤的index(默认nil,同win中设置)
  767. #    size → 姓名框文字大小(默认nil,取Font默认值)
  768. #    bg → 姓名框背景图片的index(按常量设置进行 index → 图片名称 映射)
  769. #        (若读取成功,将不显示窗口皮肤;若读取失败,仍绘制窗口皮肤)
  770. #    bgo → 姓名框背景图片与姓名框的对齐原点(对应九宫格小键盘)
  771. #        (默认7,背景图片的左上角与姓名框左上角对齐)
  772. #    cx/cy → 姓名框的文字起始绘制位置(默认为0,0)
  773. #
  774. # 【高级】
  775. #  - 由于姓名框可能遮挡脸图,因此本对话框新增了自动调整,确保姓名框不遮挡脸图
  776. #    可利用 $game_message.no_name_overlap_face = true/false
  777. #      来设置是否开启该功能(默认 true 代表开启)
  778. DEFAULT_NO_OVERLAP_FACE = true
  779. #
  780. # 【常量设置:参数预设值】
  781. NAME_PARAMS_INIT = {
  782. # \name[]
  783.   :o => 7, # 自身的显示原点位置
  784.   :do => 0, # 相较于对话框的显示原点位置
  785.   :dx => 0, # 姓名框整体的偏移增量(如果为嵌入,则会自动增加占位的宽高)
  786.   :dy => 0,
  787.   :opa => 255, # 背景不透明度
  788.   :skin => nil, # 姓名框所用windowskin的类型(nil为与对话框一致)
  789.   :size => nil, # 姓名框文字大小
  790.   :bg => nil, # 姓名框背景所用图片index(覆盖窗口皮肤)
  791.   :bgo => 1,  # 姓名框背景图片与姓名框的对齐原点
  792.   :cx => 0,   # 姓名框内部,绘制姓名时的初始位置
  793.   :cy => 0,
  794. }
  795. #
  796. # 【常量设置:全部姓名前统一增加的字符串】
  797. # (支持draw_text_ex中的转义符)(\c[]转义符支持 TEXT_COLORS 扩展)
  798. # (由于解析问题,字符串中请将 "\" 替换成 "\e" ,并用 <> 代替 [])
  799. ESCAPE_STRING_NAME_PREFIX = "\ec<9>"
  800. #
  801. # 【常量设置:序号映射到姓名框背景图片文件名】
  802. # (如果 bgo 为 7,则图片左上角会与姓名框左上角对齐)
  803. # (其中 序号 必须为整数)
  804. # (图片存储于 Graphics/System 目录下)
  805. INDEX_TO_NAME_BG = { # 姓名框背景
  806.   # 序号数字 => " 背景图片名称"
  807. }
  808. #
  809. # 【示例】
  810. #   - 对话编写
  811. #       \name[主角]这是测试对话。\name[|o1do9]
  812. #   - 实际对话
  813. #      (显示姓名框,其中名称为“主角”,且姓名框左下角位于对话框右上角)
  814. #
  815. #----------------------------------------------------------------------------
  816. #  \pause[param]
  817. #----------------------------------------------------------------------------
  818. # 【功能】
  819. #    等待按键时的帧动画的设置
  820. #
  821. # 【参数】
  822. #    param → 变量参数字符串
  823. # (变量一览)
  824. #    id → 【默认】所用的等待按键帧动画在INDEX_TO_PAUSE中的序号
  825. #    o → 帧动画的显示原点位置类型(九宫格小键盘)(默认左上角7)
  826. #    do → 基于对话框的九宫格位置,自身显示位置的类型(0时显示在文末)(默认2)
  827. #    dx/dy → xy方向上的补足偏移值(默认0)
  828. #    t → 每两帧之间的等待帧数(默认10)
  829. #    v → 是否显示等待按键的帧动画(默认1,显示等待按键动画)
  830. #
  831. # 【常量设置:参数预设值】
  832. PAUSE_PARAMS_INIT = {
  833. # \pause[]
  834.   :id => 0,
  835.   :o => 4,  # 自身的显示原点类型
  836.   :do => 0,  # 相对于对话框的显示位置(九宫格小键盘)(0时为在文末)
  837.   :dx => 0,  # xy偏移值
  838.   :dy => 0,
  839.   :t => 7, # 每两帧之间的等待帧数
  840.   :v => 1,  # 是否显示
  841. }
  842. #
  843. # 【常量设置:序号映射到等待按键的帧动画】
  844. # (其中 index 必须为整数)
  845. # (图片存储于 Graphics/System 目录下)
  846. # (帧动画统一从左上开始设为0号位置,并按行优先从左往右遍历)
  847. INDEX_TO_PAUSE = {
  848. #         文件名 范围(nil则为整张图) 一行中的帧数 一列中的帧数
  849. #index=>[String, Rect, Integer, Integer]
  850. -1 => ["", nil, 1, 1], # 不显示
  851.   0 => ["Window", Rect.new(96,64,32,32), 2, 2], # 默认 使用皮肤窗口里的箭头
  852. }
  853. #
  854. # 【常量设置:是否屏蔽默认的输入等待动画】
  855. # (指默认位于对话框底部中央的4帧动画,推荐屏蔽,只用pause的帧动画)
  856. NO_DEFAULT_PAUSE = true
  857. #
  858. # 【示例】
  859. #   - 对话编写
  860. #       这是测试对话。\pause[0o5do3dx-12dy-12]
  861. #   - 实际对话
  862. #      (等待按键的精灵位于对话框右下角)
  863. #
  864. #----------------------------------------------------------------------------
  865. #  \shake[param]
  866. #----------------------------------------------------------------------------
  867. # 【功能】
  868. #    进行对话框震动(与事件指令中的屏幕震动一致)并等待至结束
  869. #
  870. # 【参数】
  871. #    param → 变量参数字符串
  872. # (变量一览)
  873. #    p → 震动的强度(默认5)
  874. #    s → 震动的速度(默认5)
  875. #    t → 【默认】震动的持续帧数(将补足平滑结束的帧数)(默认40)
  876. #    y → 是否由 x 方向的震动修改为 y 方向的震动(默认0,即false,依然为x方向)
  877. #
  878. # 【示例】
  879. #   - 对话编写
  880. #       这是测试对话,\shake[p7]吓死我了,还以为地震了。
  881. #   - 实际对话
  882. #      (在显示完逗号后,开始对话框震动,并等待结束)
  883. #
  884. #----------------------------------------------------------------------------
  885. #  \wait[t]
  886. #----------------------------------------------------------------------------
  887. # 【功能】
  888. #    直接等待指定帧数
  889. #
  890. # 【参数】
  891. #    t → 等待的帧数
  892. #
  893. # 【注意】
  894. #   - 和默认的等待转义符保持一致,不会被快进、期间不处理按键
  895. #
  896. #----------------------------------------------------------------------------
  897. #  \ins 【预先】
  898. #----------------------------------------------------------------------------
  899. # 【功能】
  900. #    当前对话框不再处理绘制间隔的等待(先完成打开,再一次性绘制全部内容)
  901. #
  902. #----------------------------------------------------------------------------
  903. #  \hold 【结尾】
  904. #----------------------------------------------------------------------------
  905. # 【功能】
  906. #    保留当前对话框,直至没有该指令的对话框关闭,关闭所有保留的对话框
  907. #
  908. #----------------------------------------------------------------------------
  909. #  \close 【结尾】
  910. #----------------------------------------------------------------------------
  911. # 【功能】
  912. #    当前对话框不再受 settings_changed? 影响,必定进行关闭处理
  913. #
  914. #----------------------------------------------------------------------------
  915. #  \next 【结尾】
  916. #----------------------------------------------------------------------------
  917. # 【功能】
  918. #    当前对话框在按键继续后不关闭,而是保留显示,
  919. #    在处理下一条事件指令-显示文本时,文本将继续显示在对话框的新行。
  920. #    (中途可以调用其它事件指令,对话框将一直保持开启状态。)
  921. #
  922. #----------------------------------------------------------------------------
  923. #  \clc
  924. #----------------------------------------------------------------------------
  925. # 【功能】
  926. #    将当前全部已经绘制的文字上移,直至移出对话框的显示范围,
  927. #    然后在新的一行中继续绘制剩余文字。
  928. #    (在输入等待时,依然可以通过方向键进行滚动,以浏览之前移出显示范围的文字)
  929. #    (最好先固定对话框的显示高度,再使用本功能,否则下侧可能出现较多的空白区域,
  930. #       因为在动态高度情况下,对话框高度由全部文字的高度和决定,与这些移动无关)
  931. #
  932. # 【常量设置:文字移出的所用帧数】
  933. CLC_CHARAS_OUT_FRAME = 20
  934.  
  935. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  936. # ○ 文字特效类
  937. #     以下 param 传入 任意非0非空字符(如 1)代表以预设值开启特效
  938. #                只传入 0 代表关闭该特效
  939. #     除非标注【叠加】,否则多特效同时执行可能会造成奇怪效果
  940. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  941. # 【常量设置:初始激活的文字特效转义符及其变量参数】
  942. CHARA_PARAMS_INIT = {
  943. # 文字特效类转义符sym => 变量参数字符串"code_string"
  944.   #:cin => "1",
  945. }
  946. #----------------------------------------------------------------------------
  947. #  \cin[param] 【独占】(移入完成后才进行其余特效的更新)
  948. #----------------------------------------------------------------------------
  949. # 【功能】
  950. #    开启文字移入的特效
  951. #
  952. # 【注意】
  953. #    移入使用缓动函数,具体可以见 MESSAGE_EX.ease_value 方法
  954. #
  955. # 【参数】
  956. #    param → 变量参数字符串
  957. # (变量一览)
  958. #    r → 是否将以下全部变量的值变更为正负范围内的随机数?
  959. #         比如传入的 vx5,则实际的 vx 为 -5 ~ 5 中随机一个值
  960. #    t → 移入所用帧数(即移动到最终位置所用帧数)(不透明度从0平滑增加到255)
  961. #    vzt/vz → 每zvt(最小值1)帧zoom放缩值增加vz的值(整数)
  962. #    va → 每帧内angle的增值
  963. #    dx/dy → 移入前所在位置的偏移量
  964. #  (以下参数不受 r 的影响)
  965. #    do → 移入前所在位置
  966. #        (大于0时为对话框的九宫格位置,小于0时为屏幕九宫格位置,0时最终显示位置)
  967. #          如:do5dx0dy0 就是文字从对话框中心位置移入到最终显示位置
  968. #    vo → 每帧不透明度的增量(默认0,将设置为 255/t)
  969. #    rxt/rx → 每rxt(最小值1)帧src_rect的x增加rx像素的值(默认0)
  970. #    ryt/ry → 每ryt(最小值1)帧src_rect的y增加ry像素的值(默认0)
  971. #
  972. # 【常量设置:参数预设值】
  973. CIN_PARAMS_INIT = {
  974. # \cin[]
  975.   :r => 0, # 随机取值?
  976.   :t => 15, # 移入所用帧数
  977.   :do => 0, # 移入前所在位置
  978.   :dx => 0, # 移入前所在位置的偏移量
  979.   :dy => 0,
  980.   :vz => 0,  # 每vzt帧zoom的增量
  981.   :vzt => 1,
  982.   :va => 0,  # 每帧角度增量
  983.   :vo => 0,  # 每帧不透明度增量
  984.   :rxt => 1,
  985.   :rx => 0, # 每rxt帧src_rect.x的增量
  986.   :ryt => 1,
  987.   :ry => 0, # 每ryt帧src_rect.y的增值
  988. }
  989. #
  990. # 【示例】
  991. #   - 对话编写
  992. #       \cin[dy20]这是测试对话,看看移入效果如何。
  993. #   - 实际对话
  994. #      (文字移入效果修改为由下方20像素处往目的地移入)
  995. #
  996. #----------------------------------------------------------------------------
  997. #  \cout[param] 【独占】(移出时关闭其余特效更新)
  998. #----------------------------------------------------------------------------
  999. # 【功能】
  1000. #    开启文字移出的特效
  1001. #
  1002. # 【注意】
  1003. #    移出使用缓动函数,具体可以见 MESSAGE_EX.ease_value 方法
  1004. #
  1005. # 【参数】
  1006. #    param → 变量参数字符串
  1007. # (变量一览)
  1008. #    r → 是否将以下全部变量的值变更为正负范围内的随机数?
  1009. #         比如传入的 vx5,则实际的 vx 为 -5 ~ 5 中随机一个值
  1010. #    t → 移出所用帧数(即移动到最终位置所用帧数)(不透明度从255平滑减小到0)
  1011. #    vzt/vz → 每zvt(最小值1)帧zoom放缩值增加vz的值(整数)
  1012. #    va → 每帧内angle的增值
  1013. #    dx/dy → 移出后所在位置的偏移量
  1014. #  (以下参数不受 r 的影响)
  1015. #    do → 移出后所在位置
  1016. #        (大于0时为对话框的九宫格位置,小于0时为屏幕九宫格位置,0时当前位置)
  1017. #          如:do5dx0dy0 就是文字移出到对话框中心位置
  1018. #    vo → 每帧不透明度的减量(默认为 255/t)
  1019. #    rxt/rx → 每rxt(最小值1)帧src_rect的x增加rx像素的值(默认0)
  1020. #    ryt/ry → 每ryt(最小值1)帧src_rect的y增加ry像素的值(默认0)
  1021. #
  1022. # 【常量设置:参数预设值】
  1023. COUT_PARAMS_INIT = {
  1024. # \cout[]
  1025.   :r => 0, # 随机取值?
  1026.   :t => 15, # 移出所用帧数
  1027.   :do => 0, # 移出后所在位置
  1028.   :dx => 0, # 移出后所在位置的偏移量
  1029.   :dy => 0,
  1030.   :vz => 0,  # 每vzt帧zoom的增量
  1031.   :vzt => 1,
  1032.   :va => 0,  # 每帧角度增量
  1033.   :vo => 0,  # 每帧不透明度减量
  1034.   :rxt => 1, # 每rxt帧src_rect.x的增量
  1035.   :rx => 0,
  1036.   :ryt => 1, # 每ryt帧src_rect.y的增值
  1037.   :ry => 0,
  1038. }
  1039. #
  1040. # 【示例】
  1041. #   - 对话编写
  1042. #       \cout[do5]这是测试对话,看看移出效果如何。
  1043. #   - 实际对话
  1044. #      (文字移出效果修改为移到对话框中心处渐隐)
  1045. #
  1046. #----------------------------------------------------------------------------
  1047. #  \uout[param] 【独占】
  1048. #----------------------------------------------------------------------------
  1049. # 【功能】
  1050. #    【需要前置Unravel_Bitmap插件】利用消散移出文字
  1051. #
  1052. # 【参数】
  1053. #    param → 变量参数字符串
  1054. # (变量一览)
  1055. #    n → 消散的粒子总数(大约)
  1056. #    d → 单个粒子的大小(直径/边长)
  1057. #    o → 单个粒子消失时的透明度变更最小值
  1058. #    dir → 整体消散方向类型(同九宫格小键盘)(1379-四角;5-四方向;46-左右向上)
  1059. #    s → 粒子形状类型(0-正方向;1-圆形;2-三角形)
  1060. #
  1061. # 【常量设置:参数预设值】
  1062. UOUT_PARAMS_INIT = {
  1063. # \uout[]
  1064.   :n => 200, # 消散的粒子总数
  1065.   :d =>  2, # 消散的粒子的大小(直径/边长)
  1066.   :o =>  1, # 透明度变更量的最小值
  1067.   :dir => 4, # 消散方向类型
  1068.   :s =>  0, # 粒子的形状类型
  1069. }
  1070. #
  1071. # 【常量设置:类型序号映射到消散方向类型】
  1072. CU_PARAM_DIR = { # 定义消散方向类型的id
  1073.   1 => :LD, 3 => :RD, 4 => :LR, 5 => :LRUD, 6 => :LR, 7 => :LU, 9 => :RU
  1074. }
  1075. #
  1076. # 【常量设置:类型序号映射到粒子形状类型】
  1077. CU_PARAM_S = { # 定义粒子形状类型的id
  1078.   0 => :S, # 正方形
  1079.   1 => :C, # 圆形(耗时)
  1080.   2 => :T  # 三角形
  1081. }
  1082. #
  1083. # 【示例】
  1084. #   - 对话编写
  1085. #       \uout[1]这是测试对话,看看移出效果如何。
  1086. #   - 实际对话
  1087. #      (文字移出效果修改为消散)
  1088. #
  1089. #----------------------------------------------------------------------------
  1090. #  \csin[param]
  1091. #----------------------------------------------------------------------------
  1092. # 【功能】
  1093. #    开启正弦波浪扭曲特效
  1094. #
  1095. # 【参数】
  1096. #    param → 变量参数字符串
  1097. # (变量一览)
  1098. #    a → 正弦波浪的幅度(像素数)
  1099. #    l → 正弦波浪的频度(像素数)
  1100. #    s → 正弦波浪的动画速度(默认360)
  1101. #    p → 正弦波浪的相位角度(最大360°)(一般不需要设置)
  1102. #
  1103. # 【常量设置:参数预设值】
  1104. CSIN_PARAMS_INIT = {
  1105.   :a => 6, # 幅度
  1106.   :l => 10, # 频度
  1107.   :s => 30, # 速度
  1108.   :p => 0, # 相位
  1109. }
  1110. #
  1111. #----------------------------------------------------------------------------
  1112. #  \cwave[param]
  1113. #----------------------------------------------------------------------------
  1114. # 【功能】
  1115. #    开启文字上下浮动特效
  1116. #
  1117. # 【参数】
  1118. #    param → 变量参数字符串
  1119. # (变量一览)
  1120. #    h → 上下浮动的最大偏移像素值
  1121. #    t → 每隔t帧进行一次1像素的偏移
  1122. #    vy → 起始时的y方向移动速度(正数为向下)
  1123. #
  1124. # 【常量设置:参数预设值】
  1125. CWAVE_PARAMS_INIT = {
  1126. # \cwave[]
  1127.   :h  => 2,  # Y方向上的最大偏移值
  1128.   :t  => 4,  # 移动一像素所耗帧数
  1129.   :vy => -1, # Y方向速度(正数向下)
  1130. }
  1131. #
  1132. #----------------------------------------------------------------------------
  1133. #  \cswing[param]
  1134. #----------------------------------------------------------------------------
  1135. # 【功能】
  1136. #    开启左右摇摆特效(本质为精灵旋转)
  1137. #
  1138. # 【参数】
  1139. #    param → 变量参数字符串
  1140. # (变量一览)
  1141. #    d → 每次更新增加的角度值(0时随机取正负1)
  1142. #    t → 每次角度更新后等待t帧
  1143. #    a → 角度可到达的最大值(左右对称)
  1144. #    o → 摇摆不动点所在位置类型(键盘九宫格)
  1145. #
  1146. # 【常量设置:参数预设值】
  1147. CSWING_PARAMS_INIT = {
  1148. # \cswing[]
  1149.   :d => 0, # 每次更新增加的角度值(0时随机取正负1)
  1150.   :t => 1, # 每次角度更新后等待t帧
  1151.   :a => 15, # 角度可到达的最大值(左右对称)
  1152.   :o => 2, # 摇摆不动点所在位置类型(键盘九宫格)(2为底部中心)
  1153. }
  1154. #
  1155. #----------------------------------------------------------------------------
  1156. #  \czoom[param]
  1157. #----------------------------------------------------------------------------
  1158. # 【功能】
  1159. #    开启文字缩放特效(本质为精灵缩放)
  1160. #
  1161. # 【参数】
  1162. #    param → 变量参数字符串
  1163. # (变量一览)
  1164. #    t → 在进行一次缩放变更后的等待帧数
  1165. #    dx → x方向的每次缩放增量(单位%,即 1 代表每t帧放大1%,zoom_x增加0.01)
  1166. #    dy → y方向的每次缩放增量(单位%,即 1 代表每t帧放大1%,zoom_y增加0.01)
  1167. #    o → 缩放不动点所在位置类型(键盘九宫格)
  1168. #    min → x和y方向上缩放总量的最小值
  1169. #          (在RGSS3中,负数的缩放量不会显示,推荐设置为自然数)
  1170. #          (在RGD中,负数的缩放量将反向显示,推荐设置为最大值的相反数)
  1171. #    max → x和y方向上缩放总量的最大值
  1172. #
  1173. # 【常量设置:参数预设值】
  1174. CZOOM_PARAMS_INIT = {
  1175. # \czoom[]
  1176.   :t => 0, # 在进行一次缩放变更后的等待帧数
  1177.   :dx => 2, # x方向的每次缩放增量(缩放总量在-100~100之间,整数)
  1178.   :dy => 0, # y方向的每次缩放增量
  1179.   :o => 5, # 缩放不动点所在位置类型(键盘九宫格)(5为中心)
  1180.   :min => 0, # xy缩放总量的最小值
  1181.   :max => 100, # xy缩放总量的最大值
  1182. }
  1183. #
  1184. #----------------------------------------------------------------------------
  1185. #  \cshake[param]
  1186. #----------------------------------------------------------------------------
  1187. # 【功能】
  1188. #    开启抖动特效
  1189. #
  1190. # 【参数】
  1191. #    param → 变量参数字符串
  1192. # (变量一览)
  1193. #    l/r/u/d → 设置 左右上下 四个方向的最大移动偏移值
  1194. #    vx/vy → 设置x、y方向上的初始移动速度(正数为向右、向下)(0为随机方向)
  1195. #    vxt/vyt → 设置x、y方向上移动一次后的等待帧数
  1196. #
  1197. # 【常量设置:参数预设值】
  1198. CSHAKE_PARAMS_INIT = {
  1199. # \cshake[]
  1200.   :l => 0,  # 距离所在原点的最大偏移量(左右上下)
  1201.   :r => 1,
  1202.   :u => 1,
  1203.   :d => 1,
  1204.   :vx  => 0,  # x的初始移动方向(0为随机方向)
  1205.   :vxt => 2,  # x方向移动一像素所耗帧数
  1206.   :vy  => 0,  # y的初始移动方向(0为随机方向)
  1207.   :vyt => 1,  # y方向移动一像素所耗帧数
  1208. }
  1209. #
  1210. #----------------------------------------------------------------------------
  1211. #  \cshake2[param]
  1212. #----------------------------------------------------------------------------
  1213. # 【功能】
  1214. #    开启抖动特效(频率更大的震动)
  1215. #
  1216. # 【参数】
  1217. #    param → 变量参数字符串
  1218. # (变量一览)
  1219. #    dx → 往左或往右的最大震动距离
  1220. #    dy → 往上或往下的最大震动距离
  1221. #    l → 震动幅度
  1222. #
  1223. # 【常量设置:参数预设值】
  1224. CSHAKE2_PARAMS_INIT = {
  1225. # \cshake[]
  1226.   :dx => 4,
  1227.   :dy => 4,
  1228.   :l  => 3,
  1229. }
  1230. #
  1231. #----------------------------------------------------------------------------
  1232. #  \cflash[param] 【叠加】
  1233. #----------------------------------------------------------------------------
  1234. # 【功能】
  1235. #    开启文字闪烁特效(本质为精灵flash)
  1236. #
  1237. # 【参数】
  1238. #    param → 变量参数字符串
  1239. # (变量一览)
  1240. #    r/g/b/a → 闪烁的颜色(红、绿、蓝、不透明度)(默认均255)
  1241. #            (如:r50g50b100a200)
  1242. #    d → 闪烁从开始到完成需要的帧数
  1243. #    t → 闪烁完成后的等待帧数
  1244. #
  1245. # 【常量设置:参数预设值】
  1246. CFLASH_PARAMS_INIT = {
  1247. # \cflash[]
  1248.   :r => 255, # 闪烁颜色RGBA
  1249.   :g => 255,
  1250.   :b => 255,
  1251.   :a => 255,
  1252.   :d => 60,  # 闪烁帧数
  1253.   :t => 60,  # 闪烁后的等待时间
  1254. }
  1255. #
  1256. #----------------------------------------------------------------------------
  1257. #  \cmirror[param] 【叠加】
  1258. #----------------------------------------------------------------------------
  1259. # 【功能】
  1260. #    开启横轴镜像绘制(本质为精灵mirror)
  1261. #
  1262. # 【参数】
  1263. #    param → 变量参数字符串(无任何设置参数)
  1264. #
  1265. # 【常量设置:参数预设值】
  1266. CMIRROR_PARAMS_INIT = {}
  1267. #
  1268. # 【示例】
  1269. #   - 对话编写
  1270. #       这是\cmirror[1]测试对话\cmirror[0],看看效果如何。
  1271. #   - 实际对话
  1272. #      (“测试对话”四个字将开启左右翻转)
  1273. #
  1274. #----------------------------------------------------------------------------
  1275. #  \cu[param] 【叠加】
  1276. #----------------------------------------------------------------------------
  1277. # 【功能】
  1278. #    【需要前置Unravel_Bitmap插件】开启字符消散特效
  1279. #
  1280. # 【参数】
  1281. #    param → 变量参数字符串
  1282. # (变量一览)
  1283. #    t → 每两次执行消散之间的间隔帧数(正整数)
  1284. #    (其余同 \uout 转义符)
  1285. #
  1286. # 【常量设置:参数预设值】
  1287. CU_PARAMS_INIT = {
  1288. # \cu[]
  1289.   :t => 10, # 每两次消散之间的时间间隔
  1290.   :n => 20, # 消散的粒子总数
  1291.   :d =>  2, # 消散的粒子的大小(直径/边长)
  1292.   :o =>  1, # 透明度变更量的最小值
  1293.   :dir => 4, # 消散方向类型
  1294.   :s =>  0, # 粒子的形状类型
  1295. }
  1296. #
  1297. #----------------------------------------------------------------------------
  1298. #  \ctog[param] 【叠加】
  1299. #----------------------------------------------------------------------------
  1300. # 【功能】
  1301. #    开启文字切换特效(本质为切换精灵的bitmap)
  1302. #
  1303. # 【参数】
  1304. #    param → 变量参数字符串
  1305. # (变量一览)
  1306. #    i → 使用 i 号对应的文字组(具体见 CTOG_CHARAS 常量,设置 i → 文字组)
  1307. #    n → 从文字组中挑选出 n 个字符作为切换文字(若为0,则取全部)
  1308. #    t → 文字切换一次后的等待帧数
  1309. #    r → 是否启用随机切换
  1310. #
  1311. # 【常量设置:参数预设值】
  1312. CTOG_PARAMS_INIT = {
  1313. # \ctog[]
  1314.   :i => 0,  # 选取i号文字组
  1315.   :n => 0,  # 从文字组中选取n个字符
  1316.   :t => 10,  # 文字切换的等待帧数
  1317.   :r => 1,  # 是否随机选择下一个文字?
  1318. }
  1319. #
  1320. # 【常量设置:序号映射到文字切换组】
  1321. CTOG_CHARAS = {
  1322.   # 定义文字切换特效的文字组(若为数字,则取 IconSet 中的图标)
  1323.   0 => ['▀', '▄', '█', '▌', '✖'],
  1324.   1 => ['0','1','2','3','4','5','6','7','8','9'],
  1325.   2 => [376,377,378,379,380,381,382,383],
  1326. }
  1327. #
  1328. #----------------------------------------------------------------------------
  1329. #  \cneon[param] 【叠加】
  1330. #----------------------------------------------------------------------------
  1331. # 【功能】
  1332. #    开启文字渐变更新特效(本质为精灵color变换)
  1333. #
  1334. # 【参数】
  1335. #    param → 变量参数字符串
  1336. # (变量一览)
  1337. #    t → 颜色之间的渐变帧数
  1338. #    c → 【可重复填写】指定渐变颜色的索引号
  1339. #        从 当前颜色开始(默认0号颜色),按照传入顺序依次变化
  1340. #
  1341. # 【常量设置:参数预设值】
  1342. CNEON_PARAMS_INIT = {
  1343. # \cneon[]
  1344.   :t => 60, # 颜色之间的切换帧数
  1345. }
  1346. #
  1347. # 【示例】
  1348. #   - 对话编写
  1349. #       这是\cneon[t60c1c10c17]测试对话\cneon[0]。
  1350. #   - 实际对话
  1351. #      (“测试对话”四个字将按照 0→1→10→17→1→10→17... 的颜色索引进行循环变色)
  1352. #
  1353. #----------------------------------------------------------------------------
  1354. #  \cmc[param]  【叠加】
  1355. #----------------------------------------------------------------------------
  1356. # 【功能】
  1357. #    叠加绘制文字
  1358. #
  1359. # 【参数】
  1360. #    param → 变量参数字符串
  1361. # (变量一览)
  1362. #    i → 使用 i 号对应的文字组(具体见 CMC_CHARAS 常量)
  1363. #    n → 从文字组中挑选出 n 个字符作为切换文字(若为0,则取全部)
  1364. #    c → 指定叠加绘制的文字的颜色索引号(-1时与原始文字颜色一致)
  1365. #
  1366. # 【常量设置:参数预设值】
  1367. CMC_PARAMS_INIT = {
  1368. # \cmc[]
  1369.   :i => 0,  # 选取i号文字组
  1370.   :n => 0,  # 从文字组中选取n个字符(若为0,则取全部)
  1371.   :c => 10,  # 叠加绘制的文字的颜色索引号
  1372. }
  1373. #
  1374. # 【常量设置:序号映射到叠加绘制文字组】
  1375. CMC_CHARAS = {
  1376.   # 定义文字叠加绘制的文字组(若为数字,则取 IconSet 中的图标)
  1377.   0 => ['✖'],
  1378.   1 => [4],
  1379. }
  1380. #
  1381. #----------------------------------------------------------------------------
  1382. #  \cjump[param]
  1383. #----------------------------------------------------------------------------
  1384. # 【功能】
  1385. #    开启文字跳跃特效
  1386. #
  1387. # 【参数】
  1388. #    param → 变量参数字符串
  1389. # (变量一览)
  1390. #    tc → 跳跃前的等待帧数
  1391. #    t → 跳跃的持续帧数
  1392. #    h → 跳跃的最大高度
  1393. #    w → 下一次跳跃前的等待帧数(nil时不再跳跃)
  1394. #
  1395. # 【常量设置:参数预设值】
  1396. CJUMP_PARAMS_INIT = {
  1397. # \cjump[]
  1398.   :tc => 0,  # 跳跃前的等待帧数
  1399.   :t => 20,  # 跳跃的持续帧数
  1400.   :h => 4,  # 跳跃的最大高度
  1401.   :w => 60,   # 下一次跳跃前的等待帧数(nil时不再跳跃)
  1402. }
  1403. #
  1404. #----------------------------------------------------------------------------
  1405. #  \cfk[param]
  1406. #----------------------------------------------------------------------------
  1407. # 【功能】
  1408. #    开启文字明灭闪烁特效
  1409. #
  1410. # 【参数】
  1411. #    param → 变量参数字符串
  1412. # (变量一览)
  1413. #    t → 明灭的持续帧数(不透明度从255到0的所用时间)
  1414. #       (0时直接显隐,负数时代表 0~数字 之间的随机数)
  1415. #    w → 下一次明灭前的等待帧数(nil时不再明灭)
  1416. #
  1417. # 【常量设置:参数预设值】
  1418. CFK_PARAMS_INIT = {
  1419. # \cfk[]
  1420.   :t => 30,
  1421.   :w => 60,  
  1422. }
  1423. #
  1424. # 【常量设置:当t为0时,完全隐藏后、显示前的等待帧数】
  1425. CFK_T0_WAIT = 20
  1426.  
  1427. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1428. # ○ 变量环境
  1429. #    此处放置环境处理,效仿python的conda,将对话框的设置状态进行打包存储与读取
  1430. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1431. # 【关于环境】
  1432. #    由于对话框可设置的变量众多,
  1433. #    当需要不同情况使用不同样式的对话框时,不得不编写一大串的转义符进行设置;
  1434. #    而转义符的设置在默认情况下是跨对话框的,想要改回之前的又要写一大串,非常不便。
  1435. #    因此引入了该类别的转义符,以简化不同设置间切换所需的操作。
  1436. #
  1437. #    环境本质上是 Game_Message 类实例的拷贝。
  1438. #
  1439. #----------------------------------------------------------------------------
  1440. #  \env[sym] 【预先】
  1441. #----------------------------------------------------------------------------
  1442. # 【功能】
  1443. #    读取名称为 sym 的环境,并立即应用于当前与之后的对话框
  1444. #    当前环境被设置为 sym
  1445. #
  1446. # 【注意】
  1447. #    - 默认激活的环境为 0,因此可以用 \env[0] 切回最原始的环境
  1448. #    - 环境的命名没有限制,但最好为字母和数字的组合
  1449. #    - 当不存在 sym 环境时,将会把当前对话框执行前的环境存储为 sym
  1450. #
  1451. # 【示例】
  1452. #   - 对话编写
  1453. #       \env[测试]这是测试用对话。
  1454. #   - 实际对话
  1455. #      (进入 "测试" 对应的环境,之后的转义符修改都将只修改 "测试" 环境中的设置)
  1456. #      (若不存在 "测试" 环境,则将当前的环境存储为 "测试")
  1457. #
  1458. # 【常量设置:环境预设】
  1459. # (此处环境的初始状态为脚本中预设的全部值,之后再依据此处设置进行覆盖)
  1460. # (出于便捷考虑,读档后此处设置的环境均会被重置,即不保存游戏中途对这些环境的修改)
  1461. # (因此,此处设置的环境请不要与游戏中途的可保存的环境发生名称冲突)
  1462. # (和文本预设一致,此处转义符需要将 \ 替换成 \\ )
  1463. DEFAULT_ENVS = {
  1464.   # 环境名称 => "字符串"
  1465.   "0" => "", # 默认初始环境,全部为预设值,推荐不要修改
  1466.   "底部" => "\\win[o2do-2dy-30w200h3]", # 对话框居下显示
  1467. }
  1468. #
  1469. # 【常量设置:设置当对话框关闭时,是否把环境重置为默认的0】
  1470. # (若设置为 true,则每次对话框关闭时,环境重置为 0)
  1471. # (若设置为 false ,则不会自动重置环境,请手动写 \env[0])
  1472. # (若设置为 数字,则该序号的开关 $game_switches[id] 开启时,才自动重置环境 )
  1473. S_ID_RESET_ENV = true
  1474. #
  1475. # (对话框关闭的情形:
  1476. #     1.下一个事件指令不为显示文本
  1477. #     2.下一个事件指令为显示文本,但对话框的背景与当前的不同
  1478. #     3.当前对话中有\close转义符)
  1479. #----------------------------------------------------------------------------
  1480. #  \env[sym|save] 【结尾】
  1481. #----------------------------------------------------------------------------
  1482. # 【功能】
  1483. #    将当前对话框绘制完成时的环境,保存为 sym
  1484. #    同时当前环境设置为 sym
  1485. #
  1486. # 【注意】
  1487. #    - 在每一次对话框开启前,以及env生效并切换环境后,都会更新一次当前环境
  1488. #
  1489. # 【示例】
  1490. #   - 对话编写
  1491. #       \env[底部对话|save]\win[o2do-2dy-30]这是测试用对话。
  1492. #   - 实际对话
  1493. #      (将当前对话框的环境存为 "底部对话" ,若环境已经存在则覆盖,
  1494. #        之后进入 "底部对话" 的环境)
  1495. #
  1496. #----------------------------------------------------------------------------
  1497. #  \temp 【结尾】
  1498. #----------------------------------------------------------------------------
  1499. # 【功能】
  1500. #    当前对话框结束时,将环境重置回对话框开启前的环境
  1501. #
  1502. # 【注意】
  1503. #   - 在当前对话框结束前,转义符参数的修改仍然生效
  1504. #     因此可能导致中途生成的 并行对话 等,继承了当前修改后的参数
  1505. #
  1506. #   - 当同时存在 \temp、\env[sym2]、\env[sym3|save] 时,执行顺序如下(当前环境为 sym1):
  1507. #     1、在绘制开始前,存储了一次 sym1 环境
  1508. #     2、执行预先转义符:temp记录下最初环境为 sym1;env将当前激活环境修改为sym2并应用
  1509. #     3、对话框关闭后:当前对话框修改后的环境存入 sym3;
  1510. #                   temp生效,将环境重置为 sym1,继续下一个对话
  1511. #
  1512.  
  1513. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1514. # ○ 高级
  1515. #    此处放置高级处理,需要结合一定的脚本知识才能灵活运用
  1516. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1517. #----------------------------------------------------------------------------
  1518. #  \func[param] 【预先】
  1519. #----------------------------------------------------------------------------
  1520. # 【功能】
  1521. #    设置一些进阶的功能,将在对话框打开前生效
  1522. #
  1523. # 【参数】
  1524. #    param → 变量参数字符串
  1525. # (变量一览)
  1526. #    open → 使用 i 号对应的对话框打开方式
  1527. #    close → 使用 i 号对应的对话框关闭方式
  1528. #         0 为默认的上下打开关闭,1 为淡入淡出,2 为动态缩放展开
  1529. #
  1530. #    aw → 是否开启对话框的自动换行(auto wrap)
  1531. #        若开启,当文字绘制到对话框边界padding处时,将进行自动换行
  1532. #        只是非常基础的按单个文字切割的自动换行方式,会切割单词,不考虑标点符号
  1533. #
  1534. #    para → 是否并行处理子窗口
  1535. #        若开启,则对话框的下一条指令为 选择支/数字输入/物品选择 时,
  1536. #        会在对话框打开、开始绘制文字时,同步打开并激活选择框/数字输入框/物品选择
  1537. #
  1538. #        当子窗口的按键处理结束并关闭时,对话框将同步强制关闭
  1539. #       (警告:对话框中未被绘制的转义符可能不会生效!)
  1540. #       (注意:子窗口的嵌入对话框会失效!)
  1541. #
  1542. # 【常量设置:参数预设值】
  1543. FUNC_PARAMS_INIT = {
  1544. # \func[]
  1545.   :open => 2,   # 打开方式
  1546.   :close => 2,  # 关闭方式
  1547.   :aw => 1,  # 自动换行
  1548.   :para => 0, # 并行处理子窗口
  1549. }
  1550. #
  1551. # 【示例】
  1552. #   - 对话编写
  1553. #       这是测试用对话。\func[para=1]
  1554. #   - 实际对话
  1555. #      (若下条指令为选择框,将并行打开)
  1556. #
  1557. #----------------------------------------------------------------------------
  1558. #  \eval{string} 或 {{string}}
  1559. #----------------------------------------------------------------------------
  1560. # 【功能】
  1561. #    当绘制到该转义符时,执行 eval(string),并丢弃返回值
  1562. #
  1563. # 【参数】
  1564. #    string → Ruby语句的字符串,可以用 ; 进行分割多句
  1565. #
  1566. # 【注意】
  1567. #   - 该转义符使用花括号,同时 string 中不可以出现花括号
  1568. #
  1569. #   - 可用 s 代替 $game_switches ,用 v 代替 $game_variables
  1570. #     可用 msg 代表当前对话(Window_Message类的实例)
  1571. #      如 \eval{s[1]=true} 或 {{s[1]=true}}
  1572. #       就是当文字绘制到该转义符时,打开1号开关,并继续绘制
  1573. #
  1574. #   - 由于文本替换类的转义符优先级最高,实际绘制的内容为对话框打开时的状态
  1575. #      即如果存在 \eval{v[1]=5}\v[1],其中1号变量初值为0,
  1576. #      尽管绘制时其值变为了5,但实际绘制的\v[1]仍然为对话框打开时的值0
  1577. #
  1578. #----------------------------------------------------------------------------
  1579. #  \set[sym]
  1580. #----------------------------------------------------------------------------
  1581. # 【功能】
  1582. #    打开标识符为 sym 字符串的分组(初始时为空分组),
  1583. #    之后绘制的文字均会被存入该分组中
  1584. #
  1585. # 【注意】
  1586. #   - 单个文字可以被存入多个分组中
  1587. #   - 约定 0 分组为全部文字所在分组,因此可以传入 0 来回到无分组状态
  1588. #
  1589. # 【参数】
  1590. #    sym → 分组的唯一标识符(字符串)
  1591. #
  1592. # 【高级】
  1593. #    Window_EagleMessage 类新增方法 chara_set(sym) { |s| do_something }
  1594. #     该方法能够用于对 sym 分组中的文字精灵s进行逐个操作,
  1595. #     若 不传入sym 或 传入 0 或 传入 '0' 或传入 "",则转为对全部文字精灵进行操作
  1596. #
  1597. # 【示例】
  1598. #   - 对话编写
  1599. #       \set[1]这是测试用\set[0]对话。
  1600. #   - 实际对话
  1601. #      (“这是测试用”被存入标识符为 "1" 的分组,全部文字被存入标识符为 "0" 的分组)
  1602. #
  1603. #----------------------------------------------------------------------------
  1604. #  \setm[sym|effect|param]
  1605. #----------------------------------------------------------------------------
  1606. # 【功能】
  1607. #    对sym分组中的文字精灵,执行effect特效,并传入param变量参数字符串作为特效的参数
  1608. #
  1609. # 【参数】
  1610. #    sym → 分组的唯一标识符,同 \set 中的注释
  1611. #    effect → 文字特效类转义符中的转义符,比如 ctog
  1612. #    param → 对应文字特效的变量参数字符串,与转义符自己的帮助保持一致
  1613. #            若只传入 0,则为关闭该特效
  1614. #
  1615. # 【示例】
  1616. #   - 对话编写
  1617. #       \ctog[1]这是测试用\ctog[0]对话。\wait[60]\setm[0|ctog|0]
  1618. #   - 实际对话
  1619. #      (文本显示完的1s后,关闭全部文字精灵的ctog特效)
  1620. #      (“这是测试用” 的 ctog 特效在对话结尾处被关闭)
  1621. #
  1622. # 【示例】
  1623. #   - 对话编写
  1624. #       \set[1]\ctog[1]测试用文字\set[0],\!第二句话。\setm[1|ctog|0]
  1625. #   - 实际对话
  1626. #      (在对话结尾时,仅关闭 1 分组中 “测试用文字” 的 ctog 特效)
  1627. #
  1628.  
  1629. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1630. # ○ 扩展类
  1631. #     此处放置整合其他插件效果的转义符,统一放置于 $game_message.ex_params 中
  1632. #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1633. # 【常量设置:定义初始激活的扩展类转义符的预设变量参数字符串】
  1634. EX_PARAMS_INIT = {
  1635. # 渐变绘制转义符 \cg => "颜色索引字符串",
  1636.   :cg => "",
  1637. }
  1638. #----------------------------------------------------------------------------
  1639. #  \cg[c1..]
  1640. #----------------------------------------------------------------------------
  1641. # 【功能】
  1642. #    【需要前置Sion_GradientText插件】之后的文本开启纵轴渐变描绘
  1643. #
  1644. # 【参数】
  1645. #    按序排列的 c + Windowskin颜色索引号,可以重复填写
  1646. #    不传入任何参数时,代表关闭渐变绘制
  1647. #
  1648. # 【示例】
  1649. #   - 对话编写
  1650. #       \cg[c1c2c1]测试用\cg[]文字。
  1651. #   - 实际对话
  1652. #      (用 1号 2号 1号颜色由上至下渐变绘制“测试用”三个字)
  1653. #
  1654.  
  1655. #=============================================================================
  1656. # ● 其它设置
  1657. #=============================================================================
  1658. #----------------------------------------------------------------------------
  1659. # ○ 新游戏开始时,对话框预定将要显示的文本
  1660. # (由于解析问题,请将 "\" 替换成 "\\")
  1661. ESCAPE_STRING_INIT = ""
  1662.  
  1663. #--------------------------------------------------------------------------
  1664. # ○ 切换显示/隐藏
  1665. # (每帧判定,返回 true 时,会切换对话框的显示/隐藏)
  1666. # (文字将执行其移入移出效果)
  1667. def self.toggle_visible?
  1668.   false #Input.trigger?(:A)
  1669. end
  1670.  
  1671. #----------------------------------------------------------------------------
  1672. # ○ 内容滚动
  1673. #
  1674. # - 当对话框的宽度或高度被固定时,
  1675. #     若所绘制的文字超出对话框范围,将自动开启内容滚动效果
  1676. #
  1677. # - 当进入 等待按键 状态时,按住 方向键 即可朝对应方向滚动浏览对话框全部内容
  1678.  
  1679. #----------------------------------------------------------------------------
  1680. # ○ 当文字绘制超出对话框区域,导致内容需要滚动时,新增了一个缓动动画来获得空行
  1681. #  该项设置缓动动画的持续帧数
  1682. CHARAS_SCROLL_OUT_FRAME = 12
  1683.  
  1684. #----------------------------------------------------------------------------
  1685. # ○ 当对话框内容无需滚动浏览时,若该常量设置为 true,则使用方向键也可以继续对话
  1686. # 如果设置为 false,则无改变(仍然需要按确定键或取消键继续对话)
  1687. INPUT_NEXT_WITH_DIR4 = false
  1688.  
  1689. #----------------------------------------------------------------------------
  1690. # ○ 预定绘制文本
  1691. #
  1692. # - 利用该脚本存储文本,在下次打开对话框时,全部存储文本将按序插入到对话开头
  1693. #
  1694. #        $game_message.add_escape(param_string)
  1695. #
  1696. #   param_string 解析: 【String】型常量
  1697. #
  1698. # - 示例:
  1699. #     $game_message.add_escape("\\win[ali1]")
  1700. #        → 之后的对话框中 文本居中 绘制
  1701. #     $game_message.add_escape("\\pop[0]")
  1702. #        → 下一次的对话框为pop类型,绑定在当前执行对话框的事件上
  1703. #
  1704. # - 注意:
  1705. #   · 由于解析问题,在 param_string 中请将 "\" 替换成 "\\"
  1706. #   · 当存在多条预定文本,将按照预定时间的先后顺序,依次放入下一次对话框的开头
  1707. #   · 预定的字符串只会被放入对话框一次
  1708. #   · 不会去除 param_string 中的非转义符文本
  1709. #   · 为了确保win、pop等转义符能够顺利更改对话框位置等属性,
  1710. #     位于开头的转义符将会在对话框打开前执行完毕
  1711. #
  1712.  
  1713. #=============================================================================
  1714. # ● 特别感谢
  1715. #=============================================================================
  1716. # - 葱兔([url]http://onira.lofter.com/[/url])
  1717.  
  1718. #=============================================================================
  1719. # - 请不要轻易修改以下内容!
  1720. #=============================================================================
  1721. end
  1722. module MESSAGE_EX
  1723.   #--------------------------------------------------------------------------
  1724.   # ● 【计算】获取缓动函数的返回值
  1725.   #  type 为该函数被调用的场景
  1726.   #  x 为缓动函数的 当前时间/总时间 的比值(0~1之间小数)
  1727.   #  若使用了【组件-缓动函数 by老鹰】,则可以调用其中的缓动函数
  1728.   #--------------------------------------------------------------------------
  1729.   def self.ease_value(type, x)
  1730.     if $imported["EAGLE-EasingFunction"]
  1731.       case type
  1732.       when :msg_open  # 对话框打开
  1733.         return EasingFuction.call("easeOutBack", x)
  1734.       when :msg_close # 对话框关闭
  1735.         return EasingFuction.call("easeInBack", x)
  1736.       when :msg_xywh  # 对话框通常情况下变更位置和大小
  1737.         return EasingFuction.call("easeOutQuart", x)
  1738.       when :msg_vp    # 视图ox和oy变动时(文字绘制在可视范围外,或clc清屏)
  1739.         return EasingFuction.call("easeOutQuart", x)
  1740.       when :face_xy   # 脸图移动处理
  1741.         return EasingFuction.call("easeOutElastic", x)
  1742.       when :chara_xy  # 文字移动处理
  1743.         return EasingFuction.call("easeOutExpo", x)
  1744.       end
  1745.     end
  1746.     return 1 - 2**(-10 * x)
  1747.   end
  1748.   #--------------------------------------------------------------------------
  1749.   # ● 获取指定转义符的基础设置
  1750.   #--------------------------------------------------------------------------
  1751.   def self.get_default_params(param_sym)
  1752.     MESSAGE_EX.const_get("#{param_sym.to_s.upcase}_PARAMS_INIT".to_sym) rescue {}
  1753.   end
  1754.   #--------------------------------------------------------------------------
  1755.   # ● 读取指定文字组
  1756.   #--------------------------------------------------------------------------
  1757.   def self.get_charas_array(sym, index, num)
  1758.     h = MESSAGE_EX.const_get("#{sym.to_s.upcase}_CHARAS".to_sym) rescue {}
  1759.     array = h[index]
  1760.     return [] if array.nil?
  1761.     return array if num == 0
  1762.     return array.sample(num)
  1763.   end
  1764.   #--------------------------------------------------------------------------
  1765.   # ● 获取\conv[string]的替换字符串
  1766.   #--------------------------------------------------------------------------
  1767.   def self.get_conv(s)
  1768.     CONVERT_ESCAPE[s] || ""
  1769.   end
  1770.   #--------------------------------------------------------------------------
  1771.   # ● 获取姓名框绘制内容的前缀
  1772.   #--------------------------------------------------------------------------
  1773.   def self.get_name_prefix
  1774.     ESCAPE_STRING_NAME_PREFIX
  1775.   end
  1776.   #--------------------------------------------------------------------------
  1777.   # ● 读取对应的 windowskin 位图
  1778.   #--------------------------------------------------------------------------
  1779.   def self.windowskin(index)
  1780.     begin
  1781.       return Cache.system(INDEX_TO_WINDOWSKIN[index])
  1782.     rescue
  1783.       return Cache.system(INDEX_TO_WINDOWSKIN[0])
  1784.     end
  1785.   end
  1786.   #--------------------------------------------------------------------------
  1787.   # ● 读取对应的 bg 位图
  1788.   #--------------------------------------------------------------------------
  1789.   def self.windowbg(index, w = nil, h = nil)
  1790.     Cache.system(INDEX_TO_WINDOW_BG[index]) rescue nil
  1791.   end
  1792.   def self.namebg(index, w = nil, h = nil)
  1793.     Cache.system(INDEX_TO_NAME_BG[index]) rescue nil
  1794.   end
  1795.   #--------------------------------------------------------------------------
  1796.   # ● 播放对应的SE
  1797.   #--------------------------------------------------------------------------
  1798.   def self.se(index)
  1799.     params = INDEX_TO_SE[index] || INDEX_TO_SE[0]
  1800.     return if params[0] == ""
  1801.     volume = params[1] || INDEX_TO_SE[0][1]
  1802.     pitch = params[2] || INDEX_TO_SE[0][2]
  1803.     Audio.se_play("Audio/SE/" + params[0], volume, pitch)
  1804.   end
  1805.   #--------------------------------------------------------------------------
  1806.   # ● 读取对应的 tag 位图
  1807.   #--------------------------------------------------------------------------
  1808.   def self.windowtag(index)
  1809.     begin
  1810.       return Cache.system(INDEX_TO_WINDOWTAG[index])
  1811.     rescue
  1812.       return Cache.empty_bitmap
  1813.     end
  1814.   end
  1815.   #--------------------------------------------------------------------------
  1816.   # ● 重设tag
  1817.   #  i => 具体在tag位图上的帧序号,九宫格顺序排列
  1818.   #  o => tag位图的显示原点,理论上为pop对话框的do
  1819.   #  _do => tag位图的显示位置原点,理论上为pop对话框的o
  1820.   #--------------------------------------------------------------------------
  1821.   def self.set_windowtag(window, sprite, i, o, _do)
  1822.     w = sprite.src_rect.width; h = sprite.src_rect.height # 单个tag的宽度和高度
  1823.     sprite.src_rect.x = w * (2 - (9 - i) % 3)
  1824.     sprite.src_rect.y = h * ((9 - i) / 3)
  1825.     self.reset_xy_dorigin(sprite, window, _do)
  1826.     self.reset_xy_origin(sprite, o)
  1827.   end
  1828.   #--------------------------------------------------------------------------
  1829.   # ● 读取 pause 按键等待精灵的信息组
  1830.   #--------------------------------------------------------------------------
  1831.   def self.pause_params(index)
  1832.     INDEX_TO_PAUSE[index] || INDEX_TO_PAUSE[0]
  1833.   end
  1834.   #--------------------------------------------------------------------------
  1835.   # ● 读取绘制图片时的图片名称
  1836.   #--------------------------------------------------------------------------
  1837.   def self.get_pic_file(filename)
  1838.     filename
  1839.   end
  1840. #==============================================================================
  1841. # ○ 共享方法
  1842. #==============================================================================
  1843.   #--------------------------------------------------------------------------
  1844.   # ● 判定当前场景
  1845.   #--------------------------------------------------------------------------
  1846.   def self.in_scene?(s)
  1847.     return SceneManager.scene_is?(Scene_Map) if s == :map  # 地图场景中?
  1848.     return SceneManager.scene_is?(Scene_Battle) if s == :battle # 战斗场景中?
  1849.     return false
  1850.   end
  1851.   #--------------------------------------------------------------------------
  1852.   # ● 获取指定对象的信息文本
  1853.   #--------------------------------------------------------------------------
  1854.   def self.get_data_info(type, id, n ='0')
  1855.     case type
  1856.     when 's'; obj = $data_skills[id]
  1857.     when 'i'; obj = $data_items[id]
  1858.     when 'w'; obj = $data_weapons[id]
  1859.     when 'a'; obj = $data_armors[id]
  1860.     end
  1861.     if obj
  1862.       case n
  1863.       when 0, '0'; return "\ei[#{obj.icon_index}]#{obj.name}"
  1864.       when 1, '1'; return "\ei[#{obj.icon_index}]"
  1865.       when 2, '2'; return "#{obj.name}"
  1866.       end
  1867.     end
  1868.     return ""
  1869.   end
  1870.   #--------------------------------------------------------------------------
  1871.   # ● 解析字符串参数
  1872.   #--------------------------------------------------------------------------
  1873.   def self.parse_param(param_hash, param_text, default_type = "default")
  1874.     param_text = param_text.downcase rescue ""
  1875.     # 只有首位是省略名字的参数设置
  1876.     param_text.slice!(/ */)
  1877.     t = param_text.slice!(/^\-?\d+/)
  1878.     param_hash[default_type.to_sym] = t.to_i if t && t != ""
  1879.     while(param_text != "")
  1880.       param_text.slice!(/ */)
  1881.       t = param_text.slice!(/^[a-z]+/)
  1882.       param_text.slice!(/ */)
  1883.       if param_text[0] == '='
  1884.         param_text[0] = ''
  1885.         param_text.slice!(/ */)
  1886.       end
  1887.       if param_text[0] == "$"
  1888.         param_text[0] = ''
  1889.         next param_hash[t.to_sym] = nil
  1890.       end
  1891.       param_hash[t.to_sym] = (param_text.slice!(/^\-?\d+/)).to_i
  1892.     end
  1893.   end
  1894.   #--------------------------------------------------------------------------
  1895.   # ● 获取文本颜色
  1896.   #--------------------------------------------------------------------------
  1897.   def self.text_color(n, windowskin = Cache.system("Window"))
  1898.     return TEXT_COLORS[n] if TEXT_COLORS[n]
  1899.     n_ = n.to_i
  1900.     n_ = DEFAULT_COLOR_INDEX if n_ < 0
  1901.     windowskin.get_pixel(64 + (n_ % 8) * 8, 96 + (n_ / 8) * 8)
  1902.   end
  1903.   #--------------------------------------------------------------------------
  1904.   # ● 将指定值变更为布尔量
  1905.   #--------------------------------------------------------------------------
  1906.   def self.check_bool(v)
  1907.     return true if v == true
  1908.     return false if v.nil? || v == false || v == 0
  1909.     return true
  1910.   end
  1911.   #--------------------------------------------------------------------------
  1912.   # ● 应用font参数到font对象上
  1913.   #--------------------------------------------------------------------------
  1914.   def self.apply_font_params(font, ps)
  1915.     font.name = INDEX_TO_FONT[ps[:name]] if ps[:name]
  1916.     font.size = ps[:size] || Font.default_size
  1917.     font.color.alpha = ps[:ca]
  1918.     font.italic = ps[:i] ? MESSAGE_EX.check_bool(ps[:i]) : Font.default_italic
  1919.     font.bold = ps[:b] ? MESSAGE_EX.check_bool(ps[:b]) : Font.default_bold
  1920.     font.shadow = ps[:s] ? MESSAGE_EX.check_bool(ps[:s]) : Font.default_shadow
  1921.     font.outline = ps[:o] ? MESSAGE_EX.check_bool(ps[:o]) : Font.default_outline
  1922.     if ps[:or]
  1923.       font.out_color.set(ps[:or],ps[:og],ps[:ob],ps[:oa])
  1924.     else
  1925.       font.out_color = Font.default_out_color
  1926.     end
  1927.     ps[:l] = MESSAGE_EX.check_bool(ps[:l])
  1928.     ps[:lc] ||= 0
  1929.     ps[:lp] ||= 2
  1930.     ps[:d] = MESSAGE_EX.check_bool(ps[:d])
  1931.     ps[:dc] ||= 0
  1932.     ps[:u] = MESSAGE_EX.check_bool(ps[:u])
  1933.     ps[:uc] ||= 0
  1934.     ps[:k] = MESSAGE_EX.check_bool(ps[:k])
  1935.     ps[:kv] ||= 50
  1936.   end
  1937.   #--------------------------------------------------------------------------
  1938.   # ● 重置指定精灵的显示原点
  1939.   #--------------------------------------------------------------------------
  1940.   def self.reset_sprite_oxy(obj, o)
  1941.     case o # 固定不动点的位置类型 以九宫格小键盘察看
  1942.     when 1
  1943.       obj.ox = 0
  1944.       obj.oy = obj.height
  1945.     when 2
  1946.       obj.ox = obj.width / 2
  1947.       obj.oy = obj.height
  1948.     when 3
  1949.       obj.ox = obj.width
  1950.       obj.oy = obj.height
  1951.     when 4
  1952.       obj.ox = 0
  1953.       obj.oy = obj.height / 2
  1954.     when 5
  1955.       obj.ox = obj.width / 2
  1956.       obj.oy = obj.height / 2
  1957.     when 6
  1958.       obj.ox = obj.width
  1959.       obj.oy = obj.height / 2
  1960.     when 7 # 【默认】显示原点为左上角
  1961.       obj.ox = 0
  1962.       obj.oy = 0
  1963.     when 8
  1964.       obj.ox = obj.width / 2
  1965.       obj.oy = 0
  1966.     when 9
  1967.       obj.ox = obj.width
  1968.       obj.oy = 0
  1969.     end
  1970.   end
  1971.   #--------------------------------------------------------------------------
  1972.   # ● 重置指定对象的显示原点位置
  1973.   #--------------------------------------------------------------------------
  1974.   def self.reset_xy_origin(obj, o)
  1975.     case o  # 固定不动点的位置类型 以九宫格小键盘察看
  1976.     when 1
  1977.       obj.y = obj.y - obj.height
  1978.     when 2
  1979.       obj.x = obj.x - obj.width / 2
  1980.       obj.y = obj.y - obj.height
  1981.     when 3
  1982.       obj.x = obj.x - obj.width
  1983.       obj.y = obj.y - obj.height
  1984.     when 4
  1985.       obj.y = obj.y - obj.height / 2
  1986.     when 5
  1987.       obj.x = obj.x - obj.width / 2
  1988.       obj.y = obj.y - obj.height / 2
  1989.     when 6
  1990.       obj.x = obj.x - obj.width
  1991.       obj.y = obj.y - obj.height / 2
  1992.     when 7; return # 【默认】显示原点为左上角
  1993.     when 8
  1994.       obj.x = obj.x - obj.width / 2
  1995.     when 9
  1996.       obj.x = obj.x - obj.width
  1997.     end
  1998.   end
  1999.   #--------------------------------------------------------------------------
  2000.   # ● 重置指定对象依据另一对象小键盘位置的新位置
  2001.   #--------------------------------------------------------------------------
  2002.   def self.reset_xy_dorigin(obj, obj2, o) # 左上角和左上角对齐
  2003.     if o < 0 # o小于0时,将obj2重置为全屏
  2004.       obj2 = Rect.new(0,0,Graphics.width,Graphics.height)
  2005.       o = o.abs
  2006.     end
  2007.     case o
  2008.     when 1,4,7; obj.x = obj2.x
  2009.     when 2,5,8; obj.x = obj2.x + obj2.width / 2
  2010.     when 3,6,9; obj.x = obj2.x + obj2.width
  2011.     end
  2012.     case o
  2013.     when 1,2,3; obj.y = obj2.y + obj2.height
  2014.     when 4,5,6; obj.y = obj2.y + obj2.height / 2
  2015.     when 7,8,9; obj.y = obj2.y
  2016.     end
  2017.   end
  2018.   #--------------------------------------------------------------------------
  2019.   # ● 基于指定位图,计算文本块所占宽高
  2020.   # (只进行 \\ 到 \e 的文本替换、忽略除\i以外的全部转义符、未考虑字号变化)
  2021.   #  k → 字符间距  ld → 行间距
  2022.   #--------------------------------------------------------------------------
  2023.   def self.calculate_text_wh(bitmap, text, k = 0, ld = 0)
  2024.     text_clone = text.dup; array_width = []; array_height = []
  2025.     # 转义符替换
  2026.     text_clone.gsub!(/\\/)      { "\e" }
  2027.     text_clone.gsub!(/\e\e/)    { "\\" }
  2028.     text_clone.gsub!(/\e[\.\|\^\!\$<>\{|\}]/i) { "" }
  2029.     # 每一行计算宽度高度
  2030.     text_clone.each_line do |line|
  2031.       icon_count = 0
  2032.       # 获取 \i[] 数目
  2033.       line.gsub!(/\ei\[\d+\]/i){ icon_count += 1; "" }
  2034.       # 清除掉全部的\w[wd]格式转义符
  2035.       line.gsub!(/\e\w+\[(\d|\w)+\]/i) { "" }
  2036.       r = bitmap.text_size(line)
  2037.       w = r.width + icon_count * 24 + (line.length - 1 + icon_count) * k
  2038.       array_width.push(w)
  2039.       h = icon_count > 0 ? [r.height, 24].max : r.height
  2040.       array_height.push(h)
  2041.     end
  2042.     return [array_width.max, array_height.inject{|sum, v| sum = sum + v + ld}]
  2043.   end
  2044.   #--------------------------------------------------------------------------
  2045.   # ● 基于指定文本设置game_message的参数
  2046.   #--------------------------------------------------------------------------
  2047.   def self.set_game_message(game_message, text)
  2048.     @window_clone_env ||= Window_EagleMessage_CloneEnv.new(game_message)
  2049.     @window_clone_env.set_game_message(game_message, text)
  2050.   end
  2051.   #--------------------------------------------------------------------------
  2052.   # ● 计算最小包围盒
  2053.   #--------------------------------------------------------------------------
  2054.   def self.get_smallest_box(rects)
  2055.     return Rect.new if rects.empty?
  2056.     r = rects.pop
  2057.     rects.each do |r2|
  2058.       r.width = [r.x + r.width, r2.x + r2.width].max - [r.x, r2.x].min
  2059.       r.height = [r.y + r.height, r2.y + r2.height].max - [r.y, r2.y].min
  2060.       r.x = r2.x if r2.x < r.x  # 新矩形在现有矩形的左外侧,更新x位置
  2061.       r.y = r2.y if r2.y < r.y  # 新矩形在现有矩形的上外侧,更新y位置
  2062.     end
  2063.     return r
  2064.   end
  2065.   #--------------------------------------------------------------------------
  2066.   # ● 矩形之间碰撞?
  2067.   #--------------------------------------------------------------------------
  2068.   def self.rect_collide_rect?(rect1, rect2)
  2069.     if((rect1.x > rect2.x && rect1.x > rect2.x + rect2.width-1) ||
  2070.        (rect1.x < rect2.x && rect1.x + rect1.width-1 < rect2.x) ||
  2071.        (rect1.y > rect2.y && rect1.y > rect2.y + rect2.height-1) ||
  2072.        (rect1.y < rect2.y && rect1.y + rect1.height-1 < rect2.y))
  2073.       return false
  2074.     end
  2075.     return true
  2076.   end
  2077. end # end of MESSAGE_EX
  2078.  
  2079. #==============================================================================
  2080. # ○ 定义能够响应的文字特效
  2081. #==============================================================================
  2082. module MESSAGE_EX::CHARA_EFFECTS
  2083.   def eagle_chara_effect_cin(param = ''); end
  2084.   def eagle_chara_effect_cout(param = ''); end
  2085.   if defined?(Unravel_Bitmap)
  2086.     def eagle_chara_effect_uout(param = ''); end
  2087.     def eagle_chara_effect_cu(param = ''); end
  2088.   end
  2089.   def eagle_chara_effect_csin(param = ''); end
  2090.   def eagle_chara_effect_cwave(param = ''); end
  2091.   def eagle_chara_effect_cswing(param = ''); end
  2092.   def eagle_chara_effect_czoom(param = ''); end
  2093.   def eagle_chara_effect_cshake(param = ''); end
  2094.   def eagle_chara_effect_cshake2(param = ''); end
  2095.   def eagle_chara_effect_cflash(param = ''); end
  2096.   def eagle_chara_effect_cmirror(param = ''); end
  2097.   def eagle_chara_effect_ctog(param = ''); end
  2098.   def eagle_chara_effect_cneon(param = ''); end
  2099.   def eagle_chara_effect_cmc(param = ''); end
  2100.   def eagle_chara_effect_cjump(param = ''); end
  2101.   def eagle_chara_effect_cfk(param = ''); end
  2102. end
  2103.  
  2104. #=============================================================================
  2105. # ○ DataManager
  2106. #=============================================================================
  2107. class << DataManager
  2108.   #--------------------------------------------------------------------------
  2109.   # ● 设置新游戏
  2110.   #--------------------------------------------------------------------------
  2111.   alias eagle_message_ex_setup_new_game setup_new_game
  2112.   def setup_new_game
  2113.     eagle_message_ex_setup_new_game
  2114.     $game_message.add_escape(MESSAGE_EX::ESCAPE_STRING_INIT)
  2115.     $game_system.reset_game_message_envs
  2116.   end
  2117. end
  2118.  
  2119. #=============================================================================
  2120. # ○ Game_Message
  2121. #=============================================================================
  2122. class Game_Message
  2123.   attr_reader   :params_need_apply # 存储需要被预定应用的符号(调用对应处理方法)
  2124.   attr_accessor :escape_strings # 存储预定要添加的字符串
  2125.   attr_accessor :chara_params # 存储文字特效预设 code_symbol => param_string
  2126.   attr_accessor :font_params, :win_params, :pop_params
  2127.   attr_accessor :face_params, :name_params, :pause_params
  2128.   attr_accessor :func_params, :ex_params, :env, :default_env
  2129.   attr_accessor :event_id, :child_window_w_des, :child_window_h_des
  2130.   attr_accessor :no_name_overlap_face, :no_input_pause, :active # 对话框在显示中
  2131.   attr_accessor :eagle_text # 存储实际绘制的文本(去除了预处理的转义符)
  2132.   attr_accessor :eagle_message # 兼容模式
  2133.   #--------------------------------------------------------------------------
  2134.   # ● 初始化对象
  2135.   #--------------------------------------------------------------------------
  2136.   alias eagle_message_ex_init initialize
  2137.   def initialize
  2138.     eagle_message_ex_init
  2139.     check_flags
  2140.     set_default_params
  2141.     reset_child_window_wh_add
  2142.   end
  2143.   #--------------------------------------------------------------------------
  2144.   # ● 检查flags
  2145.   #--------------------------------------------------------------------------
  2146.   def check_flags
  2147.     # 当前环境(默认 '0')
  2148.     @env = '0' if @env.nil?
  2149.     # 姓名框不遮挡脸图?
  2150.     if @no_name_overlap_face == nil
  2151.       @no_name_overlap_face = MESSAGE_EX::DEFAULT_NO_OVERLAP_FACE
  2152.     end
  2153.     # 不进入按键等待?(扩展用)
  2154.     @no_input_pause = false if @no_input_pause.nil?
  2155.     # 如果处于兼容模式,且变量值为nil,确保变量值为false
  2156.     if EAGLE_MSG_EX_COMPAT_MODE == true
  2157.       @eagle_message = false if @eagle_message.nil?
  2158.     end
  2159.   end
  2160.   #--------------------------------------------------------------------------
  2161.   # ● 获取全部可保存params的符号的数组
  2162.   #--------------------------------------------------------------------------
  2163.   def eagle_params
  2164.     [:chara, :font, :win, :pop, :face, :name, :pause, :func, :ex]
  2165.   end
  2166.   #--------------------------------------------------------------------------
  2167.   # ● 获取params的初始值
  2168.   #--------------------------------------------------------------------------
  2169.   def set_default_params
  2170.     eagle_params.each do |sym|
  2171.       send("#{sym}_params=".to_sym, MESSAGE_EX.get_default_params(sym).dup)
  2172.     end
  2173.     @params_need_apply = eagle_params.dup # 添加修改预定,用于应用初始值
  2174.     @escape_strings = [] # 存储等待执行的转义符字符串
  2175.   end
  2176.   #--------------------------------------------------------------------------
  2177.   # ● 检查params是否都存在(读档后调用,确保新增变量写入旧存档中)
  2178.   #--------------------------------------------------------------------------
  2179.   def check_params
  2180.     check_flags
  2181.     eagle_params.each do |sym|
  2182.       params = self.send("#{sym}_params".to_sym)
  2183.       def_params = MESSAGE_EX.get_default_params(sym).dup
  2184.       if params == nil
  2185.         self.send("#{sym}_params=".to_sym, def_params)
  2186.         add_apply(sym)
  2187.       else
  2188.         params = def_params.merge(params)
  2189.         self.send("#{sym}_params=".to_sym, params)
  2190.       end
  2191.     end
  2192.   end
  2193.   #--------------------------------------------------------------------------
  2194.   # ● 清除(每次对话框关闭前被调用)
  2195.   #--------------------------------------------------------------------------
  2196.   alias eagle_message_ex_clear clear
  2197.   def clear
  2198.     eagle_message_ex_clear
  2199.     @eagle_text = ""
  2200.     @event_id = 0 # 存储当前执行的Game_Interpreter的事件ID
  2201.     if EAGLE_MSG_EX_COMPAT_MODE == false # 如果不处于兼容模式,确保变量恒为true
  2202.       @eagle_message = true
  2203.     end
  2204.   end
  2205.   #--------------------------------------------------------------------------
  2206.   # ● 重置额外增加的宽高(new_page时调用)
  2207.   #--------------------------------------------------------------------------
  2208.   def reset_child_window_wh_add
  2209.     @child_window_w_des = 0 # 因子窗口嵌入而额外增加的宽高
  2210.     @child_window_h_des = 0
  2211.   end
  2212.   #--------------------------------------------------------------------------
  2213.   # ● 下一次对话时要解析的转义符
  2214.   # 【由于解析问题,字符串中请将 "\" 替换成 "\e" 】
  2215.   #--------------------------------------------------------------------------
  2216.   def add_escape(string)
  2217.     @escape_strings.push(string)
  2218.   end
  2219.   #--------------------------------------------------------------------------
  2220.   # ● 判定是否需要进入等待按键状态
  2221.   #--------------------------------------------------------------------------
  2222.   def input_pause?
  2223.     return false if @no_input_pause
  2224.     !(choice? || num_input? || item_choice?)
  2225.   end
  2226.   #--------------------------------------------------------------------------
  2227.   # ● 使用了各个对话框组件?
  2228.   #--------------------------------------------------------------------------
  2229.   def pop?;     @pop_params[:type] != nil; end
  2230.   def pop_tag?; @pop_params[:tag] > 0;     end
  2231.   def face?;    @face_params[:name] != ""; end
  2232.   def name?;    @name_params[:name] != ""; end
  2233.   #--------------------------------------------------------------------------
  2234.   # ● 添加修改预定
  2235.   #--------------------------------------------------------------------------
  2236.   def add_apply(param_sym)
  2237.     return if @params_need_apply.include?(param_sym)
  2238.     @params_need_apply.push(param_sym)
  2239.   end
  2240.   #--------------------------------------------------------------------------
  2241.   # ● 清空预定修改
  2242.   #--------------------------------------------------------------------------
  2243.   def clear_applys
  2244.     @params_need_apply.clear
  2245.   end
  2246.   #--------------------------------------------------------------------------
  2247.   # ● 重置指定参数
  2248.   #--------------------------------------------------------------------------
  2249.   def reset_params(param_sym, code_string = nil)
  2250.     return eagle_params.each{|sym| reset_params(sym)} if param_sym.nil?
  2251.     return reset_params_c(code_string) if param_sym == :chara
  2252.     return reset_params_ex(code_string) if param_sym == :ex
  2253.     default_params = MESSAGE_EX.get_default_params(param_sym)
  2254.     if code_string.nil? # 直接清除全部参数
  2255.       new_params = default_params.dup
  2256.     else
  2257.       new_params = method( param_sym.to_s + "_params" ).call.dup # 获取旧的hash
  2258.       code_string.split("|").each { |c|
  2259.         new_params[c.to_sym] = default_params[c.to_sym]
  2260.       }
  2261.     end
  2262.     self.send((param_sym.to_s+"_params=").to_sym, new_params)
  2263.     add_apply(param_sym) # 添加修改预定,用于应用结果
  2264.   end
  2265.   #--------------------------------------------------------------------------
  2266.   # ● 重置指定文字特效
  2267.   #--------------------------------------------------------------------------
  2268.   def reset_params_c(code_string = nil)
  2269.     default_params = MESSAGE_EX.get_default_params(:chara)
  2270.     return @chara_params = default_params if code_string.nil?
  2271.     code_string.split("|").each { |c|
  2272.       if default_params[c.to_sym]
  2273.         @chara_params[c.to_sym] = default_params[c.to_sym]
  2274.       else
  2275.         @chara_params.delete(c.to_sym)
  2276.       end
  2277.     }
  2278.   end
  2279.   #--------------------------------------------------------------------------
  2280.   # ● 重置扩展转义符
  2281.   #--------------------------------------------------------------------------
  2282.   def reset_params_ex(code_string = nil)
  2283.     default_params = MESSAGE_EX.get_default_params(:ex)
  2284.     return @ex_params = default_params if code_string.nil?
  2285.     code_string.split("|").each { |c|
  2286.       if default_params[c.to_sym]
  2287.         @ex_params[c.to_sym] = default_params[c.to_sym]
  2288.       else
  2289.         @ex_params.delete(c.to_sym)
  2290.       end
  2291.     }
  2292.   end
  2293.   #--------------------------------------------------------------------------
  2294.   # ● 参数拷贝
  2295.   #--------------------------------------------------------------------------
  2296.   def clone2
  2297.     t = Game_Message.new
  2298.     t.visible = true
  2299.     eagle_params.each do |sym|
  2300.       m = "#{sym}_params"
  2301.       t.send("#{m}=".to_sym, method(m.to_sym).call.clone)
  2302.     end
  2303.     clone_ex(t)
  2304.     t
  2305.   end
  2306.   #--------------------------------------------------------------------------
  2307.   # ● 参数拷贝(扩展)
  2308.   #--------------------------------------------------------------------------
  2309.   def clone_ex(t)
  2310.     t.background = @background
  2311.     t.position = @position
  2312.     t.no_name_overlap_face = @no_name_overlap_face
  2313.   end
  2314.   #--------------------------------------------------------------------------
  2315.   # ● 保存当前环境
  2316.   #--------------------------------------------------------------------------
  2317.   def save_env(sym = '0')
  2318.     if sym == '0' # 如果是默认环境,则保存到自己,防止与子窗口的默认环境相互干扰
  2319.       @default_env = self.clone2
  2320.       return
  2321.     end
  2322.     $game_system.message_envs[sym] = self.clone2
  2323.   end
  2324.   #--------------------------------------------------------------------------
  2325.   # ● 读取指定环境
  2326.   #--------------------------------------------------------------------------
  2327.   def load_env(sym = '0')
  2328.     t = $game_system.message_envs[sym]
  2329.     t = @default_env if sym == '0'
  2330.     return false if t.nil?
  2331.     # 应用params
  2332.     eagle_params.each do |s|
  2333.       m = "#{s}_params"
  2334.       self.send("#{m}=".to_sym, t.method(m.to_sym).call.clone)
  2335.     end
  2336.     # 新增转义符的应用预定
  2337.     @params_need_apply = eagle_params
  2338.     # 应用扩展数据
  2339.     t.clone_ex(self)
  2340.     return true
  2341.   end
  2342.   #--------------------------------------------------------------------------
  2343.   # ● 将临时环境存入指定环境,并返回临时环境
  2344.   #--------------------------------------------------------------------------
  2345.   def load_temp_env(sym = '0', temp = :eagle_temp)
  2346.     if sym == '0'
  2347.       @default_env = $game_system.message_envs[temp]
  2348.     else
  2349.       $game_system.message_envs[sym] = $game_system.message_envs[temp]
  2350.     end
  2351.     return $game_system.message_envs[temp]
  2352.   end
  2353. end
  2354. #=============================================================================
  2355. # ○ Game_System
  2356. #=============================================================================
  2357. class Game_System
  2358.   attr_reader   :message_envs  # 对话框环境
  2359.   #--------------------------------------------------------------------------
  2360.   # ● 初始化对象
  2361.   #--------------------------------------------------------------------------
  2362.   alias eagle_message_ex_initialize initialize
  2363.   def initialize
  2364.     eagle_message_ex_initialize
  2365.     @message_envs = {} # sym => game_message
  2366.   end
  2367.   #--------------------------------------------------------------------------
  2368.   # ● 读档后的处理
  2369.   #--------------------------------------------------------------------------
  2370.   alias eagle_message_ex_on_after_load on_after_load
  2371.   def on_after_load
  2372.     eagle_message_ex_on_after_load
  2373.     reset_game_message_envs
  2374.     $game_message.check_params # 确保新增AddOn时,参数hash存在
  2375.     @message_envs.each { |sym, g| g.check_params }
  2376.   end
  2377.   #--------------------------------------------------------------------------
  2378.   # ● 重置初始环境
  2379.   #--------------------------------------------------------------------------
  2380.   def reset_game_message_envs
  2381.     MESSAGE_EX::DEFAULT_ENVS.each do |sym, text|
  2382.       g = Game_Message.new
  2383.       MESSAGE_EX.set_game_message(g, text)
  2384.       @message_envs[sym] = g
  2385.     end
  2386.     $game_message.save_env if $game_message.default_env == nil
  2387.   end
  2388. end
  2389. #=============================================================================
  2390. # ○ Game_Interpreter
  2391. #=============================================================================
  2392. class Game_Interpreter
  2393.   #--------------------------------------------------------------------------
  2394.   # ● 显示文字
  2395.   #--------------------------------------------------------------------------
  2396.   alias eagle_message_ex_command_101 command_101
  2397.   def command_101
  2398.     $game_message.event_id = @event_id
  2399.     eagle_message_ex_command_101
  2400.   end
  2401. end
  2402.  
  2403. #=============================================================================
  2404. # ○ Window_EagleMessage
  2405. #=============================================================================
  2406. class Window_EagleMessage < Window_Base
  2407.   include MESSAGE_EX::CHARA_EFFECTS
  2408.   attr_reader :eagle_charas_w, :eagle_charas_h, :eagle_chara_viewport
  2409.   #--------------------------------------------------------------------------
  2410.   # ● 获取主参数组(方便子窗口修改为自己的game_message)
  2411.   #--------------------------------------------------------------------------
  2412.   def game_message;     $game_message;      end
  2413.   def game_message=(g); $game_message = g;  end
  2414.   #--------------------------------------------------------------------------
  2415.   # ● 【通用方法】
  2416.   #--------------------------------------------------------------------------
  2417.   def parse_param(param_hash, param_text, default_type = "default")
  2418.     MESSAGE_EX.parse_param(param_hash, param_text, default_type)
  2419.   end
  2420.   def text_color(n)
  2421.     MESSAGE_EX.text_color(n, self.windowskin)
  2422.   end
  2423.  
  2424.   #--------------------------------------------------------------------------
  2425.   # ● 初始化对象
  2426.   #--------------------------------------------------------------------------
  2427.   def initialize
  2428.     super(0, 0, window_width, window_height)
  2429.     create_all_windows
  2430.     eagle_message_init_assets
  2431.     eagle_message_init_params
  2432.     eagle_message_reset
  2433.     self.openness = 0
  2434.   end
  2435.   #--------------------------------------------------------------------------
  2436.   # ● 生成所有子窗口
  2437.   #--------------------------------------------------------------------------
  2438.   def create_all_windows
  2439.     @gold_window = Window_EagleMsgGold.new(self)
  2440.     @choice_window = Window_EagleChoiceList.new(self) rescue Window_ChoiceList.new(self)
  2441.     @number_window = Window_EagleNumberInput.new(self) rescue Window_NumberInput.new(self)
  2442.     @item_window = Window_EagleKeyItem.new(self) rescue Window_KeyItem.new(self)
  2443.   end
  2444.   #--------------------------------------------------------------------------
  2445.   # ● 初始化组件
  2446.   # (在进行 clone 时,需要将该方法中的组件直接赋值给拷贝窗口)
  2447.   #--------------------------------------------------------------------------
  2448.   def eagle_message_init_assets
  2449.     @back_sprite = Sprite.new  # 显示背景图片的精灵
  2450.     @eagle_chara_viewport = Viewport.new # 文字精灵的显示区域
  2451.     @eagle_chara_sprites = []  # 存储全部的文字精灵
  2452.     @eagle_sprite_pop_tag = Sprite.new # pop状态下的tag精灵
  2453.     @eagle_sprite_face = nil   # 脸图精灵
  2454.     @eagle_window_name = Window_EagleMsgName.new(self) # 姓名框
  2455.     @eagle_sprite_pause = Sprite_EaglePauseTag.new(self) # 等待按键的精灵
  2456.   end
  2457.   #--------------------------------------------------------------------------
  2458.   # ● 初始化参数(只会在 initialize 时执行一次)
  2459.   # (推荐将一些不需要传递给拷贝窗口的数据置于此处)
  2460.   #--------------------------------------------------------------------------
  2461.   def eagle_message_init_params
  2462.     self.back_opacity = 255     # 背景不透明度
  2463.     self.arrows_visible = false # 内容位图未完全显示时出现的箭头
  2464.     @fiber = nil                # 纤程
  2465.     @background = 0             # 背景类型
  2466.     @position = 2               # 显示位置
  2467.     @flag_draw = true           # true 代表进行实际的绘制
  2468.     @flag_open_close = false    # 当正在进行打开/关闭时,置为 true
  2469.     @flag_input_pause = false   # 当正在进行按键等待时,置为 true
  2470.     @flag_need_open = true      # true 代表需要执行open_and_wait
  2471.     @flag_need_change_wh = false # true 代表需要进行宽高的动态变化
  2472.     @flag_need_close = false    # true 代表当前对话框必需处理关闭
  2473.     @flag_hold = false          # true 代表当前对话框会被拷贝保留,并同步更新
  2474.     @flag_instant = false       # true 代表当前对话框不再处理文字显示时的等待
  2475.     @flag_next = false          # true 代表当前对话框不关闭,下一显示文字将继续使用
  2476.     @flag_temp = false          # true 代表当前对话框的任何修改将不被保存
  2477.     @flag_temp_env = nil        # 存储当前对话框开启前的环境
  2478.     @flag_save_env = nil        # 当不为 nil 时,当前对话框状态保存到对应环境中
  2479.     @eagle_dup_windows ||= []   # 存储生成的全部拷贝对话框
  2480.     @eagle_evals = []           # 当前对话中的待执行脚本 [eval_str, eval_str...]
  2481.     @eagle_chara_sets = {}      # 存储文字的全部分组 {分组名 => [文字精灵]}
  2482.     @eagle_current_set = nil    # 当前分组的名称
  2483.     # 对话框动态移动偏移量(此处新增定义,防止子类覆盖了 eagle_message_reset)
  2484.     @eagle_move_x = @eagle_move_y = 0
  2485.     # 存储对话框在上一帧的位置(此处新增定义,防止子类覆盖了 eagle_message_reset)
  2486.     @eagle_last_x = @eagle_last_y = nil
  2487.     eagle_check_func("")        # 预先执行一遍func,确保它们都是布尔量
  2488.   end
  2489.   #--------------------------------------------------------------------------
  2490.   # ● 拷贝自身
  2491.   #--------------------------------------------------------------------------
  2492.   def clone(window = Window_EagleMessage_Clone)
  2493.     t = window.new(game_message.clone2)
  2494.     t.game_message.win_params[:z] = 0
  2495.     t.move(self.x, self.y, self.width, self.height)
  2496.     t.z = self.z - 5
  2497.     t.windowskin = self.windowskin
  2498.     # 拷贝背景精灵
  2499.     t.back_bitmap = @back_bitmap
  2500.     t.back_sprite = @back_sprite
  2501.     @back_bitmap = nil
  2502.     # 拷贝视图
  2503.     t.eagle_chara_viewport = @eagle_chara_viewport
  2504.     # 拷贝文字组
  2505.     t.eagle_chara_sprites = @eagle_chara_sprites
  2506.     t.eagle_chara_sprites.each { |s| s.bind_window(t) }
  2507.     # 复制文本宽高
  2508.     t.eagle_set_chara_wh(@eagle_charas_w, @eagle_charas_h,
  2509.       @eagle_charas_w_final, @eagle_charas_h_final)
  2510.     # 拷贝pop对象
  2511.     t.eagle_pop_obj = @eagle_pop_obj
  2512.     # 拷贝pop的tag
  2513.     t.eagle_sprite_pop_tag = @eagle_sprite_pop_tag
  2514.     # 拷贝脸图
  2515.     if @eagle_sprite_face
  2516.       t.eagle_sprite_face = @eagle_sprite_face
  2517.       t.eagle_sprite_face.bind_window(t)
  2518.     end
  2519.     # 拷贝姓名框
  2520.     t.eagle_window_name = @eagle_window_name
  2521.     t.eagle_window_name.bind_window(t)
  2522.     # 拷贝pause精灵
  2523.     t.eagle_sprite_pause = @eagle_sprite_pause
  2524.     t.eagle_sprite_pause.bind_window(t)
  2525.     # 扩展
  2526.     t = clone_ex(t)
  2527.     # 集体更新z值
  2528.     t.eagle_reset_z
  2529.     # 自身初始化组件与重置
  2530.     eagle_message_init_assets
  2531.     # 更新自身的z值
  2532.     eagle_reset_z
  2533.     t
  2534.   end
  2535.   #--------------------------------------------------------------------------
  2536.   # ● 拷贝自身(扩展用处理)
  2537.   #--------------------------------------------------------------------------
  2538.   def clone_ex(t)
  2539.     t
  2540.   end
  2541.   #--------------------------------------------------------------------------
  2542.   # ● 释放
  2543.   #--------------------------------------------------------------------------
  2544.   def dispose
  2545.     dispose_all_windows
  2546.     dispose_back_bitmap
  2547.     @back_sprite.dispose
  2548.     @eagle_chara_sprites.each { |s| s.dispose }
  2549.     @eagle_window_name.dispose
  2550.     @eagle_sprite_face.dispose if @eagle_sprite_face
  2551.     @eagle_sprite_pop_tag.dispose
  2552.     @eagle_sprite_pause.dispose
  2553.     @eagle_dup_windows.each { |w| w.dispose if !w.disposed? }
  2554.     @eagle_chara_viewport.dispose
  2555.     super
  2556.   end
  2557.   #--------------------------------------------------------------------------
  2558.   # ● 释放所有窗口
  2559.   #--------------------------------------------------------------------------
  2560.   def dispose_all_windows
  2561.     @gold_window.dispose
  2562.     @choice_window.dispose
  2563.     @number_window.dispose
  2564.     @item_window.dispose
  2565.   end
  2566.   #--------------------------------------------------------------------------
  2567.   # ● 释放背景位图
  2568.   #--------------------------------------------------------------------------
  2569.   def dispose_back_bitmap
  2570.     @back_bitmap.dispose if @back_bitmap
  2571.     @back_bitmap = nil
  2572.   end
  2573.  
  2574.   #--------------------------------------------------------------------------
  2575.   # ● 重置对话框
  2576.   #--------------------------------------------------------------------------
  2577.   def eagle_message_reset
  2578.     eagle_message_reset_continue
  2579.     eagle_move_out_assets    # 移出全部组件
  2580.     @eagle_last_x = @eagle_last_y = nil  # 重置存储的对话框的上一个位置
  2581.     @eagle_move_x = @eagle_move_y = 0    # 重置对话框动态移动位置
  2582.     @eagle_win_des_w = @eagle_win_des_h = 0  # 重置对话框最终显示宽高
  2583.     @eagle_charas_w = @eagle_charas_h = 0    # 重置文字区域的宽高
  2584.     @eagle_charas_w_final = @eagle_charas_h_final = 0
  2585.     face_params[:width] = 0  # 重置脸图的宽度(用于文字偏移)
  2586.     @eagle_pop_obj = nil     # 重置pop对象,防止报错
  2587.     eagle_reset_z            # 重置z值
  2588.     clear_flags              # 清除显示标志
  2589.   end
  2590.   #--------------------------------------------------------------------------
  2591.   # ● 重置对话框(对话框不关闭,清空全部设置,并继续显示)
  2592.   #--------------------------------------------------------------------------
  2593.   def eagle_message_reset_continue
  2594.     show if !self.visible    # 确保对话框显示
  2595.     if @flag_next  # 如果继续显示在当前对话框里,则不移出文字
  2596.     else
  2597.       eagle_message_sprites_move_out  # 移出全部文字精灵
  2598.       eagle_reset_charas_oxy  # 重置文字显示区域
  2599.       @eagle_chara_sets.clear  # 清空文字分组
  2600.     end
  2601.     eagle_process_env        # 处理环境的存储或读取
  2602.     eagle_process_temp       # 处理临时环境
  2603.     @eagle_sprite_pop_tag.visible = false # 隐藏pop的tag
  2604.     @eagle_sprite_pause.visible = false   # 隐藏等待按键pause精灵
  2605.     @eagle_sprite_pause.bind_last_chara(nil)  # 重置pause精灵的文末位置
  2606.     @eagle_sprite_pause_width_add = 0     # 因pause精灵而扩展的窗口宽度
  2607.     @eagle_next_chara_x = 0     # 重置下一个文字的绘制坐标x(左对齐、不考虑换行)
  2608.     @eagle_force_close = false  # 重置强制关闭
  2609.   end
  2610.   #--------------------------------------------------------------------------
  2611.   # ● 移出全部组件
  2612.   #--------------------------------------------------------------------------
  2613.   def eagle_move_out_assets
  2614.     pop_params[:with_tag] = false
  2615.     @eagle_sprite_pop_tag.visible = false  # 隐藏pop的tag
  2616.     @eagle_sprite_pause.visible = false    # 隐藏pause精灵
  2617.     face_params[:name] = ""   # 移出显示的脸图
  2618.     eagle_move_out_face
  2619.     # 关闭姓名框(因为对话框关闭后,姓名框不再更新,调小openness确保先关闭)
  2620.     @eagle_window_name.close
  2621.     @eagle_window_name.openness -= 15
  2622.   end
  2623.   #--------------------------------------------------------------------------
  2624.   # ● 更新全部组件的不透明度
  2625.   #--------------------------------------------------------------------------
  2626.   def update_assets_opacity(opa)
  2627.     @eagle_chara_sprites.each { |c| c.opacity = opa }
  2628.     if game_message.pop? && pop_params[:with_tag]
  2629.       @eagle_sprite_pop_tag.opacity = opa
  2630.     end
  2631.     @eagle_sprite_face.opa = opa if @eagle_sprite_face
  2632.     if game_message.name?
  2633.       @eagle_window_name.opacity = opa
  2634.       @eagle_window_name.contents_opacity = opa
  2635.     end
  2636.     update_back_sprite_opa(opa)
  2637.   end
  2638.   #--------------------------------------------------------------------------
  2639.   # ● 重设z值
  2640.   #--------------------------------------------------------------------------
  2641.   def eagle_reset_z
  2642.     self.z = win_params[:z] if win_params[:z] > 0
  2643.     @back_sprite.z = self.z
  2644.     @eagle_chara_viewport.z = self.z + 1
  2645.     @eagle_sprite_pop_tag.z = self.z + 1
  2646.     @eagle_sprite_pause.z = self.z + 2
  2647.     @eagle_window_name.z = self.z + 3
  2648.   end
  2649.   #--------------------------------------------------------------------------
  2650.   # ● 显示窗口
  2651.   #--------------------------------------------------------------------------
  2652.   def show
  2653.     self.visible = true
  2654.     @back_sprite.visible = true if self.opacity == 0
  2655.     @eagle_chara_sprites.each { |s| s.move_in }
  2656.     if game_message.pop? && pop_params[:with_tag]
  2657.       @eagle_sprite_pop_tag.visible = true
  2658.     end
  2659.     @eagle_sprite_face.visible = true if @eagle_sprite_face
  2660.     @eagle_window_name.show if game_message.name?
  2661.     @eagle_sprite_pause.visible = true if @flag_input_pause
  2662.     show_ex
  2663.     self
  2664.   end
  2665.   #--------------------------------------------------------------------------
  2666.   # ● 显示(扩展用)
  2667.   #--------------------------------------------------------------------------
  2668.   def show_ex
  2669.     @eagle_dup_windows.each { |w| w.show }
  2670.   end
  2671.   #--------------------------------------------------------------------------
  2672.   # ● 隐藏窗口
  2673.   #--------------------------------------------------------------------------
  2674.   def hide
  2675.     self.visible = false
  2676.     @back_sprite.visible = false
  2677.     @eagle_chara_sprites.each { |s| s.move_out_temp }
  2678.     @eagle_sprite_pop_tag.visible = false
  2679.     @eagle_sprite_face.visible = false if @eagle_sprite_face
  2680.     @eagle_window_name.hide
  2681.     @eagle_sprite_pause.visible = false
  2682.     hide_ex
  2683.     self
  2684.   end
  2685.   #--------------------------------------------------------------------------
  2686.   # ● 隐藏(扩展用)
  2687.   #--------------------------------------------------------------------------
  2688.   def hide_ex
  2689.     @eagle_dup_windows.each { |w| w.hide }
  2690.   end
  2691.  
  2692.   #--------------------------------------------------------------------------
  2693.   # ● 更新画面
  2694.   #--------------------------------------------------------------------------
  2695.   def update
  2696.     super
  2697.     eagle_update_before_fiber
  2698.     update_fiber
  2699.     eagle_update_after_fiber
  2700.   end
  2701.   #--------------------------------------------------------------------------
  2702.   # ● 更新fiber
  2703.   #--------------------------------------------------------------------------
  2704.   def update_fiber
  2705.     if @fiber
  2706.       @fiber.resume
  2707.     elsif game_message.busy? && !game_message.scroll_mode
  2708.       @fiber = Fiber.new { fiber_main }
  2709.       @fiber.resume
  2710.     else
  2711.       game_message.visible = false
  2712.     end
  2713.   end
  2714.   #--------------------------------------------------------------------------
  2715.   # ● 更新(在 @fiber 更新之前)
  2716.   #--------------------------------------------------------------------------
  2717.   def eagle_update_before_fiber
  2718.     update_all_windows
  2719.     update_back_sprite
  2720.     if self.openness > 0
  2721.       eagle_update_assets_after_open
  2722.       eagle_update_func_after_open
  2723.     end
  2724.   end
  2725.   #--------------------------------------------------------------------------
  2726.   # ● 更新所有窗口
  2727.   #--------------------------------------------------------------------------
  2728.   def update_all_windows
  2729.     @gold_window.update
  2730.     @choice_window.update
  2731.     @number_window.update
  2732.     @item_window.update
  2733.   end
  2734.   #--------------------------------------------------------------------------
  2735.   # ● 对话框打开后进行组件更新
  2736.   #--------------------------------------------------------------------------
  2737.   def eagle_update_assets_after_open
  2738.     eagle_pop_update if game_message.pop?
  2739.     @eagle_window_name.update
  2740.     @eagle_sprite_face.update if @eagle_sprite_face
  2741.     @eagle_sprite_pause.update if @eagle_sprite_pause.visible
  2742.   end
  2743.   #--------------------------------------------------------------------------
  2744.   # ● 对话框打开后进行扩展功能更新
  2745.   #--------------------------------------------------------------------------
  2746.   def eagle_update_func_after_open
  2747.     (self.visible ? hide : show) if MESSAGE_EX.toggle_visible?
  2748.   end
  2749.   #--------------------------------------------------------------------------
  2750.   # ● 更新(在 @fiber 更新之后)
  2751.   #--------------------------------------------------------------------------
  2752.   def eagle_update_after_fiber
  2753.     @eagle_chara_sprites.each { |s| s.update }
  2754.     eagle_update_dup_windows
  2755.   end
  2756.   #--------------------------------------------------------------------------
  2757.   # ● 更新拷贝窗口
  2758.   #--------------------------------------------------------------------------
  2759.   def eagle_update_dup_windows
  2760.     if @eagle_dup_windows.size > 0
  2761.       @eagle_dup_windows.each { |w| w.update }
  2762.       if @eagle_dup_windows[-1].openness <= 0
  2763.         t = @eagle_dup_windows.pop
  2764.         t.dispose
  2765.       end
  2766.     end
  2767.   end
  2768.  
  2769.   #--------------------------------------------------------------------------
  2770.   # ● 打开直至完成(当有文字绘制完成时执行)
  2771.   #--------------------------------------------------------------------------
  2772.   def open_and_wait
  2773.     @flag_open_close = true
  2774.     @eagle_window_name.start if game_message.name?
  2775.     eagle_process_open_and_wait
  2776.     @flag_open_close = false
  2777.     @flag_need_open = false
  2778.   end
  2779.   #--------------------------------------------------------------------------
  2780.   # ● 处理打开方式(打开直至完成)
  2781.   #--------------------------------------------------------------------------
  2782.   def eagle_process_open_and_wait
  2783.     case func_params[:open]
  2784.     when 2
  2785.       eagle_open_type_ease
  2786.     when 1
  2787.       eagle_open_type_fade
  2788.     else # :default
  2789.       eagle_open_type_default
  2790.     end
  2791.   end
  2792.   #--------------------------------------------------------------------------
  2793.   # ● 打开-动态展开
  2794.   #--------------------------------------------------------------------------
  2795.   def eagle_open_type_ease
  2796.     @eagle_chara_sprites.each { |c| c.visible = false }
  2797.     eagle_set_wh({:w => 1, :h => 1, :ins => true, :open => true}) if self.openness == 0
  2798.     self.openness = 255
  2799.     eagle_set_wh({:open => true})
  2800.     @eagle_chara_sprites.each { |c| c.move_in; c.visible = true }
  2801.   end
  2802.   #--------------------------------------------------------------------------
  2803.   # ● 打开-淡入
  2804.   #--------------------------------------------------------------------------
  2805.   def eagle_open_type_fade
  2806.     eagle_set_wh({:ins => true, :open => true})
  2807.     update_back_sprite_zoom(nil, nil) # 将背景精灵的缩放重置为 1.0
  2808.     @eagle_chara_sprites.each { |c| c.move_in }
  2809.     self.openness = 255
  2810.     @eagle_window_name.openness = 255 if game_message.name?
  2811.     _opa = 0
  2812.     while ( _opa < 255 )
  2813.       _opa += 26
  2814.       self.opacity = _opa if @background == 0 && !@back_sprite.visible
  2815.       update_assets_opacity(_opa)
  2816.       Fiber.yield
  2817.     end
  2818.   end
  2819.   #--------------------------------------------------------------------------
  2820.   # ● 打开-默认openness
  2821.   #--------------------------------------------------------------------------
  2822.   def eagle_open_type_default
  2823.     eagle_set_wh({:ins => true, :open => true})
  2824.     update_back_sprite_zoom(nil, nil) # 将背景精灵的缩放重置为 1
  2825.     @eagle_chara_sprites.each { |c| c.visible = false }
  2826.     open
  2827.     until open?
  2828.       update_back_sprite_opa(self.openness)
  2829.       Fiber.yield
  2830.     end
  2831.     @eagle_chara_sprites.each { |c| c.move_in; c.visible = true }
  2832.   end
  2833.   #--------------------------------------------------------------------------
  2834.   # ● 关闭直至完成
  2835.   #--------------------------------------------------------------------------
  2836.   def close_and_wait
  2837.     @flag_open_close = true
  2838.     show if !self.visible
  2839.     Fiber.yield # 关闭前等待1帧,用于截图等
  2840.     eagle_message_sprites_move_out
  2841.     eagle_process_close_and_wait
  2842.     @flag_open_close = false
  2843.     @flag_need_open = true
  2844.   end
  2845.   #--------------------------------------------------------------------------
  2846.   # ● 处理关闭方式(关闭直至完成)
  2847.   #--------------------------------------------------------------------------
  2848.   def eagle_process_close_and_wait
  2849.     case func_params[:close]
  2850.     when 2
  2851.       eagle_close_type_ease
  2852.     when 1
  2853.       eagle_close_type_fade
  2854.     else # :default
  2855.       eagle_close_type_default
  2856.     end
  2857.   end
  2858.   #--------------------------------------------------------------------------
  2859.   # ● 关闭-动态缩小
  2860.   #--------------------------------------------------------------------------
  2861.   def eagle_close_type_ease
  2862.     eagle_move_out_assets
  2863.     eagle_set_wh({:w => 1, :h => 1, :close => true}) if self.openness > 0
  2864.     self.openness = 0
  2865.     close
  2866.   end
  2867.   #--------------------------------------------------------------------------
  2868.   # ● 关闭-淡出
  2869.   #--------------------------------------------------------------------------
  2870.   def eagle_close_type_fade
  2871.     _opa = [self.opacity, @back_sprite.opacity].max
  2872.     while ( _opa > 0 )
  2873.       _opa -= 30
  2874.       self.opacity = _opa if @background == 0 && !@back_sprite.visible
  2875.       update_assets_opacity(_opa)
  2876.       Fiber.yield
  2877.     end
  2878.     self.openness = 0
  2879.     close
  2880.   end
  2881.   #--------------------------------------------------------------------------
  2882.   # ● 关闭-默认openness
  2883.   #--------------------------------------------------------------------------
  2884.   def eagle_close_type_default
  2885.     close
  2886.     until all_close?
  2887.       update_back_sprite_opa(self.openness)
  2888.       Fiber.yield
  2889.     end
  2890.   end
  2891.   #--------------------------------------------------------------------------
  2892.   # ● 关闭
  2893.   #--------------------------------------------------------------------------
  2894.   def close
  2895.     super
  2896.     eagle_message_reset
  2897.     eagle_reset_env # 特殊:重置环境
  2898.   end
  2899.   #--------------------------------------------------------------------------
  2900.   # ● 判定是否所有窗口已全部关闭
  2901.   #--------------------------------------------------------------------------
  2902.   def all_close?
  2903.     close? && @choice_window.close? &&
  2904.     @number_window.close? && @item_window.close?
  2905.   end
  2906.   #--------------------------------------------------------------------------
  2907.   # ● 移出全部文字精灵
  2908.   #--------------------------------------------------------------------------
  2909.   def eagle_message_sprites_move_out
  2910.     while(!@eagle_chara_sprites.empty?)
  2911.       c = eagle_take_out_a_chara
  2912.       ensure_character_visible(c, true) # 不要聚焦当前文字的缓动动画,太慢
  2913.       c.move_out # 已经交由文字池进行后续更新释放
  2914.       if @eagle_force_close  # 如果强制关闭,则不等待移出了
  2915.       else
  2916.         win_params[:cwo].times { Fiber.yield }
  2917.         if @flag_need_change_wh || # 如果预定了宽高变化,则这里不需要再逐个变化了
  2918.            win_params[:cwo] == 0  # 如果根本没有逐个移出,也不需要动态变化宽高
  2919.         else
  2920.           eagle_recalc_charas_wh_when_out
  2921.         end
  2922.       end
  2923.     end
  2924.     @eagle_chara_sets.clear
  2925.   end
  2926.   #--------------------------------------------------------------------------
  2927.   # ● 取出一个文字精灵
  2928.   #--------------------------------------------------------------------------
  2929.   def eagle_take_out_a_chara
  2930.     case win_params[:cor]
  2931.     when 0, false; return @eagle_chara_sprites.shift
  2932.     when 1, true; return @eagle_chara_sprites.pop
  2933.     when 2;
  2934.       i = rand(@eagle_chara_sprites.size)
  2935.       return @eagle_chara_sprites.delete_at(i)
  2936.     end
  2937.   end
  2938.   #--------------------------------------------------------------------------
  2939.   # ● 取出一个文字精灵后,重新计算宽高
  2940.   #--------------------------------------------------------------------------
  2941.   def eagle_recalc_charas_wh_when_out
  2942.     rects = @eagle_chara_sprites.collect { |s| s.screen_rect }
  2943.     r = MESSAGE_EX.get_smallest_box(rects)
  2944.     @eagle_charas_w = r.width
  2945.     @eagle_charas_h = r.height
  2946.     eagle_set_wh({:ins => true})
  2947.   end
  2948.  
  2949.   #--------------------------------------------------------------------------
  2950.   # ● 设置对话框大小位置,并等待更新结束
  2951.   #--------------------------------------------------------------------------
  2952.   def eagle_set_wh(_p = {})
  2953.     eagle_before_set_xywh(_p)
  2954.     eagle_set_params_xywh(_p)
  2955.     eagle_apply_params_xywh(_p)
  2956.     wait_until_des_wh(_p)
  2957.     eagle_after_set_xywh(_p)
  2958.   end
  2959.   #--------------------------------------------------------------------------
  2960.   # ● 对话框位置大小更新前的处理
  2961.   #--------------------------------------------------------------------------
  2962.   def eagle_before_set_xywh(_p)
  2963.   end
  2964.   #--------------------------------------------------------------------------
  2965.   # ● 设置对话框xywh的参数Hash
  2966.   #--------------------------------------------------------------------------
  2967.   def eagle_set_params_xywh(_p = {})
  2968.     _p[:update] = [] # 将会进行更新的属性
  2969.     _p[:ins] = false if _p[:ins].nil? # 如果需要立刻更新完成,置为 true
  2970.     _p[:ins] = true if @background == 2 # 透明背景时直接更新完成
  2971.     _p[:open] = false if _p[:open].nil? # 如果目标是打开窗口,置为 true
  2972.     _p[:t] ||= 20 # 更新所需时间(帧)
  2973.  
  2974.     # 先计算目标宽高(该变量与其它参数均无关,只需要预绘制后的文字区域宽高)
  2975.     #_p[:w] 与 _p[:h] 为更新结束时的宽高,如果为 nil,将自动计算
  2976.     _p[:w_init] = self.width
  2977.     if _p[:w].nil?
  2978.       _p[:w]  = eagle_window_width
  2979.       _p[:w] += eagle_window_width_add(_p[:w])
  2980.     end
  2981.     _p[:w_d] = _p[:w] - _p[:w_init]
  2982.     _p[:update].push(:w) if _p[:w_d] != 0
  2983.  
  2984.     _p[:h_init] = self.height
  2985.     if _p[:h].nil?
  2986.       _p[:h]  = eagle_window_height
  2987.       _p[:h] += eagle_window_height_add(_p[:h])
  2988.     end
  2989.     _p[:h_d] = _p[:h] - _p[:h_init]
  2990.     _p[:update].push(:h) if _p[:h_d] != 0
  2991.  
  2992.     # 如果为打开/预定变更宽高,记录最终的宽高
  2993.     if _p[:open] || @flag_need_change_wh
  2994.       @eagle_win_des_w = _p[:w]
  2995.       @eagle_win_des_h = _p[:h]
  2996.     end
  2997.     # 需要先计算出目标宽高,再更新该设置,才能保证更新后的xy为真正的移动目标位置
  2998.     eagle_win_update
  2999.  
  3000.     #_p[:x] 与 _p[:y] 为更新结束时的位置,如果为 nil,且对话框未关闭,将自动计算
  3001.     if _p[:open] || @eagle_last_x.nil? || @eagle_last_y.nil?
  3002.       # 如果为打开,则已经直接移到了目的地,此处不再变更xy
  3003.       _p[:x] = nil
  3004.       _p[:y] = nil
  3005.     elsif self.openness == 255
  3006.       _p[:x_init] = @eagle_last_x
  3007.       _p[:y_init] = @eagle_last_y
  3008.       _p[:x] = self.x if _p[:x].nil?
  3009.       _p[:y] = self.y if _p[:y].nil?
  3010.     end
  3011.     if _p[:x]
  3012.       _p[:x_d] = _p[:x] - _p[:x_init]
  3013.       _p[:update].push(:x) if _p[:x_d] != 0
  3014.     end
  3015.     if _p[:y]
  3016.       _p[:y_d] = _p[:y] - _p[:y_init]
  3017.       _p[:update].push(:y) if _p[:y_d] != 0
  3018.     end
  3019.   end
  3020.   #--------------------------------------------------------------------------
  3021.   # ● 应用对话框xywh的参数Hash的预修改
  3022.   #--------------------------------------------------------------------------
  3023.   def eagle_apply_params_xywh(_p = {})
  3024.     if _p[:x_d] # 如果设置了移动,则覆盖移动增量来进行对话框的移动
  3025.       @eagle_move_x = - _p[:x_d]
  3026.     end
  3027.     if _p[:y_d]
  3028.       @eagle_move_y = - _p[:y_d]
  3029.     end
  3030.     if _p[:ins] # 处理立即完成宽高的更新
  3031.       @eagle_move_x = 0
  3032.       @eagle_move_y = 0
  3033.       self.width = _p[:w]
  3034.       self.height = _p[:h]
  3035.       _p[:update].clear
  3036.     end
  3037.   end
  3038.   #--------------------------------------------------------------------------
  3039.   # ● 更新对话框宽高直至完成
  3040.   #--------------------------------------------------------------------------
  3041.   def wait_until_des_wh(_p = {})
  3042.     return eagle_after_wh_change if _p[:update].empty?
  3043.     max_w = [_p[:w], _p[:w_init]].max
  3044.     max_h = [_p[:h], _p[:h_init]].max
  3045.     _i = 0; _t = _p[:t]
  3046.     _t = 0 if _t < 0
  3047.     while(true)
  3048.       break if self.openness == 0
  3049.       break if _i > _t
  3050.       per = _i * 1.0 / _t
  3051.       if _i == _t
  3052.         per = 1
  3053.       else
  3054.         f = :msg_xywh
  3055.         f = :msg_open if _p[:open]
  3056.         f = :msg_close if _p[:close]
  3057.         per = MESSAGE_EX.ease_value(f, per)
  3058.       end
  3059.       _p[:update].each do |sym|
  3060.         case sym
  3061.         when :x
  3062.           _x = _p[:x_init] + _p[:x_d] * per
  3063.           @eagle_move_x = (_x - _p[:x]).round
  3064.         when :y
  3065.           _y = _p[:y_init] + _p[:y_d] * per
  3066.           @eagle_move_y = (_y - _p[:y]).round
  3067.         when :w
  3068.           self.width = (_p[:w_init] + _p[:w_d] * per).round
  3069.         when :h
  3070.           self.height = (_p[:h_init] + _p[:h_d] * per).round
  3071.         end
  3072.       end
  3073.       eagle_after_wh_change
  3074.       update_back_sprite_zoom(max_w, max_h)
  3075.       Fiber.yield
  3076.       _i += 1
  3077.     end
  3078.   end
  3079.   #--------------------------------------------------------------------------
  3080.   # ● 在宽度高度变化后的处理
  3081.   # 此时 self.width 与 self.height 为实时的宽高,非最终完成时的宽高
  3082.   #--------------------------------------------------------------------------
  3083.   def eagle_after_wh_change
  3084.     eagle_recreate_back_bitmap(self.width, self.height)  # 生成新背景位图
  3085.     eagle_win_update  # 更新对话框位置
  3086.   end
  3087.   #--------------------------------------------------------------------------
  3088.   # ● 对话框进行位置大小更新后的处理
  3089.   #--------------------------------------------------------------------------
  3090.   def eagle_after_set_xywh(_p)
  3091.     @eagle_last_x = self.x  # 存储对话框的新位置,之后将作为移动前的初始值
  3092.     @eagle_last_y = self.y
  3093.   end
  3094.   #--------------------------------------------------------------------------
  3095.   # ● 获取窗口的初始宽度高度
  3096.   #--------------------------------------------------------------------------
  3097.   def window_width;   Graphics.width;     end
  3098.   def window_height;  fitting_height(4);  end
  3099.   #--------------------------------------------------------------------------
  3100.   # ● 获取窗口的实际宽度高度
  3101.   #--------------------------------------------------------------------------
  3102.   def eagle_window_width
  3103.     w = eagle_window_charas_width
  3104.     if w
  3105.       w = [w, eagle_name_width].max  # 确保姓名框的嵌入
  3106.       w += eagle_face_width          # 确保脸图有地方显示
  3107.       w += standard_padding * 2      # 增加边框
  3108.       return w
  3109.     end
  3110.     return window_width
  3111.   end
  3112.   def eagle_window_height
  3113.     h = eagle_window_charas_height
  3114.     if h
  3115.       h += eagle_name_height         # 确保姓名框的嵌入
  3116.       h = [h, eagle_face_height].max if eagle_face_in_window? # 确保脸图完整显示
  3117.       h += standard_padding * 2      # 增加边框
  3118.       return h
  3119.     end
  3120.     return window_height
  3121.   end
  3122.   #--------------------------------------------------------------------------
  3123.   # ● 获取窗口的文字的宽度高度
  3124.   #--------------------------------------------------------------------------
  3125.   def eagle_window_charas_width
  3126.     return pop_params[:w] if game_message.pop? && pop_params[:w] > 0
  3127.     return win_params[:w] if win_params[:w] > 0
  3128.     w = nil
  3129.     w = @eagle_charas_w       if eagle_dynamic_w?
  3130.     w = @eagle_charas_w_final if eagle_dyn_fit_w?
  3131.     if w
  3132.       w = win_params[:wmin] if win_params[:wmin] > 0 && w < win_params[:wmin]
  3133.       w = win_params[:wmax] if win_params[:wmax] > 0 && w > win_params[:wmax]
  3134.     end
  3135.     return w
  3136.   end
  3137.   def eagle_window_charas_height
  3138.     if game_message.pop? && pop_params[:h] > 0
  3139.       return eagle_check_param_h(pop_params[:h])
  3140.     end
  3141.     return eagle_check_param_h(win_params[:h]) if win_params[:h] > 0
  3142.     h = nil
  3143.     h = [@eagle_charas_h, line_height].max if eagle_dynamic_h?
  3144.     h = @eagle_charas_h_final if eagle_dyn_fit_h?
  3145.     if h
  3146.       h = win_params[:hmin] if win_params[:hmin] > 0 && h < win_params[:hmin]
  3147.       h = win_params[:hmax] if win_params[:hmax] > 0 && h > win_params[:hmax]
  3148.     end
  3149.     return h
  3150.   end
  3151.   #--------------------------------------------------------------------------
  3152.   # ● 检查内容高度参数
  3153.   #  如果h小于行高,则判定其为行数
  3154.   #--------------------------------------------------------------------------
  3155.   def eagle_check_param_h(h)
  3156.     return 0 if h <= 0
  3157.     h = line_height * h + win_params[:ld] * (h - 1) if h < line_height
  3158.     return h
  3159.   end
  3160.   #--------------------------------------------------------------------------
  3161.   # ● 直接指定宽度高度?
  3162.   #--------------------------------------------------------------------------
  3163.   def eagle_fix_w?
  3164.     return pop_params[:w] > 0 if game_message.pop?
  3165.     return win_params[:w] > 0
  3166.   end
  3167.   def eagle_fix_h?
  3168.     return pop_params[:h] > 0 if game_message.pop?
  3169.     return win_params[:h] > 0
  3170.   end
  3171.   #--------------------------------------------------------------------------
  3172.   # ● 动态调整宽度高度?
  3173.   #--------------------------------------------------------------------------
  3174.   def eagle_dynamic_w?
  3175.     game_message.pop? ? pop_params[:dw] : win_params[:dw]
  3176.   end
  3177.   def eagle_dynamic_h?
  3178.     game_message.pop? ? pop_params[:dh] : win_params[:dh]
  3179.   end
  3180.   #--------------------------------------------------------------------------
  3181.   # ● 预计算完整文字区域的宽度高度?
  3182.   #--------------------------------------------------------------------------
  3183.   def eagle_dyn_fit_w?
  3184.     game_message.pop? ? pop_params[:fw] : win_params[:fw]
  3185.   end
  3186.   def eagle_dyn_fit_h?
  3187.     game_message.pop? ? pop_params[:fh] : win_params[:fh]
  3188.   end
  3189.   #--------------------------------------------------------------------------
  3190.   # ● 可由子窗口增加对话框的宽度高度?
  3191.   #--------------------------------------------------------------------------
  3192.   def eagle_add_w_by_child_window?
  3193.     return false if eagle_fix_w?
  3194.     return true  if eagle_dynamic_w? || eagle_dyn_fit_w?
  3195.     return false
  3196.   end
  3197.   def eagle_add_h_by_child_window?
  3198.     return false if eagle_fix_h?
  3199.     return true  if eagle_dynamic_h? || eagle_dyn_fit_h?
  3200.     return false
  3201.   end
  3202.   #--------------------------------------------------------------------------
  3203.   # ● 额外增加的窗口宽度高度
  3204.   #--------------------------------------------------------------------------
  3205.   def eagle_window_width_add(cur_width)
  3206.     eagle_window_w_empty + game_message.child_window_w_des
  3207.   end
  3208.   def eagle_window_height_add(cur_height)
  3209.     eagle_window_h_empty + game_message.child_window_h_des
  3210.   end
  3211.   #--------------------------------------------------------------------------
  3212.   # ● 窗口内容中,无法被用于文本绘制的宽高
  3213.   #--------------------------------------------------------------------------
  3214.   def eagle_window_w_empty
  3215.     win_params[:cdx] + @eagle_sprite_pause_width_add + win_params[:cdw]
  3216.   end
  3217.   def eagle_window_h_empty
  3218.     win_params[:cdy] + win_params[:cdh]
  3219.   end
  3220.  
  3221.   #--------------------------------------------------------------------------
  3222.   # ● 更新win参数组(初始化/一页绘制完成时调用)
  3223.   #--------------------------------------------------------------------------
  3224.   def eagle_win_update
  3225.     return eagle_pop_update if game_message.pop? && @eagle_pop_obj
  3226.     eagle_change_windowskin
  3227.     self.x = win_params[:x] || default_init_x
  3228.     self.y = win_params[:y] || default_init_y
  3229.     MESSAGE_EX.reset_xy_dorigin(self, nil, win_params[:do]) if win_params[:do] < 0
  3230.     MESSAGE_EX.reset_xy_origin(self, win_params[:o])
  3231.     eagle_set_xy_ex
  3232.     self.x = self.x + win_params[:dx] + @eagle_move_x
  3233.     self.y = self.y + win_params[:dy] + @eagle_move_y
  3234.     eagle_fix_position if win_params[:fix]
  3235.     eagle_after_update_xy
  3236.   end
  3237.   #--------------------------------------------------------------------------
  3238.   # ● 获取对话框的初始位置
  3239.   #--------------------------------------------------------------------------
  3240.   def default_init_x;  0;  end
  3241.   def default_init_y; (@position*(Graphics.height-@eagle_win_des_h)/2); end
  3242.   #--------------------------------------------------------------------------
  3243.   # ● 重定义对话框的位置(此时已经处理完了xy或do的初始指定位置)(扩展用)
  3244.   #--------------------------------------------------------------------------
  3245.   def eagle_set_xy_ex
  3246.   end
  3247.   #--------------------------------------------------------------------------
  3248.   # ● 修正位置(确保对话框完整显示)
  3249.   #--------------------------------------------------------------------------
  3250.   def eagle_fix_position
  3251.     self.x = [[self.x, 0].max, Graphics.width - self.width].min
  3252.     self.y = [[self.y, 0].max, Graphics.height - self.height].min
  3253.   end
  3254.   #--------------------------------------------------------------------------
  3255.   # ● 更新xy后的操作
  3256.   #--------------------------------------------------------------------------
  3257.   def eagle_after_update_xy
  3258.     eagle_set_charas_viewport
  3259.     eagle_name_update if game_message.name?
  3260.     if game_message.pop? && pop_params[:with_tag]
  3261.       eagle_pop_tag_fix_position  # 可能修改了对话框位置,检查下tag要不要显示
  3262.     end
  3263.   end
  3264.   #--------------------------------------------------------------------------
  3265.   # ● 设置文字显示区域的矩形(屏幕坐标)
  3266.   #--------------------------------------------------------------------------
  3267.   def eagle_set_charas_viewport
  3268.     @eagle_chara_viewport.rect.set(eagle_charas_x0, eagle_charas_y0,
  3269.       eagle_charas_max_w + eagle_window_w_empty,
  3270.       eagle_charas_max_h + eagle_window_h_empty)
  3271.   end
  3272.   #--------------------------------------------------------------------------
  3273.   # ● 更新pop参数组
  3274.   #--------------------------------------------------------------------------
  3275.   def eagle_pop_update
  3276.     eagle_change_windowskin(pop_params[:skin])
  3277.     eagle_pop_init_xy
  3278.     o = pop_params[:o] # 设置对话框的显示原点
  3279.     o ||= 10 - pop_params[:do]  # 显示原点恰好与绑定对象的位置相反
  3280.     MESSAGE_EX.reset_xy_origin(self, o)
  3281.     # 将对话框移动到绑定对象的对应方向上,并加上偏移量
  3282.     case pop_params[:do]
  3283.     when 1,4,7; self.x -= (pop_params[:chara_w] / 2 + pop_params[:d])
  3284.     when 3,6,9; self.x += (pop_params[:chara_w] / 2 + pop_params[:d])
  3285.     end
  3286.     case pop_params[:do]
  3287.     when 1,2,3; self.y += (pop_params[:d])
  3288.     when 4,5,6; self.y -= (pop_params[:chara_h] / 2)
  3289.     when 7,8,9; self.y -= (pop_params[:chara_h] + pop_params[:d])
  3290.     end
  3291.     self.x += @eagle_move_x  # 坐标的运动偏移量
  3292.     self.y += @eagle_move_y
  3293.     eagle_pop_tag_update  # 更新pop的tag的位置
  3294.     self.x += pop_params[:dx]  # 坐标的补足偏移量
  3295.     self.y += pop_params[:dy]
  3296.     eagle_fix_position if pop_params[:fix]
  3297.     eagle_after_update_xy
  3298.   end
  3299.   #--------------------------------------------------------------------------
  3300.   # ● 更新pop的初始位置
  3301.   #--------------------------------------------------------------------------
  3302.   def eagle_pop_init_xy
  3303.     # 对话框左上角定位到绑定对象位图的对应o位置
  3304.     case pop_params[:type]
  3305.     when :map_chara
  3306.       # 如果对象使用的是行走图,则为Game_Chacter(行走图底部中心为显示原点)
  3307.       self.x = @eagle_pop_obj.screen_x
  3308.       self.y = @eagle_pop_obj.screen_y
  3309.     when :battle_sprite
  3310.       # 如果对象为战斗者精灵,则为Sprite_Battler(底部中心为显示原点)
  3311.       self.x = @eagle_pop_obj.x
  3312.       self.y = @eagle_pop_obj.y
  3313.     when :map_grid
  3314.       # 如果为地图格子,则格子底部中心为显示原点
  3315.       self.x = $game_map.adjust_x(@eagle_pop_obj[0]) * 32 + 16
  3316.       self.y = $game_map.adjust_y(@eagle_pop_obj[1]) * 32 + 32
  3317.     end
  3318.   end
  3319.   #--------------------------------------------------------------------------
  3320.   # ● 更新pop的tag
  3321.   #--------------------------------------------------------------------------
  3322.   def eagle_pop_tag_update
  3323.     return if !pop_params[:with_tag]
  3324.     i = 10 - pop_params[:do] # tag的显示帧恰好与pop对话框的do值相对
  3325.     # tag的显示原点,是pop对话框的do,即目标物体的九宫格位置
  3326.     o = pop_params[:do]
  3327.     #  但注意,需要调整到 2468 的位置
  3328.     o = 2 if o == 1 || o == 3
  3329.     o = 8 if o == 7 || o == 9
  3330.     _do = pop_params[:o] # 对话框的显示原点是tag的显示位置
  3331.     _do ||= 10 - pop_params[:do]
  3332.     MESSAGE_EX.set_windowtag(self, @eagle_sprite_pop_tag, i, o, _do)
  3333.     case i # 坐标距离事件格子中心的偏移量
  3334.     when 1,4,7; @eagle_sprite_pop_tag.x -= pop_params[:td]
  3335.     when 3,6,9; @eagle_sprite_pop_tag.x += pop_params[:td]
  3336.     end
  3337.     case i
  3338.     when 1,2,3; @eagle_sprite_pop_tag.y -= pop_params[:td]
  3339.     when 7,8,9; @eagle_sprite_pop_tag.y += pop_params[:td]
  3340.     end
  3341.   end
  3342.   #--------------------------------------------------------------------------
  3343.   # ● 修正pop的tag的位置
  3344.   #--------------------------------------------------------------------------
  3345.   def eagle_pop_tag_fix_position
  3346.     # 若tag因为对话框的fix position而位于对话框内,则隐藏
  3347.     s = @eagle_sprite_pop_tag
  3348.     return if !pop_params[:with_tag]
  3349.     s.visible = true
  3350.     d = pop_params[:td]
  3351.     rect1 = Rect.new(s.x+d, s.y+d, s.width-2*d, s.height-2*d)
  3352.     rect2 = Rect.new(self.x, self.y, self.width, self.height)
  3353.     if MESSAGE_EX.rect_collide_rect?(rect1, rect2)
  3354.       s.visible = false
  3355.     end
  3356.   end
  3357.   #--------------------------------------------------------------------------
  3358.   # ● 更新name参数组(随win/pop参数组更新)
  3359.   #--------------------------------------------------------------------------
  3360.   def eagle_name_update
  3361.     if name_params[:do] == 0  # 嵌入
  3362.       # 考虑到姓名框自己也有边框,此处 standard_padding 一加一减抵消了
  3363.       @eagle_window_name.x = self.x +  \
  3364.         @eagle_window_name.rect_real.x + eagle_face_left_width
  3365.       @eagle_window_name.y = self.y +  \
  3366.         @eagle_window_name.rect_real.y
  3367.     else
  3368.       MESSAGE_EX.reset_xy_dorigin(@eagle_window_name, self, name_params[:do])
  3369.       MESSAGE_EX.reset_xy_origin(@eagle_window_name, name_params[:o])
  3370.       # 若姓名框遮挡了脸图,则移动到不遮挡的地方
  3371.       if game_message.no_name_overlap_face && eagle_face_width > 0
  3372.         lx = self.x + eagle_face_left_width
  3373.         rx = self.x + self.width - eagle_face_right_width
  3374.         w = @eagle_window_name.width
  3375.         @eagle_window_name.x = lx if @eagle_window_name.x < lx
  3376.         @eagle_window_name.x = rx-w if @eagle_window_name.x+w > rx
  3377.       end
  3378.     end
  3379.     @eagle_window_name.x += name_params[:dx]  # 坐标的补足偏移量
  3380.     @eagle_window_name.y += name_params[:dy]
  3381.     @eagle_window_name.update_with_msg
  3382.   end
  3383.  
  3384.   #--------------------------------------------------------------------------
  3385.   # ● 变更窗口皮肤
  3386.   #--------------------------------------------------------------------------
  3387.   def eagle_change_windowskin(index = nil)
  3388.     index = win_params[:skin] if index.nil?
  3389.     eagle_set_pop_tag_by_windowskin(index)
  3390.     return if @win_skin_draw == index
  3391.     @win_skin_draw = index
  3392.     self.windowskin = MESSAGE_EX.windowskin(index)
  3393.     change_color(text_color(font_params[:c]))
  3394.   end
  3395.   #--------------------------------------------------------------------------
  3396.   # ● 获取当前窗口皮肤的序号
  3397.   #--------------------------------------------------------------------------
  3398.   def get_cur_windowskin_index(index = nil)
  3399.     return index if index
  3400.     return pop_params[:skin] if game_message.pop? && !pop_params[:skin].nil?
  3401.     return win_params[:skin]
  3402.   end
  3403.   #--------------------------------------------------------------------------
  3404.   # ● 依据窗口皮肤设置tag序号
  3405.   #--------------------------------------------------------------------------
  3406.   def eagle_set_pop_tag_by_windowskin(index = nil)
  3407.     tag_id = MESSAGE_EX::WINDOWSKIN_TO_WINDOWTAG[index]
  3408.     return if tag_id.nil?
  3409.     eagle_reset_pop_tag_bitmap(tag_id)
  3410.   end
  3411.  
  3412.   #--------------------------------------------------------------------------
  3413.   # ● 重新生成背景位图
  3414.   #--------------------------------------------------------------------------
  3415.   def eagle_recreate_back_bitmap(w = self.width, h = self.height)
  3416.     case @background
  3417.     when 1 # 暗色背景
  3418.       if @back_bitmap && @back_bitmap.width == w && @back_bitmap.height == h
  3419.       else # 重绘
  3420.         @back_bitmap.dispose if @back_bitmap
  3421.         @back_bitmap = Bitmap.new(w, h)
  3422.         rect1 = Rect.new(0, 0, w, 12)
  3423.         rect2 = Rect.new(0, 12, w, h - 24)
  3424.         rect3 = Rect.new(0, h - 12, w, 12)
  3425.         @back_bitmap.gradient_fill_rect(rect1, back_color2, back_color1, true)
  3426.         @back_bitmap.fill_rect(rect2, back_color1)
  3427.         @back_bitmap.gradient_fill_rect(rect3, back_color1, back_color2, true)
  3428.       end
  3429.       @back_sprite.bitmap = @back_bitmap
  3430.       update_back_sprite
  3431.       @back_sprite.visible = true
  3432.       self.opacity = 0
  3433.     when 2 # 透明背景
  3434.       @back_sprite.visible = false
  3435.       self.opacity = 0
  3436.     else # 普通
  3437.       return if win_params[:bg] && eagle_draw_bg_pic(w, h)
  3438.       @back_sprite.visible = false
  3439.       self.opacity = 255
  3440.     end
  3441.   end
  3442.   #--------------------------------------------------------------------------
  3443.   # ● 获取暗色背景的背景色
  3444.   #--------------------------------------------------------------------------
  3445.   def back_color1; Color.new(0, 0, 0, 160); end
  3446.   def back_color2; Color.new(0, 0, 0,   0); end
  3447.   #--------------------------------------------------------------------------
  3448.   # ● 绘制背景图片
  3449.   #--------------------------------------------------------------------------
  3450.   def eagle_draw_bg_pic(w, h)
  3451.     @back_sprite.visible = true
  3452.     self.opacity = 0
  3453.     _bitmap = MESSAGE_EX.windowbg(win_params[:bg], w, h)
  3454.     if _bitmap != nil
  3455.       @back_sprite.bitmap = _bitmap
  3456.       return true
  3457.     end
  3458.     return false
  3459.   end
  3460.   #--------------------------------------------------------------------------
  3461.   # ● 更新背景精灵
  3462.   #--------------------------------------------------------------------------
  3463.   def update_back_sprite
  3464.     _o = win_params[:bgo]
  3465.     _o = win_params[:o] if @background == 1  # 暗色背景下,与对话框的原点一致
  3466.     MESSAGE_EX.reset_xy_dorigin(@back_sprite, self, _o)
  3467.     MESSAGE_EX.reset_sprite_oxy(@back_sprite, _o)
  3468.     @back_sprite.update
  3469.   end
  3470.   #--------------------------------------------------------------------------
  3471.   # ● 更新背景精灵的缩放
  3472.   #--------------------------------------------------------------------------
  3473.   def update_back_sprite_zoom(max_w = nil, max_h = nil)
  3474.     if @background != 0  # 正常背景下,使用了图片背景,才进行缩放
  3475.       @back_sprite.zoom_x = @back_sprite.zoom_y = 1
  3476.       return
  3477.     end
  3478.     if max_w == nil
  3479.       @back_sprite.zoom_x = 1
  3480.     else
  3481.       @back_sprite.zoom_x = self.width * 1.0 / max_w
  3482.     end
  3483.     if max_h == nil
  3484.       @back_sprite.zoom_y = 1
  3485.     else
  3486.       @back_sprite.zoom_y = self.height * 1.0 / max_h
  3487.     end
  3488.   end
  3489.   #--------------------------------------------------------------------------
  3490.   # ● 更新背景精灵的不透明度
  3491.   #--------------------------------------------------------------------------
  3492.   def update_back_sprite_opa(opa); @back_sprite.opacity = opa; end
  3493.  
  3494.   #--------------------------------------------------------------------------
  3495.   # ● 处理纤程的主逻辑
  3496.   #--------------------------------------------------------------------------
  3497.   def fiber_main
  3498.     game_message.visible = true
  3499.     eagle_process_before_start
  3500.     loop do
  3501.       eagle_process_before_draw
  3502.       process_all_text
  3503.       process_input
  3504.       eagle_process_before_close
  3505.       Fiber.yield
  3506.       break unless text_continue?
  3507.       eagle_process_after_check_continue
  3508.     end
  3509.     close_and_wait if !@flag_next
  3510.     game_message.visible = false
  3511.     @fiber = nil
  3512.   end
  3513.   #--------------------------------------------------------------------------
  3514.   # ● 首次开启对话框时的处理
  3515.   #--------------------------------------------------------------------------
  3516.   def eagle_process_before_start
  3517.     @background = game_message.background
  3518.     @position   = game_message.position
  3519.   end
  3520.   #--------------------------------------------------------------------------
  3521.   # ● 绘制全部文本前
  3522.   #--------------------------------------------------------------------------
  3523.   def eagle_process_before_draw
  3524.     @flag_temp_env = game_message.env  # 保存处理文本前的环境名(用于temp)
  3525.     game_message.save_env(:eagle_temp) # 保存处理文本前的环境(用于temp)
  3526.     game_message.active = true   # 对话框开始处理文字,该flag置为true用于判定
  3527.   end
  3528.   #--------------------------------------------------------------------------
  3529.   # ● 关闭前
  3530.   #--------------------------------------------------------------------------
  3531.   def eagle_process_before_close
  3532.     game_message.clear
  3533.     @gold_window.close if @gold_window
  3534.     game_message.active = false   # 对话框不再显示了,将该flag置为false
  3535.   end
  3536.   #--------------------------------------------------------------------------
  3537.   # ● 判定文字是否继续显示(覆盖)
  3538.   #--------------------------------------------------------------------------
  3539.   def text_continue?
  3540.     return false if @flag_need_close
  3541.     return game_message.has_text? && !settings_changed?
  3542.   end
  3543.   #--------------------------------------------------------------------------
  3544.   # ● 判定对话框设置是否被更改(覆盖)
  3545.   #  此时 $game_message 中存储了下一条指令的对话信息
  3546.   #  若返回 false,则会保留当前对话框不关闭,继续显示下一个指令的文本
  3547.   #--------------------------------------------------------------------------
  3548.   def settings_changed?
  3549.     @background != game_message.background #|| @position != game_message.position
  3550.   end
  3551.   #--------------------------------------------------------------------------
  3552.   # ● 当前对话框继续显示,一些变量重置的处理
  3553.   #--------------------------------------------------------------------------
  3554.   def eagle_process_after_check_continue
  3555.     if @flag_hold  # 保留当前对话框时
  3556.       # 如果当前对话框还要继续显示,则重新打开,确保移动的动画从当前位置开始
  3557.       self.openness = 255
  3558.       @flag_need_open = false
  3559.     end
  3560.     eagle_message_reset_continue
  3561.     @flag_need_change_wh = true  # 由于没有打开关闭,需要执行一次更新宽高
  3562.   end
  3563.  
  3564.   #--------------------------------------------------------------------------
  3565.   # ● 获取即将绘制的所有文本内容
  3566.   #--------------------------------------------------------------------------
  3567.   def eagle_all_text
  3568.     text = game_message.all_text
  3569.     if !game_message.escape_strings.empty? # 如果存在待处理的转义符串,加到开头
  3570.       text = game_message.escape_strings.inject("") { |sum, s| sum = sum + s } + text
  3571.       game_message.escape_strings.clear
  3572.     end
  3573.     text = convert_escape_characters(text)
  3574.     text
  3575.   end
  3576.   #--------------------------------------------------------------------------
  3577.   # ● 进行控制符的事前变换
  3578.   #    在实际绘制前、将控制符替换为实际的内容。
  3579.   #    为了减少歧异,文字「\」会被首先替换为转义符(\e)。
  3580.   #--------------------------------------------------------------------------
  3581.   def convert_escape_characters(text)
  3582.     result = text.to_s.clone
  3583.     result = eagle_process_conv(result)
  3584.     result = eagle_process_rb(result)
  3585.     result = super(result) # 此处将 \\ 替换成了 \e
  3586.     result = eagle_process_extra(result)
  3587.     result
  3588.   end
  3589.   #--------------------------------------------------------------------------
  3590.   # ● 替换转义符(此时依旧是 \\ 开头的转义符)
  3591.   #--------------------------------------------------------------------------
  3592.   def eagle_process_conv(text)
  3593.     text.gsub!(/\\(conv|M)\[(.*?)\]/i) { MESSAGE_EX.get_conv($2) }
  3594.     text
  3595.   end
  3596.   #--------------------------------------------------------------------------
  3597.   # ● 处理脚本转义符(此时依旧是 \\ 开头的转义符)
  3598.   #--------------------------------------------------------------------------
  3599.   def eagle_process_rb(text)
  3600.     s = $game_switches; v = $game_variables
  3601.     event = $game_map.events[game_message.event_id] rescue nil
  3602.     text.gsub!(/\\RB\{(.*?)\}/i) { eval($1).to_s }
  3603.     text
  3604.   end
  3605.   #--------------------------------------------------------------------------
  3606.   # ● 处理其它转义符(此时是 \e 开头的转义符)
  3607.   #--------------------------------------------------------------------------
  3608.   def eagle_process_extra(text)
  3609.     text.gsub!(/\eINFO\[(\w)[ ,]*(\d+)[ ,]*(\d+)?\]/i) {
  3610.       MESSAGE_EX.get_data_info($1, $2.to_i, $3 || '0')
  3611.     }
  3612.     text.gsub!(/\eNL/i) { "\n" } # 换行转义符
  3613.     text
  3614.   end
  3615.  
  3616.   #--------------------------------------------------------------------------
  3617.   # ● (覆盖)处理所有文本内容
  3618.   #--------------------------------------------------------------------------
  3619.   def process_all_text
  3620.     return if !game_message.has_text?
  3621.     text = eagle_all_text; pos = {}
  3622.     new_page(text, pos)
  3623.     if func_params[:para] && !input_pause?
  3624.       @fiber_para = Fiber.new { process_all_text_para(text, pos);
  3625.         @fiber_para = nil }
  3626.       return
  3627.     end
  3628.     process_all_text_para(text, pos)
  3629.   end
  3630.   #--------------------------------------------------------------------------
  3631.   # ● 处理所有文本内容(并行用)
  3632.   #--------------------------------------------------------------------------
  3633.   def process_all_text_para(text, pos)
  3634.     if @flag_need_open # 打开窗口
  3635.       open_and_wait
  3636.     elsif @flag_need_change_wh # 如果需要更新宽高
  3637.       eagle_set_wh
  3638.       @flag_need_change_wh = false
  3639.     end
  3640.     loop do # 循环绘制每个文字
  3641.       break if text.empty?
  3642.       process_character(text.slice!(0, 1), text, pos)
  3643.       break @pause_skip = true if @eagle_force_close
  3644.     end
  3645.     eagle_process_draw_update if !@eagle_chara_sprites.empty?
  3646.   end
  3647.   #--------------------------------------------------------------------------
  3648.   # ● 强制中断绘制全部文本
  3649.   #--------------------------------------------------------------------------
  3650.   def force_close
  3651.     @eagle_force_close = true  # 若还在绘制,则直接结束绘制并跳过最后的等待按键
  3652.     @eagle_auto_continue_c = 0 # 若进入了按键等待,则将计数置0,并依靠auto跳过按键
  3653.   end
  3654.   #--------------------------------------------------------------------------
  3655.   # ● 翻页处理(删去了翻页功能)
  3656.   #--------------------------------------------------------------------------
  3657.   def new_page(text, pos)
  3658.     game_message.reset_child_window_wh_add  # 重置子窗口嵌入时占据的宽高
  3659.     @eagle_force_close = false  # 重置强制关闭
  3660.     pos[:x] = 0; pos[:y] = 0    # 重置pos参数
  3661.     pos[:new_x] = 0; pos[:height] = line_height
  3662.  
  3663.     if @flag_next  # 旧页面不清空,继续绘制
  3664.       pos[:y] = @eagle_charas_h_final + win_params[:ld]  # 不要忘记加个行间距
  3665.       @flag_need_change_wh = true  # 如果是旧页面继续绘制,则需要更新宽高
  3666.       eagle_after_set_xywh({})  # 重置记录的当前xy,作为窗口移动的初始位置
  3667.     end
  3668.  
  3669.     reset_font_settings
  3670.     eagle_check_pre_settings(text)  # 处理预先内容(脸图、姓名等)
  3671.     # 存储实际绘制的文本,预先转义符已删去(扩展用,获取显示的对话文本)
  3672.     game_message.eagle_text = text.clone
  3673.     eagle_apply_params_changes  # 执行预定的转义符修改
  3674.     clear_flags
  3675.     pre_calc_charas_wh(text, pos)  # 预绘制,计算最终宽高
  3676.     clear_flags  # 重置绘制会用到的变量
  3677.  
  3678.     # 打开窗口前执行位于文本开头的转义符,确保pop等修改对话框位置
  3679.     loop do
  3680.       break if text[0] == nil or text[0] != "\e"
  3681.       text[0] = ''
  3682.       process_escape_character(obtain_escape_code(text), text, pos)
  3683.     end
  3684.   end
  3685.   #--------------------------------------------------------------------------
  3686.   # ● 清除标志(此处放置每次绘制前需要清空的数据)
  3687.   #--------------------------------------------------------------------------
  3688.   def clear_flags
  3689.     @show_fast = false          # 快进的标志
  3690.     @line_show_fast = false     # 行单位快进的标志
  3691.     @pause_skip = false         # “不等待输入”的标志
  3692.     pop_params[:type] = nil     # pop绑定对象的类型
  3693.   end
  3694.   #--------------------------------------------------------------------------
  3695.   # ● 应用预定的转义符更新
  3696.   #--------------------------------------------------------------------------
  3697.   def eagle_apply_params_changes
  3698.     game_message.params_need_apply.each do |sym|
  3699.       m_c = ("eagle_text_control_#{sym}").to_sym
  3700.       method(m_c).call("") if respond_to?(m_c)
  3701.     end
  3702.     game_message.clear_applys
  3703.   end
  3704.   #--------------------------------------------------------------------------
  3705.   # ● 预先绘制一次,获取文字区域绘制完成时的宽高
  3706.   #--------------------------------------------------------------------------
  3707.   def pre_calc_charas_wh(text, pos)
  3708.     text_ = text.clone; pos_ = pos.clone
  3709.     @flag_draw = false  # 不进行实际绘制
  3710.     game_message.save_env(:pre_draw)  # 保存预绘制前的环境
  3711.     last_c_w = @eagle_charas_w  # 保存预绘制前的文字区域宽高
  3712.     last_c_h = @eagle_charas_h
  3713.     @eagle_charas_w = @eagle_charas_h = 0
  3714.     process_character(text_.slice!(0, 1), text_, pos_) until text_.empty?
  3715.     @eagle_charas_w_final = [@eagle_charas_w, last_c_w].max # 文字绘制后的宽高
  3716.     @eagle_charas_h_final = @eagle_charas_h
  3717.     before_input_pause unless @pause_skip  # 此处追加对pause精灵占用宽度的处理
  3718.     @eagle_charas_w = last_c_w
  3719.     @eagle_charas_h = last_c_h  # 复原当前文字区域宽高
  3720.     self.ox = self.oy = 0
  3721.     game_message.load_env(:pre_draw)  # 复原转义符环境
  3722.     game_message.clear_applys
  3723.     @flag_draw = true
  3724.   end
  3725.  
  3726.   #--------------------------------------------------------------------------
  3727.   # ● 文字显示区域的左上角位置(屏幕坐标系)
  3728.   #--------------------------------------------------------------------------
  3729.   def eagle_charas_x0
  3730.     self.x + standard_padding + eagle_face_left_width + win_params[:cdx]
  3731.   end
  3732.   def eagle_charas_y0
  3733.     self.y + standard_padding + eagle_name_height + win_params[:cdy]
  3734.   end
  3735.   #--------------------------------------------------------------------------
  3736.   # ● 计算文字显示区域的宽度和高度
  3737.   #--------------------------------------------------------------------------
  3738.   def eagle_charas_max_w
  3739.     self.width - standard_padding*2 - eagle_face_width - eagle_window_w_empty
  3740.   end
  3741.   def eagle_charas_max_h
  3742.     self.height - standard_padding*2 - eagle_name_height - eagle_window_h_empty
  3743.   end
  3744.   #--------------------------------------------------------------------------
  3745.   # ● 文字显示区域的显示原点
  3746.   #--------------------------------------------------------------------------
  3747.   def eagle_charas_ox; self.ox; end
  3748.   def eagle_charas_oy; self.oy; end
  3749.   #--------------------------------------------------------------------------
  3750.   # ● 更新正在移入移出文字的显示区域的显示原点
  3751.   #--------------------------------------------------------------------------
  3752.   def update_moving_charas_oxy
  3753.     @eagle_chara_sprites.each { |c|
  3754.       c.reset_window_oxy(self.ox, self.oy) if c.move_updating?
  3755.     }
  3756.   end
  3757.   #--------------------------------------------------------------------------
  3758.   # ● 重置文字显示区域
  3759.   #--------------------------------------------------------------------------
  3760.   def eagle_reset_charas_oxy
  3761.     # 重置初始区域
  3762.     self.ox = self.oy = 0
  3763.     # 重置显示区域
  3764.     @eagle_chara_viewport.rect.set(0,0,Graphics.width,Graphics.height)
  3765.     # 重置文字宽高
  3766.     @eagle_charas_w = @eagle_charas_h = 0
  3767.     @eagle_charas_w_final = @eagle_charas_h_final = 0
  3768.   end
  3769.   #--------------------------------------------------------------------------
  3770.   # ● 重新生成适合全部文字的位图
  3771.   #--------------------------------------------------------------------------
  3772.   def recreate_contents_for_charas
  3773.     w = @eagle_charas_w + eagle_window_w_empty
  3774.     h = @eagle_charas_h + eagle_window_h_empty
  3775.     w = 1 if w == 0
  3776.     h = 1 if h == 0
  3777.     f = self.contents.font.dup
  3778.     self.contents.dispose if self.contents
  3779.     self.contents = Bitmap.new(w, h)
  3780.     self.contents.font = f
  3781.   end
  3782.   #--------------------------------------------------------------------------
  3783.   # ● (覆盖)普通文字的处理
  3784.   #--------------------------------------------------------------------------
  3785.   def process_normal_character(c, pos)
  3786.     c_rect = text_size(c); c_w = c_rect.width; c_h = c_rect.height
  3787.     eagle_auto_new_line(c_w, pos)
  3788.     if @flag_draw
  3789.       s = eagle_new_chara_sprite(pos[:x], pos[:y], c_w, c_h)
  3790.       s.eagle_font.draw(s.bitmap, 0, 0, c_w, c_h, c, 0)
  3791.     end
  3792.     eagle_process_draw_end(c_w, c_h, pos)
  3793.   end
  3794.   #--------------------------------------------------------------------------
  3795.   # ● (覆盖)处理控制符指定的图标绘制
  3796.   #--------------------------------------------------------------------------
  3797.   def process_draw_icon(icon_index, pos)
  3798.     eagle_auto_new_line(24, pos)
  3799.     if @flag_draw
  3800.       s = eagle_new_chara_sprite(pos[:x], pos[:y], 24, 24)
  3801.       s.eagle_font.draw_icon(s.bitmap, 0, 0, icon_index)
  3802.     end
  3803.     eagle_process_draw_end(24, 24, pos)
  3804.   end
  3805.   #--------------------------------------------------------------------------
  3806.   # ● 处理控制符指定的图片绘制
  3807.   #--------------------------------------------------------------------------
  3808.   def process_draw_pic(text, pos)
  3809.     param = text.slice!(/^\[.*?\]/)[1..-2]
  3810.     params = param.split('|') # [filename, param_str]
  3811.     begin
  3812.       _bitmap = Cache.picture(MESSAGE_EX.get_pic_file(params[0]))
  3813.     rescue
  3814.       p "【对话框扩展】未找到\\pic所需的Graphics/Pictures/#{params[0]}图片!"
  3815.       return
  3816.     end
  3817.     h = {}
  3818.     parse_param(h, params[1], :opa) if params[1]
  3819.     h[:w] ||= _bitmap.width
  3820.     h[:h] ||= _bitmap.height
  3821.     h[:opa] ||= 255
  3822.     eagle_auto_new_line(h[:w], pos)
  3823.     if @flag_draw
  3824.       s = eagle_new_chara_sprite(pos[:x], pos[:y], h[:w], h[:h])
  3825.       s.eagle_font.draw_pic(s.bitmap, _bitmap, h)
  3826.     end
  3827.     eagle_process_draw_end(h[:w], h[:h], pos)
  3828.   end
  3829.   #--------------------------------------------------------------------------
  3830.   # ● (封装)生成一个新的文字精灵
  3831.   #--------------------------------------------------------------------------
  3832.   def eagle_new_chara_sprite(c_x, c_y, c_w, c_h)
  3833.     f = Font_EagleCharacter.new(font_params)
  3834.     f.set_param(:skin, win_params[:skin])
  3835.     f.set_param(:ex_cg, ex_params[:cg])
  3836.     s = MESSAGE_EX.charapool_new(self, f, c_x, c_y, c_w, c_h, @eagle_chara_viewport)
  3837.     s.start_effects(game_message.chara_params)
  3838.     @eagle_chara_sprites.push(s) # 存入实时更新的文字数组
  3839.     @eagle_chara_sets[@eagle_current_set].push(s) if @eagle_current_set # 分组
  3840.     s
  3841.   end
  3842.   #--------------------------------------------------------------------------
  3843.   # ● 检查自动换行
  3844.   #--------------------------------------------------------------------------
  3845.   def eagle_auto_new_line(c_w, pos)
  3846.     return if func_params[:aw] == false
  3847.     return if @flag_draw == false
  3848.     return if !eagle_fix_w? && eagle_dynamic_w?
  3849.     max_w = eagle_charas_max_w
  3850.     return if max_w <= 0
  3851.     return if pos[:x] + c_w <= max_w # 若当前文字绘制完成后会超出边界,则换行
  3852.     process_new_line('', pos)
  3853.   end
  3854.   #--------------------------------------------------------------------------
  3855.   # ● 绘制完成时的处理
  3856.   #--------------------------------------------------------------------------
  3857.   def eagle_process_draw_end(c_w, c_h, pos)
  3858.     # 处理下一次绘制的参数
  3859.     pos[:x] += (c_w + game_message.win_params[:ck])
  3860.     pos[:height] = [pos[:height], c_h].max
  3861.     # 记录下一个文字绘制位置x
  3862.     @eagle_next_chara_x = pos[:x]
  3863.     # 处理文字区域大小更改
  3864.     @eagle_charas_w = pos[:x] if @eagle_charas_w < pos[:x]
  3865.     @eagle_charas_h = pos[:y] + pos[:height] if @eagle_charas_h < pos[:y] + pos[:height]
  3866.     return if !@flag_draw
  3867.     return if show_fast? # 如果是立即显示,则不更新
  3868.     eagle_process_draw_update
  3869.     wait_for_one_character
  3870.   end
  3871.   #--------------------------------------------------------------------------
  3872.   # ● 绘制完成时的更新
  3873.   #--------------------------------------------------------------------------
  3874.   def eagle_process_draw_update
  3875.     # 重设对话框宽高,并更新对话框位置
  3876.     eagle_set_wh({:ins => true})
  3877.     # 对齐需要用到对话框的宽高,因此在更新xywh后执行
  3878.     eagle_charas_reset_alignment(win_params[:ali])
  3879.     # 确保最后绘制的文字在视图区域内
  3880.     ensure_character_visible(@eagle_chara_sprites[-1])
  3881.   end
  3882.   #--------------------------------------------------------------------------
  3883.   # ● 重排列全部文字精灵
  3884.   #--------------------------------------------------------------------------
  3885.   def eagle_charas_reset_alignment(align)
  3886.     return if @eagle_chara_sprites.empty?
  3887.     charas = [] # 存储当前迭代行的全部文字精灵
  3888.     # 存储当前迭代行的y值(同y的为同一行)(未考虑列排文字)
  3889.     charas_y = @eagle_chara_sprites[0].origin_y  # 初始为第一行
  3890.     # 最大宽度 = [可供文字绘制区域的最大宽度, 文字占据宽度].max
  3891.     max_w = [eagle_charas_max_w, @eagle_charas_w].max
  3892.     @eagle_chara_sprites.each do |s|
  3893.       next charas.push(s) if s.origin_y == charas_y # 第一行的首字符会存入
  3894.       # 对同一行的字符重排
  3895.       eagle_charas_realign_line(charas, align, max_w)
  3896.       charas.clear
  3897.       # 将当前迭代的 下一行的首字符 存入
  3898.       charas.push(s)
  3899.       charas_y = s.origin_y
  3900.     end
  3901.     # 对最后一行进行重排列
  3902.     eagle_charas_realign_line(charas, align, max_w) if !charas.empty?
  3903.   end
  3904.   #--------------------------------------------------------------------------
  3905.   # ● 重排列同一行上的文字精灵
  3906.   #--------------------------------------------------------------------------
  3907.   def eagle_charas_realign_line(charas, align, max_w)
  3908.     w_line = charas[-1].origin_x - charas[0].origin_x + charas[-1].width
  3909.     h_line = charas.collect{ |c| c.height }.max
  3910.     charas.each do |c|
  3911.       case align
  3912.       when 0 # 左对齐(默认对齐方式)
  3913.         _x = c.origin_x
  3914.       when 1 # 居中排列
  3915.         _x = c.origin_x + (max_w - w_line) / 2
  3916.       when 2 # 右排列
  3917.         _x = c.origin_x + max_w - w_line
  3918.       end
  3919.       _y = c.origin_y + h_line - c.height # 底部对齐
  3920.       c.reset_xy(_x, _y)
  3921.     end
  3922.   end
  3923.   #--------------------------------------------------------------------------
  3924.   # ● 确保指定文字在视图内
  3925.   #--------------------------------------------------------------------------
  3926.   def ensure_character_visible(c, no_anim = false)
  3927.     return if c.nil?
  3928.     ox_1 = self.ox
  3929.     ox_d = 0
  3930.     ox_d = c._x - self.ox if c._x < self.ox
  3931.     d = c._x + c.width - @eagle_chara_viewport.rect.width - self.ox
  3932.     ox_d = d if d > 0
  3933.  
  3934.     oy_1 = self.oy
  3935.     oy_d = 0
  3936.     oy_d = c._y - self.oy if c._y < self.oy
  3937.     d = c._y + c.height - @eagle_chara_viewport.rect.height - self.oy
  3938.     oy_d = d if d > 0
  3939.  
  3940.     if !no_anim && @flag_draw && !@flag_open_close && (ox_d != 0 || oy_d != 0)
  3941.       # 因为是在新行的首字符绘制完成后调用该方法,因此先把这个字符隐藏了
  3942.       c.visible = false
  3943.       t = MESSAGE_EX::CHARAS_SCROLL_OUT_FRAME
  3944.       (t+1).times do |i|
  3945.         per = i * 1.0 / t
  3946.         per = MESSAGE_EX.ease_value(:msg_vp, per)
  3947.         self.ox = (ox_1 + ox_d * per).round if ox_d != 0
  3948.         self.oy = (oy_1 + oy_d * per).round if oy_d != 0
  3949.         update_moving_charas_oxy
  3950.         Fiber.yield
  3951.       end
  3952.       c.visible = true
  3953.     end
  3954.     self.ox = ox_1 + ox_d
  3955.     self.oy = oy_1 + oy_d
  3956.     update_moving_charas_oxy # 保证文字跟着contents一起移动
  3957.   end
  3958.   #--------------------------------------------------------------------------
  3959.   # ● 处于快进显示?
  3960.   #--------------------------------------------------------------------------
  3961.   def show_fast?
  3962.     @flag_instant || @show_fast || @line_show_fast
  3963.   end
  3964.   #--------------------------------------------------------------------------
  3965.   # ● 输出一个字符后的等待
  3966.   #--------------------------------------------------------------------------
  3967.   def wait_for_one_character
  3968.     MESSAGE_EX.se(game_message.win_params[:se])
  3969.     win_params[:cwi].times do
  3970.       return if show_fast?
  3971.       update_show_fast if win_params[:cfast]
  3972.       Fiber.yield
  3973.     end
  3974.   end
  3975.   #--------------------------------------------------------------------------
  3976.   # ● 监听“确定”键的按下,更新快进的标志
  3977.   #--------------------------------------------------------------------------
  3978.   def update_show_fast
  3979.     @show_fast = true if Input.trigger?(:C)
  3980.   end
  3981.   #--------------------------------------------------------------------------
  3982.   # ● 换行文字的处理(删去翻页)
  3983.   #  由于自动对齐的存在,无需预先计算当前行高,text参数无效
  3984.   #--------------------------------------------------------------------------
  3985.   def process_new_line(text, pos)
  3986.     pos[:height] += win_params[:ld] # 当前行增加一个行间距
  3987.     @line_show_fast = false
  3988.     pos[:x] = pos[:new_x]
  3989.     pos[:y] += pos[:height]
  3990.     pos[:height] = line_height
  3991.   end
  3992.  
  3993.   #--------------------------------------------------------------------------
  3994.   # ● 设置【预先】指令的参数
  3995.   #--------------------------------------------------------------------------
  3996.   def eagle_check_pre_settings(text)
  3997.     eagle_check_temp(text)
  3998.     eagle_check_env(text)
  3999.     eagle_check_hold(text)
  4000.     eagle_check_instant(text)
  4001.     eagle_check_close(text)
  4002.     eagle_check_next(text)
  4003.     eagle_check_eval(text)
  4004.     eagle_draw_face(text)
  4005.     eagle_draw_name(text)
  4006.     eagle_check_func(text)
  4007.   end
  4008.   #--------------------------------------------------------------------------
  4009.   # ● 设置/执行temp指令
  4010.   #--------------------------------------------------------------------------
  4011.   def eagle_check_temp(text)
  4012.     text.gsub!(/\e(temp)/i) { "" }
  4013.     @flag_temp = true if $1
  4014.   end
  4015.   def eagle_process_temp
  4016.     return if @flag_temp == false
  4017.     @flag_temp = false
  4018.     game_message.load_temp_env(@flag_temp_env, :eagle_temp)
  4019.     game_message.load_env(@flag_temp_env)
  4020.     game_message.env = @flag_temp_env
  4021.   end
  4022.   #--------------------------------------------------------------------------
  4023.   # ● 设置env指令
  4024.   #--------------------------------------------------------------------------
  4025.   def eagle_check_env(text)
  4026.     text.gsub!(/\eenv\[(.*?)\]/m) {
  4027.       t = $1; sym = t
  4028.       t.include?('|') ? sym = t.slice!(/.*?\|/).chop : t = "load"
  4029.       eagle_check_env_method(sym, t)
  4030.       ""
  4031.     }
  4032.   end
  4033.   def eagle_check_env_method(sym, m = "load")
  4034.     case m
  4035.     when "save"
  4036.       @flag_save_env = sym
  4037.     when "load"
  4038.       game_message.env = sym
  4039.       game_message.save_env(sym) if !game_message.load_env(sym)
  4040.     else
  4041.       p "对话框的 env 转义符参数错误!环境 #{sym} 与未定义的 #{m} 动作。"
  4042.     end
  4043.   end
  4044.   def eagle_process_env
  4045.     return if @flag_save_env == nil
  4046.     game_message.save_env(@flag_save_env)
  4047.     game_message.env = @flag_save_env
  4048.     @flag_save_env = nil
  4049.   end
  4050.   def eagle_reset_env  # 在 close 方法中调用
  4051.     v = MESSAGE_EX::S_ID_RESET_ENV
  4052.     if v == true || (v.is_a?(Integer) && $game_switches[v] == true)
  4053.       game_message.env = '0'
  4054.       game_message.load_env('0')
  4055.     end
  4056.   end
  4057.   #--------------------------------------------------------------------------
  4058.   # ● 设置/执行hold指令
  4059.   #--------------------------------------------------------------------------
  4060.   def eagle_check_hold(text)
  4061.     text.gsub!(/\e(hold)/i) { "" }
  4062.     @flag_hold = $1 ? true : false
  4063.   end
  4064.   def eagle_process_hold
  4065.     if @flag_hold
  4066.       t = self.clone
  4067.       # 重置之前存储的窗口的z值(确保最近的显示在最上面)
  4068.       @eagle_dup_windows.each_with_index do |w, i|
  4069.         w.z = t.z - (i+1) * 5; w.eagle_reset_z
  4070.       end
  4071.       @eagle_dup_windows.unshift(t)
  4072.       self.openness = 0
  4073.       @flag_need_open = true
  4074.     else
  4075.       eagle_release_hold
  4076.     end
  4077.   end
  4078.   def eagle_release_hold # 所有暂存窗口关闭
  4079.     @eagle_dup_windows.each { |w| w.close_clone }
  4080.   end
  4081.   #--------------------------------------------------------------------------
  4082.   # ● 设置instant指令
  4083.   #--------------------------------------------------------------------------
  4084.   def eagle_check_instant(text)
  4085.     text.gsub!(/\e(ins)/i) { "" }
  4086.     @flag_instant = $1 ? true : false
  4087.   end
  4088.   #--------------------------------------------------------------------------
  4089.   # ● 设置close指令
  4090.   #--------------------------------------------------------------------------
  4091.   def eagle_check_close(text)
  4092.     text.gsub!(/\e(close)/i) { "" }
  4093.     @flag_need_close = $1 ? true : false
  4094.   end
  4095.   #--------------------------------------------------------------------------
  4096.   # ● 设置next指令
  4097.   #--------------------------------------------------------------------------
  4098.   def eagle_check_next(text)
  4099.     text.gsub!(/\e(next)/i) { "" }
  4100.     @flag_next = $1 ? true : false
  4101.   end
  4102.   #--------------------------------------------------------------------------
  4103.   # ● 设置eval指令
  4104.   #--------------------------------------------------------------------------
  4105.   def eagle_check_eval(text)
  4106.     @eagle_evals.clear # 清除旧的
  4107.     text.gsub!(/\eeval\{(.*?)\}/m) {
  4108.       @eagle_evals.push($1) # ID 从 1 开始,防止之后param传入nil出错
  4109.       "\eeval[#{@eagle_evals.size}]"
  4110.     }
  4111.     text.gsub!(/\{\{(.*?)\}\}/m) {
  4112.       @eagle_evals.push($1)
  4113.       "\eeval[#{@eagle_evals.size}]"
  4114.     }
  4115.   end
  4116.  
  4117.   #--------------------------------------------------------------------------
  4118.   # ● 分析【预先】转义符的全部参数(按出现顺序处理)
  4119.   #--------------------------------------------------------------------------
  4120.   def parse_pre_params(text, sym, hash, default_type = :default)
  4121.     params = []
  4122.     text.gsub!(/\e#{sym}\[(.*?)\]/i) { params.push($1); "" }
  4123.     params.push("") if params.empty?
  4124.     params.each { |param| parse_param(hash, param, default_type) }
  4125.   end
  4126.   #--------------------------------------------------------------------------
  4127.   # ● 初始化脸图
  4128.   #--------------------------------------------------------------------------
  4129.   def eagle_draw_face(text)
  4130.     face_params[:ls] = -1 # 设置循环开始编号(递增至le,再从ls循环)
  4131.     face_params[:le] = -1 # 设置循环结束编号
  4132.     parse_pre_params(text, 'facep', face_params, :dir)
  4133.     face_params[:dir] = MESSAGE_EX.check_bool(face_params[:dir])
  4134.     face_params[:m] = MESSAGE_EX.check_bool(face_params[:m])
  4135.     face_params[:name] = game_message.face_name
  4136.     face_params[:i] = game_message.face_index
  4137.     return eagle_move_out_face if face_params[:name] == ""
  4138.     if @eagle_sprite_face
  4139.       return if @eagle_sprite_face.no_change?
  4140.       eagle_move_out_face
  4141.     end
  4142.     @eagle_sprite_face = MESSAGE_EX.facepool_new
  4143.     @eagle_sprite_face.reset(self)
  4144.     @eagle_sprite_face.motion(:fade_in)
  4145.   end
  4146.   #--------------------------------------------------------------------------
  4147.   # ● 初始化姓名框
  4148.   #--------------------------------------------------------------------------
  4149.   def name_params; game_message.name_params; end
  4150.   def eagle_draw_name(text)
  4151.     # 用 | 分隔需要绘制的name字符串(其中转义符用<>代替[])和参数组
  4152.     str_name = ""
  4153.     text.gsub!(/\ename\[(.*?)\]/i) {
  4154.       t = $1.dup
  4155.       if t.include?('|')
  4156.         s = t.slice!(/.*?\|/).chop
  4157.         str_name = s if !s.empty?
  4158.         "\ename[#{t}]"
  4159.       else
  4160.         str_name = t
  4161.         ""
  4162.       end
  4163.     }
  4164.     parse_pre_params(text, 'name', name_params, :o)
  4165.     name_params[:name] = str_name
  4166.     process_draw_name
  4167.   end
  4168.   def process_draw_name
  4169.     @eagle_window_name.reset if @eagle_window_name
  4170.   end
  4171.   #--------------------------------------------------------------------------
  4172.   # ● 姓名框占用的宽度
  4173.   #--------------------------------------------------------------------------
  4174.   def eagle_name_width
  4175.     return 0 if !game_message.name?
  4176.     return 0 if name_params[:do] != 0  # 不是嵌入,则不占用
  4177.     return @eagle_window_name.contents.width + \
  4178.       @eagle_window_name.rect_real.x + @eagle_window_name.rect_real.width + \
  4179.       name_params[:dx]
  4180.   end
  4181.   #--------------------------------------------------------------------------
  4182.   # ● 姓名框占用的高度
  4183.   #--------------------------------------------------------------------------
  4184.   def eagle_name_height
  4185.     return 0 if !game_message.name?
  4186.     return 0 if name_params[:do] != 0  # 不是嵌入,则不占用
  4187.     return @eagle_window_name.contents.height + \
  4188.       @eagle_window_name.rect_real.y + @eagle_window_name.rect_real.height + \
  4189.       name_params[:dy] + standard_padding
  4190.   end
  4191.   #--------------------------------------------------------------------------
  4192.   # ● 设置func参数
  4193.   #--------------------------------------------------------------------------
  4194.   def func_params; game_message.func_params; end
  4195.   def eagle_check_func(text)
  4196.     parse_pre_params(text, 'func', func_params)
  4197.     func_params[:aw] = MESSAGE_EX.check_bool(func_params[:aw])
  4198.     func_params[:para] = MESSAGE_EX.check_bool(func_params[:para])
  4199.   end
  4200.   #--------------------------------------------------------------------------
  4201.   # ● 子窗口可以嵌入?
  4202.   #--------------------------------------------------------------------------
  4203.   def child_window_embed_in?
  4204.     open? && func_params[:para] == false
  4205.   end
  4206.  
  4207.   #--------------------------------------------------------------------------
  4208.   # ● 控制符的处理
  4209.   #     code : 控制符的实际形式(比如“\C[1]”是“C”)
  4210.   #     text : 绘制处理中的字符串缓存(字符串可能会被修改)
  4211.   #     pos  : 绘制位置 {:x, :y, :new_x, :height}
  4212.   #--------------------------------------------------------------------------
  4213.   def process_escape_character(code, text, pos)
  4214.     return if eagle_call_process_escape(code, text, pos)
  4215.     temp_code = code.downcase
  4216.     m_c = ("eagle_text_control_" + temp_code).to_sym
  4217.     m_e = ("eagle_chara_effect_" + temp_code).to_sym
  4218.     if respond_to?(m_c)
  4219.       param = obtain_escape_param_string(text)
  4220.       method(m_c).call(param)
  4221.     elsif respond_to?(m_e)
  4222.       param = obtain_escape_param_string(text)
  4223.       # 当只传入 0 时,代表关闭该特效
  4224.       return eagle_chara_effect_clear(temp_code.to_sym) if param == '0'
  4225.       game_message.chara_params[temp_code.to_sym] = param
  4226.       method(m_e).call(param)
  4227.     else
  4228.       super(code, text, pos)
  4229.     end
  4230.   end
  4231.   #--------------------------------------------------------------------------
  4232.   # ● 控制符的处理(方便扩展的编写方式)
  4233.   #     code : 控制符的实际形式(比如“\C[1]”是“C”)
  4234.   #     text : 绘制处理中的字符串缓存(字符串可能会被修改)
  4235.   #     pos  : 绘制位置 {:x, :y, :new_x, :height}
  4236.   #  返回 true 则代表转义符执行成功,否则继续匹配组件和默认转义符
  4237.   #--------------------------------------------------------------------------
  4238.   def eagle_call_process_escape(code, text, pos)
  4239.     c = code.upcase
  4240.     if c == '$' && @gold_window
  4241.       @gold_window.open? ? @gold_window.close : @gold_window.open
  4242.       return true
  4243.     end
  4244.     if c == '.'
  4245.       wait(15); return true
  4246.     end
  4247.     if c == '|'
  4248.       wait(60); return true
  4249.     end
  4250.     if c == '!'
  4251.       input_pause; return true
  4252.     end
  4253.     if c == '>'
  4254.       @line_show_fast = true; return true
  4255.     end
  4256.     if c == '<'
  4257.       @line_show_fast = false; return true
  4258.     end
  4259.     if c == '^'
  4260.       @pause_skip = true; return true
  4261.     end
  4262.     if c == 'C'
  4263.       font_params[:c] = obtain_escape_param_string(text)
  4264.       change_color(text_color(font_params[:c]))
  4265.       return true
  4266.     end
  4267.     if c == "PIC"
  4268.       process_draw_pic(text, pos)
  4269.       return true
  4270.     end
  4271.     if c == "CLC"
  4272.       process_pos_clc(text, pos)
  4273.       return true
  4274.     end
  4275.     return false
  4276.   end
  4277.   #--------------------------------------------------------------------------
  4278.   # ● (覆盖)获取控制符的实际形式(这个方法会破坏原始数据)
  4279.   #--------------------------------------------------------------------------
  4280.   def obtain_escape_code(text)
  4281.     text.slice!(/^[\$\.\|\^!><\{\}\\]|^[\d\w]+/i)
  4282.   end
  4283.   #--------------------------------------------------------------------------
  4284.   # ● 获取控制符的参数(变量参数字符串形式)(这个方法会破坏原始数据)
  4285.   #--------------------------------------------------------------------------
  4286.   def obtain_escape_param_string(text)
  4287.     text.slice!(/^\[[ =\|\$\-\d\w]+\]/)[1..-2] rescue ""
  4288.   end
  4289.   #--------------------------------------------------------------------------
  4290.   # ● 清除暂存的指定文字特效
  4291.   #--------------------------------------------------------------------------
  4292.   def eagle_chara_effect_clear(code_sym)
  4293.     game_message.chara_params.delete(code_sym)
  4294.   end
  4295.   #--------------------------------------------------------------------------
  4296.   # ● 设置\clc清屏效果
  4297.   #--------------------------------------------------------------------------
  4298.   def process_pos_clc(text, pos)
  4299.     text[0] = '' if text[0] == "\n"
  4300.     process_new_line(text, pos)
  4301.  
  4302.     oy_1 = self.oy
  4303.     oy_d = pos[:y]
  4304.     if @flag_draw
  4305.       t = MESSAGE_EX::CLC_CHARAS_OUT_FRAME
  4306.       (t+1).times do |i|
  4307.         per = i * 1.0 / t
  4308.         per = MESSAGE_EX.ease_value(:msg_vp, per)
  4309.         self.oy = (oy_1 + oy_d * per).round
  4310.         update_moving_charas_oxy
  4311.         Fiber.yield
  4312.       end
  4313.     end
  4314.     self.oy = oy_1 + oy_d
  4315.     update_moving_charas_oxy
  4316.   end
  4317.  
  4318.   #--------------------------------------------------------------------------
  4319.   # ● 设置font参数
  4320.   #--------------------------------------------------------------------------
  4321.   def font_params; game_message.font_params; end
  4322.   def eagle_text_control_font(param = "")
  4323.     parse_param(font_params, param, :size)
  4324.     change_color(text_color(font_params[:c]))
  4325.     MESSAGE_EX.apply_font_params(self.contents.font, font_params)
  4326.   end
  4327.   #--------------------------------------------------------------------------
  4328.   # ● (覆盖)重置字体设置
  4329.   #--------------------------------------------------------------------------
  4330.   def reset_font_settings
  4331.     font_params[:c] = MESSAGE_EX::DEFAULT_COLOR_INDEX
  4332.     font_params[:ca] = 255
  4333.     change_color(text_color(font_params[:c]))
  4334.   end
  4335.   #--------------------------------------------------------------------------
  4336.   # ● (覆盖)放大字体尺寸
  4337.   #--------------------------------------------------------------------------
  4338.   def make_font_bigger
  4339.     self.contents.font.size += 4 if self.contents.font.size <= 64
  4340.     font_params[:size] = self.contents.font.size
  4341.   end
  4342.   #--------------------------------------------------------------------------
  4343.   # ● (覆盖)缩小字体尺寸
  4344.   #--------------------------------------------------------------------------
  4345.   def make_font_smaller
  4346.     self.contents.font.size -= 4 if self.contents.font.size >= 16
  4347.     font_params[:size] = self.contents.font.size
  4348.   end
  4349.  
  4350.   #--------------------------------------------------------------------------
  4351.   # ● 设置win参数
  4352.   #--------------------------------------------------------------------------
  4353.   def win_params; game_message.win_params; end
  4354.   def eagle_text_control_win(param = "")
  4355.     parse_param(win_params, param, :o)
  4356.     win_params[:hmin] = eagle_check_param_h(win_params[:hmin])
  4357.     win_params[:hmax] = eagle_check_param_h(win_params[:hmax])
  4358.     win_params[:dw] = MESSAGE_EX.check_bool(win_params[:dw])
  4359.     win_params[:fw] = MESSAGE_EX.check_bool(win_params[:fw])
  4360.     win_params[:dh] = MESSAGE_EX.check_bool(win_params[:dh])
  4361.     win_params[:fh] = MESSAGE_EX.check_bool(win_params[:fh])
  4362.     win_params[:cwi] = 0 if win_params[:cwi] < 0
  4363.     win_params[:cwo] = 0 if win_params[:cwo] < 0
  4364.     win_params[:cfast] = MESSAGE_EX.check_bool(win_params[:cfast])
  4365.     win_params[:fix] = MESSAGE_EX.check_bool(win_params[:fix])
  4366.     eagle_reset_z
  4367.   end
  4368.   #--------------------------------------------------------------------------
  4369.   # ● (覆盖)获取基础行高
  4370.   #--------------------------------------------------------------------------
  4371.   def line_height
  4372.     h = win_params[:lh] || Font.default_size
  4373.     return h if h > 0
  4374.     return super
  4375.   end
  4376.  
  4377.   #--------------------------------------------------------------------------
  4378.   # ● 设置pop参数
  4379.   #--------------------------------------------------------------------------
  4380.   def pop_params; game_message.pop_params; end
  4381.   def eagle_text_control_pop(param = "")
  4382.     pop_params[:id] = nil # 重置绑定对象
  4383.     pop_params[:mx] = nil
  4384.     pop_params[:my] = nil
  4385.     parse_param(pop_params, param, :id)
  4386.     pop_params[:type] = nil # 清除可能的误设置
  4387.     @eagle_pop_obj = eagle_get_pop_obj # 获取所绑定的对象
  4388.     return pop_params[:type] = nil if @eagle_pop_obj.nil?
  4389.     s = eagle_get_pop_sprite # 获取所绑定对象的精灵
  4390.     return pop_params[:type] = nil if s.nil?
  4391.     eagle_set_pop_sprite_info(s)
  4392.     pop_params[:dw] = MESSAGE_EX.check_bool(pop_params[:dw])
  4393.     pop_params[:fw] = MESSAGE_EX.check_bool(pop_params[:fw])
  4394.     pop_params[:dh] = MESSAGE_EX.check_bool(pop_params[:dh])
  4395.     pop_params[:fh] = MESSAGE_EX.check_bool(pop_params[:fh])
  4396.     pop_params[:fix] = MESSAGE_EX.check_bool(pop_params[:fix])
  4397.     pop_params[:with_tag] = show_pop_tag? # 设置pop的tag
  4398.     @eagle_sprite_pop_tag.visible = pop_params[:with_tag]
  4399.     eagle_reset_pop_tag_bitmap if @eagle_sprite_pop_tag.visible
  4400.     eagle_pop_update
  4401.   end
  4402.   #--------------------------------------------------------------------------
  4403.   # ● 获取pop的弹出对象(需要有x、y、width、height方法)
  4404.   #--------------------------------------------------------------------------
  4405.   def eagle_get_pop_obj
  4406.     if pop_params[:id]
  4407.       return eagle_get_pop_obj_m if MESSAGE_EX.in_scene?(:map)
  4408.       return eagle_get_pop_obj_b if MESSAGE_EX.in_scene?(:battle)
  4409.     end
  4410.     return eagle_get_pop_obj_ex
  4411.   end
  4412.   #--------------------------------------------------------------------------
  4413.   # ● 获取pop的对象(地图场景中)(Game_Character的实例)
  4414.   #--------------------------------------------------------------------------
  4415.   def eagle_get_pop_obj_m
  4416.     pop_params[:type] = :map_chara
  4417.     id = pop_params[:id]
  4418.     if id == 0 # 当前事件
  4419.       return $game_map.events[game_message.event_id]
  4420.     elsif id > 0 # 第id号事件
  4421.       chara = $game_map.events[id]
  4422.       chara ||= $game_map.events[game_message.event_id]
  4423.       return chara
  4424.     elsif id < 0 # 队伍中数据库id号角色(不存在则取队长)
  4425.       id = id.abs
  4426.       $game_player.followers.each { |f|
  4427.         return f if f.actor && f.actor.actor.id == id
  4428.       }
  4429.       return $game_player
  4430.     end
  4431.   end
  4432.   #--------------------------------------------------------------------------
  4433.   # ● 获取pop的对象(战斗场景中)(Sprite_Battler的实例)
  4434.   #--------------------------------------------------------------------------
  4435.   def eagle_get_pop_obj_b
  4436.     pop_params[:type] = :battle_sprite
  4437.     id = pop_params[:id]
  4438.     return nil if id.nil?
  4439.     if id > 0 # 敌人index
  4440.       SceneManager.scene.spriteset.battler_sprites.each do |s|
  4441.         return s if s.battler && s.battler.enemy? && s.battler.index == id-1
  4442.       end
  4443.     elsif id < 0 # 我方数据库id
  4444.       id = id.abs
  4445.       SceneManager.scene.spriteset.battler_sprites.each do |s|
  4446.         return s if s.battler && s.battler.actor? && s.battler.id == id
  4447.       end
  4448.     end
  4449.     return nil
  4450.   end
  4451.   #--------------------------------------------------------------------------
  4452.   # ● 获取pop的对象(无 id 设置时)
  4453.   #--------------------------------------------------------------------------
  4454.   def eagle_get_pop_obj_ex
  4455.     if MESSAGE_EX.in_scene?(:map) && pop_params[:mx] && pop_params[:my]
  4456.       pop_params[:type] = :map_grid
  4457.       return [pop_params[:mx], pop_params[:my]]
  4458.     end
  4459.     return nil
  4460.   end
  4461.   #--------------------------------------------------------------------------
  4462.   # ● 获取pop对象的精灵(用于计算偏移值)
  4463.   #--------------------------------------------------------------------------
  4464.   def eagle_get_pop_sprite
  4465.     # 地图场景中,所存储的并非精灵,需要再次检索
  4466.     if pop_params[:type] == :map_chara
  4467.       begin
  4468.         SceneManager.scene.spriteset.character_sprites.each do |s|
  4469.           return s if s.character == @eagle_pop_obj
  4470.         end
  4471.       rescue
  4472.         p "【对话框扩展 by老鹰】未找到pop转义符绑定事件的精灵!可能存在兼容问题!"
  4473.       end
  4474.       return nil
  4475.     end
  4476.     return @eagle_pop_obj
  4477.   end
  4478.   #--------------------------------------------------------------------------
  4479.   # ● 存储用于pop更新的精灵对象的信息
  4480.   #--------------------------------------------------------------------------
  4481.   def eagle_set_pop_sprite_info(s)
  4482.     if s.is_a?(Sprite)
  4483.       pop_params[:chara_w] = s.width
  4484.       pop_params[:chara_h] = s.height
  4485.     end
  4486.     if pop_params[:type] == :map_grid
  4487.       pop_params[:chara_w] = 32
  4488.       pop_params[:chara_h] = 32
  4489.     end
  4490.   end
  4491.   #--------------------------------------------------------------------------
  4492.   # ● 可以显示pop的tag?
  4493.   #--------------------------------------------------------------------------
  4494.   def show_pop_tag?
  4495.     game_message.pop_tag? && @background == 0 &&
  4496.     pop_params[:do] > 0 && pop_params[:do] < 10
  4497.   end
  4498.   #--------------------------------------------------------------------------
  4499.   # ● 重置tag的位图
  4500.   #--------------------------------------------------------------------------
  4501.   def eagle_reset_pop_tag_bitmap(tag_id = pop_params[:tag])
  4502.     @eagle_sprite_pop_tag.bitmap = MESSAGE_EX.windowtag(tag_id)
  4503.     w = @eagle_sprite_pop_tag.bitmap.width
  4504.     h = @eagle_sprite_pop_tag.bitmap.height
  4505.     @eagle_sprite_pop_tag.src_rect.width = w / 3
  4506.     @eagle_sprite_pop_tag.src_rect.height = h / 3
  4507.   end
  4508.  
  4509.   #--------------------------------------------------------------------------
  4510.   # ● 设置face参数
  4511.   #--------------------------------------------------------------------------
  4512.   def face_params; game_message.face_params; end
  4513.   def eagle_text_control_face(param = "")
  4514.     return if !@flag_draw
  4515.     face_params[:ls] = -1 # 设置循环开始编号(+1直至le,再从ls循环)
  4516.     face_params[:le] = -1 # 设置循环结束编号
  4517.     parse_param(face_params, param, :i)
  4518.     @eagle_sprite_face.apply_face_params if @eagle_sprite_face
  4519.   end
  4520.   #--------------------------------------------------------------------------
  4521.   # ● 执行facem
  4522.   #--------------------------------------------------------------------------
  4523.   def eagle_text_control_facem(param = "")
  4524.     return if !@flag_draw
  4525.     return if @eagle_sprite_face == nil
  4526.     params = param.split('|')
  4527.     @eagle_sprite_face.motion(params[0], params[1] || "")
  4528.   end
  4529.   #--------------------------------------------------------------------------
  4530.   # ● 移出脸图
  4531.   #--------------------------------------------------------------------------
  4532.   def eagle_move_out_face
  4533.     return if @eagle_sprite_face.nil?
  4534.     @eagle_sprite_face.motion(:fade_out)
  4535.     MESSAGE_EX.facepool_push(@eagle_sprite_face) # 由精灵池接管
  4536.     @eagle_sprite_face = nil
  4537.   end
  4538.   #--------------------------------------------------------------------------
  4539.   # ● 脸图占用的宽度
  4540.   #--------------------------------------------------------------------------
  4541.   def eagle_face_width
  4542.     return 0 if !game_message.face?
  4543.     return 0 if face_params[:z] < 0
  4544.     face_params[:width] + face_params[:dw]
  4545.   end
  4546.   #--------------------------------------------------------------------------
  4547.   # ● 脸图在左侧占用的宽度(用于调整文字区域的左侧起始位置)
  4548.   #--------------------------------------------------------------------------
  4549.   def eagle_face_left_width
  4550.     return 0 if face_params[:dir] # 显示在右侧时
  4551.     v = eagle_face_width + face_params[:dx]
  4552.     [v, 0].max
  4553.   end
  4554.   #--------------------------------------------------------------------------
  4555.   # ● 脸图在右侧占用的宽度
  4556.   #--------------------------------------------------------------------------
  4557.   def eagle_face_right_width
  4558.     return 0 if !face_params[:dir] # 显示在左侧时
  4559.     v = eagle_face_width - face_params[:dx]
  4560.     [v, 0].max
  4561.   end
  4562.   #--------------------------------------------------------------------------
  4563.   # ● 脸图占用的高度
  4564.   #--------------------------------------------------------------------------
  4565.   def eagle_face_height
  4566.     face_params[:height] || 0
  4567.   end
  4568.   #--------------------------------------------------------------------------
  4569.   # ● 保证脸图完全显示在对话框内?
  4570.   #--------------------------------------------------------------------------
  4571.   def eagle_face_in_window?
  4572.     return false if @eagle_sprite_face == nil
  4573.     return MESSAGE_EX::FORCE_WIN_H_BIGGER_THAN_DEFAULT_FACE &&
  4574.       @eagle_sprite_face.face_default_size?
  4575.   end
  4576.  
  4577.   #--------------------------------------------------------------------------
  4578.   # ● 设置pause参数
  4579.   #--------------------------------------------------------------------------
  4580.   def pause_params; game_message.pause_params; end
  4581.   def eagle_text_control_pause(param = "")
  4582.     parse_param(pause_params, param, :id)
  4583.     @eagle_sprite_pause.reset if @eagle_sprite_pause
  4584.   end
  4585.   #--------------------------------------------------------------------------
  4586.   # ● 设置wait参数
  4587.   #--------------------------------------------------------------------------
  4588.   def eagle_text_control_wait(param = '0')
  4589.     wait(param.to_i)
  4590.   end
  4591.   #--------------------------------------------------------------------------
  4592.   # ● (覆盖)等待
  4593.   #--------------------------------------------------------------------------
  4594.   def wait(duration)
  4595.     return if !@flag_draw
  4596.     # 如果在对话快速显示的中途进行等待,则执行一次绘制后处理,以进行排版等
  4597.     eagle_process_draw_update if show_fast?
  4598.     duration.times { break if @eagle_force_close; Fiber.yield }
  4599.   end
  4600.   #--------------------------------------------------------------------------
  4601.   # ● 设置auto参数
  4602.   #--------------------------------------------------------------------------
  4603.   def eagle_text_control_auto(param = '0')
  4604.     win_params[:auto_t] = param.to_i
  4605.   end
  4606.   #--------------------------------------------------------------------------
  4607.   # ● 执行shake
  4608.   #--------------------------------------------------------------------------
  4609.   def eagle_text_control_shake(param = '0')
  4610.     return if !@flag_draw
  4611.     h = {}
  4612.     h[:p] = 5 # shake power
  4613.     h[:s] = 5 # shake speed
  4614.     h[:t] = 40 # shake duration
  4615.     h[:y] = 0 # 震动方向
  4616.     parse_param(h, param, :t)
  4617.     # 等待震动至结束
  4618.     shake = 0 # 对话框的偏移值
  4619.     shake_direction = 1 # 下一次位移量
  4620.     while h[:t] > 0
  4621.       delta = (h[:p] * h[:s] * shake_direction) / 10.0
  4622.       shake += delta
  4623.       shake_direction = -1 if shake > h[:p] * 2
  4624.       shake_direction = 1 if shake < - h[:p] * 2
  4625.       h[:t] -= 1
  4626.       if h[:y] == 0
  4627.         self.x += shake
  4628.       else
  4629.         self.y += shake
  4630.       end
  4631.       eagle_after_update_xy
  4632.       Fiber.yield
  4633.     end
  4634.     shake = shake.to_i # 平滑移动回初始位置
  4635.     d = shake > 0 ? -1 : 1
  4636.     while shake != 0
  4637.       shake += d
  4638.       if h[:y] == 0
  4639.         self.x += shake
  4640.       else
  4641.         self.y += shake
  4642.       end
  4643.       eagle_after_update_xy
  4644.       Fiber.yield
  4645.     end
  4646.   end
  4647.   #--------------------------------------------------------------------------
  4648.   # ● 执行move指令
  4649.   #--------------------------------------------------------------------------
  4650.   def eagle_text_control_move(param = '0')
  4651.     return if !@flag_draw
  4652.     return if win_params[:do] < 0 || game_message.pop?
  4653.     win_params[:move_init_x] ||= (win_params[:x] || default_init_x)
  4654.     win_params[:move_init_y] ||= (win_params[:y] || default_init_y)
  4655.  
  4656.     h = { :x => nil, :y => nil, :dx => nil, :dy => nil, :t => 20 }
  4657.     parse_param(h, param, :t)
  4658.     _x = nil; _y = nil
  4659.     if h[:x]
  4660.       _x = (h[:x] == 0 ? win_params[:move_init_x] : h[:x])
  4661.     else
  4662.       _x = self.x + h[:dx] if h[:dx]
  4663.     end
  4664.     if h[:y]
  4665.       _y = (h[:y] == 0 ? win_params[:move_init_y] : h[:y])
  4666.     else
  4667.       _y = self.y + h[:dy] if h[:dy]
  4668.     end
  4669.     # 直接重设目的地xy
  4670.     win_params[:x] = _x if _x
  4671.     win_params[:y] = _y if _y
  4672.     # 执行移动
  4673.     h2 = {}
  4674.     h2[:x] = _x if _x
  4675.     h2[:y] = _y if _y
  4676.     h2[:t] = h[:t]
  4677.     eagle_set_wh(h2)
  4678.   end
  4679.   #--------------------------------------------------------------------------
  4680.   # ● 执行eval指令
  4681.   #--------------------------------------------------------------------------
  4682.   def eagle_text_control_eval(param = '0')
  4683.     return if !@flag_draw
  4684.     id_ = param.to_i
  4685.     if id_ > 0 && @eagle_evals[id_ - 1]
  4686.       s = $game_switches; v = $game_variables; msg = self
  4687.       eval( @eagle_evals[id_ - 1] )
  4688.     end
  4689.   end
  4690.   #--------------------------------------------------------------------------
  4691.   # ● 设置set参数
  4692.   #--------------------------------------------------------------------------
  4693.   def eagle_text_control_set(param = '0')
  4694.     return if !@flag_draw
  4695.     return @eagle_current_set = nil if param == '0'
  4696.     @eagle_current_set = param
  4697.     @eagle_chara_sets[@eagle_current_set] ||= []
  4698.   end
  4699.   def eagle_text_control_setm(param = '0')
  4700.     return if !@flag_draw
  4701.     params = param.split('|') # [set_sym, effect_sym, param]
  4702.     if params[2] == "0"
  4703.       chara_set(params[0]) { |s| s.finish_effect(params[1].to_sym) }
  4704.     else
  4705.       chara_set(params[0]) { |s| s.start_effect(params[1].to_sym, params[2]) }
  4706.     end
  4707.   end
  4708.   #--------------------------------------------------------------------------
  4709.   # ● 对指定分组内的文字执行block
  4710.   #   传入空字符串或 0 时为全部文字
  4711.   #--------------------------------------------------------------------------
  4712.   def chara_set(set_sym = nil) # block
  4713.     if set_sym.nil? || set_sym.empty? || set_sym == 0 || set_sym == '0'
  4714.       @eagle_chara_sprites.each { |s| yield(s) }
  4715.       return
  4716.     end
  4717.     return if @eagle_chara_sets[set_sym].nil?
  4718.     @eagle_chara_sets[set_sym].each { |s| yield(s) }
  4719.   end
  4720.   #--------------------------------------------------------------------------
  4721.   # ● 设置扩展参数
  4722.   #--------------------------------------------------------------------------
  4723.   def ex_params; game_message.ex_params; end
  4724.   #--------------------------------------------------------------------------
  4725.   # ● 设置cg参数 / 渐变绘制预定
  4726.   #--------------------------------------------------------------------------
  4727.   if defined?(Sion_GradientText)
  4728.   def eagle_text_control_cg(param = '0')
  4729.     ex_params[:cg].clear
  4730.     ex_params[:cg] = param if param != '' && param != '0'
  4731.   end
  4732.   end
  4733.  
  4734.   #--------------------------------------------------------------------------
  4735.   # ● 输入处理(此处为全部绘制完成后,判定接下来的输入类型)
  4736.   #--------------------------------------------------------------------------
  4737.   def process_input
  4738.     if game_message.choice?
  4739.       input_choice
  4740.     elsif game_message.num_input?
  4741.       input_number
  4742.     elsif game_message.item_choice?
  4743.       input_item
  4744.     elsif input_pause?
  4745.       input_pause
  4746.     end
  4747.     eagle_process_hold
  4748.   end
  4749.   #--------------------------------------------------------------------------
  4750.   # ● 需要输入等待?
  4751.   #--------------------------------------------------------------------------
  4752.   def input_pause?
  4753.     game_message.input_pause? && !@pause_skip
  4754.   end
  4755.   #--------------------------------------------------------------------------
  4756.   # ● 处理输入等待
  4757.   #--------------------------------------------------------------------------
  4758.   def input_pause
  4759.     return if !@flag_draw
  4760.     before_input_pause
  4761.     eagle_process_draw_update # 统一更新一次
  4762.     @eagle_sprite_pause.bind_last_chara(@eagle_chara_sprites[-1])
  4763.     @eagle_sprite_pause.show
  4764.     @flag_input_pause = true
  4765.     self.pause = true unless MESSAGE_EX::NO_DEFAULT_PAUSE
  4766.     process_input_pause
  4767.     self.pause = false
  4768.     @flag_input_pause = false
  4769.     @eagle_sprite_pause.hide
  4770.   end
  4771.   #--------------------------------------------------------------------------
  4772.   # ● 输入等待前的操作
  4773.   #--------------------------------------------------------------------------
  4774.   def before_input_pause
  4775.     # 当pause精灵位于句末且紧靠边界时
  4776.     #  增加对话框宽度保证它在对话框内部(不可占用padding)
  4777.     if pause_params[:v] != 0 && pause_params[:do] <= 0 &&
  4778.        input_pause? && eagle_add_w_by_child_window?
  4779.       # 最大可用于文字绘制的宽度 eagle_charas_max_w
  4780.       # 全部文字实际绘制的宽度 @eagle_charas_w_final + win_params[:cdw]
  4781.       # 最后一行所需的绘制宽度 @eagle_next_chara_x
  4782.       if @eagle_next_chara_x >= @eagle_charas_w_final
  4783.         @eagle_sprite_pause_width_add = @eagle_sprite_pause.width
  4784.       else
  4785.         d = @eagle_charas_w_final + win_params[:cdw] - @eagle_next_chara_x
  4786.         d -= @eagle_sprite_pause.width
  4787.         @eagle_sprite_pause_width_add = -d if d <= 0
  4788.       end
  4789.     else
  4790.       @eagle_sprite_pause_width_add = 0
  4791.     end
  4792.   end
  4793.   #--------------------------------------------------------------------------
  4794.   # ● 执行输入等待
  4795.   #--------------------------------------------------------------------------
  4796.   def process_input_pause
  4797.     @eagle_auto_continue_c = win_params[:auto_t] || MESSAGE_EX::WIN_AUTO_T
  4798.     recreate_contents_for_charas
  4799.     ox_max = [self.ox, @eagle_charas_w - @eagle_chara_viewport.rect.width].max
  4800.     oy_max = self.oy
  4801.     flag_move = ox_max != 0 || oy_max != 0
  4802.     self.arrows_visible = true
  4803.     d_oxy = 1; last_input = nil; last_input_c = 0
  4804.     @flag_input_loop = true
  4805.     while @flag_input_loop
  4806.       Fiber.yield
  4807.       process_input_pause_auto # 处理自动继续
  4808.       process_input_pause_key # 处理按键继续
  4809.       if flag_move # 处理内容滚动
  4810.         if last_input == Input.dir4  # 先处理变速,防止同时按多个方向,导致速度不对
  4811.           last_input_c += 1
  4812.           d_oxy += 1 if last_input_c % 10 == 0
  4813.         else
  4814.           d_oxy = 1
  4815.           last_input_c = 0
  4816.         end
  4817.         last_input = Input.dir4
  4818.         _ox = self.ox; _oy = self.oy
  4819.         if Input.press?(:UP)
  4820.           self.oy -= d_oxy
  4821.           self.oy = 0 if self.oy < 0
  4822.         elsif Input.press?(:DOWN)
  4823.           self.oy += d_oxy
  4824.           self.oy = oy_max if self.oy > oy_max
  4825.         elsif Input.press?(:LEFT)
  4826.           self.ox -= d_oxy
  4827.           self.ox = 0 if self.ox < 0
  4828.         elsif Input.press?(:RIGHT)
  4829.           self.ox += d_oxy
  4830.           self.ox = ox_max if self.ox > ox_max
  4831.         end
  4832.         update_moving_charas_oxy if _ox != self.ox || _oy != self.oy
  4833.       elsif MESSAGE_EX::INPUT_NEXT_WITH_DIR4
  4834.         @flag_input_loop = false if Input.dir4 > 0
  4835.       end
  4836.     end
  4837.     self.arrows_visible = false
  4838.     Fiber.yield
  4839.   end
  4840.   #--------------------------------------------------------------------------
  4841.   # ● 等待按键时,自动继续的处理
  4842.   #--------------------------------------------------------------------------
  4843.   def process_input_pause_auto
  4844.     if @eagle_auto_continue_c
  4845.       return @flag_input_loop = false if @eagle_auto_continue_c <= 0
  4846.       process_while_auto_wait_input_pause(@eagle_auto_continue_c)
  4847.       @eagle_auto_continue_c -= 1
  4848.     end
  4849.   end
  4850.   #--------------------------------------------------------------------------
  4851.   # ● 等待按键时,启用auto时的额外处理
  4852.   #  c 为自动继续的剩余帧数,从 win_params[:auto_t] 获取总等待帧数
  4853.   #--------------------------------------------------------------------------
  4854.   def process_while_auto_wait_input_pause(c)
  4855.     @eagle_sprite_pause.redraw_auto_countdown(c)
  4856.   end
  4857.   #--------------------------------------------------------------------------
  4858.   # ● 等待按键时,按键继续的处理
  4859.   #--------------------------------------------------------------------------
  4860.   def process_input_pause_key
  4861.     return @flag_input_loop = false if check_input?
  4862.   end
  4863.   #--------------------------------------------------------------------------
  4864.   # ● 检查输入等待的按键
  4865.   #--------------------------------------------------------------------------
  4866.   def check_input?
  4867.     Input.trigger?(:B) || Input.trigger?(:C)
  4868.   end
  4869.   #--------------------------------------------------------------------------
  4870.   # ● 处理选项的输入(覆盖)
  4871.   #--------------------------------------------------------------------------
  4872.   def input_choice
  4873.     input_wait_until_msg_wh(@choice_window)
  4874.     input_wait_while_active(@choice_window)
  4875.   end
  4876.   #--------------------------------------------------------------------------
  4877.   # ● 处理数值的输入(覆盖)
  4878.   #--------------------------------------------------------------------------
  4879.   def input_number
  4880.     input_wait_until_msg_wh(@number_window)
  4881.     input_wait_while_active(@number_window)
  4882.   end
  4883.   #--------------------------------------------------------------------------
  4884.   # ● 处理物品的选择(覆盖)
  4885.   #--------------------------------------------------------------------------
  4886.   def input_item
  4887.     input_wait_until_msg_wh(@item_window)
  4888.     input_wait_while_active(@item_window)
  4889.   end
  4890.   #--------------------------------------------------------------------------
  4891.   # ● 等待对话框宽高处理结束
  4892.   #--------------------------------------------------------------------------
  4893.   def input_wait_until_msg_wh(child_window)
  4894.     child_window.hide.start
  4895.     eagle_set_wh if child_window_embed_in? # 执行因子窗口嵌入而变更的窗口大小
  4896.     child_window.show.open.activate
  4897.   end
  4898.   #--------------------------------------------------------------------------
  4899.   # ● 并行等待子窗口处理结束
  4900.   #--------------------------------------------------------------------------
  4901.   def input_wait_while_active(child_window)
  4902.     add_w = game_message.child_window_w_des
  4903.     add_h = game_message.child_window_h_des
  4904.     while child_window.active
  4905.       break child_window.deactivate.close if @eagle_force_close
  4906.       @fiber_para.resume if @fiber_para
  4907.       if add_w != game_message.child_window_w_des ||
  4908.          add_h != game_message.child_window_h_des
  4909.         eagle_set_wh # 执行因子窗口嵌入而变更的窗口大小
  4910.         add_w = game_message.child_window_w_des
  4911.         add_h = game_message.child_window_h_des
  4912.       end
  4913.       Fiber.yield
  4914.     end
  4915.     @fiber_para = nil
  4916.   end
  4917. end # end of class Window_EagleMessage
  4918.  
  4919. #=============================================================================
  4920. # ○ 对话框拷贝
  4921. #=============================================================================
  4922. class Window_EagleMessage_Clone < Window_EagleMessage
  4923.   attr_accessor :back_bitmap, :back_sprite
  4924.   attr_accessor :eagle_chara_viewport
  4925.   attr_accessor :eagle_chara_sprites, :eagle_sprite_pop_tag
  4926.   attr_accessor :eagle_sprite_face, :eagle_window_name, :eagle_sprite_pause
  4927.   attr_accessor :eagle_pop_obj
  4928.   #--------------------------------------------------------------------------
  4929.   # ● 初始化对象
  4930.   #--------------------------------------------------------------------------
  4931.   def initialize(game_message)
  4932.     @game_message = game_message
  4933.     super()
  4934.     self.openness = 255
  4935.     @fin = false # 结束显示?
  4936.   end
  4937.   #--------------------------------------------------------------------------
  4938.   # ● 获取主参数
  4939.   #--------------------------------------------------------------------------
  4940.   def game_message; @game_message; end
  4941.   #--------------------------------------------------------------------------
  4942.   # ● 初始化组件(覆盖,不再初始化,防止在赋值前还要dispose)
  4943.   #--------------------------------------------------------------------------
  4944.   def eagle_message_init_assets; end
  4945.   #--------------------------------------------------------------------------
  4946.   # ● (覆盖)去除全部子窗口
  4947.   #--------------------------------------------------------------------------
  4948.   def create_all_windows; end
  4949.   def dispose_all_windows; end
  4950.   def update_all_windows; end
  4951.   #--------------------------------------------------------------------------
  4952.   # ● (覆盖)判定是否所有窗口已全部关闭
  4953.   #--------------------------------------------------------------------------
  4954.   def all_close?; close?; end
  4955.   #--------------------------------------------------------------------------
  4956.   # ● 设置xywh
  4957.   #--------------------------------------------------------------------------
  4958.   def move(x, y, w, h)
  4959.     super
  4960.     @eagle_win_des_w = w  # 同时记录该变量,防止nil时 default_init_y 报错
  4961.     @eagle_win_des_h = h
  4962.     @eagle_last_x = x # 同时设置上次更新的位置,确保 eagle_set_wh 能用
  4963.     @eagle_last_y = y
  4964.   end
  4965.   #--------------------------------------------------------------------------
  4966.   # ○ 记录文本的宽高(用于更新大小)
  4967.   #--------------------------------------------------------------------------
  4968.   def eagle_set_chara_wh(w, h, w_final, h_final)
  4969.     @eagle_charas_w = w
  4970.     @eagle_charas_h = h
  4971.     @eagle_charas_w_final = w_final
  4972.     @eagle_charas_h_final = h_final
  4973.   end
  4974.   #--------------------------------------------------------------------------
  4975.   # ○ 关闭对话框
  4976.   #--------------------------------------------------------------------------
  4977.   def close_clone
  4978.     @fin = true
  4979.   end
  4980.   #--------------------------------------------------------------------------
  4981.   # ● 重置单页对话框(覆盖,防止过早移出组件)
  4982.   #--------------------------------------------------------------------------
  4983.   def eagle_message_reset
  4984.     @eagle_sprite_pause_width_add = 0 # 拷贝窗口中不存在pause精灵
  4985.   end
  4986.   #--------------------------------------------------------------------------
  4987.   # ● 更新纤程
  4988.   #--------------------------------------------------------------------------
  4989.   def update_fiber
  4990.     if @fiber
  4991.       @fiber.resume
  4992.     elsif self.openness >= 255 && !@fin
  4993.       @fiber = Fiber.new { fiber_main }
  4994.       @fiber.resume
  4995.     end
  4996.   end
  4997.   #--------------------------------------------------------------------------
  4998.   # ● 处理纤程的主逻辑
  4999.   #--------------------------------------------------------------------------
  5000.   def fiber_main
  5001.     eagle_set_wh( {:open => true} ) # 由于pause精灵需要去除,增加更新宽高
  5002.     loop do
  5003.       Fiber.yield
  5004.       break if @fin
  5005.     end
  5006.     eagle_process_before_close
  5007.     close_and_wait
  5008.     @fiber = nil
  5009.   end
  5010. end
  5011. #=============================================================================
  5012. # ○ 对话框拷贝 - 用于环境初始化
  5013. #=============================================================================
  5014. class Window_EagleMessage_CloneEnv < Window_EagleMessage
  5015.   #--------------------------------------------------------------------------
  5016.   # ● 初始化对象
  5017.   #--------------------------------------------------------------------------
  5018.   def initialize(game_message)
  5019.     @game_message = game_message
  5020.     super()
  5021.     self.openness = 0
  5022.   end
  5023.   #--------------------------------------------------------------------------
  5024.   # ● 获取主参数
  5025.   #--------------------------------------------------------------------------
  5026.   def game_message; @game_message; end
  5027.   def game_message=(g); @game_message = g; end
  5028.  
  5029.   #--------------------------------------------------------------------------
  5030.   # ● 初始化组件(覆盖,不再初始化,防止在赋值前还要dispose)
  5031.   #--------------------------------------------------------------------------
  5032.   def eagle_message_init_assets; end
  5033.   #--------------------------------------------------------------------------
  5034.   # ● (覆盖)去除全部子窗口
  5035.   #--------------------------------------------------------------------------
  5036.   def create_all_windows; end
  5037.   def dispose_all_windows; end
  5038.   def update_all_windows; end
  5039.   #--------------------------------------------------------------------------
  5040.   # ● (覆盖)重置对话框
  5041.   #--------------------------------------------------------------------------
  5042.   def eagle_message_reset; end
  5043.   #--------------------------------------------------------------------------
  5044.   # ● 重设z值
  5045.   #--------------------------------------------------------------------------
  5046.   def eagle_reset_z; end
  5047.   #--------------------------------------------------------------------------
  5048.   # ● (覆盖)更新
  5049.   #--------------------------------------------------------------------------
  5050.   def update; end
  5051.   #--------------------------------------------------------------------------
  5052.   # ● 设置game_message
  5053.   #  本质上为全部绘制一次(但不真实绘制)
  5054.   #  空方法为去除对组件的设置
  5055.   #--------------------------------------------------------------------------
  5056.   def set_game_message(game_message, text)
  5057.     @game_message = game_message
  5058.     text_ = text.clone
  5059.     text_ = convert_escape_characters(text_)
  5060.     pos_  = { :x => 0, :y => 0, :new_x => 0, :height => 0}
  5061.     @flag_draw = false
  5062.     process_character(text_.slice!(0, 1), text_, pos_) until text_.empty?
  5063.   end
  5064.   #--------------------------------------------------------------------------
  5065.   # ● 绘制完成时的处理
  5066.   #--------------------------------------------------------------------------
  5067.   def eagle_process_draw_end(c_w, c_h, pos); end
  5068.   #--------------------------------------------------------------------------
  5069.   # ● 可以显示pop的tag?
  5070.   #--------------------------------------------------------------------------
  5071.   def show_pop_tag?; false; end
  5072. end
  5073.  
  5074. #=============================================================================
  5075. # ○ 金钱框窗口
  5076. #=============================================================================
  5077. class Window_EagleMsgGold < Window_Gold
  5078.   #--------------------------------------------------------------------------
  5079.   # ● 初始化对象
  5080.   #--------------------------------------------------------------------------
  5081.   def initialize(window_msg)
  5082.     bind_window(window_msg)
  5083.     super()
  5084.     self.x = Graphics.width - self.width
  5085.     self.y = 0
  5086.     self.openness = 0
  5087.   end
  5088.   def bind_window(window); @window_msg = window; end
  5089. end
  5090.  
  5091. #=============================================================================
  5092. # ○ 姓名框窗口
  5093. #=============================================================================
  5094. class Window_EagleMsgName < Window_Base
  5095.   attr_reader  :rect_real
  5096.   #--------------------------------------------------------------------------
  5097.   # ● 获取文字颜色
  5098.   #     n : 文字颜色编号(0..31)
  5099.   #--------------------------------------------------------------------------
  5100.   def text_color(n)
  5101.     MESSAGE_EX.text_color(n, self.windowskin)
  5102.   end
  5103.   #--------------------------------------------------------------------------
  5104.   # ● 初始化对象
  5105.   #--------------------------------------------------------------------------
  5106.   def initialize(window_msg)
  5107.     bind_window(window_msg)
  5108.     super(0, 0, 32, 32)
  5109.     self.openness = 0
  5110.     @back_sprite = Sprite.new
  5111.     @flag_use_back_sprite = false
  5112.     @params = {}
  5113.     # 在背景图片的影响下,姓名框四个方向的增加量
  5114.     @rect_real = Rect.new(0, 0, 0, 0)
  5115.   end
  5116.   def bind_window(window); @window_msg = window; end
  5117.   def name_params; @window_msg.name_params; end
  5118.   #--------------------------------------------------------------------------
  5119.   # ● 获取行高
  5120.   #--------------------------------------------------------------------------
  5121.   def line_height; name_params[:size] || Font.default_size; end
  5122.   #--------------------------------------------------------------------------
  5123.   # ● 获取全部文本
  5124.   #--------------------------------------------------------------------------
  5125.   def all_text
  5126.     t = MESSAGE_EX.get_name_prefix + name_params[:name]
  5127.     t.gsub!(/<(.*?)>/) { "[" + $1 + "]" }
  5128.     t = @window_msg.convert_escape_characters(t)
  5129.     t
  5130.   end
  5131.   #--------------------------------------------------------------------------
  5132.   # ● 姓名没有变化?
  5133.   #--------------------------------------------------------------------------
  5134.   def no_change?
  5135.     @params[:name] == name_params[:name]
  5136.   end
  5137.   #--------------------------------------------------------------------------
  5138.   # ● 开始
  5139.   #--------------------------------------------------------------------------
  5140.   def start
  5141.     self.show.open
  5142.   end
  5143.   #--------------------------------------------------------------------------
  5144.   # ● 重置
  5145.   #--------------------------------------------------------------------------
  5146.   def reset
  5147.     return close if name_params[:name] == ""
  5148.     skin = @window_msg.get_cur_windowskin_index(name_params[:skin])
  5149.     self.windowskin = MESSAGE_EX.windowskin(skin)
  5150.     return if open? && no_change?
  5151.     @params[:name] = name_params[:name]
  5152.     t = all_text
  5153.     reset_size(t)
  5154.     redraw(t)
  5155.     if name_params[:bg] && eagle_draw_bg_pic(self.width, self.height)
  5156.       @flag_use_back_sprite = true
  5157.       @back_sprite.visible = true
  5158.       self.opacity = 0
  5159.       self.back_opacity = 0
  5160.     else
  5161.       @flag_use_back_sprite = false
  5162.       @back_sprite.visible = false
  5163.       self.opacity = name_params[:opa]
  5164.       self.back_opacity = name_params[:opa]
  5165.       if name_params[:do] == 0  # 嵌入时,隐藏背景框
  5166.         self.opacity = 0
  5167.         self.back_opacity = 0
  5168.       end
  5169.     end
  5170.     reset_rect_real
  5171.     @back_sprite.z = self.z - 1
  5172.     self.contents_opacity = 255
  5173.     open
  5174.   end
  5175.   #--------------------------------------------------------------------------
  5176.   # ● 重设窗口大小
  5177.   #--------------------------------------------------------------------------
  5178.   def reset_size(t)
  5179.     reset_font_settings
  5180.     w, h = MESSAGE_EX.calculate_text_wh(contents, t)
  5181.     h = [h, contents.font.size].max
  5182.     w = w + name_params[:cx]
  5183.     h = h + name_params[:cy]
  5184.     move(0, 0, w + standard_padding * 2, h + standard_padding * 2)
  5185.     create_contents
  5186.   end
  5187.   #--------------------------------------------------------------------------
  5188.   # ● 重绘
  5189.   #--------------------------------------------------------------------------
  5190.   def redraw(t)
  5191.     change_color(text_color(@window_msg.font_params[:c]))
  5192.     MESSAGE_EX.apply_font_params(contents.font, @window_msg.font_params)
  5193.     draw_text_ex(name_params[:cx], name_params[:cy], t)
  5194.   end
  5195.   #--------------------------------------------------------------------------
  5196.   # ● 重置字体设置
  5197.   #--------------------------------------------------------------------------
  5198.   def reset_font_settings
  5199.     change_color(normal_color)
  5200.     contents.font.size = name_params[:size] || Font.default_size
  5201.   end
  5202.   #--------------------------------------------------------------------------
  5203.   # ● 获取控制符的参数(这个方法会破坏原始数据)
  5204.   #--------------------------------------------------------------------------
  5205.   def obtain_escape_param_string(text)
  5206.     text.slice!(/^\[[\|\$\-\d\w]+\]/)[1..-2] rescue ""
  5207.   end
  5208.   #--------------------------------------------------------------------------
  5209.   # ● 控制符的处理
  5210.   #     code : 控制符的实际形式(比如“\C[1]”是“C”)
  5211.   #     text : 绘制处理中的字符串缓存(字符串可能会被修改)
  5212.   #     pos  : 绘制位置 {:x, :y, :new_x, :height}
  5213.   #--------------------------------------------------------------------------
  5214.   def process_escape_character(code, text, pos)
  5215.     if code.upcase == 'C'
  5216.       change_color(text_color(obtain_escape_param_string(text)))
  5217.       return
  5218.     end
  5219.     super(code, text, pos)
  5220.   end
  5221.   #--------------------------------------------------------------------------
  5222.   # ● 绘制背景图片
  5223.   #--------------------------------------------------------------------------
  5224.   def eagle_draw_bg_pic(w, h)
  5225.     _bitmap = MESSAGE_EX.namebg(name_params[:bg], w, h)
  5226.     if _bitmap != nil
  5227.       @back_sprite.bitmap = _bitmap
  5228.       return true
  5229.     end
  5230.     return false
  5231.   end
  5232.   #--------------------------------------------------------------------------
  5233.   # ● 更新背景精灵
  5234.   #--------------------------------------------------------------------------
  5235.   def update_back_sprite
  5236.     MESSAGE_EX.reset_xy_dorigin(@back_sprite, self, name_params[:bgo])
  5237.     MESSAGE_EX.reset_sprite_oxy(@back_sprite, name_params[:bgo])
  5238.     @back_sprite.z = self.z - 1
  5239.   end
  5240.   #--------------------------------------------------------------------------
  5241.   # ● 计算四方向上的增量(因为背景图片可能大于文字区域)
  5242.   #--------------------------------------------------------------------------
  5243.   def reset_rect_real
  5244.     if @flag_use_back_sprite
  5245.       update_back_sprite
  5246.       xw = self.x + standard_padding; ww = self.width - standard_padding * 2
  5247.       yw = self.y + standard_padding; hw = self.height - standard_padding * 2
  5248.       xp = @back_sprite.x - @back_sprite.ox
  5249.       yp = @back_sprite.y - @back_sprite.oy
  5250.       @rect_real.x = 0
  5251.       @rect_real.x = xw - xp if xp < xw
  5252.       @rect_real.y = 0
  5253.       @rect_real.y = yw - yp if yp < yw
  5254.       t = xp + @back_sprite.width - xw - ww
  5255.       @rect_real.width = 0
  5256.       @rect_real.width = t if t > 0
  5257.       t = yp + @back_sprite.height - yw - hw
  5258.       @rect_real.height = 0
  5259.       @rect_real.height = t if t > 0
  5260.     end
  5261.   end
  5262.   #--------------------------------------------------------------------------
  5263.   # ● 更新(在 eagle_win_update 中调用)
  5264.   #--------------------------------------------------------------------------
  5265.   def update_with_msg
  5266.     update_position
  5267.     update_back_sprite if @flag_use_back_sprite
  5268.   end
  5269.   #--------------------------------------------------------------------------
  5270.   # ● 更新位置
  5271.   #  尽管已经更新了姓名框位置,但保留此处用于扩展
  5272.   #--------------------------------------------------------------------------
  5273.   def update_position
  5274.   end
  5275.  
  5276.   #--------------------------------------------------------------------------
  5277.   # ● 显示
  5278.   #--------------------------------------------------------------------------
  5279.   def show
  5280.     @back_sprite.visible = true if @flag_use_back_sprite
  5281.     super
  5282.   end
  5283.   #--------------------------------------------------------------------------
  5284.   # ● 隐藏
  5285.   #--------------------------------------------------------------------------
  5286.   def hide
  5287.     @back_sprite.visible = false if @flag_use_back_sprite
  5288.     super
  5289.   end
  5290.   #--------------------------------------------------------------------------
  5291.   # ● 更新(每帧调用)
  5292.   #--------------------------------------------------------------------------
  5293.   def update
  5294.     super
  5295.     if @flag_use_back_sprite
  5296.       @back_sprite.opacity = self.openness
  5297.       @back_sprite.opacity = 0 if self.openness < 255 || self.contents_opacity < 255
  5298.     end
  5299.   end
  5300. end
  5301.  
  5302. #=============================================================================
  5303. # ○ 等待按键的精灵
  5304. #=============================================================================
  5305. class Sprite_EaglePauseTag < Sprite
  5306.   #--------------------------------------------------------------------------
  5307.   # ● 初始化对象
  5308.   #--------------------------------------------------------------------------
  5309.   def initialize(window_bind)
  5310.     super(nil)
  5311.     bind_window(window_bind)
  5312.     @type_source = 0 # 记录当前源位图的类型(见module中对应【设置】)
  5313.     @type_pos = 0 # 记录当前相对于对话框的位置类型
  5314.     @last_chara = nil
  5315.     @last_pause_index = ""
  5316.     init_auto_countdown
  5317.     reset
  5318.     hide
  5319.   end
  5320.   def bind_window(window_bind); @window_bind = window_bind; end
  5321.   def params; @window_bind.pause_params; end
  5322.   #--------------------------------------------------------------------------
  5323.   # ● 释放
  5324.   #--------------------------------------------------------------------------
  5325.   def dispose
  5326.     @sprite_auto.bitmap.dispose if @sprite_auto.bitmap
  5327.     @sprite_auto.dispose
  5328.     @s_bitmap.dispose
  5329.     self.bitmap.dispose
  5330.     super
  5331.   end
  5332.   #--------------------------------------------------------------------------
  5333.   # ● 绑定文末精灵
  5334.   #--------------------------------------------------------------------------
  5335.   def bind_last_chara(sprite_chara)
  5336.     @last_chara = sprite_chara
  5337.     reset_position
  5338.   end
  5339.   #--------------------------------------------------------------------------
  5340.   # ● 重置
  5341.   #--------------------------------------------------------------------------
  5342.   def reset
  5343.     reset_source if @last_pause_index != params[:id]
  5344.     reset_bitmap
  5345.   end
  5346.   #--------------------------------------------------------------------------
  5347.   # ● 重置源位图
  5348.   #--------------------------------------------------------------------------
  5349.   def reset_source
  5350.     @s_bitmap.dispose if @s_bitmap
  5351.     @last_pause_index = params[:id]
  5352.     _params = MESSAGE_EX.pause_params(@last_pause_index)
  5353.     _bitmap = Cache.system(_params[0])
  5354.     _rect = _params[1].nil? ? _bitmap.rect : _params[1]
  5355.     @s_bitmap_row = _params[2] # 源位图中一行中帧数目
  5356.     @s_bitmap_col = _params[3] # 源位图中一列中帧数目
  5357.     @s_bitmap_n = @s_bitmap_row * @s_bitmap_col # 总帧数
  5358.  
  5359.     @s_bitmap = Bitmap.new(_rect.width, _rect.height)
  5360.     @s_bitmap.blt(0, 0, _bitmap, _rect)
  5361.     @s_rect = Rect.new(0, 0, @s_bitmap.width / @s_bitmap_row,
  5362.       @s_bitmap.height / @s_bitmap_col)
  5363.  
  5364.     self.bitmap.dispose if self.bitmap
  5365.     self.bitmap = Bitmap.new(@s_rect.width, @s_rect.height)
  5366.     @index = 0 # 当前index
  5367.   end
  5368.   #--------------------------------------------------------------------------
  5369.   # ● 重绘位图
  5370.   #--------------------------------------------------------------------------
  5371.   def reset_bitmap
  5372.     self.bitmap.clear
  5373.     @s_rect.x = (@index % @s_bitmap_row) * @s_rect.width
  5374.     @s_rect.y = (@index / @s_bitmap_row) * @s_rect.height
  5375.     self.bitmap.blt(0, 0, @s_bitmap, @s_rect)
  5376.     @count = 0
  5377.   end
  5378.   #--------------------------------------------------------------------------
  5379.   # ● 更新位置
  5380.   #--------------------------------------------------------------------------
  5381.   def reset_position
  5382.     self.viewport = nil
  5383.     if params[:do] > 0
  5384.       MESSAGE_EX.reset_xy_dorigin(self, @window_bind, params[:do])
  5385.     elsif @last_chara
  5386.       self.viewport = @window_bind.eagle_chara_viewport
  5387.       self.x = @last_chara._x + @last_chara.width - @window_bind.eagle_charas_ox
  5388.       self.y = @last_chara._y + @last_chara.height/2 - @window_bind.eagle_charas_oy
  5389.     else
  5390.       self.x = @window_bind.eagle_charas_x0
  5391.       self.y = @window_bind.eagle_charas_y0
  5392.     end
  5393.     self.x += params[:dx]
  5394.     self.y += params[:dy]
  5395.     MESSAGE_EX.reset_xy_origin(self, params[:o])
  5396.     reset_auto_countdown_position
  5397.   end
  5398.   #--------------------------------------------------------------------------
  5399.   # ● 更新
  5400.   #--------------------------------------------------------------------------
  5401.   def update
  5402.     super
  5403.     update_index
  5404.     reset_position if self.viewport && @last_chara
  5405.   end
  5406.   #--------------------------------------------------------------------------
  5407.   # ● 更新帧动画
  5408.   #--------------------------------------------------------------------------
  5409.   def update_index
  5410.     return if (@count += 1) < params[:t]
  5411.     @index = (@index + 1) % @s_bitmap_n
  5412.     reset_bitmap
  5413.   end
  5414.   #--------------------------------------------------------------------------
  5415.   # ● 显示
  5416.   #--------------------------------------------------------------------------
  5417.   def show
  5418.     return if params[:v] == 0
  5419.     reset_position
  5420.     self.visible = true
  5421.     self
  5422.   end
  5423.   #--------------------------------------------------------------------------
  5424.   # ● 隐藏
  5425.   #--------------------------------------------------------------------------
  5426.   def hide
  5427.     @sprite_auto.visible = false
  5428.     self.visible = false
  5429.     self
  5430.   end
  5431.   #--------------------------------------------------------------------------
  5432.   # ● 初始化自动倒计时
  5433.   #--------------------------------------------------------------------------
  5434.   def init_auto_countdown
  5435.     @sprite_auto = Sprite.new
  5436.     @sprite_auto.bitmap = Bitmap.new(MESSAGE_EX::WIN_AUTO_W,
  5437.       MESSAGE_EX::WIN_AUTO_H)
  5438.     @sprite_auto.bitmap.font.color = Color.new(0,0,0,255)
  5439.     @sprite_auto.bitmap.font.shadow = false
  5440.     @sprite_auto.bitmap.font.outline = false
  5441.     # 用于复制的白色文字
  5442.     @auto_temp_bitmap = Bitmap.new(@sprite_auto.width, @sprite_auto.height)
  5443.     @auto_temp_bitmap.font.color = Color.new(255,255,255,150)
  5444.     @auto_temp_bitmap.font.shadow = false
  5445.     @auto_temp_bitmap.font.outline = false
  5446.     t = MESSAGE_EX::WIN_AUTO_TEXT
  5447.     @auto_temp_bitmap.draw_text(0, 0, @sprite_auto.width, @sprite_auto.height, t, 1)
  5448.   end
  5449.   #--------------------------------------------------------------------------
  5450.   # ● 重置自动倒计时的位置
  5451.   #--------------------------------------------------------------------------
  5452.   def reset_auto_countdown_position
  5453.     MESSAGE_EX.reset_sprite_oxy(@sprite_auto, MESSAGE_EX::WIN_AUTO_O)
  5454.     MESSAGE_EX.reset_xy_dorigin(@sprite_auto, @window_bind, MESSAGE_EX::WIN_AUTO_DO)
  5455.     @sprite_auto.x += MESSAGE_EX::WIN_AUTO_DX
  5456.     @sprite_auto.y += MESSAGE_EX::WIN_AUTO_DY
  5457.     @sprite_auto.z = self.z + 1
  5458.     @sprite_auto.visible = @window_bind.win_params[:auto_t] != nil
  5459.   end
  5460.   #--------------------------------------------------------------------------
  5461.   # ● 重绘自动倒计时
  5462.   #--------------------------------------------------------------------------
  5463.   def redraw_auto_countdown(cd)
  5464.     count_rate = cd * 1.0 / @window_bind.win_params[:auto_t]
  5465.     b = @sprite_auto.bitmap
  5466.     b.clear
  5467.     b.fill_rect(0, 0, b.width, b.height, Color.new(255,255,255,150))
  5468.     _x = (b.width-2) * (1-count_rate)
  5469.     r = Rect.new(1+_x, 1, b.width-2-_x, b.height-2)
  5470.     b.fill_rect(r, Color.new(0,0,0,150))
  5471.     # 绘制黑色文字
  5472.     t = MESSAGE_EX::WIN_AUTO_TEXT
  5473.     b.draw_text(0, 0, b.width, b.height, t, 1)
  5474.     # 绘制白色文字
  5475.     r2 = Rect.new(_x, 0, b.width, b.height)
  5476.     b.blt(_x, 0, @auto_temp_bitmap, r2)
  5477.   end
  5478. end
  5479.  
  5480. #==============================================================================
  5481. # ○ 精灵池(用于更新需要延迟消失的精灵)
  5482. #==============================================================================
  5483. module MESSAGE_EX
  5484.   #--------------------------------------------------------------------------
  5485.   # ● 重置
  5486.   #--------------------------------------------------------------------------
  5487.   def self.pools_reset
  5488.     all_pools.each do |type|
  5489.       get_pool(type).each { |s| s.dispose }
  5490.       get_pool(type).clear
  5491.     end
  5492.   end
  5493.   #--------------------------------------------------------------------------
  5494.   # ● 更新
  5495.   #--------------------------------------------------------------------------
  5496.   def self.pools_update
  5497.     all_pools.each do |type|
  5498.       get_pool(type).each { |s| s.update if !s.disposed? && !s.finish? }
  5499.     end
  5500.   end
  5501.   #--------------------------------------------------------------------------
  5502.   # ● 从指定池子中取出一个可用的精灵(失败则返回nil)
  5503.   #--------------------------------------------------------------------------
  5504.   def self.pool_new(type)
  5505.     while true
  5506.       s = get_pool(type).shift
  5507.       return nil if s.nil?
  5508.       next if s.disposed?
  5509.       if !s.finish?
  5510.         get_pool(type).unshift(s)
  5511.         return nil
  5512.       end
  5513.       return s
  5514.     end
  5515.   end
  5516.   #--------------------------------------------------------------------------
  5517.   # ● 将指定精灵放入指定池子
  5518.   # 【注】精灵需要存在 finish? 方法,该方法返回 true 代表可以被重置复用
  5519.   #      返回 false 代表需要继续自己的 update
  5520.   #--------------------------------------------------------------------------
  5521.   def self.pool_push(type, s)
  5522.     return if s.disposed?
  5523.     return get_pool(type).unshift(s) if s.finish?
  5524.     get_pool(type).push(s)
  5525.   end
  5526.  
  5527.   #--------------------------------------------------------------------------
  5528.   # ● 定义可用的池
  5529.   #--------------------------------------------------------------------------
  5530.   def self.all_pools
  5531.     [:chara, :face]
  5532.   end
  5533.   #--------------------------------------------------------------------------
  5534.   # ● 定义全局数组
  5535.   #--------------------------------------------------------------------------
  5536.   @pool_charas = [] # 文字精灵池
  5537.   @pool_faces  = [] # 脸图精灵池
  5538.   def self.get_pool(type)
  5539.     return @pool_charas if type == :chara
  5540.     return @pool_faces if type == :face
  5541.   end
  5542.  
  5543.   #--------------------------------------------------------------------------
  5544.   # ● 对文字精灵池的操作
  5545.   #--------------------------------------------------------------------------
  5546.   def self.charapool_push(s)
  5547.     pool_push(:chara, s)
  5548.   end
  5549.   def self.charapool_new(window, font, x,y,w,h, viewport)
  5550.     s = pool_new(:chara)
  5551.     return Sprite_EagleCharacter.new(window, font, x,y,w,h, viewport) if s.nil?
  5552.     s.bind_viewport(viewport)
  5553.     s.bind_window(window)
  5554.     s.bind_font(font)
  5555.     s.reset(x,y,w,h)
  5556.     s
  5557.   end
  5558.  
  5559.   #--------------------------------------------------------------------------
  5560.   # ● 对脸图精灵池的操作
  5561.   #--------------------------------------------------------------------------
  5562.   def self.facepool_push(s)
  5563.     pool_push(:face, s)
  5564.   end
  5565.   def self.facepool_new
  5566.     s = pool_new(:face)
  5567.     return Sprite_EagleFace.new if s.nil?
  5568.     s
  5569.   end
  5570. end
  5571. #=============================================================================
  5572. # ○ Scene_Base
  5573. #=============================================================================
  5574. class Scene_Base
  5575.   #--------------------------------------------------------------------------
  5576.   # ● 开始处理
  5577.   #--------------------------------------------------------------------------
  5578.   alias eagle_message_pool_start start
  5579.   def start
  5580.     MESSAGE_EX.pools_reset
  5581.     eagle_message_pool_start
  5582.   end
  5583.   #--------------------------------------------------------------------------
  5584.   # ● 更新画面(基础)
  5585.   #--------------------------------------------------------------------------
  5586.   alias eagle_message_pool_update_basic update_basic
  5587.   def update_basic
  5588.     eagle_message_pool_update_basic
  5589.     MESSAGE_EX.pools_update
  5590.   end
  5591.   #--------------------------------------------------------------------------
  5592.   # ● 结束处理
  5593.   #--------------------------------------------------------------------------
  5594.   alias eagle_message_pool_terminate terminate
  5595.   def terminate
  5596.     eagle_message_pool_terminate
  5597.     MESSAGE_EX.pools_reset
  5598.   end
  5599. end
  5600.  
  5601. #=============================================================================
  5602. # ○ 脸图精灵
  5603. #=============================================================================
  5604. class Sprite_EagleFace < Sprite
  5605.   attr_accessor :opa
  5606.   #--------------------------------------------------------------------------
  5607.   # ● 绑定
  5608.   #--------------------------------------------------------------------------
  5609.   def bind_window(w); @window = w; end
  5610.   def face_params; @window.face_params; end
  5611.   #--------------------------------------------------------------------------
  5612.   # ● 已经结束使用?
  5613.   #--------------------------------------------------------------------------
  5614.   def finish?
  5615.     @flag_fin == true
  5616.   end
  5617.   #--------------------------------------------------------------------------
  5618.   # ● 初始化/重置
  5619.   #--------------------------------------------------------------------------
  5620.   def reset(window)
  5621.     bind_window(window)
  5622.     init_params
  5623.     apply_face_bitmap
  5624.     apply_face_params
  5625.   end
  5626.   #--------------------------------------------------------------------------
  5627.   # ● 初始化参数
  5628.   #--------------------------------------------------------------------------
  5629.   def init_params
  5630.     @params = {}   # 自用参数组
  5631.     @flag_fin = false  # 可复用的标志
  5632.     @fiber = nil # 移动用 fiber
  5633.     @fiber_tmp = nil # 若fiber未执行完,则只预存一个 fiber
  5634.     # 为了更好的扩展性,不直接使用默认属性,而是利用中间变量去赋值
  5635.     @x0 = @y0 = 0 # 因绑定对话框而获得的基础坐标
  5636.     @x1 = @y1 = 0 # 因为移动而增加的偏移
  5637.     @opa = 0 # 不透明度
  5638.   end
  5639.   #--------------------------------------------------------------------------
  5640.   # ● 脸图未更改?
  5641.   #--------------------------------------------------------------------------
  5642.   def no_change?
  5643.     self.bitmap && !self.bitmap.disposed? &&
  5644.     @params[:name] == face_params[:name] &&
  5645.     @params[:i] == face_params[:i]
  5646.   end
  5647.   #--------------------------------------------------------------------------
  5648.   # ● 设置脸图文件
  5649.   #--------------------------------------------------------------------------
  5650.   def apply_face_bitmap
  5651.     @params[:name] = face_params[:name]
  5652.     self.bitmap = Cache.face(@params[:name])
  5653.     @params[:name] =~ /_(\d+)x(\d+)_?/i  # 从文件名获取行数和列数(默认为2行4列)
  5654.     @params[:num_line] = $1 ? $1.to_i : face_default_line
  5655.     @params[:num_col] = $2 ? $2.to_i : face_default_col
  5656.     @params[:num] = @params[:num_line] * @params[:num_col]
  5657.     @params[:sole_w] = self.bitmap.width / @params[:num_col]
  5658.     @params[:sole_h] = self.bitmap.height / @params[:num_line]
  5659.     # 传出脸图宽高,用于对话框中的文字位移
  5660.     face_params[:width] = @params[:sole_w]
  5661.     face_params[:height] = @params[:sole_h]
  5662.     # 脸图以底部中心为显示原点
  5663.     self.ox = @params[:sole_w] / 2
  5664.     self.oy = @params[:sole_h]
  5665.   end
  5666.   #--------------------------------------------------------------------------
  5667.   # ● 脸图默认规格(行和列)
  5668.   #--------------------------------------------------------------------------
  5669.   def face_default_line; 2; end
  5670.   def face_default_col;  4; end
  5671.   #--------------------------------------------------------------------------
  5672.   # ● 默认大小的脸图?
  5673.   #--------------------------------------------------------------------------
  5674.   def face_default_size?
  5675.     @params[:sole_w] == 96 && @params[:sole_h] == 96
  5676.   end
  5677.   #--------------------------------------------------------------------------
  5678.   # ● 导入face参数
  5679.   #--------------------------------------------------------------------------
  5680.   def apply_face_params
  5681.     # 移入移出的参数
  5682.     @params[:it] = face_params[:it]
  5683.     @params[:ot] = face_params[:ot]
  5684.  
  5685.     # 判断是否需要循环的flag
  5686.     @params[:flag_l] = (face_params[:ls] > -1 && face_params[:le] > face_params[:ls])
  5687.     @params[:ls] = face_params[:ls]
  5688.     @params[:lt] = face_params[:lt]
  5689.     @params[:lw] = face_params[:lw]
  5690.     @params[:li_c] = face_params[:ls] # 循环用index计数
  5691.     @params[:lt_c] = face_params[:lt] # 循环用time计数
  5692.     @params[:lw_c] = face_params[:lw] # 循环后wait计数
  5693.  
  5694.     @params[:i] = face_params[:i]
  5695.     apply_index
  5696.   end
  5697.   #--------------------------------------------------------------------------
  5698.   # ● 应用当前帧
  5699.   #--------------------------------------------------------------------------
  5700.   def apply_index
  5701.     return if @params[:i] == nil
  5702.     @params[:i] = 0 if @params[:i] >= @params[:num]
  5703.     w = @params[:sole_w]
  5704.     h = @params[:sole_h]
  5705.     x = @params[:i] % @params[:num_col] * w
  5706.     y = @params[:i] / @params[:num_col] * h
  5707.     rect = Rect.new(x, y, w, h)
  5708.     self.src_rect = rect
  5709.   end
  5710.   #--------------------------------------------------------------------------
  5711.   # ● 更新
  5712.   #--------------------------------------------------------------------------
  5713.   def update
  5714.     super
  5715.     @fiber.resume if @fiber
  5716.     update_position
  5717.     update_pattern
  5718.   end
  5719.   #--------------------------------------------------------------------------
  5720.   # ● 更新位置
  5721.   #--------------------------------------------------------------------------
  5722.   def update_position
  5723.     if @window
  5724.       if face_params[:dir] # 脸图放置于右侧时
  5725.         @x0 = @window.x + @window.width - @window.standard_padding - self.ox
  5726.       else # 脸图放置于左侧时
  5727.         @x0 = @window.x + @window.standard_padding + self.ox
  5728.       end
  5729.       @x0 += face_params[:dx]
  5730.       @y0 = @window.y + @window.height - @window.standard_padding + face_params[:dy]
  5731.       self.mirror = face_params[:m]
  5732.       self.z = @window.z + face_params[:z]
  5733.     end
  5734.     self.x = @x0 + @x1
  5735.     self.y = @y0 + @y1
  5736.     self.opacity = @opa
  5737.   end
  5738.   #--------------------------------------------------------------------------
  5739.   # ● 更新自动播放
  5740.   #--------------------------------------------------------------------------
  5741.   def update_pattern
  5742.     if @params[:flag_l]
  5743.       if @params[:li_c] >= @params[:le]
  5744.         # 每次loop之间的等待
  5745.         return if @params[:lw].nil?
  5746.         @params[:lw_c] -= 1
  5747.         return if @params[:lw_c] > 0
  5748.         @params[:lw_c] = @params[:lw]
  5749.         @params[:li_c] = @params[:ls]
  5750.       else
  5751.         # 每帧之间的等待
  5752.         @params[:lt_c] -= 1
  5753.         return if @params[:lt_c] > 0
  5754.         @params[:lt_c] = @params[:lt]
  5755.         @params[:li_c] += 1
  5756.       end
  5757.       @params[:i] = @params[:li_c]
  5758.       apply_index
  5759.     end
  5760.   end
  5761.   #--------------------------------------------------------------------------
  5762.   # ● 执行动作
  5763.   #--------------------------------------------------------------------------
  5764.   def motion(type, param_str = "")
  5765.     m_c = ("fiber_#{type}").to_sym
  5766.     if respond_to?(m_c)
  5767.       if @fiber
  5768.         @fiber_tmp = Fiber.new { fiber_main(m_c, param_str) }
  5769.       else
  5770.         @fiber = Fiber.new { fiber_main(m_c, param_str) }
  5771.       end
  5772.     else
  5773.       p "对话框中 \epicm 转义符,指令 #{type} 无效!请检查指令名称及其大小写!"
  5774.     end
  5775.   end
  5776.   #--------------------------------------------------------------------------
  5777.   # ● Fiber主逻辑
  5778.   #--------------------------------------------------------------------------
  5779.   def fiber_main(m_c, param_str)
  5780.     method(m_c).call(param_str)
  5781.     @fiber = nil
  5782.     @fiber = @fiber_tmp if @fiber_tmp
  5783.     @fiber_tmp = nil
  5784.   end
  5785.   #--------------------------------------------------------------------------
  5786.   # ● 动作:淡入
  5787.   #--------------------------------------------------------------------------
  5788.   def fiber_fade_in(param_str = "")
  5789.     v = 255.0 / @params[:it]
  5790.     while(@opa < 255)
  5791.       @opa += v
  5792.       yield self if block_given?
  5793.       Fiber.yield
  5794.     end
  5795.   end
  5796.   def fiber_in(param_str = ""); fiber_fade_in(param_str); end
  5797.   #--------------------------------------------------------------------------
  5798.   # ● 动作:淡出
  5799.   #--------------------------------------------------------------------------
  5800.   def fiber_fade_out(param_str = "")
  5801.     bind_window(nil)
  5802.     v = 255.0 / @params[:ot]
  5803.     while(@opa > 0)
  5804.       @opa -= v
  5805.       yield self if block_given?
  5806.       Fiber.yield
  5807.     end
  5808.     @flag_fin = true
  5809.   end
  5810.   def fiber_out(param_str = ""); fiber_fade_out(param_str); end
  5811.   #--------------------------------------------------------------------------
  5812.   # ● 动作:跳跃
  5813.   #--------------------------------------------------------------------------
  5814.   def fiber_jump(param_str = "")
  5815.     t = 0
  5816.     while t <= 10
  5817.       @y1 = (t-5)**2 * 40 * 1.0/25 - 40
  5818.       yield self if block_given?
  5819.       Fiber.yield
  5820.       t += 1
  5821.     end
  5822.   end
  5823.   #--------------------------------------------------------------------------
  5824.   # ● 动作:移动
  5825.   #--------------------------------------------------------------------------
  5826.   def fiber_move(param_str = "")
  5827.     h = { :x => nil, :y => nil, :dx => nil, :dy => nil, :t => 30 }
  5828.     MESSAGE_EX.parse_param(h, param_str, :t)
  5829.  
  5830.     init_x1 = @x1
  5831.     des_x = init_x1
  5832.     des_x = init_x1 + h[:dx] if h[:dx]
  5833.     des_x = h[:x] if h[:x]
  5834.     init_y1 = @y1
  5835.     des_y = init_y1
  5836.     des_y = init_y1 + h[:dy] if h[:dy]
  5837.     des_y = h[:y] if h[:y]
  5838.     return if init_x1 == des_x && init_y1 == des_y
  5839.     d_x = des_x - init_x1
  5840.     d_y = des_y - init_y1
  5841.  
  5842.     _i = 0; _t = h[:t]
  5843.     while(true)
  5844.       break if _i > _t
  5845.       per = _i * 1.0 / _t
  5846.       per = (_i == _t ? 1 : MESSAGE_EX.ease_value(:face_xy, per))
  5847.       @x1 = (init_x1 + d_x * per).round
  5848.       @y1 = (init_y1 + d_y * per).round
  5849.       yield self if block_given?
  5850.       Fiber.yield
  5851.       _i += 1
  5852.     end
  5853.   end
  5854. end
  5855.  
  5856. #=============================================================================
  5857. # ○ 文字绘制类
  5858. #=============================================================================
  5859. class Font_EagleCharacter
  5860.   attr_reader   :text  # 上一次绘制的文本
  5861.   #--------------------------------------------------------------------------
  5862.   # ● 初始化
  5863.   #--------------------------------------------------------------------------
  5864.   def initialize(font_params)
  5865.     @params = font_params.dup
  5866.     @text = ""
  5867.   end
  5868.   #--------------------------------------------------------------------------
  5869.   # ● 设置参数
  5870.   #--------------------------------------------------------------------------
  5871.   def set_param(sym, value)
  5872.     @params[sym] = value
  5873.   end
  5874.   #--------------------------------------------------------------------------
  5875.   # ● 获取文字颜色
  5876.   #     n : 文字颜色编号(0..31)
  5877.   #--------------------------------------------------------------------------
  5878.   def text_color(n)
  5879.     MESSAGE_EX.text_color(n, MESSAGE_EX.windowskin(@params[:skin]))
  5880.   end
  5881.   #--------------------------------------------------------------------------
  5882.   # ● 获取渐变色数组
  5883.   #--------------------------------------------------------------------------
  5884.   def get_gradient_color(str)
  5885.     result = []
  5886.     param = str.downcase
  5887.     while(param != "")
  5888.       param.slice!(/\D+/)
  5889.       result.push((param.slice!(/\d+/)).to_i)
  5890.     end
  5891.     result
  5892.   end
  5893.   #--------------------------------------------------------------------------
  5894.   # ● 执行文字绘制
  5895.   #--------------------------------------------------------------------------
  5896.   def draw(bitmap, x, y, w, h, c, ali = 0)
  5897.     @text = c
  5898.     bitmap.font.color = text_color(@params[:c])
  5899.     MESSAGE_EX.apply_font_params(bitmap.font, @params)
  5900.  
  5901.     draw_param_p(bitmap, x, y, w, h) if @params[:p]
  5902.     draw_param_l(bitmap, x, y, w, h, c, ali) if @params[:l]
  5903.     if defined?(Sion_GradientText) && @params[:ex_cg] && @params[:ex_cg] != ''
  5904.       grad_cs = get_gradient_color(@params[:ex_cg])
  5905.       Sion_GradientText.draw_text(bitmap,x,y,w*2,h,c,ali,grad_cs)
  5906.     else
  5907.       bitmap.draw_text(x, y, w*2, h, c, ali)
  5908.     end
  5909.     draw_param_m(bitmap, x, y, w, h) if @params[:m]
  5910.     draw_param_k(bitmap, x, y, w, h) if @params[:k]
  5911.     draw_param_d(bitmap) if @params[:d]
  5912.     draw_param_u(bitmap) if @params[:u]
  5913.   end
  5914.   #--------------------------------------------------------------------------
  5915.   # ● 执行图标绘制
  5916.   #--------------------------------------------------------------------------
  5917.   def draw_icon(bitmap, x, y, icon_index)
  5918.     draw_param_p(bitmap, x, y, 24, 24) if @params[:p]
  5919.     draw_param_l_rect(bitmap, x, y, 24, 24) if @params[:l]
  5920.     _bitmap = Cache.system("Iconset")
  5921.     rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
  5922.     bitmap.blt(x, y, _bitmap, rect, 255)
  5923.     draw_param_m(bitmap, x, y, 24, 24) if @params[:m]
  5924.     draw_param_k(bitmap, x, y, 24, 24) if @params[:k]
  5925.     draw_param_d(bitmap) if @params[:d]
  5926.     draw_param_u(bitmap) if @params[:u]
  5927.   end
  5928.   #--------------------------------------------------------------------------
  5929.   # ● 绘制底纹
  5930.   #--------------------------------------------------------------------------
  5931.   def draw_param_p(bitmap, x, y, w, h)
  5932.     color = text_color(@params[:pc])
  5933.     case @params[:p]
  5934.     when 1 # 边框
  5935.       bitmap.fill_rect(x, y, w, h, color)
  5936.       bitmap.clear_rect(x+1, y+1, w-2, h-2)
  5937.     when 2 # 纯色方块
  5938.       bitmap.fill_rect(x, y, w, h, color)
  5939.     end
  5940.   end
  5941.   #--------------------------------------------------------------------------
  5942.   # ● 绘制外发光
  5943.   #--------------------------------------------------------------------------
  5944.   def draw_param_l(bitmap, x, y, w, h, c, ali)
  5945.     bitmap.font.outline = false
  5946.     bitmap.font.shadow = false
  5947.     color = bitmap.font.color.dup
  5948.     bitmap.font.color = text_color(@params[:lc])
  5949.     @params[:lp].times do
  5950.       bitmap.draw_text(x, y, w+4, h, c, ali)
  5951.       bitmap.blur
  5952.     end
  5953.     bitmap.font.color = color
  5954.   end
  5955.   def draw_param_l_rect(bitmap, x, y, w, h)
  5956.     c = text_color(@params[:lc])
  5957.     bitmap.fill_rect(x, y, w, h, c)
  5958.     bitmap.blur
  5959.   end
  5960.   #--------------------------------------------------------------------------
  5961.   # ● 绘制删除线
  5962.   #--------------------------------------------------------------------------
  5963.   def draw_param_d(bitmap)
  5964.     c = text_color(@params[:dc])
  5965.     bitmap.fill_rect(0, bitmap.height/2 - 1, bitmap.width, 1, c)
  5966.   end
  5967.   #--------------------------------------------------------------------------
  5968.   # ● 绘制下划线
  5969.   #--------------------------------------------------------------------------
  5970.   def draw_param_u(bitmap)
  5971.     c = text_color(@params[:uc])
  5972.     bitmap.fill_rect(0, bitmap.height - 1, bitmap.width, 1, c)
  5973.   end
  5974.   #--------------------------------------------------------------------------
  5975.   # ● 绘制叠加文字
  5976.   #--------------------------------------------------------------------------
  5977.   def draw_param_m(bitmap, x, y, w, h)
  5978.     color = bitmap.font.color.dup
  5979.     bitmap.font.color = text_color(@params[:mc]) if @params[:mc] >= 0
  5980.     @params[:m].each do |c|
  5981.       if c.is_a?(Integer)
  5982.         _bitmap = Cache.system("Iconset")
  5983.         rect = Rect.new(c % 16 * 24, c / 16 * 24, 24, 24)
  5984.         bitmap.blt(x+w/2-12, y+h/2-12, _bitmap, rect, 255)
  5985.       else
  5986.         bitmap.draw_text(x, y, w, h, c, 1)
  5987.       end
  5988.     end
  5989.     bitmap.font.color = color
  5990.   end
  5991.   #--------------------------------------------------------------------------
  5992.   # ● 文字破碎
  5993.   #--------------------------------------------------------------------------
  5994.   def draw_param_k(bitmap, x, y, w, h)
  5995.     v = @params[:kv]
  5996.     if v >= 100
  5997.       bitmap.clear_rect(x, y, w, h)
  5998.       return
  5999.     end
  6000.     for xi in x...(x + w)
  6001.       for yi in y...(y + h)
  6002.         c = bitmap.get_pixel(xi, yi)
  6003.         next if c.alpha == 0
  6004.         bitmap.set_pixel(xi, yi, Color.new(255,255,255, 0)) if rand(100) < v
  6005.       end
  6006.     end
  6007.   end
  6008.   #--------------------------------------------------------------------------
  6009.   # ● 执行图片绘制
  6010.   #--------------------------------------------------------------------------
  6011.   def draw_pic(bitmap, pic_bitmap, h)
  6012.     bitmap.stretch_blt(bitmap.rect, pic_bitmap, pic_bitmap.rect, h[:opa])
  6013.   end
  6014. end
  6015. #=============================================================================
  6016. # ○ 单个文字的精灵
  6017. #=============================================================================
  6018. class Sprite_EagleCharacter < Sprite
  6019.   attr_reader :origin_x, :origin_y, :_x, :_y, :eagle_font
  6020.   attr_accessor :flag_update_pos
  6021.   #--------------------------------------------------------------------------
  6022.   # ● 初始化对象
  6023.   #  window_bind :所绑定的显示窗口,需要有以下方法
  6024.   #    .z 返回窗口的z值(当前文字精灵将高于该值)
  6025.   #    .eagle_charas_x0 .eagle_charas_y0 返回文字显示区域的左上角坐标(屏幕坐标)
  6026.   #    .eagle_charas_ox .eagle_charas_oy 返回文字显示区域的显示原点(文字区域坐标)
  6027.   #    .eagle_charas_max_h 返回文字区域的最大高度
  6028.   #  font_bind :所绑定的字符绘制类 Font_EagleCharacter 的对象
  6029.   #--------------------------------------------------------------------------
  6030.   def initialize(window_bind, font_bind, x, y, w, h, viewport = nil)
  6031.     super(viewport)
  6032.     bind_viewport(viewport)
  6033.     bind_window(window_bind)
  6034.     bind_font(font_bind)
  6035.     reset(x, y, w, h)
  6036.   end
  6037.   #--------------------------------------------------------------------------
  6038.   # ● 释放
  6039.   #--------------------------------------------------------------------------
  6040.   def dispose
  6041.     self.bitmap.dispose if !self.bitmap.disposed?
  6042.     super
  6043.   end
  6044.   #--------------------------------------------------------------------------
  6045.   # ● 获取文字在屏幕上的碰撞矩形(计算了绑定的viewport的位置)
  6046.   #--------------------------------------------------------------------------
  6047.   def screen_rect
  6048.     r = Rect.new(self.x - self.ox, self.y - self.oy, self.width, self.height)
  6049.     if self.viewport
  6050.       r.x += self.viewport.rect.x
  6051.       r.y += self.viewport.rect.y
  6052.     end
  6053.     r
  6054.   end
  6055.   #--------------------------------------------------------------------------
  6056.   # ● 文字中心点是否在视图内部?
  6057.   #--------------------------------------------------------------------------
  6058.   def in_viewport?
  6059.     return true if self.viewport.nil?
  6060.     lux = self.x; luy = self.y
  6061.     rdx = lux + self.width; rdy = luy + self.height
  6062.     return false if lux < 0 || rdx > self.viewport.rect.width
  6063.     return false if luy < 0 || rdy > self.viewport.rect.height
  6064.     return true
  6065.   end
  6066.   #--------------------------------------------------------------------------
  6067.   # ● 设置绑定的视图
  6068.   #--------------------------------------------------------------------------
  6069.   def bind_viewport(vp)
  6070.     @viewport_bind = vp
  6071.     self.viewport = vp
  6072.   end
  6073.   # 临时解绑与重新绑定
  6074.   def unbind_viewport
  6075.     self.viewport = nil
  6076.   end
  6077.   def rebind_viewport
  6078.     self.viewport = @viewport_bind
  6079.   end
  6080.   #--------------------------------------------------------------------------
  6081.   # ● 设置绑定的窗口
  6082.   #--------------------------------------------------------------------------
  6083.   def bind_window(window_bind)
  6084.     @window_bind = window_bind
  6085.     self.z = @window_bind.z + 1 if @window_bind
  6086.   end
  6087.   #--------------------------------------------------------------------------
  6088.   # ● 设置绑定的绘制参数
  6089.   #--------------------------------------------------------------------------
  6090.   def bind_font(font_bind)
  6091.     @eagle_font = font_bind
  6092.   end
  6093.   #--------------------------------------------------------------------------
  6094.   # ● 在位置不变的情况下,文字精灵不再受限于对话框
  6095.   #--------------------------------------------------------------------------
  6096.   def free_from_msg
  6097.     reset_oxy(7)
  6098.     bind_viewport(nil) # 取消视图,确保不会出现资源崩溃,且不再限制可见范围
  6099.     update_position    # 更新一次位置,用于刷新保存的@x0和@_ox
  6100.     @window_bind = nil # 取消窗口的绑定
  6101.   end
  6102.   #--------------------------------------------------------------------------
  6103.   # ● 重置
  6104.   #--------------------------------------------------------------------------
  6105.   def reset(x, y, w, h)
  6106.     self.bitmap.dispose if self.bitmap
  6107.     self.bitmap = Bitmap.new(w, h)
  6108.     # (x0,y0) 当前的文字显示区域的左上角的屏幕坐标
  6109.     @x0 = 0; @y0 = 0
  6110.     # (_ox,_oy) 当前的文字显示区域的显示原点位置(对话框内部坐标系)
  6111.     @_ox = 0; @_oy = 0
  6112.     # 左对齐时,本文字的显示位置(存储为标准位置,方便对齐)
  6113.     @origin_x = x; @origin_y = y
  6114.     # 设置本文字的显示位置
  6115.     reset_xy(x, y)
  6116.     reset_oxy(7)
  6117.     # 重置参数
  6118.     @dx = 0; @dy = 0 # 动态移动时的偏移值
  6119.     @flag_first_move_in = true # 第一次移入?
  6120.     @flag_update_pos = true # 需要更新位置?
  6121.     @flag_move = nil # 在移动中?
  6122.     # 重置特效参数
  6123.     @effects = {} # effect_sym => param_string
  6124.     @effect_params = {} # effect_sym => param_has
  6125.     # 重置精灵参数
  6126.     self.src_rect = Rect.new(0,0,self.width,self.height)
  6127.     self.zoom_x = self.zoom_y = 1.0
  6128.     self.angle = 0
  6129.     self.wave_amp    = 0
  6130.     self.wave_length = 0
  6131.     self.wave_speed  = 0
  6132.     self.wave_phase  = 0
  6133.     self.mirror = false
  6134.     self.blend_type = 0
  6135.     self.color = Color.new(255,255,255,0)
  6136.     self.opacity = 255
  6137.     self.visible = true
  6138.   end
  6139.   #--------------------------------------------------------------------------
  6140.   # ● 设置相对偏移值(以对话框中的文字显示区域的屏幕左上角为原点)
  6141.   #--------------------------------------------------------------------------
  6142.   def reset_xy(x = nil, y = nil)
  6143.     @_x = x if x # 存储文字相对对话框左上角的显示位置
  6144.     @_y = y if y
  6145.   end
  6146.   #--------------------------------------------------------------------------
  6147.   # ● 设置移动增量
  6148.   #--------------------------------------------------------------------------
  6149.   def reset_dxy(dx = nil, dy = nil)
  6150.     @dx = dx if dx
  6151.     @dy = dy if dy
  6152.   end
  6153.   #--------------------------------------------------------------------------
  6154.   # ● 设置显示原点
  6155.   #--------------------------------------------------------------------------
  6156.   def reset_oxy(o)
  6157.     MESSAGE_EX.reset_sprite_oxy(self, o)
  6158.   end
  6159.   #--------------------------------------------------------------------------
  6160.   # ● 设置显示视图的原点位置
  6161.   # (当在移入移出时,若所绑定窗口的内容原点变动,靠此方法强制移动)
  6162.   #--------------------------------------------------------------------------
  6163.   def reset_window_oxy(ox = nil, oy = nil)
  6164.     @_ox = ox if ox
  6165.     @_oy = oy if oy
  6166.   end
  6167.   #--------------------------------------------------------------------------
  6168.   # ● 结束
  6169.   #--------------------------------------------------------------------------
  6170.   def finish
  6171.     @flag_move = :end
  6172.     self.opacity = 0
  6173.   end
  6174.   #--------------------------------------------------------------------------
  6175.   # ● 结束使命?(在文字池中使用,进行文字精灵的复用)
  6176.   #--------------------------------------------------------------------------
  6177.   def finish?
  6178.     @flag_move == :end
  6179.   end
  6180.  
  6181.   #--------------------------------------------------------------------------
  6182.   # ● 解析参数
  6183.   #--------------------------------------------------------------------------
  6184.   def parse_param(params, param_s, default_type = "default")
  6185.     MESSAGE_EX.parse_param(params, param_s, default_type)
  6186.   end
  6187.   #--------------------------------------------------------------------------
  6188.   # ● 初始化特效的默认参数
  6189.   #--------------------------------------------------------------------------
  6190.   def init_effect_params(sym)
  6191.     MESSAGE_EX.get_default_params(sym)
  6192.   end
  6193.   #--------------------------------------------------------------------------
  6194.   # ● 开始特效(整合)
  6195.   #--------------------------------------------------------------------------
  6196.   def start_effects(effects)
  6197.     @effects = {} # code_symbol => param_string
  6198.     effects.each { |sym, param_s| start_effect(sym, param_s) }
  6199.   end
  6200.   #--------------------------------------------------------------------------
  6201.   # ● 开始特效
  6202.   #--------------------------------------------------------------------------
  6203.   def start_effect(sym, param_s)
  6204.     @effects[sym] = param_s
  6205.     @effect_params[sym] = init_effect_params(sym).dup # 初始化
  6206.     m = ("start_effect_" + sym.to_s).to_sym
  6207.     method(m).call(@effect_params[sym], param_s.dup) if respond_to?(m)
  6208.   end
  6209.   # def start_effect_code(param)  code → 转义符
  6210.   # end
  6211.   #--------------------------------------------------------------------------
  6212.   # ● 更新特效(整合)
  6213.   #--------------------------------------------------------------------------
  6214.   def update_effects
  6215.     @effects.each { |sym, param_s|
  6216.       m = ("update_effect_" + sym.to_s).to_sym
  6217.       method(m).call(@effect_params[sym]) if respond_to?(m)
  6218.     }
  6219.   end
  6220.   # def update_effect_code(param)  code → 转义符
  6221.   # end
  6222.   #--------------------------------------------------------------------------
  6223.   # ● 结束特效(整合)
  6224.   #--------------------------------------------------------------------------
  6225.   def finish_effects
  6226.     @effects.each { |sym, param|
  6227.       m = ("finish_effect_" + sym.to_s).to_sym
  6228.       method(m).call(@effect_params[sym]) if respond_to?(m)
  6229.     }
  6230.     @effects.clear
  6231.   end
  6232.   #--------------------------------------------------------------------------
  6233.   # ● 结束特效
  6234.   #--------------------------------------------------------------------------
  6235.   def finish_effect(sym)
  6236.     return if !@effects.include?(sym)
  6237.     m = ("finish_effect_" + sym.to_s).to_sym
  6238.     method(m).call(@effect_params[sym]) if respond_to?(m)
  6239.     @effects.delete(sym)
  6240.   end
  6241.   # def finish_effect_code(param)  code → 转义符
  6242.   # end
  6243.  
  6244.   #--------------------------------------------------------------------------
  6245.   # ● 更新
  6246.   #--------------------------------------------------------------------------
  6247.   def update
  6248.     return if finish?
  6249.     update_position if @flag_update_pos
  6250.     return move_update(@flag_move) if @flag_move
  6251.     if update_effects?
  6252.       super
  6253.       update_effects
  6254.     end
  6255.   end
  6256.   #--------------------------------------------------------------------------
  6257.   # ● 可以更新特效?
  6258.   #--------------------------------------------------------------------------
  6259.   def update_effects?
  6260.     self.visible && !finish? && !@effects.empty?
  6261.   end
  6262.   #--------------------------------------------------------------------------
  6263.   # ● 更新位置
  6264.   #--------------------------------------------------------------------------
  6265.   def update_position
  6266.     self.x = @_x + @dx + self.ox
  6267.     self.y = @_y + @dy + self.oy
  6268.     if @window_bind
  6269.       @x0 = @window_bind.eagle_charas_x0
  6270.       @y0 = @window_bind.eagle_charas_y0
  6271.       if self.viewport
  6272.         @_ox = @window_bind.eagle_charas_ox
  6273.         @_oy = @window_bind.eagle_charas_oy
  6274.         self.x -= self.viewport.rect.x
  6275.         self.y -= self.viewport.rect.y
  6276.       end
  6277.     end
  6278.     self.x += (@x0 - @_ox)
  6279.     self.y += (@y0 - @_oy)
  6280.   end
  6281.   #--------------------------------------------------------------------------
  6282.   # ● 更新移动
  6283.   #--------------------------------------------------------------------------
  6284.   def move_update(sym = :cin) # 只有移动结束时,才进行其他更新
  6285.     params = @effect_params[sym]
  6286.     params[:tc] += 1
  6287.  
  6288.     per = params[:tc] * 1.0 / params[:t]
  6289.     per = (params[:tc] == params[:t] ? 1 : MESSAGE_EX.ease_value(:chara_xy, per))
  6290.     @dx = (params[:dx_init] + params[:dx_d] * per).round
  6291.     @dy = (params[:dy_init] + params[:dy_d] * per).round
  6292.  
  6293.     if (params[:rxc] += 1) == params[:rxt]
  6294.       params[:rxc] = 0
  6295.       self.src_rect.x += params[:rx]
  6296.     end
  6297.     if (params[:ryc] += 1) == params[:ryt]
  6298.       params[:ryc] = 0
  6299.       self.src_rect.y += params[:ry]
  6300.     end
  6301.     (params[:vzc] = 0;@_zoom += params[:vz]) if (params[:vzc] += 1) == params[:vzt]
  6302.     self.zoom_x = self.zoom_y = 1.0 + @_zoom/100.0
  6303.     self.angle += params[:va]
  6304.     self.opacity += params[:vo]
  6305.     move_end(sym) if params[:tc] == params[:t]
  6306.   end
  6307.   def move_end(sym = :cin)
  6308.     @flag_move = nil
  6309.     rebind_viewport
  6310.     reset_oxy(7)
  6311.     if sym == :cin
  6312.       @dx = @dy = 0
  6313.       update_position
  6314.       self.zoom_x = self.zoom_y = 1.0
  6315.       self.opacity = 255
  6316.       @flag_first_move_in = false
  6317.     elsif sym == :cout
  6318.       finish
  6319.       @flag_move = :end
  6320.     end
  6321.   end
  6322.   #--------------------------------------------------------------------------
  6323.   # ● 正在进行移入移出?
  6324.   #--------------------------------------------------------------------------
  6325.   def move_updating?
  6326.     @flag_move != nil
  6327.   end
  6328.  
  6329.   #--------------------------------------------------------------------------
  6330.   # ● 移入
  6331.   #--------------------------------------------------------------------------
  6332.   def start_effect_cin(params, param_s, flag_move_in = true)
  6333.     parse_param(params, param_s)
  6334.     params[:t] = 1 if params[:t] < 1
  6335.     params[:vzc] = 0 # 计数用
  6336.     params[:vzt] = 1 if params[:vzt] < 1
  6337.     rand_cin(params, param_s) if params[:r] != 0
  6338.     _vo = 255 / params[:t] # 移入时每帧不透明度增量
  6339.     params[:vo] = [_vo, params[:vo], 1].max
  6340.     params[:rxc] = 0; params[:ryc] = 0
  6341.     params[:rxt] = 1 if params[:rxt] < 1
  6342.     params[:ryt] = 1 if params[:ryt] < 1
  6343.     move_in if flag_move_in
  6344.   end
  6345.   #--------------------------------------------------------------------------
  6346.   # ● 随机移入
  6347.   #--------------------------------------------------------------------------
  6348.   RAND_V = lambda { |v| rand(v * 2 + 1) - v }
  6349.   def rand_cin(params, param_s)
  6350.     params[:t] = rand(params[:t]) + 1
  6351.     params[:vz] = RAND_V.call(params[:vz])
  6352.     params[:vzt] = rand(params[:vzt]) + 1
  6353.     params[:va] = RAND_V.call(params[:va])
  6354.     params[:dx] = RAND_V.call(params[:dx])
  6355.     params[:dy] = RAND_V.call(params[:dy])
  6356.   end
  6357.   #--------------------------------------------------------------------------
  6358.   # ● 执行移入
  6359.   #--------------------------------------------------------------------------
  6360.   def move_in
  6361.     params = @effect_params[:cin]
  6362.     rebind_viewport # 重新绑定视图
  6363.     update_position # 记录包含视图位移的值
  6364.      # 如果没有定义移入特效 或 不是首次移入且在视图外
  6365.     if params.nil? || (!@flag_first_move_in && !in_viewport?)
  6366.       self.opacity = 255 # 直接指定不透明度
  6367.       @flag_move = nil
  6368.       return
  6369.     end
  6370.     unbind_viewport # 为了移入,先取消视图
  6371.     @dx = @dy = 0
  6372.     update_position # 用于获取实际的最终显示位置(屏幕坐标)
  6373.  
  6374.     _rect = Rect.new(self.x, self.y, self.width, self.height)
  6375.     if params[:do] != 0
  6376.       MESSAGE_EX.reset_xy_dorigin(_rect, @window_bind, params[:do])
  6377.     end
  6378.     @dx = params[:dx_init] = _rect.x + params[:dx] - self.x
  6379.     @dy = params[:dy_init] = _rect.y + params[:dy] - self.y
  6380.     params[:dx_d] = self.x - (_rect.x + params[:dx])
  6381.     params[:dy_d] = self.y - (_rect.y + params[:dy])
  6382.  
  6383.     @_zoom = -(params[:t]/params[:vzt]) * params[:vz]
  6384.     self.angle = -params[:t] * params[:va]
  6385.     self.src_rect.x = -(params[:t]/params[:rxt]) * params[:rx]
  6386.     self.src_rect.y = -(params[:t]/params[:ryt]) * params[:ry]
  6387.     self.zoom_x = self.zoom_y = 1.0 + @_zoom/100.0
  6388.     self.opacity = 0
  6389.     reset_oxy(5)
  6390.     params[:tc] = 0
  6391.     @flag_move = :cin
  6392.   end
  6393.   #--------------------------------------------------------------------------
  6394.   # ● 移出
  6395.   #--------------------------------------------------------------------------
  6396.   def start_effect_cout(params, param_s)
  6397.     start_effect_cin(params, param_s, false)
  6398.     params[:vo] *= -1
  6399.   end
  6400.   #--------------------------------------------------------------------------
  6401.   # ● 执行移出(外部调用的方法)
  6402.   #--------------------------------------------------------------------------
  6403.   def move_out
  6404.     finish_effects # 先结束全部特效
  6405.     finish if !in_viewport? # 若精灵在视图外,则会直接结束
  6406.     if !finish?
  6407.       process_move_out  # 处理移出模式
  6408.     end
  6409.     free_from_msg  # 不再受限于对话框内,但位置保持不变
  6410.     MESSAGE_EX.charapool_push(self) # 由文字池接管
  6411.   end
  6412.   #--------------------------------------------------------------------------
  6413.   # ● 执行移出(外部调用的方法)(临时移出,之后可以再执行move_in)
  6414.   #--------------------------------------------------------------------------
  6415.   def move_out_temp
  6416.     finish if !in_viewport? # 若精灵在视图外,则会直接结束
  6417.     unbind_viewport
  6418.     if !finish?
  6419.       process_move_out
  6420.       update_position
  6421.     end
  6422.   end
  6423.   #--------------------------------------------------------------------------
  6424.   # ● 处理移出模式
  6425.   #--------------------------------------------------------------------------
  6426.   def process_move_out
  6427.     if @effect_params[:cout] && !@effect_params[:cout].empty?
  6428.       return move_out_cout(@effect_params[:cout])
  6429.     end
  6430.     if @effect_params[:uout] && !@effect_params[:uout].empty?
  6431.       return move_out_uout(@effect_params[:uout])
  6432.     end
  6433.     finish # 如果未预订任何移出模式,则直接结束
  6434.   end
  6435.   #--------------------------------------------------------------------------
  6436.   # ● 执行默认移出
  6437.   #--------------------------------------------------------------------------
  6438.   def move_out_cout(params)
  6439.     _x = self.x; _y = self.y
  6440.     if(self.viewport)
  6441.       _x += self.viewport.rect.x; _y += self.viewport.rect.y
  6442.     end
  6443.     _rect = Rect.new(_x, _y, self.width, self.height)
  6444.     if params[:do] != 0
  6445.       MESSAGE_EX.reset_xy_dorigin(_rect, @window_bind, params[:do])
  6446.       MESSAGE_EX.reset_xy_origin(_rect, 5)
  6447.     end
  6448.     params[:dx_init] = 0
  6449.     params[:dy_init] = 0
  6450.     params[:dx_d] = (_rect.x + params[:dx]) - _x
  6451.     params[:dy_d] = (_rect.y + params[:dy]) - _y
  6452.  
  6453.     @dx = @dy = @_zoom = 0
  6454.     reset_oxy(5)
  6455.     params[:tc] = 0
  6456.     @flag_move = :cout
  6457.   end
  6458.   #--------------------------------------------------------------------------
  6459.   # ● 消散移出
  6460.   #--------------------------------------------------------------------------
  6461.   def start_effect_uout(params, param_s)
  6462.     parse_param(params, param_s)
  6463.     params[:dir] = MESSAGE_EX::CU_PARAM_DIR[ params[:dir] ]
  6464.     params[:s] = MESSAGE_EX::CU_PARAM_S[ params[:s] ]
  6465.   end
  6466.   def move_out_uout(params)
  6467.     _x = self.x; _y = self.y
  6468.     if(self.viewport)
  6469.       _x += self.viewport.rect.x; _y += self.viewport.rect.y
  6470.     end
  6471.     Unravel_Bitmap.new(_x, _y, self.bitmap.clone, 0, 0, self.width,
  6472.       self.height, params[:n], params[:d], params[:o], params[:dir], params[:s])
  6473.     finish
  6474.   end
  6475.   #--------------------------------------------------------------------------
  6476.   # ● 正弦扭曲特效
  6477.   #--------------------------------------------------------------------------
  6478.   def start_effect_csin(params, param_s)
  6479.     parse_param(params, param_s)
  6480.     self.wave_amp    = params[:a]
  6481.     self.wave_length = params[:l]
  6482.     self.wave_speed  = params[:s]
  6483.     self.wave_phase  = params[:p]
  6484.   end
  6485.   #--------------------------------------------------------------------------
  6486.   # ● 波浪特效
  6487.   #--------------------------------------------------------------------------
  6488.   def start_effect_cwave(params, param_s)
  6489.     params[:tc] = 0  # 移动计数用初值(一次性)
  6490.     parse_param(params, param_s)
  6491.   end
  6492.   def update_effect_cwave(params)
  6493.     return if (params[:tc] += 1) < params[:t]
  6494.     params[:tc] = 0
  6495.     @dy += params[:vy]
  6496.     params[:vy] *= -1 if @dy < -params[:h] || @dy > params[:h]
  6497.   end
  6498.   #--------------------------------------------------------------------------
  6499.   # ● 抖动特效
  6500.   #--------------------------------------------------------------------------
  6501.   def start_effect_cshake(params, param_s)
  6502.     params[:vxc] = 0  # 移动计数用初值(一次性)
  6503.     params[:vyc] = 0  # 移动计数用初值(一次性)
  6504.     parse_param(params, param_s)
  6505.     params[:vx] = rand(2) * 2 - 1 if params[:vx] == 0
  6506.     params[:vy] = rand(2) * 2 - 1 if params[:vy] == 0
  6507.   end
  6508.   def update_effect_cshake(params)
  6509.     if (params[:vxc] += 1) > params[:vxt]
  6510.       params[:vxc] = 0
  6511.       @dx += params[:vx]
  6512.       params[:vx] *= -1 if @dx < -params[:l] || @dx > params[:r]
  6513.     end
  6514.     if (params[:vyc] += 1) > params[:vyt]
  6515.       params[:vyc] = 0
  6516.       @dy += params[:vy]
  6517.       params[:vy] *= -1 if @dy < -params[:u] || @dy > params[:d]
  6518.     end
  6519.   end
  6520.   #--------------------------------------------------------------------------
  6521.   # ● 抖动特效2
  6522.   #--------------------------------------------------------------------------
  6523.   def start_effect_cshake2(params, param_s)
  6524.     parse_param(params, param_s)
  6525.   end
  6526.   def update_effect_cshake2(params)
  6527.     @dx = (-1.0 + params[:l] * rand()) * params[:dx]
  6528.     @dy = (-1.0 + params[:l] * rand()) * params[:dy]
  6529.   end
  6530.   #--------------------------------------------------------------------------
  6531.   # ● 摇摆特效
  6532.   #--------------------------------------------------------------------------
  6533.   def start_effect_cswing(params, param_s)
  6534.     params[:ac] = 0 # 当前偏移角度和
  6535.     params[:tc] = 0
  6536.     parse_param(params, param_s)
  6537.     params[:d] = rand(2) * 2 - 1 if params[:d] == 0
  6538.     reset_oxy(params[:o])
  6539.     self.angle = 0
  6540.   end
  6541.   def update_effect_cswing(params)
  6542.     return if (params[:tc] -= 1) > 0
  6543.     params[:tc] = params[:t]
  6544.     params[:ac] += params[:d]
  6545.     if params[:ac].abs > params[:a]
  6546.       params[:ac] = params[:a] * (params[:ac] > 0 ? 1 : -1)
  6547.       params[:d] *= -1
  6548.     end
  6549.     self.angle = params[:ac]
  6550.   end
  6551.   #--------------------------------------------------------------------------
  6552.   # ● 缩放特效
  6553.   #--------------------------------------------------------------------------
  6554.   def start_effect_czoom(params, param_s)
  6555.     params[:tc] = 0 # 计时
  6556.     parse_param(params, param_s)
  6557.     params[:zoom_x] = 100 # 初始的总缩放量
  6558.     params[:zoom_y] = 100
  6559.     reset_oxy(params[:o])
  6560.   end
  6561.   def update_effect_czoom(params)
  6562.     return if (params[:tc] -= 1) > 0
  6563.     params[:tc] = params[:t]
  6564.     if params[:dx] != 0
  6565.       params[:zoom_x] += params[:dx]
  6566.       params[:dx] *= -1 if params[:zoom_x] > params[:max] || params[:zoom_x] < params[:min]
  6567.       self.zoom_x = params[:zoom_x] * 1.0 / 100
  6568.     end
  6569.     if params[:dy] != 0
  6570.       params[:zoom_y] += params[:dy]
  6571.       params[:dy] *= -1 if params[:zoom_y] > params[:max] || params[:zoom_y] < params[:min]
  6572.       self.zoom_y = params[:zoom_y] * 1.0 / 100
  6573.     end
  6574.   end
  6575.   #--------------------------------------------------------------------------
  6576.   # ● 闪烁特效
  6577.   #--------------------------------------------------------------------------
  6578.   def start_effect_cflash(params, param_s)
  6579.     params[:tc] = 0  # 闪烁后的等待时间计数
  6580.     parse_param(params, param_s)
  6581.     params[:color] = Color.new(params[:r], params[:g], params[:b], params[:a])
  6582.   end
  6583.   def update_effect_cflash(params)
  6584.     return if (params[:tc] -= 1) > 0
  6585.     params[:tc] = params[:t] + params[:d]
  6586.     self.flash(params[:color], params[:d])
  6587.   end
  6588.   #--------------------------------------------------------------------------
  6589.   # ● 镜像特效
  6590.   #--------------------------------------------------------------------------
  6591.   def start_effect_cmirror(params, param_s)
  6592.     params[:b]  = '0'
  6593.     parse_param(params, param_s, :b)
  6594.     self.mirror = (params[:b] == '0' ? false : true)
  6595.   end
  6596.   def finish_effect_cmirror(params)
  6597.     self.mirror = false
  6598.   end
  6599.   #--------------------------------------------------------------------------
  6600.   # ● 消散特效
  6601.   #--------------------------------------------------------------------------
  6602.   def start_effect_cu(params, param_s)
  6603.     params[:t_c] = 0 # 间隔计数
  6604.     parse_param(params, param_s)
  6605.     params[:dir] = MESSAGE_EX::CU_PARAM_DIR[ params[:dir] ]
  6606.     params[:s] = MESSAGE_EX::CU_PARAM_S[ params[:s] ]
  6607.   end
  6608.   def update_effect_cu(params)
  6609.     return if !in_viewport?
  6610.     return if (params[:t_c] += 1) < params[:t]
  6611.     params[:t_c] = 0
  6612.     _x = self.x; _y = self.y
  6613.     if(self.viewport)
  6614.       _x += self.viewport.rect.x; _y += self.viewport.rect.y
  6615.     end
  6616.     Unravel_Bitmap.new(_x, _y, self.bitmap.clone, 0, 0, self.width,
  6617.       self.height, params[:n], params[:d], params[:o], params[:dir], params[:s])
  6618.   end
  6619.   #--------------------------------------------------------------------------
  6620.   # ● 位图切换特效
  6621.   #--------------------------------------------------------------------------
  6622.   def start_effect_ctog(params, param_s)
  6623.     parse_param(params, param_s)
  6624.     params[:bitmaps] = []
  6625.     params[:bitmaps].push(self.bitmap)
  6626.     charas = MESSAGE_EX.get_charas_array(:ctog, params[:i], params[:n])
  6627.     charas.each do |c|
  6628.       s = Bitmap.new(self.width, self.height)
  6629.       if c.is_a?(Integer)
  6630.         @eagle_font.draw_icon(s, 0+self.width/2-12, 0+self.height/2-12, c)
  6631.       else
  6632.         r = s.text_size(c)
  6633.         @eagle_font.draw(s, (self.width-r.width)/2, (self.height-r.height)/2,
  6634.           self.width, self.height, c, 0)
  6635.       end
  6636.       params[:bitmaps].push(s)
  6637.     end
  6638.     params[:i_cur] = 0
  6639.     params[:i_max] = params[:bitmaps].size
  6640.     params[:tc] = 0
  6641.   end
  6642.   def update_effect_ctog(params)
  6643.     return if (params[:tc] += 1) < params[:t]
  6644.     params[:tc] = 0
  6645.     if(params[:r] > 0)
  6646.       params[:i_cur] = rand(params[:i_max])
  6647.     else
  6648.       params[:i_cur] += 1
  6649.       params[:i_cur] %= params[:i_max]
  6650.     end
  6651.     self.bitmap = params[:bitmaps][params[:i_cur]]
  6652.   end
  6653.   def finish_effect_ctog(params)
  6654.     self.bitmap = params[:bitmaps].shift
  6655.     params[:bitmaps].each { |b| b.dispose }
  6656.     params[:bitmaps].clear
  6657.   end
  6658.   #--------------------------------------------------------------------------
  6659.   # ● 霓虹灯特效
  6660.   #--------------------------------------------------------------------------
  6661.   def start_effect_cneon(params, param_s)
  6662.     params[:c] = []
  6663.     s = param_s.downcase
  6664.     while(s != "")
  6665.       sym = s.slice!(/\D+/)
  6666.       v = (s.slice!(/\d+/)).to_i
  6667.       next params[:c].push(v) if sym == "c"
  6668.       params[sym.to_sym] = v
  6669.     end
  6670.     params[:tc] = 0
  6671.     params[:c1] = self.color
  6672.     params[:c1].alpha = 255
  6673.     params[:c2] = @window_bind.text_color(params[:c][0])
  6674.     params[:i] = 0
  6675.   end
  6676.   def update_effect_cneon(params)
  6677.     return if @window_bind.nil?
  6678.     params[:tc] += 1
  6679.     self.color.red = params[:c1].red +
  6680.       (params[:c2].red - params[:c1].red)*1.0/ params[:t] * params[:tc]
  6681.     self.color.green = params[:c1].green +
  6682.       (params[:c2].green - params[:c1].green)*1.0 / params[:t] * params[:tc]
  6683.     self.color.blue = params[:c1].blue +
  6684.       (params[:c2].blue - params[:c1].blue)*1.0 / params[:t] * params[:tc]
  6685.  
  6686.     if params[:tc] >= params[:t]
  6687.       params[:c1] = @window_bind.text_color(params[:c][params[:i]])
  6688.       params[:i] += 1
  6689.       params[:i] = 0 if params[:i] >= params[:c].size
  6690.       params[:c2] = @window_bind.text_color(params[:c][params[:i]])
  6691.       params[:tc] = 0
  6692.     end
  6693.   end
  6694.   #--------------------------------------------------------------------------
  6695.   # ● 文字叠加绘制
  6696.   #--------------------------------------------------------------------------
  6697.   def start_effect_cmc(params, param_s)
  6698.     parse_param(params, param_s)
  6699.     charas = MESSAGE_EX.get_charas_array(:cmc, params[:i], params[:n])
  6700.     @eagle_font.set_param(:m, charas)
  6701.     @eagle_font.set_param(:mc, params[:c])
  6702.   end
  6703.   #--------------------------------------------------------------------------
  6704.   # ● 跳跃特效
  6705.   #--------------------------------------------------------------------------
  6706.   def start_effect_cjump(params, param_s)
  6707.     parse_param(params, param_s)
  6708.     params[:tc] *= -1
  6709.     # 二次函数的x项系数
  6710.     params[:A] = (4.0 * params[:h]) / (params[:t] * params[:t])
  6711.   end
  6712.   def update_effect_cjump(params)
  6713.     if params[:tc] < 0 # 等待中
  6714.     elsif params[:tc] <= params[:t] # 跳跃中
  6715.       @dy = (params[:tc]-params[:t]/2)**2 * params[:A] - params[:h]
  6716.     elsif params[:w] && params[:tc] >= params[:t] + params[:w]
  6717.       # 跳跃后的等待结束
  6718.       params[:tc] = 0
  6719.     end
  6720.     params[:tc] += 1
  6721.   end
  6722.   #--------------------------------------------------------------------------
  6723.   # ● 明灭特效
  6724.   #--------------------------------------------------------------------------
  6725.   def start_effect_cfk(params, param_s)
  6726.     parse_param(params, param_s)
  6727.     params[:c] = 0
  6728.     params[:wait] = 0
  6729.   end
  6730.   def update_effect_cfk(params)
  6731.     return if params[:wait] == nil || (params[:wait] -= 1) > 0
  6732.     if params[:c] == 0
  6733.       self.opacity = 255
  6734.       if params[:t] > 0
  6735.         params[:t_] = params[:t]
  6736.         params[:dopa] = 255.0 / params[:t_]
  6737.       elsif params[:t] == 0
  6738.         params[:t_] = MESSAGE_EX::CFK_T0_WAIT
  6739.         params[:dopa] = 255
  6740.       else
  6741.         params[:t_] = rand(-params[:t])
  6742.         params[:dopa] = 255.0 / params[:t_]
  6743.       end
  6744.     end
  6745.     params[:c] += 1
  6746.     self.opacity += (params[:c]<=params[:t_] ? -params[:dopa] : params[:dopa])
  6747.     if self.opacity >= 255
  6748.       params[:c] = 0
  6749.       params[:wait] = params[:w]
  6750.     end
  6751.   end
  6752. end
  6753.  
  6754. #=============================================================================
  6755. # ○ 兼容模式
  6756. #=============================================================================
  6757. module MESSAGE_EX::COMPA_MODE
  6758.   #--------------------------------------------------------------------------
  6759.   # ● 更新画面
  6760.   #--------------------------------------------------------------------------
  6761.   def update_all_windows
  6762.     if $game_message.eagle_message == true
  6763.       @message_window = @msg_windows[1]
  6764.     else
  6765.       @message_window = @msg_windows[0]
  6766.     end
  6767.     eagle_message_ex_compa_mode_update_all_windows
  6768.   end
  6769.   #--------------------------------------------------------------------------
  6770.   # ● 释放所有窗口
  6771.   #--------------------------------------------------------------------------
  6772.   def dispose_all_windows
  6773.     @msg_windows.each { |w| w.dispose }
  6774.     @message_window = nil
  6775.     eagle_message_ex_compa_mode_dispose_all_windows
  6776.   end
  6777. end
  6778. #=============================================================================
  6779. # ○ Scene_Map
  6780. #=============================================================================
  6781. class Spriteset_Map; attr_reader :character_sprites; end
  6782. class Scene_Map
  6783.   attr_reader :spriteset, :message_window
  6784. if EAGLE_MSG_EX_COMPAT_MODE == true
  6785.   alias eagle_message_ex_compa_mode_update_all_windows update_all_windows
  6786.   alias eagle_message_ex_compa_mode_dispose_all_windows dispose_all_windows
  6787.   include MESSAGE_EX::COMPA_MODE
  6788.   #--------------------------------------------------------------------------
  6789.   # ● 生成信息窗口
  6790.   #--------------------------------------------------------------------------
  6791.   alias eagle_message_ex_compa_mode_create_message_window create_message_window
  6792.   def create_message_window
  6793.     eagle_message_ex_compa_mode_create_message_window
  6794.     @msg_windows = [@message_window, Window_EagleMessage.new]
  6795.   end
  6796. else
  6797.   #--------------------------------------------------------------------------
  6798.   # ● 生成信息窗口
  6799.   #--------------------------------------------------------------------------
  6800.   def create_message_window
  6801.     @message_window = Window_EagleMessage.new
  6802.   end
  6803. end
  6804. end
  6805. #=============================================================================
  6806. # ○ Scene_Battle
  6807. #=============================================================================
  6808. class Scene_Battle
  6809.   attr_reader :spriteset, :message_window
  6810. if EAGLE_MSG_EX_COMPAT_MODE == true
  6811.   alias eagle_message_ex_compa_mode_update_all_windows update_all_windows
  6812.   alias eagle_message_ex_compa_mode_dispose_all_windows dispose_all_windows
  6813.   include MESSAGE_EX::COMPA_MODE
  6814.   #--------------------------------------------------------------------------
  6815.   # ● 生成信息窗口
  6816.   #--------------------------------------------------------------------------
  6817.   alias eagle_message_ex_compa_mode_create_message_window create_message_window
  6818.   def create_message_window
  6819.     eagle_message_ex_compa_mode_create_message_window
  6820.     @msg_windows = [@message_window, Window_EagleMessage.new]
  6821.   end
  6822. else
  6823.   #--------------------------------------------------------------------------
  6824.   # ● 生成信息窗口
  6825.   #--------------------------------------------------------------------------
  6826.   def create_message_window
  6827.     @message_window = Window_EagleMessage.new
  6828.   end
  6829. end
  6830. end
百里_飞柳 发表于 2026-4-16 22:20:32
额,光看错误提示是无法知道具体为啥报错的,还需要原本的脚本

我的对话框现在更新到 2.2.6 了,所以我也不知道你这个2384行是什么东西
拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2026-6-5 00:14

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表