赞 | 7 |
VIP | 0 |
好人卡 | 0 |
积分 | 11 |
经验 | 469 |
最后登录 | 2018-11-19 |
在线时间 | 127 小时 |
Lv3.寻梦者
- 梦石
- 0
- 星屑
- 1078
- 在线时间
- 127 小时
- 注册时间
- 2017-9-27
- 帖子
- 42
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
https://littledrago.blogspot.jp/2014/08/rgss3-xp-map-loader-ii.html
↑原作者地址(需要科学上网)作者 : LiTTleDRAgo
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=: # XP地图读取及多层地图制作 # 版本: 2.05 # 作者 : LiTTleDRAgo #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=: ($imported ||= {})[:drg_xp_map_loader] = 2.05 #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=: # # 介绍: # # XP地图读取及多层地图制作的整合脚本第2版。 # # 特性: # # 读取RMXP制作的地图: # - 在Drago的Custom Resolution II这一脚本中,缩放功能不可使用。 # - 可用于RMVA读取RMXP的地图,不可反向用RMXP读取RMVA的地图。 # - 只在RMVA可用。 # # 多层地图: # - 层数越多卡得越厉害。 # # 译者补充,原文来自littledrago.blogspot.jp/2014/08/rgss3-xp-map-loader-ii.html) # 使用方法: # - 需要前置脚本Drago - Core Engine和Custom Resolution(超长,懒得翻译用法) # # - 读取RMXP制作的地图:先在RMXP中做好你的地图,然后把所有地图涉及的文件复制到 # 你的RMVA工程的文件夹下对应位置。 # 包括:原工程\Data文件夹下所有名为MapXXX.rxdata(XXX是地图ID),Tileset.rxdata以及 # 原工程\Graphics文件夹下的Autotiles, Fog, Panorama,Tileset这四个文件夹所有内容。 # - 请注意把需要对应的RMVA地图的文件名与复制来的XP地图文件名一一对应起来。 # # - 多层地图: # - 在需要使用多层地图的原地图下面建立一个名叫"[join]"的子地图。 # - 可以用写标签[join:1][join:2]等指定多层。是否显示的条件可以在下面设定。 # - 同类脚本可能会冲突 # - 需要额外注意A5和B图块中一些透明但不通行的图块,如果通行度不正常请首先排查。 # # 注意: # - 此脚本只调用RMXP工程中的地图、远景、雾图形、通行度、灌木柜台等特殊地形标志, # 其余图像文件及地图涉及到的BGM、BGS仍沿用原本的RMVA工程。 # #============================================================================== module LiTTleDRAgo # Condition for layer to be joined MultiLayerCond = proc do |i| condition = { 1 => $game_switches[1], # 1号开关开启时本层显示,否则不显示 2 => $game_variables[1] == 200, #1号变量=200时显示,否则不显示 } condition[i] #请勿删除本行 end end core = "This script needs Drago - Core Engine ver 1.44 or above" implemented = "%1$s has already implemented, Please remove the %1$s script" ($imported[:drg_core_engine] || 0) >= 1.44 || raise(core) ($imported[:drg_multi_layer])&& raise(sprintf(implemented,"Multi Layer")) #============================================================================== # ** Game_Map #------------------------------------------------------------------------------ # This class handles maps. It includes scrolling and passage determination # functions. The instance of this class is referenced by $game_map. #============================================================================== class Game_Map #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_sec_accessor :panorama_name, :fog_name, 'String.new' attr_sec_accessor :panorama_hue, :fog_hue, :fog_zoom, 1 attr_sec_accessor :fog_opacity, :fog_blend_type, 0 attr_sec_accessor :fog_sx, :fog_sy, :fog_ox, :fog_oy, 0 attr_sec_accessor :fog_tone, :fog_tone_target, 'Tone.new(0,0,0)' attr_sec_accessor :multi_layer_condition_true, 'Array.new' attr_sec_accessor :multi_layer_condition_false, 'Array.new' attr_sec_reader :xpmap, 'Array.new' attr_sec_reader :vxamap, 'Array.new' #-------------------------------------------------------------------------- # * Class Variable #-------------------------------------------------------------------------- tileset = "Data/Tilesets.rxdata" @@tileset_xp = File.exist?(tileset) ? load_data(tileset) : nil @@rpgmakerxp = LiTTleDRAgo::XP #-------------------------------------------------------------------------- # * Define Method #-------------------------------------------------------------------------- unless @@rpgmakerxp define_method(:zoom_x) { 1 } define_method(:zoom_y) { 1 } end #-------------------------------------------------------------------------- # * Undefine Method #-------------------------------------------------------------------------- if !@@rpgmakerxp && method_defined?(:zoom) undef :zoom, :zoom_in, :zoom_out, :zoom_x=, :zoom_y=, :start_zoom end #-------------------------------------------------------------------------- # * Alias Listing #-------------------------------------------------------------------------- alias_sec_method :xpmap_loader_setup, :setup alias_sec_method :xpmap_loader_update, :update alias_sec_method :layered_tiles_flag_vxlayer, :layered_tiles_flag? #-------------------------------------------------------------------------- # * Aliased Method : setup #-------------------------------------------------------------------------- def setup(*args) xpmap_loader_setup(*args) setup_map_xp setup_map_layer end #-------------------------------------------------------------------------- # * New Method : setup_map_xp #-------------------------------------------------------------------------- def setup_map_xp reset_map_xp map = sprintf("Map%03d",@map_id) b = "The dimension on %1$s.rvdata2 %2$s and %1$s.rxdata %3$s is not same" return unless @@tileset_xp && File.exist?("Data/"+map+".rxdata") return if @@rpgmakerxp return if self.xpmap.detect {|xp| xp && xp[:map_id] == @map_id } _xp = load_map_data(@map_id,:rxdata) _sz = [@map,_xp].flatten.map {|m| [m.width,m.height]}.uniq fail( sprintf( b, map, *_sz.map {|s| s.inspect})) if _sz.size > 1 self.xpmap[0] = {} self.xpmap[0][:map_id] = @map_id self.xpmap[0][:map] = _xp self.xpmap[0][:tileset_id] = _xp.tileset_id _xp = @@tileset_xp[_xp.tileset_id] self.xpmap[0][:tileset_name] = _xp.tileset_name self.xpmap[0][:autotile_names] = _xp.autotile_names self.xpmap[0][:passages] = _xp.passages self.xpmap[0][:priorities] = _xp.priorities self.xpmap[0][:terrain_tags] = _xp.terrain_tags @panorama_name = _xp.panorama_name @panorama_hue = _xp.panorama_hue @fog_name = _xp.fog_name @fog_hue = _xp.fog_hue @fog_opacity = _xp.fog_opacity @fog_blend_type = _xp.fog_blend_type @fog_zoom = _xp.fog_zoom @fog_sx = _xp.fog_sx @fog_sy = _xp.fog_sy end #-------------------------------------------------------------------------- # * Aliased Method : update #-------------------------------------------------------------------------- def update(*args) xpmap_loader_update(*args) update_fog unless @@rpgmakerxp update_layer_condition end #-------------------------------------------------------------------------- # * New Method : reset_map_xp #-------------------------------------------------------------------------- def reset_map_xp self.xpmap.clear self.vxamap.clear self.multi_layer_condition_true.clear self.multi_layer_condition_false.clear @mapinfo = nil self.clear_panorama unless @@rpgmakerxp self.clear_fog unless @@rpgmakerxp end #-------------------------------------------------------------------------- # * New Method : setup_map_layer #-------------------------------------------------------------------------- def setup_map_layer layered = false self.child_ids.each_with_index do |submap_id,index| next if self.vxamap.detect {|vxa| vxa && vxa[:map_id] == submap_id } next if self.xpmap.detect {|xp| xp && xp[:map_id] == submap_id } next unless (map_info = mapInfo[submap_id]).not.nil? next unless (map_info.parent_id == map_id) join = map_info.name[/\[\s*join\s*\]/] if map_info.name[/\[\s*join:\s*([-]?\d+)\s*\]/] id = $1.to_i cond = LiTTleDRAgo::MultiLayerCond.call(id) if !cond && multi_layer_condition_true.not.include?(id) @multi_layer_condition_true << id end if cond && multi_layer_condition_false.not.include?(id) @multi_layer_condition_false << id end join ||= cond end next unless join map = sprintf("Map%03d",submap_id) org = sprintf("Map%03d",map_id) notsame = "The dimension of Parent map and Child map must be same" if @@tileset_xp && File.exist?("Data/"+map+".rxdata") _xp = load_map_data(submap_id,:rxdata) _sz = [@map,_xp].flatten.map {|m| [m.width,m.height]}.uniq _sz.size > 1 && fail(notsame) self.xpmap[index+1] = {} self.xpmap[index+1][:map_id] = submap_id self.xpmap[index+1][:map] = _xp self.xpmap[index+1][:tileset_id] = _xp.tileset_id _xp = @@tileset_xp[_xp.tileset_id] self.xpmap[index+1][:tileset_name] = _xp.tileset_name self.xpmap[index+1][:autotile_names] = _xp.autotile_names self.xpmap[index+1][:passages] = _xp.passages self.xpmap[index+1][:priorities] = _xp.priorities self.xpmap[index+1][:terrain_tags] = _xp.terrain_tags elsif File.exist?("Data/"+map+".rvdata2") _vxa = load_map_data(submap_id,:rvdata2) _sz = [@map,_vxa].flatten.map {|m| [m.width,m.height]}.uniq _sz.size > 1 && fail(notsame) self.vxamap[index] = {} self.vxamap[index][:map_id] = submap_id self.vxamap[index][:map] = _vxa self.vxamap[index][:tileset_id] = _vxa.tileset_id tileset = $data_tilesets[_vxa.tileset_id] self.vxamap[index][:tileset] = tileset end layered = _xp || _vxa end spriteset.create_multi_layer if spriteset end #-------------------------------------------------------------------------- # * New Method : update_layer_condition #-------------------------------------------------------------------------- def update_layer_condition meth = LiTTleDRAgo::MultiLayerCond condition = multi_layer_condition_true.any? {|id| meth.call(id) } || multi_layer_condition_false.any? {|id| meth.not.call(id)} condition && [setup_map_xp, setup_map_layer] end #-------------------------------------------------------------------------- # * New Method : reset_fog_variable #-------------------------------------------------------------------------- def reset_fog_variable @fog_ox = @fog_oy = @fog_tone = @fog_tone_target = nil @fog_tone_duration = @fog_opacity_duration = @fog_opacity_target = 0 end #-------------------------------------------------------------------------- # * New Method : start_fog_tone_change #-------------------------------------------------------------------------- unless method_defined?(:start_fog_tone_change) def start_fog_tone_change(tone, duration) @fog_tone_target = tone.clone @fog_tone_duration = duration if @fog_tone_duration == 0 @fog_tone = @fog_tone_target.clone end end end #-------------------------------------------------------------------------- # * New Method : start_fog_opacity_chang #-------------------------------------------------------------------------- unless method_defined?(:start_fog_opacity_change) def start_fog_opacity_change(opacity, duration) @fog_opacity_target = opacity * 1.0 @fog_opacity_duration = duration if @fog_opacity_duration == 0 @fog_opacity = @fog_opacity_target end end end #-------------------------------------------------------------------------- # * New Method : change_panorama #-------------------------------------------------------------------------- def change_panorama(panorama_name = '',panorama_hue = 0) @panorama_name = panorama_name @panorama_hue = panorama_hue end #-------------------------------------------------------------------------- # * New Method : clear_panorama #-------------------------------------------------------------------------- def clear_panorama(*args) change_panorama end #-------------------------------------------------------------------------- # * New Method : change_fog #-------------------------------------------------------------------------- def change_fog(name='',hue=0,opac = 60, blend = 0,zoom = 1.0,sx = 0,sy = 0) @fog_name = name @fog_hue = hue @fog_opacity = opac @fog_blend_type = blend @fog_zoom = zoom @fog_sx = sx @fog_sy = sy end #-------------------------------------------------------------------------- # * New Method : clear_fog #-------------------------------------------------------------------------- def clear_fog(*args) change_fog end #-------------------------------------------------------------------------- # * New Method : update_fog #-------------------------------------------------------------------------- unless method_defined?(:update_fog) def update_fog @fog_ox = fog_ox - fog_sx / 8.0 @fog_oy = fog_oy - fog_sy / 8.0 if (@fog_tone_duration ||= 0) >= 1 d = (@fog_tone_duration ||= 0) target = fog_tone_target fog_tone.red = (fog_tone.red * (d - 1) + target.red) / d fog_tone.green = (fog_tone.green * (d - 1) + target.green) / d fog_tone.blue = (fog_tone.blue * (d - 1) + target.blue) / d fog_tone.gray = (fog_tone.gray * (d - 1) + target.gray) / d @fog_tone_duration -= 1 end if (@fog_opacity_duration ||= 0) >= 1 d = (@fog_opacity_duration ||= 0) @fog_opacity = (fog_opacity * (d-1) + (@fog_opacity_target||=0)) / d @fog_opacity_duration -= 1 end end end #-------------------------------------------------------------------------- # * New Method : tile_id_obj #-------------------------------------------------------------------------- def tile_id_obj(obj, x, y, z) if $game_map.respond_to?(:reverse) && $game_map.reverse && LiTTleDRAgo::XP obj.reverse_data[x, y, z] || 0 else obj.data[x, y, z] || 0 end end #-------------------------------------------------------------------------- # * New Method : collect_flag_tiles_vxa #-------------------------------------------------------------------------- def collect_flag_tiles_vxa(x,y,*flag) result = [] vxamap.compact.each do |map| result += [2, 1, 0].collect do |z| tile_id = tile_id_obj(map[:map],x, y, z) [tile_id] + flag.collect {|s| map[s].flags[tile_id]} end end return result end #-------------------------------------------------------------------------- # * New Method : collect_flag_tiles_xp #-------------------------------------------------------------------------- def collect_flag_tiles_xp(x,y,*flag) result = [] xpmap.compact.each do |map| result += [2, 1, 0].collect do |z| tile_id = tile_id_obj(map[:map],x, y, z) [tile_id] + flag.collect {|s| map[s][tile_id]} end end return result end #-------------------------------------------------------------------------- # * New Method : collect_flag_tiles_original #-------------------------------------------------------------------------- def collect_flag_tiles_original(x,y,*flag) all_tiles_rep(x, y).collect do |t_id| @@rpgmakerxp ? [t_id] + flag.collect {|map| map[t_id]} : [t_id, tileset.flags[t_id]] end end #-------------------------------------------------------------------------- # * Aliased Method : layered_tiles_flag? #-------------------------------------------------------------------------- def layered_tiles_flag?(x, y, bit) xp = collect_flag_tiles_xp(x,y,:passages) vxa = collect_flag_tiles_vxa(x,y,:tileset) original = collect_flag_tiles_original(x,y,@passages) if @@rpgmakerxp result = (xp + vxa + original).any? { |id,flag| flag & bit != 0 } else result = layered_tiles_flag_vxlayer(x, y, bit) result ||= (xp + vxa ).any? { |id,flag| flag & bit != 0 } end return result end #-------------------------------------------------------------------------- # * Overwriten Method : check_passage #-------------------------------------------------------------------------- def check_passage(x, y, bit) original = collect_flag_tiles_original(x,y,@passages) xp = collect_flag_tiles_xp(x,y,:passages) vxa = collect_flag_tiles_vxa(x,y,:tileset) ( xp + vxa + original ).each do |t_id,flag,prio| next if flag & 0x10 != 0 # [☆]: No effect on passage #return true if flag & bit == 0 # [○] : Passable return false if flag & bit != 0 # [×] : Impassable return false if flag & bit == bit # [×] : Impassable return true if prio && prio == 0 # [○] : Passable end return true#false # Impassable end #-------------------------------------------------------------------------- # * Overwriten Method : terrain_tag #-------------------------------------------------------------------------- def terrain_tag(x, y) return 0 unless valid?(x, y) original = collect_flag_tiles_original(x,y,@terrain_tags) xp = collect_flag_tiles_xp(x,y,:terrain_tags) vxa = collect_flag_tiles_vxa(x,y,:tileset).map {|t| t >> 12} (xp + vxa).each { |t_id,tag| return tag if tag > 0 } (original).each do |t_id,flag| tag = @@rpgmakerxp ? flag : flag >> 12 return tag if tag > 0 end return 0 end #-------------------------------------------------------------------------- # * Overwriten Method : passable? #-------------------------------------------------------------------------- if @@rpgmakerxp def passable?(x, y, d, s = nil) original = (event_tiles(x, y, s) + layered_tiles(x, y)).map do |t_id| [t_id, @passages[t_id], @priorities[t_id]] end xp = collect_flag_tiles_xp(x,y,:passages,:priorities) vxa = collect_flag_tiles_vxa(x,y,:tileset) bit = (1 << (d / 2 - 1)) & 0x0f (xp + vxa + original ).each do |t_id,flag,prio| next if flag & 0x10 != 0 # [☆]: No effect on passage return false if flag & bit != 0 # [×] : Impassable return false if flag & 0x0f == 0x0f # [×] : Impassable return true if prio && prio == 0 # [○] : Passable end return true # [○] : Passable end #-------------------------------------------------------------------------- # * Overwriten Method : bush? #-------------------------------------------------------------------------- def bush?(x, y) valid?(x, y) && layered_tiles_flag?(x, y, 0x40) end #-------------------------------------------------------------------------- # * Overwriten Method : counter? #-------------------------------------------------------------------------- def counter?(x, y) valid?(x, y) && layered_tiles_flag?(x, y, 0x80) end end #-------------------------------------------------------------------------- # * New Method : event_tiles #-------------------------------------------------------------------------- def event_tiles(x, y, s = nil) e = events_xy(x,y).select {|e| e.tile_id > 0 && e != s && !e.through} e.collect {|event| event.tile_id } end #-------------------------------------------------------------------------- # * Replicated Method : layered_tiles #-------------------------------------------------------------------------- unless method_defined?(:layered_tiles) def layered_tiles(x, y) [2, 1, 0].collect {|z| tile_id_obj(@map, x, y, z) } end end #-------------------------------------------------------------------------- # * Replicated Method : all_tiles_rep #-------------------------------------------------------------------------- unless method_defined?(:all_tiles_rep) def all_tiles_rep(x, y) event_tiles(x, y) + layered_tiles(x,y) end end #-------------------------------------------------------------------------- # * Replicated Method : events_xy #-------------------------------------------------------------------------- unless method_defined?(:events_xy) def events_xy(x, y) @events.values.select {|event| event.x == x && event.y == y } end end end #============================================================================== # ** RPG #------------------------------------------------------------------------------ # #============================================================================== module RPG #============================================================================ # ** Map #---------------------------------------------------------------------------- # #============================================================================ class Map attr_accessor :tileset_id attr_sec_accessor :reverse_data, 'data.reverse(true,false,false)' end #============================================================================ # ** Tileset #---------------------------------------------------------------------------- # #============================================================================ class Tileset #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_sec_accessor :tileset_name, :panorama_name, :fog_name, :battleback_name, 'String.new' attr_sec_accessor :autotile_names, '[String.new]*7' attr_sec_accessor :panorama_hue, :fog_hue, :fog_blend_type, :fog_sx, :fog_sy, 0 attr_sec_accessor :passages, :priorities, :terrain_tags, 'Table.new(384)' attr_sec_accessor :fog_zoom, 200 attr_sec_accessor :fog_opacity, 64 end end #============================================================================== # ** Spriteset_Map #------------------------------------------------------------------------------ # This class brings together map screen sprites, tilemaps, etc. It's used # within the Scene_Map class. #============================================================================== class Spriteset_Map #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_sec_reader :tilemap_layer, 'Array.new' #-------------------------------------------------------------------------- # * Class Variable #-------------------------------------------------------------------------- @@rpgmakerxp = LiTTleDRAgo::XP @@fog_opacity = @@panorama_opacity = 0 #-------------------------------------------------------------------------- # * Alias Listing #-------------------------------------------------------------------------- alias_sec_method :update_multi_layer_cr, :update alias_sec_method :dispose_multi_layer_cr, :dispose alias_sec_method :reload_tilemap_multi_layer_cr, :reload_tilemap alias_method :fog_fix_initialize, :initialize #-------------------------------------------------------------------------- # * Aliased method: initialize #-------------------------------------------------------------------------- def initialize(*args) fog_fix_initialize @fog.opacity = @@fog_opacity || 0 if @fog @panorama.opacity = @@panorama_opacity || 0 if @panorama end #-------------------------------------------------------------------------- # * New Method : create_multi_layer #-------------------------------------------------------------------------- def create_multi_layer dispose_multi_layer @xpmap_size = $game_map.xpmap.size @vxamap_size = $game_map.vxamap.size $game_map.vxamap.compact.each do |data| next if @@rpgmakerxp tilemap_layer[(i = tilemap_layer.size)] = Tilemap.new(@viewport1) create_layer_tilemap(tilemap_layer[i],data) end $game_map.xpmap.compact.each do |data| _data = data.clone _data[:tileset] = LiTTleDRAgo.cache.tileset(data[:tileset_name]) _data[:autotiles] = [] if (tilemap = ([@tilemap]+tilemap_layer).detect {|t| obj_is_ztilemap?(t)}) data[:autotile_names].each_with_index do |name, i| _data[:autotiles][i] = LiTTleDRAgo.cache.autotile_cr_tilemap(name) end [tilemap.extra_map_data.push(_data), tilemap.refresh] && next end unless @@rpgmakerxp cr = "This script needs Drago - Custom Resolution ver 2.12 or above" ($imported[:drg_custom_resolution] || 0) >= 2.12 || raise(cr) end klass = @@rpgmakerxp ? @tilemap.class : ZTilemap tilemap_layer[(i = tilemap_layer.size)] = klass.new(@viewport1) create_layer_tilemap(tilemap_layer[i], _data) end @viewport_screen_width = 0 end #-------------------------------------------------------------------------- # * New Method : create_layer_tilemap #-------------------------------------------------------------------------- def create_layer_tilemap(tilemap,data) if (@@rpgmakerxp && tilemap.is_a?(Tilemap)) || obj_is_ztilemap?(tilemap) if obj_is_ztilemap?(tilemap) temp = tilemap.sprite_compact tilemap.sprite_compact = false end (0..6).each do |i| name = data[:autotile_names][i] bitmap = LiTTleDRAgo.cache.autotile(name) @force_tilemap_enabled = true if bitmap.height == 192 tilemap.autotiles[i] = obj_is_ztilemap?(tilemap) ? LiTTleDRAgo.cache.autotile_cr_tilemap(name) : bitmap end tilemap.tileset = data[:tileset] tilemap.priorities = data[:priorities] tilemap.map_data = data[:map].data update_layer_tilemap(tilemap) tilemap.update tilemap.sprite_compact = temp if obj_is_ztilemap?(tilemap) else tilemap.map_data = data[:map].data data[:tileset].tileset_names.each_with_index do |name, i| tilemap.bitmaps[i] = LiTTleDRAgo.cache.tileset(name) end tilemap.flags = data[:tileset].flags update_layer_tilemap(tilemap) tilemap.update end end #-------------------------------------------------------------------------- # * Aliased Method : update #-------------------------------------------------------------------------- def update unless @@rpgmakerxp update_panorama update_fog update_panorama_plane update_fog_plane end update_multi_layer_cr if @xpmap_size != $game_map.xpmap.size || @vxamap_size != $game_map.vxamap.size create_multi_layer end update_multi_layer end #-------------------------------------------------------------------------- # * New Method : dispose_multi_layer #-------------------------------------------------------------------------- def dispose_multi_layer tilemap_layer.dispose tilemap_layer.clear end #-------------------------------------------------------------------------- # * New Method : update_multi_layer #-------------------------------------------------------------------------- def update_multi_layer tilemap_layer.each { |t| update_layer_tilemap(t) } end #-------------------------------------------------------------------------- # * New Method : update_layer_tilemap #-------------------------------------------------------------------------- def update_layer_tilemap(tilemap) if obj_is_ztilemap?(tilemap) if @@rpgmakerxp tilemap.ox = @tilemap.ox tilemap.oy = @tilemap.oy tilemap.zoom_x = $game_map.zoom_x tilemap.zoom_y = $game_map.zoom_y tilemap.opacity = $game_map.tilemap_opacity tilemap.hue = $game_map.tilemap_hue tilemap.tone = $game_map.tilemap_tone else tilemap.ox = $game_map.display_x * tilemap_move_multiplier tilemap.oy = $game_map.display_y * tilemap_move_multiplier end else tilemap.ox = @tilemap.ox rescue $game_map.display_x * tilemap_move_multiplier tilemap.oy = @tilemap.oy rescue $game_map.display_y * tilemap_move_multiplier end tilemap.update end #-------------------------------------------------------------------------- # * New Method : obj_is_ztilemap? #-------------------------------------------------------------------------- def obj_is_ztilemap?(obj) defined?(ZTilemap) && obj.is_a?(ZTilemap) end #-------------------------------------------------------------------------- # * Aliased Method : dispose #-------------------------------------------------------------------------- def dispose dispose_multi_layer dispose_multi_layer_cr [dispose_fog, dispose_panorama] rescue nil unless @@rpgmakerxp end #-------------------------------------------------------------------------- # * Aliased Method : reload_tilemap #-------------------------------------------------------------------------- def reload_tilemap reload_tilemap_multi_layer_cr create_multi_layer end #-------------------------------------------------------------------------- # * New Method : tilemap_move_multiplier #-------------------------------------------------------------------------- def tilemap_move_multiplier n = 1.00 / 4 n = 1.00 / 8 if LiTTleDRAgo::VX n = 1.00 * 32 if LiTTleDRAgo::VXA return n end #-------------------------------------------------------------------------- # * New Method : update_panorama #-------------------------------------------------------------------------- unless method_defined?(:update_panorama) def update_panorama if @panorama.nil? @panorama = Plane.new(@viewport1) @panorama.opacity = (@@panorama_opacity ||= 0) @panorama.z = -1000 end if @panorama_name != $game_map.panorama_name or @panorama_hue != $game_map.panorama_hue @panorama_name = $game_map.panorama_name @panorama_hue = $game_map.panorama_hue if @panorama.bitmap.respond_to?(:dispose) && @panorama.bitmap.not.disposed? @panorama.bitmap.dispose @panorama.bitmap = nil end if @panorama_name != '' @panorama.bitmap = LiTTleDRAgo.cache.panorama(@panorama_name, @panorama_hue) end Graphics.frame_reset end end end #-------------------------------------------------------------------------- # * New Method : update_fog #-------------------------------------------------------------------------- unless method_defined?(:update_fog) def update_fog if @fog.nil? @fog = Plane.new(@viewport1) @fog.opacity = (@@fog_opacity ||= 0) @fog.z = 3000 end if @fog_name != $game_map.fog_name or @fog_hue != $game_map.fog_hue @fog_name = $game_map.fog_name @fog_hue = $game_map.fog_hue if @fog.bitmap.respond_to?(:dispose) && @fog.bitmap.not.disposed? @fog.bitmap.dispose @fog.bitmap = nil end if @fog_name != '' @fog.bitmap = LiTTleDRAgo.cache.fog(@fog_name, @fog_hue) end Graphics.frame_reset end end end #-------------------------------------------------------------------------- # * New Method : update_panorama_plane #-------------------------------------------------------------------------- unless method_defined?(:update_panorama_plane) def update_panorama_plane @panorama.ox = $game_map.display_x / 8 @panorama.oy = $game_map.display_y / 8 end end #-------------------------------------------------------------------------- # * New Method : update_fog_plane #-------------------------------------------------------------------------- unless method_defined?(:update_fog_plane) def update_fog_plane @fog.zoom_x = $game_map.fog_zoom / 100.0 @fog.zoom_y = $game_map.fog_zoom / 100.0 @fog.opacity = $game_map.fog_opacity @fog.blend_type = $game_map.fog_blend_type @fog.ox = $game_map.display_x*tilemap_move_multiplier + $game_map.fog_ox @fog.oy = $game_map.display_y*tilemap_move_multiplier + $game_map.fog_oy @fog.tone = $game_map.fog_tone end end #-------------------------------------------------------------------------- # * New Method : dispose_fog #-------------------------------------------------------------------------- unless method_defined?(:dispose_fog) def dispose_fog unless @fog.nil? || @fog.disposed? @@fog_opacity = @fog.opacity @fog.dispose end end end #-------------------------------------------------------------------------- # * New Method : dispose_panorama #-------------------------------------------------------------------------- unless method_defined?(:dispose_panorama) def dispose_panorama unless @panorama.nil? || @panorama.disposed? @@panorama_opacity = @panorama.opacity @panorama.dispose end end end end #============================================================================== # ** RPG::Cache #============================================================================== ModCache = LiTTleDRAgo.cache module ModCache #---------------------------------------------------------------------------- # * Self #---------------------------------------------------------------------------- class << self #-------------------------------------------------------------------------- # * Get Autotile Graphic #-------------------------------------------------------------------------- unless method_defined?(:autotile) def autotile(filename) load_bitmap("Graphics/Autotiles/", filename) end end #-------------------------------------------------------------------------- # * Get Panorama Graphic #-------------------------------------------------------------------------- unless method_defined?(:panorama) def panorama(filename, hue = 0) load_bitmap("Graphics/Panoramas/", filename, hue) end end #-------------------------------------------------------------------------- # * Get Fog Graphic #-------------------------------------------------------------------------- unless method_defined?(:fog) def fog(filename, hue = 0) load_bitmap("Graphics/Fogs/", filename, hue) end end end end
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# XP地图读取及多层地图制作
# 版本: 2.05
# 作者 : LiTTleDRAgo
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
($imported ||= {})[:drg_xp_map_loader] = 2.05
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
#
# 介绍:
#
# XP地图读取及多层地图制作的整合脚本第2版。
#
# 特性:
#
# 读取RMXP制作的地图:
# - 在Drago的Custom Resolution II这一脚本中,缩放功能不可使用。
# - 可用于RMVA读取RMXP的地图,不可反向用RMXP读取RMVA的地图。
# - 只在RMVA可用。
#
# 多层地图:
# - 层数越多卡得越厉害。
#
# 译者补充,原文来自littledrago.blogspot.jp/2014/08/rgss3-xp-map-loader-ii.html)
# 使用方法:
# - 需要前置脚本Drago - Core Engine和Custom Resolution(超长,懒得翻译用法)
#
# - 读取RMXP制作的地图:先在RMXP中做好你的地图,然后把所有地图涉及的文件复制到
# 你的RMVA工程的文件夹下对应位置。
# 包括:原工程\Data文件夹下所有名为MapXXX.rxdata(XXX是地图ID),Tileset.rxdata以及
# 原工程\Graphics文件夹下的Autotiles, Fog, Panorama,Tileset这四个文件夹所有内容。
# - 请注意把需要对应的RMVA地图的文件名与复制来的XP地图文件名一一对应起来。
#
# - 多层地图:
# - 在需要使用多层地图的原地图下面建立一个名叫"[join]"的子地图。
# - 可以用写标签[join:1][join:2]等指定多层。是否显示的条件可以在下面设定。
# - 同类脚本可能会冲突
# - 需要额外注意A5和B图块中一些透明但不通行的图块,如果通行度不正常请首先排查。
#
# 注意:
# - 此脚本只调用RMXP工程中的地图、远景、雾图形、通行度、灌木柜台等特殊地形标志,
# 其余图像文件及地图涉及到的BGM、BGS仍沿用原本的RMVA工程。
#
#==============================================================================
module LiTTleDRAgo
# Condition for layer to be joined
MultiLayerCond = proc do |i|
condition = {
1 => $game_switches[1], # 1号开关开启时本层显示,否则不显示
2 => $game_variables[1] == 200, #1号变量=200时显示,否则不显示
}
condition[i] #请勿删除本行
end
end
core = "This script needs Drago - Core Engine ver 1.44 or above"
implemented = "%1$s has already implemented, Please remove the %1$s script"
($imported[:drg_core_engine] || 0) >= 1.44 || raise(core)
($imported[:drg_multi_layer])&& raise(sprintf(implemented,"Multi Layer"))
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
# This class handles maps. It includes scrolling and passage determination
# functions. The instance of this class is referenced by $game_map.
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_sec_accessor :panorama_name, :fog_name, 'String.new'
attr_sec_accessor :panorama_hue, :fog_hue, :fog_zoom, 1
attr_sec_accessor :fog_opacity, :fog_blend_type, 0
attr_sec_accessor :fog_sx, :fog_sy, :fog_ox, :fog_oy, 0
attr_sec_accessor :fog_tone, :fog_tone_target, 'Tone.new(0,0,0)'
attr_sec_accessor :multi_layer_condition_true, 'Array.new'
attr_sec_accessor :multi_layer_condition_false, 'Array.new'
attr_sec_reader :xpmap, 'Array.new'
attr_sec_reader :vxamap, 'Array.new'
#--------------------------------------------------------------------------
# * Class Variable
#--------------------------------------------------------------------------
tileset = "Data/Tilesets.rxdata"
@@tileset_xp = File.exist?(tileset) ? load_data(tileset) : nil
@@rpgmakerxp = LiTTleDRAgo::XP
#--------------------------------------------------------------------------
# * Define Method
#--------------------------------------------------------------------------
unless @@rpgmakerxp
define_method(:zoom_x) { 1 }
define_method(:zoom_y) { 1 }
end
#--------------------------------------------------------------------------
# * Undefine Method
#--------------------------------------------------------------------------
if !@@rpgmakerxp && method_defined?(:zoom)
undef :zoom, :zoom_in, :zoom_out, :zoom_x=, :zoom_y=, :start_zoom
end
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_sec_method :xpmap_loader_setup, :setup
alias_sec_method :xpmap_loader_update, :update
alias_sec_method :layered_tiles_flag_vxlayer, :layered_tiles_flag?
#--------------------------------------------------------------------------
# * Aliased Method : setup
#--------------------------------------------------------------------------
def setup(*args)
xpmap_loader_setup(*args)
setup_map_xp
setup_map_layer
end
#--------------------------------------------------------------------------
# * New Method : setup_map_xp
#--------------------------------------------------------------------------
def setup_map_xp
reset_map_xp
map = sprintf("Map%03d",@map_id)
b = "The dimension on %1$s.rvdata2 %2$s and %1$s.rxdata %3$s is not same"
return unless @@tileset_xp && File.exist?("Data/"+map+".rxdata")
return if @@rpgmakerxp
return if self.xpmap.detect {|xp| xp && xp[:map_id] == @map_id }
_xp = load_map_data(@map_id,:rxdata)
_sz = [@map,_xp].flatten.map {|m| [m.width,m.height]}.uniq
fail( sprintf( b, map, *_sz.map {|s| s.inspect})) if _sz.size > 1
self.xpmap[0] = {}
self.xpmap[0][:map_id] = @map_id
self.xpmap[0][:map] = _xp
self.xpmap[0][:tileset_id] = _xp.tileset_id
_xp = @@tileset_xp[_xp.tileset_id]
self.xpmap[0][:tileset_name] = _xp.tileset_name
self.xpmap[0][:autotile_names] = _xp.autotile_names
self.xpmap[0][:passages] = _xp.passages
self.xpmap[0][:priorities] = _xp.priorities
self.xpmap[0][:terrain_tags] = _xp.terrain_tags
@panorama_name = _xp.panorama_name
@panorama_hue = _xp.panorama_hue
@fog_name = _xp.fog_name
@fog_hue = _xp.fog_hue
@fog_opacity = _xp.fog_opacity
@fog_blend_type = _xp.fog_blend_type
@fog_zoom = _xp.fog_zoom
@fog_sx = _xp.fog_sx
@fog_sy = _xp.fog_sy
end
#--------------------------------------------------------------------------
# * Aliased Method : update
#--------------------------------------------------------------------------
def update(*args)
xpmap_loader_update(*args)
update_fog unless @@rpgmakerxp
update_layer_condition
end
#--------------------------------------------------------------------------
# * New Method : reset_map_xp
#--------------------------------------------------------------------------
def reset_map_xp
self.xpmap.clear
self.vxamap.clear
self.multi_layer_condition_true.clear
self.multi_layer_condition_false.clear
@mapinfo = nil
self.clear_panorama unless @@rpgmakerxp
self.clear_fog unless @@rpgmakerxp
end
#--------------------------------------------------------------------------
# * New Method : setup_map_layer
#--------------------------------------------------------------------------
def setup_map_layer
layered = false
self.child_ids.each_with_index do |submap_id,index|
next if self.vxamap.detect {|vxa| vxa && vxa[:map_id] == submap_id }
next if self.xpmap.detect {|xp| xp && xp[:map_id] == submap_id }
next unless (map_info = mapInfo[submap_id]).not.nil?
next unless (map_info.parent_id == map_id)
join = map_info.name[/\[\s*join\s*\]/]
if map_info.name[/\[\s*join:\s*([-]?\d+)\s*\]/]
id = $1.to_i
cond = LiTTleDRAgo::MultiLayerCond.call(id)
if !cond && multi_layer_condition_true.not.include?(id)
@multi_layer_condition_true << id
end
if cond && multi_layer_condition_false.not.include?(id)
@multi_layer_condition_false << id
end
join ||= cond
end
next unless join
map = sprintf("Map%03d",submap_id)
org = sprintf("Map%03d",map_id)
notsame = "The dimension of Parent map and Child map must be same"
if @@tileset_xp && File.exist?("Data/"+map+".rxdata")
_xp = load_map_data(submap_id,:rxdata)
_sz = [@map,_xp].flatten.map {|m| [m.width,m.height]}.uniq
_sz.size > 1 && fail(notsame)
self.xpmap[index+1] = {}
self.xpmap[index+1][:map_id] = submap_id
self.xpmap[index+1][:map] = _xp
self.xpmap[index+1][:tileset_id] = _xp.tileset_id
_xp = @@tileset_xp[_xp.tileset_id]
self.xpmap[index+1][:tileset_name] = _xp.tileset_name
self.xpmap[index+1][:autotile_names] = _xp.autotile_names
self.xpmap[index+1][:passages] = _xp.passages
self.xpmap[index+1][:priorities] = _xp.priorities
self.xpmap[index+1][:terrain_tags] = _xp.terrain_tags
elsif File.exist?("Data/"+map+".rvdata2")
_vxa = load_map_data(submap_id,:rvdata2)
_sz = [@map,_vxa].flatten.map {|m| [m.width,m.height]}.uniq
_sz.size > 1 && fail(notsame)
self.vxamap[index] = {}
self.vxamap[index][:map_id] = submap_id
self.vxamap[index][:map] = _vxa
self.vxamap[index][:tileset_id] = _vxa.tileset_id
tileset = $data_tilesets[_vxa.tileset_id]
self.vxamap[index][:tileset] = tileset
end
layered = _xp || _vxa
end
spriteset.create_multi_layer if spriteset
end
#--------------------------------------------------------------------------
# * New Method : update_layer_condition
#--------------------------------------------------------------------------
def update_layer_condition
meth = LiTTleDRAgo::MultiLayerCond
condition = multi_layer_condition_true.any? {|id| meth.call(id) } ||
multi_layer_condition_false.any? {|id| meth.not.call(id)}
condition && [setup_map_xp, setup_map_layer]
end
#--------------------------------------------------------------------------
# * New Method : reset_fog_variable
#--------------------------------------------------------------------------
def reset_fog_variable
@fog_ox =
@fog_oy =
@fog_tone =
@fog_tone_target = nil
@fog_tone_duration =
@fog_opacity_duration =
@fog_opacity_target = 0
end
#--------------------------------------------------------------------------
# * New Method : start_fog_tone_change
#--------------------------------------------------------------------------
unless method_defined?(:start_fog_tone_change)
def start_fog_tone_change(tone, duration)
@fog_tone_target = tone.clone
@fog_tone_duration = duration
if @fog_tone_duration == 0
@fog_tone = @fog_tone_target.clone
end
end
end
#--------------------------------------------------------------------------
# * New Method : start_fog_opacity_chang
#--------------------------------------------------------------------------
unless method_defined?(:start_fog_opacity_change)
def start_fog_opacity_change(opacity, duration)
@fog_opacity_target = opacity * 1.0
@fog_opacity_duration = duration
if @fog_opacity_duration == 0
@fog_opacity = @fog_opacity_target
end
end
end
#--------------------------------------------------------------------------
# * New Method : change_panorama
#--------------------------------------------------------------------------
def change_panorama(panorama_name = '',panorama_hue = 0)
@panorama_name = panorama_name
@panorama_hue = panorama_hue
end
#--------------------------------------------------------------------------
# * New Method : clear_panorama
#--------------------------------------------------------------------------
def clear_panorama(*args)
change_panorama
end
#--------------------------------------------------------------------------
# * New Method : change_fog
#--------------------------------------------------------------------------
def change_fog(name='',hue=0,opac = 60, blend = 0,zoom = 1.0,sx = 0,sy = 0)
@fog_name = name
@fog_hue = hue
@fog_opacity = opac
@fog_blend_type = blend
@fog_zoom = zoom
@fog_sx = sx
@fog_sy = sy
end
#--------------------------------------------------------------------------
# * New Method : clear_fog
#--------------------------------------------------------------------------
def clear_fog(*args)
change_fog
end
#--------------------------------------------------------------------------
# * New Method : update_fog
#--------------------------------------------------------------------------
unless method_defined?(:update_fog)
def update_fog
@fog_ox = fog_ox - fog_sx / 8.0
@fog_oy = fog_oy - fog_sy / 8.0
if (@fog_tone_duration ||= 0) >= 1
d = (@fog_tone_duration ||= 0)
target = fog_tone_target
fog_tone.red = (fog_tone.red * (d - 1) + target.red) / d
fog_tone.green = (fog_tone.green * (d - 1) + target.green) / d
fog_tone.blue = (fog_tone.blue * (d - 1) + target.blue) / d
fog_tone.gray = (fog_tone.gray * (d - 1) + target.gray) / d
@fog_tone_duration -= 1
end
if (@fog_opacity_duration ||= 0) >= 1
d = (@fog_opacity_duration ||= 0)
@fog_opacity = (fog_opacity * (d-1) + (@fog_opacity_target||=0)) / d
@fog_opacity_duration -= 1
end
end
end
#--------------------------------------------------------------------------
# * New Method : tile_id_obj
#--------------------------------------------------------------------------
def tile_id_obj(obj, x, y, z)
if $game_map.respond_to?(:reverse) && $game_map.reverse && LiTTleDRAgo::XP
obj.reverse_data[x, y, z] || 0
else
obj.data[x, y, z] || 0
end
end
#--------------------------------------------------------------------------
# * New Method : collect_flag_tiles_vxa
#--------------------------------------------------------------------------
def collect_flag_tiles_vxa(x,y,*flag)
result = []
vxamap.compact.each do |map|
result += [2, 1, 0].collect do |z|
tile_id = tile_id_obj(map[:map],x, y, z)
[tile_id] + flag.collect {|s| map[s].flags[tile_id]}
end
end
return result
end
#--------------------------------------------------------------------------
# * New Method : collect_flag_tiles_xp
#--------------------------------------------------------------------------
def collect_flag_tiles_xp(x,y,*flag)
result = []
xpmap.compact.each do |map|
result += [2, 1, 0].collect do |z|
tile_id = tile_id_obj(map[:map],x, y, z)
[tile_id] + flag.collect {|s| map[s][tile_id]}
end
end
return result
end
#--------------------------------------------------------------------------
# * New Method : collect_flag_tiles_original
#--------------------------------------------------------------------------
def collect_flag_tiles_original(x,y,*flag)
all_tiles_rep(x, y).collect do |t_id|
@@rpgmakerxp ? [t_id] + flag.collect {|map| map[t_id]} :
[t_id, tileset.flags[t_id]]
end
end
#--------------------------------------------------------------------------
# * Aliased Method : layered_tiles_flag?
#--------------------------------------------------------------------------
def layered_tiles_flag?(x, y, bit)
xp = collect_flag_tiles_xp(x,y,:passages)
vxa = collect_flag_tiles_vxa(x,y,:tileset)
original = collect_flag_tiles_original(x,y,@passages)
if @@rpgmakerxp
result = (xp + vxa + original).any? { |id,flag| flag & bit != 0 }
else
result = layered_tiles_flag_vxlayer(x, y, bit)
result ||= (xp + vxa ).any? { |id,flag| flag & bit != 0 }
end
return result
end
#--------------------------------------------------------------------------
# * Overwriten Method : check_passage
#--------------------------------------------------------------------------
def check_passage(x, y, bit)
original = collect_flag_tiles_original(x,y,@passages)
xp = collect_flag_tiles_xp(x,y,:passages)
vxa = collect_flag_tiles_vxa(x,y,:tileset)
( xp + vxa + original ).each do |t_id,flag,prio|
next if flag & 0x10 != 0 # [☆]: No effect on passage
#return true if flag & bit == 0 # [○] : Passable
return false if flag & bit != 0 # [×] : Impassable
return false if flag & bit == bit # [×] : Impassable
return true if prio && prio == 0 # [○] : Passable
end
return true#false # Impassable
end
#--------------------------------------------------------------------------
# * Overwriten Method : terrain_tag
#--------------------------------------------------------------------------
def terrain_tag(x, y)
return 0 unless valid?(x, y)
original = collect_flag_tiles_original(x,y,@terrain_tags)
xp = collect_flag_tiles_xp(x,y,:terrain_tags)
vxa = collect_flag_tiles_vxa(x,y,:tileset).map {|t| t >> 12}
(xp + vxa).each { |t_id,tag| return tag if tag > 0 }
(original).each do |t_id,flag|
tag = @@rpgmakerxp ? flag : flag >> 12
return tag if tag > 0
end
return 0
end
#--------------------------------------------------------------------------
# * Overwriten Method : passable?
#--------------------------------------------------------------------------
if @@rpgmakerxp
def passable?(x, y, d, s = nil)
original = (event_tiles(x, y, s) + layered_tiles(x, y)).map do |t_id|
[t_id, @passages[t_id], @priorities[t_id]]
end
xp = collect_flag_tiles_xp(x,y,:passages,:priorities)
vxa = collect_flag_tiles_vxa(x,y,:tileset)
bit = (1 << (d / 2 - 1)) & 0x0f
(xp + vxa + original ).each do |t_id,flag,prio|
next if flag & 0x10 != 0 # [☆]: No effect on passage
return false if flag & bit != 0 # [×] : Impassable
return false if flag & 0x0f == 0x0f # [×] : Impassable
return true if prio && prio == 0 # [○] : Passable
end
return true # [○] : Passable
end
#--------------------------------------------------------------------------
# * Overwriten Method : bush?
#--------------------------------------------------------------------------
def bush?(x, y)
valid?(x, y) && layered_tiles_flag?(x, y, 0x40)
end
#--------------------------------------------------------------------------
# * Overwriten Method : counter?
#--------------------------------------------------------------------------
def counter?(x, y)
valid?(x, y) && layered_tiles_flag?(x, y, 0x80)
end
end
#--------------------------------------------------------------------------
# * New Method : event_tiles
#--------------------------------------------------------------------------
def event_tiles(x, y, s = nil)
e = events_xy(x,y).select {|e| e.tile_id > 0 && e != s && !e.through}
e.collect {|event| event.tile_id }
end
#--------------------------------------------------------------------------
# * Replicated Method : layered_tiles
#--------------------------------------------------------------------------
unless method_defined?(:layered_tiles)
def layered_tiles(x, y)
[2, 1, 0].collect {|z| tile_id_obj(@map, x, y, z) }
end
end
#--------------------------------------------------------------------------
# * Replicated Method : all_tiles_rep
#--------------------------------------------------------------------------
unless method_defined?(:all_tiles_rep)
def all_tiles_rep(x, y)
event_tiles(x, y) + layered_tiles(x,y)
end
end
#--------------------------------------------------------------------------
# * Replicated Method : events_xy
#--------------------------------------------------------------------------
unless method_defined?(:events_xy)
def events_xy(x, y)
@events.values.select {|event| event.x == x && event.y == y }
end
end
end
#==============================================================================
# ** RPG
#------------------------------------------------------------------------------
#
#==============================================================================
module RPG
#============================================================================
# ** Map
#----------------------------------------------------------------------------
#
#============================================================================
class Map
attr_accessor :tileset_id
attr_sec_accessor :reverse_data, 'data.reverse(true,false,false)'
end
#============================================================================
# ** Tileset
#----------------------------------------------------------------------------
#
#============================================================================
class Tileset
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_sec_accessor :tileset_name, :panorama_name, :fog_name,
:battleback_name, 'String.new'
attr_sec_accessor :autotile_names, '[String.new]*7'
attr_sec_accessor :panorama_hue, :fog_hue, :fog_blend_type,
:fog_sx, :fog_sy, 0
attr_sec_accessor :passages, :priorities, :terrain_tags, 'Table.new(384)'
attr_sec_accessor :fog_zoom, 200
attr_sec_accessor :fog_opacity, 64
end
end
#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
# This class brings together map screen sprites, tilemaps, etc. It's used
# within the Scene_Map class.
#==============================================================================
class Spriteset_Map
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_sec_reader :tilemap_layer, 'Array.new'
#--------------------------------------------------------------------------
# * Class Variable
#--------------------------------------------------------------------------
@@rpgmakerxp = LiTTleDRAgo::XP
@@fog_opacity = @@panorama_opacity = 0
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_sec_method :update_multi_layer_cr, :update
alias_sec_method :dispose_multi_layer_cr, :dispose
alias_sec_method :reload_tilemap_multi_layer_cr, :reload_tilemap
alias_method :fog_fix_initialize, :initialize
#--------------------------------------------------------------------------
# * Aliased method: initialize
#--------------------------------------------------------------------------
def initialize(*args)
fog_fix_initialize
@fog.opacity = @@fog_opacity || 0 if @fog
@panorama.opacity = @@panorama_opacity || 0 if @panorama
end
#--------------------------------------------------------------------------
# * New Method : create_multi_layer
#--------------------------------------------------------------------------
def create_multi_layer
dispose_multi_layer
@xpmap_size = $game_map.xpmap.size
@vxamap_size = $game_map.vxamap.size
$game_map.vxamap.compact.each do |data|
next if @@rpgmakerxp
tilemap_layer[(i = tilemap_layer.size)] = Tilemap.new(@viewport1)
create_layer_tilemap(tilemap_layer[i],data)
end
$game_map.xpmap.compact.each do |data|
_data = data.clone
_data[:tileset] = LiTTleDRAgo.cache.tileset(data[:tileset_name])
_data[:autotiles] = []
if (tilemap = ([@tilemap]+tilemap_layer).detect {|t| obj_is_ztilemap?(t)})
data[:autotile_names].each_with_index do |name, i|
_data[:autotiles][i] = LiTTleDRAgo.cache.autotile_cr_tilemap(name)
end
[tilemap.extra_map_data.push(_data), tilemap.refresh] && next
end
unless @@rpgmakerxp
cr = "This script needs Drago - Custom Resolution ver 2.12 or above"
($imported[:drg_custom_resolution] || 0) >= 2.12 || raise(cr)
end
klass = @@rpgmakerxp ? @tilemap.class : ZTilemap
tilemap_layer[(i = tilemap_layer.size)] = klass.new(@viewport1)
create_layer_tilemap(tilemap_layer[i], _data)
end
@viewport_screen_width = 0
end
#--------------------------------------------------------------------------
# * New Method : create_layer_tilemap
#--------------------------------------------------------------------------
def create_layer_tilemap(tilemap,data)
if (@@rpgmakerxp && tilemap.is_a?(Tilemap)) || obj_is_ztilemap?(tilemap)
if obj_is_ztilemap?(tilemap)
temp = tilemap.sprite_compact
tilemap.sprite_compact = false
end
(0..6).each do |i|
name = data[:autotile_names][i]
bitmap = LiTTleDRAgo.cache.autotile(name)
@force_tilemap_enabled = true if bitmap.height == 192
tilemap.autotiles[i] = obj_is_ztilemap?(tilemap) ?
LiTTleDRAgo.cache.autotile_cr_tilemap(name) : bitmap
end
tilemap.tileset = data[:tileset]
tilemap.priorities = data[:priorities]
tilemap.map_data = data[:map].data
update_layer_tilemap(tilemap)
tilemap.update
tilemap.sprite_compact = temp if obj_is_ztilemap?(tilemap)
else
tilemap.map_data = data[:map].data
data[:tileset].tileset_names.each_with_index do |name, i|
tilemap.bitmaps[i] = LiTTleDRAgo.cache.tileset(name)
end
tilemap.flags = data[:tileset].flags
update_layer_tilemap(tilemap)
tilemap.update
end
end
#--------------------------------------------------------------------------
# * Aliased Method : update
#--------------------------------------------------------------------------
def update
unless @@rpgmakerxp
update_panorama
update_fog
update_panorama_plane
update_fog_plane
end
update_multi_layer_cr
if @xpmap_size != $game_map.xpmap.size ||
@vxamap_size != $game_map.vxamap.size
create_multi_layer
end
update_multi_layer
end
#--------------------------------------------------------------------------
# * New Method : dispose_multi_layer
#--------------------------------------------------------------------------
def dispose_multi_layer
tilemap_layer.dispose
tilemap_layer.clear
end
#--------------------------------------------------------------------------
# * New Method : update_multi_layer
#--------------------------------------------------------------------------
def update_multi_layer
tilemap_layer.each { |t| update_layer_tilemap(t) }
end
#--------------------------------------------------------------------------
# * New Method : update_layer_tilemap
#--------------------------------------------------------------------------
def update_layer_tilemap(tilemap)
if obj_is_ztilemap?(tilemap)
if @@rpgmakerxp
tilemap.ox = @tilemap.ox
tilemap.oy = @tilemap.oy
tilemap.zoom_x = $game_map.zoom_x
tilemap.zoom_y = $game_map.zoom_y
tilemap.opacity = $game_map.tilemap_opacity
tilemap.hue = $game_map.tilemap_hue
tilemap.tone = $game_map.tilemap_tone
else
tilemap.ox = $game_map.display_x * tilemap_move_multiplier
tilemap.oy = $game_map.display_y * tilemap_move_multiplier
end
else
tilemap.ox = @tilemap.ox rescue $game_map.display_x * tilemap_move_multiplier
tilemap.oy = @tilemap.oy rescue $game_map.display_y * tilemap_move_multiplier
end
tilemap.update
end
#--------------------------------------------------------------------------
# * New Method : obj_is_ztilemap?
#--------------------------------------------------------------------------
def obj_is_ztilemap?(obj)
defined?(ZTilemap) && obj.is_a?(ZTilemap)
end
#--------------------------------------------------------------------------
# * Aliased Method : dispose
#--------------------------------------------------------------------------
def dispose
dispose_multi_layer
dispose_multi_layer_cr
[dispose_fog, dispose_panorama] rescue nil unless @@rpgmakerxp
end
#--------------------------------------------------------------------------
# * Aliased Method : reload_tilemap
#--------------------------------------------------------------------------
def reload_tilemap
reload_tilemap_multi_layer_cr
create_multi_layer
end
#--------------------------------------------------------------------------
# * New Method : tilemap_move_multiplier
#--------------------------------------------------------------------------
def tilemap_move_multiplier
n = 1.00 / 4
n = 1.00 / 8 if LiTTleDRAgo::VX
n = 1.00 * 32 if LiTTleDRAgo::VXA
return n
end
#--------------------------------------------------------------------------
# * New Method : update_panorama
#--------------------------------------------------------------------------
unless method_defined?(:update_panorama)
def update_panorama
if @panorama.nil?
@panorama = Plane.new(@viewport1)
@panorama.opacity = (@@panorama_opacity ||= 0)
@panorama.z = -1000
end
if @panorama_name != $game_map.panorama_name or
@panorama_hue != $game_map.panorama_hue
@panorama_name = $game_map.panorama_name
@panorama_hue = $game_map.panorama_hue
if @panorama.bitmap.respond_to?(:dispose) &&
@panorama.bitmap.not.disposed?
@panorama.bitmap.dispose
@panorama.bitmap = nil
end
if @panorama_name != ''
@panorama.bitmap =
LiTTleDRAgo.cache.panorama(@panorama_name, @panorama_hue)
end
Graphics.frame_reset
end
end
end
#--------------------------------------------------------------------------
# * New Method : update_fog
#--------------------------------------------------------------------------
unless method_defined?(:update_fog)
def update_fog
if @fog.nil?
@fog = Plane.new(@viewport1)
@fog.opacity = (@@fog_opacity ||= 0)
@fog.z = 3000
end
if @fog_name != $game_map.fog_name or @fog_hue != $game_map.fog_hue
@fog_name = $game_map.fog_name
@fog_hue = $game_map.fog_hue
if @fog.bitmap.respond_to?(:dispose) && @fog.bitmap.not.disposed?
@fog.bitmap.dispose
@fog.bitmap = nil
end
if @fog_name != ''
@fog.bitmap = LiTTleDRAgo.cache.fog(@fog_name, @fog_hue)
end
Graphics.frame_reset
end
end
end
#--------------------------------------------------------------------------
# * New Method : update_panorama_plane
#--------------------------------------------------------------------------
unless method_defined?(:update_panorama_plane)
def update_panorama_plane
@panorama.ox = $game_map.display_x / 8
@panorama.oy = $game_map.display_y / 8
end
end
#--------------------------------------------------------------------------
# * New Method : update_fog_plane
#--------------------------------------------------------------------------
unless method_defined?(:update_fog_plane)
def update_fog_plane
@fog.zoom_x = $game_map.fog_zoom / 100.0
@fog.zoom_y = $game_map.fog_zoom / 100.0
@fog.opacity = $game_map.fog_opacity
@fog.blend_type = $game_map.fog_blend_type
@fog.ox = $game_map.display_x*tilemap_move_multiplier + $game_map.fog_ox
@fog.oy = $game_map.display_y*tilemap_move_multiplier + $game_map.fog_oy
@fog.tone = $game_map.fog_tone
end
end
#--------------------------------------------------------------------------
# * New Method : dispose_fog
#--------------------------------------------------------------------------
unless method_defined?(:dispose_fog)
def dispose_fog
unless @fog.nil? || @fog.disposed?
@@fog_opacity = @fog.opacity
@fog.dispose
end
end
end
#--------------------------------------------------------------------------
# * New Method : dispose_panorama
#--------------------------------------------------------------------------
unless method_defined?(:dispose_panorama)
def dispose_panorama
unless @panorama.nil? || @panorama.disposed?
@@panorama_opacity = @panorama.opacity
@panorama.dispose
end
end
end
end
#==============================================================================
# ** RPG::Cache
#==============================================================================
ModCache = LiTTleDRAgo.cache
module ModCache
#----------------------------------------------------------------------------
# * Self
#----------------------------------------------------------------------------
class << self
#--------------------------------------------------------------------------
# * Get Autotile Graphic
#--------------------------------------------------------------------------
unless method_defined?(:autotile)
def autotile(filename)
load_bitmap("Graphics/Autotiles/", filename)
end
end
#--------------------------------------------------------------------------
# * Get Panorama Graphic
#--------------------------------------------------------------------------
unless method_defined?(:panorama)
def panorama(filename, hue = 0)
load_bitmap("Graphics/Panoramas/", filename, hue)
end
end
#--------------------------------------------------------------------------
# * Get Fog Graphic
#--------------------------------------------------------------------------
unless method_defined?(:fog)
def fog(filename, hue = 0)
load_bitmap("Graphics/Fogs/", filename, hue)
end
end
end
end
附带两个作为前置的脚本(未翻译):
#============================================================================== # ** Drago - Core Engine # Version : 1.59 # Contact : littledrago.blogspot.com / forum.chaos-project.com #============================================================================== ($imported ||= {})[:drg_core_engine] = 1.59 # ============================================================================= # NOTE: # ----------------------------------------------------------------------------- # This is a devtool for me to make me easier for scripting # If you want to use this, put above all custom script & below Scene_Debug # # ============================================================================= # DOCUMENTATION: # ----------------------------------------------------------------------------- =begin Version History 1.57 - ▼ Overhaul script (108 minor modification) ▼ Fixed glitch on BitmapDump method ▼ Added Bitmap#rotate90 ▼ Added Bitmap#rotate180 ▼ Added Bitmap#rotate270 1.50 - ▼ Overhaul script (71 minor modification) ▼ Longer script call (RMXP script call bug fix) 1.42 - ▼ Fixed Graphics.fullscreen? 1.40 - ▼ Modified Game_Map#load_event 1.39 - ▼ Fixed glitch at Bitmap#draw_icon ▼ Added Fiber class ▼ Added Game_Map#load_event ▼ Added Game_Map#call_event 1.36 - ▼ Added Color class library 1.34 - ▼ Added Module#define_third_method(sym = nil, _alias = nil, prevent_stack = true, *a, &block) ▼ Added Bitmap#blur 1.31 - ▼ Added Module#attr_sec_reader(symbol, default=0) ▼ Added Module#attr_sec_accessor(symbol, *a, &block) ▼ Added Module#alias_sec_method(sym = nil, *a, &block) ▼ Added Module#define_sec_method(sym = nil, *a, &block) 1.29 - ▼ Added Array#have_all?(array) ▼ Added Array#have_any?(array) 1.27 - ▼ Added Added Graphics.brightness ▼ Added Graphics.wait(frames = 10) ▼ Added Graphics.fadein(frames = 10) ▼ Added Graphics.fadeout(frames = 10) ▼ Added Bitmap#invert ▼ Added Bitmap#invert! ▼ Added Bitmap#brighten(amount = 10) ▼ Added Bitmap#brighten!(amount = 10) ▼ Added Bitmap#darken(amount = 10) ▼ Added Bitmap#darken!(amount = 10) ▼ Added Bitmap#grayscale ▼ Added Bitmap#grayscale! ▼ Added Bitmap#pixelate(size = 10) ▼ Added Bitmap#pixelate!(size = 10) ▼ Added Bitmap#frost(noise = 10) ▼ Added Bitmap#frost!(noise = 10) 1.24 - ▼ Added Viewport#x ▼ Added Viewport#y ▼ Added Viewport#width ▼ Added Viewport#height ▼ Added Viewport#disposed? 1.23 - ▼ Added Window_Base#draw_text (same as Bitmap#draw_text) ▼ Added Window_Base#draw_icon ▼ Added Window_Base#draw_battler ▼ Added Window_Base#draw_picture 1.22 - ▼ Added Game_Map#load_map_data ▼ Added Game_Map#load_event ▼ Rename Array#product => Array#prod (because of conflict with RGSS3) 1.21 - ▼ Fixed Glitch at Bitmap#crop 1.20 - ▼ Fixed Script Hanging Error at Bitmap#export 1.19 - ▼ Added some of RMXP method - Game_System#play_bgm ▼ Added some of RMXP method - Game_System#play_bgs ▼ Added some of RMXP method - Game_System#play_me ▼ Added some of RMXP method - Game_System#play_se 1.18 - ▼ Fixing Backtrace at Array#method_missing 1.17 - ▼ Added Bitmap#flip_vertical ▼ Added Bitmap#flip_vertical! ▼ Added Bitmap#flip_horizontal ▼ Added Bitmap#flip_horizontal! 1.16 - ▼ Added Bitmap#export (dump bitmap into .png files) 1.15 - ▼ Added Game_Characters#character_above? ▼ Added Game_Characters#character_below? ▼ Added Game_Characters#character_right? ▼ Added Game_Characters#character_left? 1.11 - ▼ Fixing Bug at changing screen size 1.10 - ▼ Added Graphics.scale_screen(width, height) 1.00 - ▼ Original Release # ----------------------------------------------------------------------------- # Below is the available command in this script # ----------------------------------------------------------------------------- # * Graphics # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- This command is not recommended to used in RMXP Graphics.scale_screen(width,height) - Resize the screen and stretched it (if not RMXP) into new resolution Graphics.fill_monitor - Maximize the screen and stretched it (if not RMXP) to fill the monitor Graphics.control_screen_size(enable = true) - Enable or disable screen size control by mouse. Resized screen will be stretched (if not RMXP) # ----------------------------------------------------------------------------- Graphics.width - Returns screen width Graphics.height - Returns screen height Graphics.fullscreen? - Returns true if Game in fullscreen mode, else false Graphics.fullscreen - Switch to fullscreen mode Graphics.window - Switch to windowed mode Graphics.toggle - Switch between fullscreen mode and windowed mode Graphics.wait(frame) - Wait for frame Graphics.wait_for_input - Wait until input is pressed Graphics.fadein(frame) - Fade in the screen Graphics.fadeout(frame) - Fade out the screen Graphics.snap_to_bitmap - Snap screen to a bitmap object Graphics.high_priority = true/false - Change process priority to high / normal Graphics.disable_alt_enter - Disable input ALT+Enter (until game is closed) # ----------------------------------------------------------------------------- # * Module # ----------------------------------------------------------------------------- Module#attr_sec_reader(symbol, default=0) - Create attr_reader with default value Example : attr_sec_reader :something, "Sprite.new" Equal : def something @something ||= Sprite.new end Module#attr_sec_accessor(symbol, *a, &block) - Create (sheer of) attr_accessor with default value Example : attr_sec_accessor :sprite1, :sprite2, :sprite3, "Sprite.new" Equal : attr_writer :sprite1, :sprite2, :sprite3 attr_sec_reader :sprite1, "Sprite.new" attr_sec_reader :sprite2, "Sprite.new" attr_sec_reader :sprite3, "Sprite.new" Module#alias_sec_method(sym = nil, *a, &block) - Create alias only if alias name is not defined and target method is exist Example : alias_sec_method :alias_method, :target_method Equal : if method_defined?(:target) && !method_defined?(:alias) alias_method :alias, :target end Module#define_sec_method(sym = nil, *a, &block) - Define method only if the method is not defined Example : define_sec_method(:some_method) { |*a| block } Equal : unless method_defined?(:some_method) def some_method(*a) block end end # ----------------------------------------------------------------------------- # * Array # ----------------------------------------------------------------------------- Array Method Distributor - Distribute unexisted method in array into each variable (will work only if the method isn't exist in Array) Example : [Graphics,Input].update # equal => Graphics.update ; Input.update [@string1,@string2,@integer1,@sprite].dispose # equal => @sprite.dispose # (all variable without dispose method is ignored) [@string1,@string2,@integer1].dispose # Throws NoMethodError if all method didn't have dispose method Array#random_each / Array#random_each_with_index Example : a = [1,2,3,4,5,6,7] a.random_each {|i| puts i} # 4,5,3,2,7,1,6 Array#sum Array#prod Array#average Example : [1,2,3,4].sum # 10 (1+2+3+4) [1,2,3,4].average # 2.5 (10 / 4) [1,2,3,4].prod # 24 (1*2*3*4) Array#shuffle / Array#shuffle! Example : [1,2,3,4].shuffle # [3,2,4,1] Array#random / Array#random! Example : [1,2,3,4].random # 3 Array#switch=(true/false) Array#switch_reverse - Turn on / off switches all variable in the array (will ignored if variable not integer or not an array) Example : [1,2,[3,2,'A'],5].switch = true # equal => $game_switches[1] = true $game_switches[2] = true $game_self_switches[[3,2,'A']] = true $game_switches[5] = true Array#variable(value = nil, method = "=") - Change all variable value in the array (ignored if variable not integer) Example : [1,2,5].variable(10) # equal => $game_variables[1] = 10 $game_variables[2] = 10 $game_variables[5] = 10 Example : [1,2,5].variable(10, "+=") # equal => $game_variables[1] += 10 $game_variables[2] += 10 $game_variables[5] += 10 Array#have_all?(array) - returns true if contains all elements of the array Array#have_any?(array) - returns true if contains any elements of the array # ----------------------------------------------------------------------------- # * Sprite # ----------------------------------------------------------------------------- Sprite#clone Sprite#dup - Clone sprite without "can't clone sprite error" Example : a = Sprite.new b = a.clone a.dispose print a.disposed? # true print b.disposed? # false # ----------------------------------------------------------------------------- # * Spriteset_Map # ----------------------------------------------------------------------------- Spriteset_Map#sprite_player - returns sprite player at @character_sprites in Spriteset_Map Spriteset_Map#find_character(character) - returns character sprite at @character_sprites in Spriteset_Map # ----------------------------------------------------------------------------- # * Game Battler # ----------------------------------------------------------------------------- Game_Battler#hp_percent(integer = false, float_points = 2) Game_Battler#sp_percent(integer = false, float_points = 2) Example : $game_actors[1].hp_percent # returns 0 - 100 based on percentage hp # ----------------------------------------------------------------------------- # * Bitmap # ----------------------------------------------------------------------------- Bitmap#export(filename) - exporting bitmap into a file (only support bmp and png) Example : bitmap = Bitmap.new(50,20) bitmap.export('empty.png') Bitmap#flip_vertical Bitmap#flip_vertical! Bitmap#flip_horizontal Bitmap#flip_horizontal! - flip the bitmap vertically or horizontally (using ! will modify self) Example : bitmap = Bitmap.new(50,20) bitmap.flip_vertical! Bitmap#rotate90 Bitmap#rotate90! Bitmap#rotate180 Bitmap#rotate180! Bitmap#rotate270 Bitmap#rotate270! Additional Bitmap Effects Note : calling this method is process consuming, use with caution Bitmap#invert Bitmap#invert! Bitmap#brighten(amount = 10) Bitmap#brighten!(amount = 10) Bitmap#darken(amount = 10) Bitmap#darken!(amount = 10) Bitmap#grayscale Bitmap#grayscale! Bitmap#pixelate(size = 10) Bitmap#pixelate!(size = 10) Bitmap#frost(noise = 10) Bitmap#frost!(noise = 10) # ----------------------------------------------------------------------------- # * Color # ----------------------------------------------------------------------------- Color RGB value shortcut List : Color.red Color.green Color.blue Color.white Color.black Color.yellow Color.magenta Color.cyan Color.purple Color.gray Color.lightgray Color.darkgray Color.pink Color.orange Color.brown Color.golden Color.invert Color Hex - You can use hex value as method in color class (not case sensitive) (need to include 'x' in front) Example : Color.xffffff, Color.x04dacf, etc # ----------------------------------------------------------------------------- # * Game_Map # ----------------------------------------------------------------------------- Game_Map#load_event(mapid, eventid, x, y, page_id) Game_Map#load_event(mapid, eventid, x, y) Game_Map#load_event(eventid, x, y) # map_id will be assumed as current map - Duplicate an event from another map to current map at position (x, y) Game_Map#call_event(mapid, eventid, page_id) Game_Map#call_event(mapid, eventid) # page_id will be assumed as -1 Game_Map#call_event(eventid) # map_id will be assumed as current map - Call an event from another map to current map Note that page_id is start from 1, not 0 If you're using RMVX or RMVXA, setting page_id to -1 will bring you to the page with met condition. # ----------------------------------------------------------------------------- # * RTP fix # ----------------------------------------------------------------------------- Longer script call - You can stack script call next to each other as many as possible and they will be connected. - In addition, this also fixes the Interpreter Script call bug when if you use $game_system..... = false, game would freeze. This will prevent that. # ----------------------------------------------------------------------------- # * End Documentation # ----------------------------------------------------------------------------- =end # ============================================================================= #============================================================================== # ** Module #------------------------------------------------------------------------------ # #============================================================================== class Module #------------------------------------------------------------------------- # * New method: attr_sec_reader (Attr Secondary Reader) #------------------------------------------------------------------------- unless method_defined?(:attr_sec_reader) def attr_sec_reader(*sym) if (1..2) === sym.size module_eval("define_method(:#{sym[0]}) { @#{sym[0]} ||= #{sym[1]||0}}") elsif sym.size > 2 (default = sym.pop) && sym.each {|s| attr_sec_reader(s,default)} end end end #------------------------------------------------------------------------- # * New method: attr_sec_accessor (Attr Secondary Accessor) #------------------------------------------------------------------------- def attr_sec_accessor(sym = nil, *args) (args.size > 0) | sym.nil? || args.push(0) (default = args.pop) && (b = [sym].concat(args).compact) (b).each {|a| (attr_writer(a) || 0) && attr_sec_reader(a,default)} end #------------------------------------------------------------------------- # * New method: alias_sec_method (Alias Secondary Method) # Note : This method will create alias only if alias name is not defined # and target alias is exist #------------------------------------------------------------------------- unless method_defined?(:alias_sec_method) private def alias_sec_method(sym = nil, *args) (args.size > 0) | sym.nil? || args.clear (t = args.pop) && (b = [sym].concat(args).compact).each do |a| c = (t == :initialize ? true : method_defined?(t)) method_defined?(a) || (c && alias_method(a, t)) end end end #------------------------------------------------------------------------- # * New method: redirect_method #------------------------------------------------------------------------- unless method_defined?(:redirect_method) private def redirect_method(sym = nil, *args, &block) (args.size > 0) | sym.nil? || args.clear (t = args.pop) && (b = [sym].concat(args).compact).each do |a| meth = "def #{a}[*args] #{t}(*args) end" meth.gsub!(/(['")}\](\d+)])\(\*args\)/i) { $1 }#' meth.gsub!(/\[\*args\]/i) { '(*args)' } method_defined?(a) || module_eval(meth) end end end #------------------------------------------------------------------------- # * New method: define_sec_method # Note : This method will not defining method if method name already # exist #------------------------------------------------------------------------- unless method_defined?(:define_sec_method) private def define_sec_method(sym = nil, *args, &block) sym && (method_defined?(s = sym.to_sym) || define_method(s,*args,&block)) end end #------------------------------------------------------------------------- # * New method: define_third_method # Note : After aliasing, define a method #------------------------------------------------------------------------- unless method_defined?(:define_third_method) private def define_third_method(sym = nil, _alias = nil, *args, &block) unless sym.nil? || _alias.nil? stack = _alias.to_s =~ /stack/i || sym.to_s == 'initialize' stack = (!stack && method_defined?(_alias.to_sym)) stack || alias_method(_alias.to_sym, sym.to_sym) define_method(sym.to_sym,*args,&block) end end end #-------------------------------------------------------------------------- # ● New method: define_pre_alias #-------------------------------------------------------------------------- unless method_defined?(:define_pre_method) private def define_pre_alias(sym = nil, *args, &block) _time = Time.now _alias = :"#{sym}_#{_time.to_i}_#{_time.usec}" define_third_method(:"#{sym}",_alias) do |*args| block.bind(self).call send(_alias,*args) end end private def define_post_alias(sym = nil, *args, &block) _time = Time.now _alias = :"#{sym}_#{_time.to_i}_#{_time.usec}" define_third_method(:"#{sym}",_alias) do |*args| send(_alias,*args) block.bind(self).call end end end #-------------------------------------------------------------------------- # ● New method: include_auto_update #-------------------------------------------------------------------------- unless method_defined?(:include_auto_update) private def include_auto_update return if method_defined?(:update_auto_update) attr_sec_accessor(:auto_update, "[]") define_method(:update_auto_update) do return if auto_update.empty? auto_update.each do |x| (x[1].nil? ? send(x[0]) : (x[2].nil? ? x[0].method(x[1]).call : (x[0].method(x[1]).call(*x[2])))) (x[3].is_a?(Numeric) && (x[3] -= 1)) end auto_update.reject! {|x| x[3].is_a?(Numeric) && x[3] <= 0 } end _time = Time.now _alias = :"update_#{_time.to_i}_#{_time.usec}" define_third_method(:update,_alias) do |*args| send(_alias,*args) update_auto_update end end end end #============================================================================== # ** LiTTleDRAgo #------------------------------------------------------------------------------ # #============================================================================== module LiTTleDRAgo #------------------------------------------------------------------------- # * Constant #------------------------------------------------------------------------- VX = defined?(Window_ActorCommand) VXA = defined?(Window_BattleActor) XP = !VX RGSS1 = defined?(Hangup) RGSS2 = RUBY_VERSION == '1.8.1' && !RGSS1 RGSS3 = RUBY_VERSION == '1.9.2' APPPATHDRAGO = "#{ENV['APPDATA']}/Drago/" end #============================================================================== # ** CoreDLL #------------------------------------------------------------------------------ # #============================================================================== module CoreDLL #------------------------------------------------------------------------- # * Constant #------------------------------------------------------------------------- DLL_USED = ['kernel32','msvcrt','user32','gdi32'] SCENEVXA = "SceneManager.send(:instance_variable_set,:@scene,args.at(0))" L = LiTTleDRAgo #------------------------------------------------------------------------- # * Public Instance Variables #------------------------------------------------------------------------- attr_sec_reader :rtlmemory_pi, "winapi(0,'RtlMoveMemory','pii','i')" attr_sec_reader :rtlmemory_ip, "winapi(0,'RtlMoveMemory','ipi','i')" attr_sec_reader :setpriority, "winapi(0,'SetPriorityClass','pi','i')" attr_sec_reader :getprocesstime,"winapi(0,'GetProcessTimes','ipppp','i')" attr_sec_reader :getdc, "winapi(2,'GetDC','i','i')" attr_sec_reader :releasedc, "winapi(2,'ReleaseDC','ii','i')" attr_sec_reader :reghotkey, "winapi(2,'RegisterHotKey', 'liii', 'i')" attr_sec_reader :sendinput, "winapi(2,'SendInput','ipi','i')" attr_sec_reader :setwindowlong, "winapi(2,'SetWindowLong','lll','l')" attr_sec_reader :getkeysta, "winapi(2,'GetKeyboardState','p','i')" attr_sec_reader :getkeylay, "winapi(2,'GetKeyboardLayout','l','l')" attr_sec_reader :mapvirkey, "winapi(2,'MapVirtualKeyEx','iil','i')" attr_sec_reader :tounicode, "winapi(2,'ToUnicodeEx','llppill','l')" attr_sec_reader :screentoclient,"winapi(2,'ScreenToClient', 'lp', 'i')" attr_sec_reader :cursorposition,"winapi(2,'GetCursorPos', 'p', 'i')" attr_sec_reader :systemmetrix, "winapi(2,'GetSystemMetrics', %w(i), 'i')" attr_sec_reader :bitblt, "winapi(3,'BitBlt','iiiiiiiii','i')" attr_sec_reader :ccdc, "winapi(3,'CreateCompatibleDC','i','i')" attr_sec_reader :ccbitmap, "winapi(3,'CreateCompatibleBitmap','iii','i')" attr_sec_reader :deleteobject, "winapi(3,'DeleteObject','i','i')" attr_sec_reader :getbitmapbits, "winapi(3,'GetBitmapBits','llp','l')" attr_sec_reader :getdibits, "winapi(3,'GetDIBits','iiiiipi','i')" attr_sec_reader :setdibits, "winapi(3,'SetDIBits','iiiiipi','i')" attr_sec_reader :selectobject, "winapi(3,'SelectObject','ii','i')" attr_sec_reader :getpixel, "winapi(3,'GetPixel','iii','i')" attr_sec_reader :setpixel, "winapi(3,'SetPixel','liil','l')" attr_sec_reader :disabled_key, "Array.new" attr_sec_reader :high_priority, 'false' #------------------------------------------------------------------------- # * Define Secondary Listing #------------------------------------------------------------------------- define_sec_method(:disable_alt_enter) { disable_keys(0x0D) } define_sec_method(:fullscreen?) { systemmetrix.call(0) == Graphics.width } define_sec_method(:fullscreen) { self.fullscreen? || toggle } define_sec_method(:window) { self.fullscreen? && toggle } #------------------------------------------------------------------------- # * Redirect Listing #------------------------------------------------------------------------- redirect_method :cache, L::VX ? '(Cache)' : '(RPG::Cache)' redirect_method :scene, L::VXA ? '(SceneManager.scene)':'($scene)' redirect_method :scene=, L::VXA ? SCENEVXA : '($scene = args[0])' #------------------------------------------------------------------------- # * Enable change window size via mouse (border required) # Screen will not resized if RMXP #------------------------------------------------------------------------- def control_screen_size(enable = true) hid = @hide_border ? 0x14000000 : 0x14CA0000 set = enable ? (0x10C70000|0x00080000) : hid self.setwindowlong.call(self.hwnd,-16, set) end #------------------------------------------------------------------------- # * Hide window border # Screen size can't be controlled via mouse #------------------------------------------------------------------------- def hide_borders control_screen_size((@hide_border = true) && false) end #------------------------------------------------------------------------- # * Show window border # Screen size can't be controlled via mouse #------------------------------------------------------------------------- def show_borders control_screen_size((@hide_border = false)) end #------------------------------------------------------------------------- # * Disable Key #------------------------------------------------------------------------- def disable_keys(*keys) keys.each do |key| disabled_key.include?(key) || disabled_key.push(key) self.reghotkey.call(self.hwnd, 1, 0x0001, key) end end #------------------------------------------------------------------------- # * Resize the screen (scaled) # Screen will not resized if RMXP #------------------------------------------------------------------------- def scale_screen(width, height) width += ((res = self.systemmetrix).call(5) + (res.call(45))) * 2 height += (res.call(6) + (res.call(46))) * 2 + res.call(4) x = [(res.call(0) - width) / 2, 0].max y = [(res.call(1) - height) / 2, 0].max self.setwindowpos(self.hwnd,0,x,y,width,height,0) end #------------------------------------------------------------------------- # * Scale the game.exe to fill the monitor # Screen will not resized if RMXP #------------------------------------------------------------------------- def fill_monitor setwindowpos(hwnd,0,0,0,(res = systemmetrix).call(0),res.call(1),0) end #------------------------------------------------------------------------- # * setwindowpos #------------------------------------------------------------------------- def setwindowpos(hwnd = self.hwnd,at = 0,x = 0,y = 0, width = 640, height = 480, ni = 0) @setwindowpos ||= winapi(2, 'SetWindowPos', 'liiiiip','i') @setwindowpos.call(hwnd, at, x, y, width, height, ni) end #------------------------------------------------------------------------- # * Toggle between fullscreen and windowed #------------------------------------------------------------------------- def toggle @keybd ||= winapi(2, 'keybd_event', %w(i i l l), 'v') [@keybd.call(0xA4, 0, 0, 0), @keybd.call(13, 0, 0, 0) ] [@keybd.call(13, 0, 2, 0), @keybd.call(0xA4, 0, 2, 0)] end #------------------------------------------------------------------------- # * Show FPS #------------------------------------------------------------------------- def show_fps @show_fps ||= winapi(2, 'keybd_event', %w(l l l l), '') @show_fps.call(0x71,0,0,0) sleep(0.1) @show_fps.call(0x71,0,2,0) end #------------------------------------------------------------------------- # * Get the Game Window's width and height #------------------------------------------------------------------------- def client_size @window_c_rect ||= winapi(2, 'GetClientRect', %w(l p), 'i') @window_c_rect.call(self.hwnd, (rect = [0, 0, 0, 0].pack('l4'))) right, bottom = rect.unpack('l4')[2..3] return right, bottom end #------------------------------------------------------------------------- # * Get the game window handle (specific to game) #------------------------------------------------------------------------- def hwnd @game_window ||= winapi(2, 'FindWindowEx', %w(l l p p), 'i'). call(0,0,"RGSS Player",0) end #------------------------------------------------------------------------- # * always_on_top (cannot be undone) #------------------------------------------------------------------------- def always_on_top res = self.systemmetrix width = Graphics.width + (res.call(5) + (res.call(45))) * 2 height = Graphics.height + (res.call(6) + (res.call(46))) * 2 + res.call(4) x = [(res.call(0) - width) / 2, 0].max y = [(res.call(1) - height) / 2, 0].max self.setwindowpos(self.hwnd,-1,x,y,width,height,0x0200) end #------------------------------------------------------------------------- # * Get the value of game.ini #------------------------------------------------------------------------- def read_ini(field, key, ini = 'Game.ini') @gpps ||= winapi(0, 'GetPrivateProfileString', 'pppplp', 'l') @gpps.call(field,key,"",result="\0"*256,256,".//#{ini}") rescue return "" return result.delete!("\0") end #------------------------------------------------------------------------- # * Data default extension #------------------------------------------------------------------------- def data_default_extension data = read_ini('Game','Scripts') data = data.split('.').last || 'rxdata' return data end #------------------------------------------------------------------------- # * High Priority (true/false) #------------------------------------------------------------------------- def high_priority=(value) @high_priority = value && true setpriority.call(-1, @high_priority ? 0x00000080 : 0x00000020) end #-------------------------------------------------------------------------- # * snap_to_bitmap #-------------------------------------------------------------------------- def snap_to_bitmap bitmap = Bitmap.new((w = client_size.at(0)),(h = client_size.at(1))) info = [40,w,h,1,32,0,0,0,0,0,0].pack('LllSSLLllLL') hDC = ccdc.call((dc = getdc.call(hwnd))) deleteobject.call(selectobject.call(hDC, (hBM = ccbitmap.call(dc, w, h)))) setdibits.call(hDC, hBM, 0, h, (a = bitmap.address), info, 0) bitblt.call(hDC, 0, 0, w, h, dc, 0, 0, 0xCC0020) getdibits.call(hDC, hBM, 0, h, a, info, 0) deleteobject.call(hBM) deleteobject.call(hDC) return bitmap end #------------------------------------------------------------------------- # * Execute Win32API #------------------------------------------------------------------------- def winapi(*a) Win32API.new(*((a[0].is_a?(Integer) ? a[0] = DLL_USED[a[0]] : a) && a)) end #---------------------------------------------------------------------------- # * unicode_to_utf8 # string - string in Unicode format # Converts a string from Unicode format to UTF-8 format as RGSS does not # support Unicode. #---------------------------------------------------------------------------- def unicode_to_utf8(string) result = '' string.unpack('L*').each do |c| if (c1 = c < 0x0080) || (c2 = c < 0x0800) || (c3 = c < 0x10000) || (c4 = c < 0x200000)|| (c5 = c < 0x4000000) || (c6 = c < 0x80000000) result += c.chr if c1 result += (0xC0 | (c >> 6)).chr if c2 result += (0xE0 | (c >> 12)).chr if c3 result += (0xF0 | (c >> 18)).chr if c4 result += (0xF8 | (c >> 24)).chr if c5 result += (0xFC | (c >> 30)).chr if c6 result += (0x80 | ((c >> 24) & 0x3F)).chr if c6 result += (0x80 | ((c >> 18) & 0x3F)).chr if c5 || c6 result += (0x80 | ((c >> 12) & 0x3F)).chr if c4 || c5 || c6 result += (0x80 | ((c >> 6) & 0x3F)).chr if c3 || c4 || c5 || c6 result += (0x80 | (c & 0x3F)).chr if c2 || c3 || c4 || c5 || c6 end end return result end end LiTTleDRAgo.extend(CoreDLL) #============================================================================== # ** RPG #------------------------------------------------------------------------------ # #============================================================================== module RPG #============================================================================ # ** System #---------------------------------------------------------------------------- # #============================================================================ class System #---------------------------------------------------------------------- # ● Class Variables #---------------------------------------------------------------------- if (VX = LiTTleDRAgo::VX) #------------------------------------------------------------------------ # ● Public Instance Variables #------------------------------------------------------------------------ attr_accessor :magic_number, :windowskin_name, :gameover_name attr_accessor :battle_transition, :battleback_name, :title_name #------------------------------------------------------------------------ # ● Redefined Methods #------------------------------------------------------------------------ redirect_method :sounds, "$data_system.sounds" redirect_method :cursor_se, "sounds[0]" redirect_method :decision_se, "sounds[1]" redirect_method :cancel_se, "sounds[2]" redirect_method :buzzer_se, "sounds[3]" redirect_method :equip_se, "sounds[4]" redirect_method :save_se, "sounds[5]" redirect_method :load_se, "sounds[6]" redirect_method :battle_start_se, "sounds[7]" redirect_method :escape_se, "sounds[8]" if (VXA = LiTTleDRAgo::VXA) redirect_method :shop_se, "sounds[21]" redirect_method :actor_collapse_se, "sounds[15]" else redirect_method :shop_se, "sounds[17]" redirect_method :actor_collapse_se, "sounds[13]" end redirect_method :enemy_collapse_se, "sounds[11]" redirect_method :words, "@words ||= RPG::System::Words.new()" #------------------------------------------------------------------------ # ● Aliased Methods #------------------------------------------------------------------------ alias_sec_method :battleback_name, :battleback1_name alias_sec_method :title_name, :title1_name end #======================================================================== # ** Words #------------------------------------------------------------------------ # #======================================================================== class Words #---------------------------------------------------------------------- # ● New Methods #---------------------------------------------------------------------- attr_sec_accessor :params, !(VXA = LiTTleDRAgo::VXA) ? !VX ? '[hp,sp,str,dex,agi,int]' : # XP '[hp,sp,atk,pdef,int,agi]' : # VX '[hp,sp,atk,pdef,int,mdef,agi,luk]' # VXA attr_sec_accessor :weapon1, VX && !VXA ? 'Vocab.weapon1' : "'Weapon 1'" attr_sec_accessor :weapon2, VX && !VXA ? 'Vocab.weapon2' : "'Weapon 2'" attr_sec_accessor :status, VX ? 'Vocab.status' : "'Status' " attr_sec_accessor :save, VX ? 'Vocab.save' : "'Save' " attr_sec_accessor :game_end, VX ? 'Vocab.game_end' : "'Game End'" attr_sec_accessor :fight, VX ? 'Vocab.fight' : "'Fight' " attr_sec_accessor :escape, VX ? 'Vocab.escape' : "'Escape' " attr_sec_accessor :new_game, VX ? 'Vocab.new_game' : "'New Game'" attr_sec_accessor :continue, VX ? 'Vocab.continue' : "'Continue'" attr_sec_accessor :shutdown, VX ? 'Vocab.shutdown' : "'Shutdown'" attr_sec_accessor :to_title, VX ? 'Vocab.to_title' : "'To Title'" attr_sec_accessor :cancel, VX ? 'Vocab.cancel' : "'Cancel' " #---------------------------------------------------------------------- # ● Redirect Listings #---------------------------------------------------------------------- redirect_method :gold, (VXA ? 'Vocab.currency_unit' : 'Vocab.gold') redirect_method :hp, 'Vocab.hp' redirect_method :sp, 'Vocab.mp' redirect_method :str, 'String.new()' redirect_method :dex, 'String.new()' redirect_method :luk, (VXA ? 'Vocab.param(7)' : 'String.new()') redirect_method :agi, (VXA ? 'Vocab.param(6)' : 'Vocab.agi') redirect_method :int, (VXA ? 'Vocab.param(4)' : 'Vocab.spi') redirect_method :atk, (VXA ? 'Vocab.param(2)' : 'Vocab.atk') redirect_method :pdef, (VXA ? 'Vocab.param(3)' : 'Vocab.def') redirect_method :mdef, (VXA ? 'Vocab.param(5)' : 'String.new()') redirect_method :weapon, (VXA ? 'Vocab.etype(0)' : 'Vocab.weapon') redirect_method :armor1, (VXA ? 'Vocab.etype(1)' : 'Vocab.armor1') redirect_method :armor2, (VXA ? 'Vocab.etype(2)' : 'Vocab.armor2') redirect_method :armor3, (VXA ? 'Vocab.etype(3)' : 'Vocab.armor3') redirect_method :armor4, (VXA ? 'Vocab.etype(4)' : 'Vocab.armor4') redirect_method :attack, 'Vocab.attack' redirect_method :skill, 'Vocab.skill' redirect_method :guard, 'Vocab.guard' redirect_method :item, 'Vocab.item' redirect_method :equip, 'Vocab.equip' end end end #============================================================================== # ** RPG_FileTest #------------------------------------------------------------------------------ # #============================================================================== module RPG_FileTest #-------------------------------------------------------------------------- # ● New method: self.exist? #-------------------------------------------------------------------------- def self.exist?(filename) dir,ext = File.dirname(filename) + '/', File.extname(filename) base = File.basename(filename, ext) if ['.png','.jpg','.bmp'].include?(ext.downcase) cache = defined?(Cache) ? Cache : RPG::Cache (cache.load_bitmap(dir,base) && true) rescue false elsif ['.rxdata','.rvdata','.rvdata2','.rb','.txt'].include?(ext.downcase) (load_data(filename) && true) rescue false else File.exist?(filename) end end end #============================================================================== # ** Sound #------------------------------------------------------------------------------ # This module plays sound effects. It obtains sound effects specified in the # database from the global variable $data_system, and plays them. #============================================================================== module Sound; end class << Sound #------------------------------------------------------------------------ # ● New Method :se_play #------------------------------------------------------------------------ unless method_defined?(:se_play) def se_play(type) system = ($game_system ||= Game_System.new) case type when :cursor then system.se_play($data_system.cursor_se) when :decision then system.se_play($data_system.decision_se) when :cancel then system.se_play($data_system.cancel_se) when :buzzer then system.se_play($data_system.buzzer_se) when :shop then system.se_play($data_system.shop_se) when :equip then system.se_play($data_system.equip_se) when :save then system.se_play($data_system.save_se) when :load then system.se_play($data_system.load_se) when :battle_start then system.se_play($data_system.battle_start_se) when :escape then system.se_play($data_system.escape_se) when :actor_collapse then system.se_play($data_system.actor_collapse_se) when :enemy_collapse then system.se_play($data_system.enemy_collapse_se) end end end #-------------------------------------------------------------------------- # * Redefined Method #-------------------------------------------------------------------------- define_sec_method(:play_cursor) { se_play(:cursor) } define_sec_method(:play_decision) { se_play(:decision) } define_sec_method(:play_cancel) { se_play(:cancel) } define_sec_method(:play_buzzer) { se_play(:buzzer) } define_sec_method(:play_equip) { se_play(:equip) } define_sec_method(:play_save) { se_play(:save) } define_sec_method(:play_load) { se_play(:load) } define_sec_method(:play_battle_start) { se_play(:battle_start) } define_sec_method(:play_escape) { se_play(:escape) } define_sec_method(:play_enemy_collapse) { se_play(:enemy_collapse) } define_sec_method(:play_actor_collapse) { se_play(:actor_collapse) } define_sec_method(:play_shop) { se_play(:shop) } #-------------------------------------------------------------------------- # * Alias Listing #-------------------------------------------------------------------------- alias_sec_method :play_ok, :play_decision end #============================================================================== # ** Game_System #------------------------------------------------------------------------------ # This class handles data surrounding the system. Backround music, etc. # is managed here as well. Refer to "$game_system" for the instance of # this class. #============================================================================== class Game_System #-------------------------------------------------------------------------- # * Constant #-------------------------------------------------------------------------- VX = LiTTleDRAgo::VX && !LiTTleDRAgo::VXA #-------------------------------------------------------------------------- # * Public Instance Variable #-------------------------------------------------------------------------- attr_sec_accessor :bgm_volume , 100 attr_sec_accessor :bgs_volume , 100 attr_sec_accessor :me_volume , 100 attr_sec_accessor :se_volume , 100 attr_sec_accessor :bgm_pitch , 100 attr_sec_accessor :bgs_pitch , 100 attr_sec_accessor :me_pitch , 100 attr_sec_accessor :se_pitch , 100 attr_sec_accessor :volume_control, 'false' #-------------------------------------------------------------------------- # * Redefined method: bgm_memorize, bgm_restore #-------------------------------------------------------------------------- VX && define_sec_method(:bgm_memorize) { @memorized_bgm = @playing_bgm } VX && define_sec_method(:bgm_restore) { bgm_play(@memorized_bgm) } #-------------------------------------------------------------------------- # * Redirect Listing #-------------------------------------------------------------------------- redirect_method :bgm_stop, 'Audio.bgm_stop' redirect_method :bgs_stop, 'Audio.bgs_stop' redirect_method :se_stop, 'Audio.se_stop' redirect_method :me_stop, 'Audio.me_stop' #-------------------------------------------------------------------------- # * Alias Listing #-------------------------------------------------------------------------- alias_sec_method :bgm_memorize, :save_bgm alias_sec_method :bgm_restore, :replay_bgm alias_sec_method :save_bgm, :bgm_memorize alias_sec_method :replay_bgm, :bgm_restore #-------------------------------------------------------------------------- # * Aliased method: bgm_play, bgs_play, me_play, se_play #-------------------------------------------------------------------------- [:bgm,:bgs,:me,:se].each do |sa| next unless method_defined?(:"#{sa}_play") alias_sec_method(:"drg_#{sa}_play", :"#{sa}_play") define_method(:"#{sa}_play") do |bgm,*a| if bgm.is_a?(String) && bgm != '' bgm = RPG::AudioFile.new(bgm,send(:"#{sa}_volume"),send(:"#{sa}_pitch")) elsif volume_control && bgm.is_a?(RPG::AudioFile) && bgm.name != "" bgm = bgm.clone bgm.volume = Math.percent(bgm.volume,send(:"#{sa}_volume")) bgm.pitch = Math.percent(bgm.pitch,send(:"#{sa}_pitch")) end @playing_bgm = bgm if "#{sa}" == 'bgm' @playing_bgs = bgm if "#{sa}" == 'bgs' if respond_to?(:"drg_#{sa}_play") send(:"drg_#{sa}_play", bgm,*a) else if bgm.is_a?(RPG::AudioFile) && bgm.name != '' Audio.send(:"#{sa}_play","Audio/#{sa}/" + bgm.name, bgm.volume.round, bgm.pitch.round,*a) else send(:"#{sa}_stop") end Graphics.frame_reset end end end end #============================================================================== # ** Object #------------------------------------------------------------------------------ # This class is superclass for all class #============================================================================== class Object #------------------------------------------------------------------------- # * New method: all_variable_dispose #------------------------------------------------------------------------- def all_variable_dispose all = instance_variables.map {|s| instance_variable_get("#{s}")}.flatten all.delete_if {|s| s.not.respond_to?(:dispose) } all.delete_if {|s| s.respond_to?(:disposed?) && s.disposed?} all.dispose end #------------------------------------------------------------------------- # * New method: rand_between #------------------------------------------------------------------------- unless method_defined?(:rand_between) def rand_between(min, max) min + rand(max - min + 1) if min.is_a?(Numeric) && max.is_a?(Numeric) end end #------------------------------------------------------------------------- # * New method: get_note #------------------------------------------------------------------------- unless method_defined?(:get_note) def get_note respond_to?(:note) ? note : "" end end #------------------------------------------------------------------------- # * New method: screen_rect #------------------------------------------------------------------------- unless method_defined?(:screen_rect) def screen_rect(as_rect = true) array = [0,0,Graphics.width,Graphics.height] as_rect ? Rect.new(*array) : array end end #------------------------------------------------------------------------- # * New method: forcesave #------------------------------------------------------------------------- unless method_defined?(:forcesave) def forcesave(index) return DataManager.save_game(index) if defined?(DataManager) save = LiTTleDRAgo::VX ? Scene_File.new(0,nil,0) : Scene_Save.new begin file = File.open(save.make_filename(index), "wb") (save.write_save_data(file) && file.close) || true rescue File.delete(save.make_filename(index)) rescue nil (Sound.play_buzzer) && false end end end #-------------------------------------------------------------------------- # * sprite_report #-------------------------------------------------------------------------- unless method_defined?(:script_report) def script_report(text,font = nil) s = (text.is_a?(String) || (text = text.inspect)) && Sprite.new s.opacity = (s.bitmap = Bitmap.new((g = Graphics).width,g.height)) && 0 s.bitmap.font.name = ['Georgia',Font.default_name].flatten s.bitmap.font = (s.z += 9999) && (font || s.bitmap.font) y = (text.split(/\n/).size * s.bitmap.text_size(text).height) / 2 s.bitmap.draw_enter_edging_text(0,0-y,g.width,g.height,text,1) (s.opacity += 10) && g.update until s.opacity >= 255 g.wait_for_input (s.opacity -= 10) && g.update until s.opacity <= 0 s.dispose end end #------------------------------------------------------------------------- # * New method: not #------------------------------------------------------------------------- define_sec_method(:not) { Not.new(self) } #============================================================================ # ** Not #---------------------------------------------------------------------------- # #============================================================================ class Not #------------------------------------------------------------------------- # * Private #------------------------------------------------------------------------- private *instance_methods.select { |m| m !~ /(^__|^\W|^binding$)/ } #------------------------------------------------------------------------- # * Object Initialization #------------------------------------------------------------------------- define_method(:initialize) {|original| @original = original } #------------------------------------------------------------------------- # * New method: method_missing #------------------------------------------------------------------------- def method_missing(sym, *a, &blk) !@original.send(sym, *a, &blk) end end end #============================================================================== # ** Kernel #------------------------------------------------------------------------------ # #============================================================================== module Kernel #------------------------------------------------------------------------- # * Alias Listing #------------------------------------------------------------------------- $@ || alias_method(:carrot, :proc) #------------------------------------------------------------------------- # * Script Check #------------------------------------------------------------------------- if LiTTleDRAgo::XP && LiTTleDRAgo::RGSS3 && !defined?(XPA_CONFIG) $@ || alias_method(:last_before_p, :p) $@ || alias_method(:last_before_print, :print) $@ || alias_method(:last_before_msgbox, :msgbox) $@ || alias_method(:last_before_msgbox_p, :msgbox_p) define_method(:p) {|*args| last_before_msgbox_p(*args)} define_method(:print) {|*args| last_before_msgbox(*args) } define_method(:msgbox) {|*args| last_before_print(*args) } define_method(:msgbox_p){|*args| last_before_p(*args) } end define_method(:draise) {|*args| (dp(*args) && !1) || exit } define_method(:dp) {|*a| script_report(a.map {|i| i.inspect}.join("\n"))} #------------------------------------------------------------------------- # * New method: dprint #------------------------------------------------------------------------- def dprint(*args) script_report(args.map {|i| i.is_a?(String) ? i : i.inspect}.join) end #------------------------------------------------------------------------- # * New method: press_any_key #------------------------------------------------------------------------- unless method_defined?(:press_any_key) def press_any_key return false if Input.nil? return true if Input.trigger?(Input::A) ||Input.trigger?(Input::B) return true if Input.trigger?(Input::C) ||Input.trigger?(Input::X) return true if Input.trigger?(Input::Y) ||Input.trigger?(Input::Z) return true if Input.trigger?(Input::L) ||Input.trigger?(Input::R) return true if Input.trigger?(Input::UP) ||Input.trigger?(Input::DOWN) return true if Input.trigger?(Input::LEFT) ||Input.trigger?(Input::RIGHT) return true if Input.trigger?(Input::SHIFT)||Input.trigger?(Input::CTRL) return true if Input.trigger?(Input::ALT) ||Input.trigger?(Input::F5) return true if Input.trigger?(Input::F6) ||Input.trigger?(Input::F7) return true if Input.trigger?(Input::F8) ||Input.trigger?(Input::F9) end end #------------------------------------------------------------------------- # * New method: inspect_instance_variable #------------------------------------------------------------------------- unless method_defined?(:inspect_instance_variable) def inspect_instance_variable(class_name, variable) Module.const_get(class_name).new.instance_variable_get(:"@#{variable}") end end end #============================================================================== # ** Proc #------------------------------------------------------------------------------ # #============================================================================== class Proc #------------------------------------------------------------------------- # * New method: bind #------------------------------------------------------------------------- unless method_defined?(:bind) def bind(object) block, time = self, Time.now class << object self end.class_eval do define_method((name = "__bind_#{time.to_i}_#{time.usec}"), &block) remove_method((method = instance_method(name)) && name) method end.bind(object) end end end #============================================================================== # ** Enumerable #------------------------------------------------------------------------------ # #============================================================================== module Enumerable #--------------------------------------------------------------------------- # * Redefined method: shuffle #--------------------------------------------------------------------------- define_sec_method(:shuffle) {(a = entries) && Array.new(size){ a.random!}} #--------------------------------------------------------------------------- # * New method: random_each #--------------------------------------------------------------------------- unless method_defined?(:random_each) def random_each() (block_given? ? shuffle.each {|s| yield s } : random) end end #--------------------------------------------------------------------------- # * New method: random_each_with_index #--------------------------------------------------------------------------- unless method_defined?(:random_each_with_index) def random_each_with_index block_given? ? self.shuffle.each_with_index {|obj, i| yield obj,i } : self.random end end #--------------------------------------------------------------------------- # * Redefined method: drop_while #--------------------------------------------------------------------------- unless method_defined?(:drop_while) def drop_while(&block) ary, state = [], false self.each do |e| state = true if !state and !block.call(e) ary << e if state end ary end end #--------------------------------------------------------------------------- # * Redefined method: take_while #--------------------------------------------------------------------------- unless method_defined?(:take_while) def take_while(&block) ary = [] self.each do |e| return ary unless block.call(e) ary << e end ary end end #--------------------------------------------------------------------------- # * Redefined method: partition #--------------------------------------------------------------------------- unless method_defined?(:partition) def partition(&block) ary_T, ary_F = [], [] self.each {|val| block.call(val) ? ary_T.push(val) : ary_F.push(val)} return ary_T, ary_F end end #--------------------------------------------------------------------------- # * Redefined method: grep #--------------------------------------------------------------------------- unless method_defined?(:grep) def grep(pattern, &block) collect {|v| pattern === v && ary.push((block)? block.call(v): v)} end end #--------------------------------------------------------------------------- # * Redefined method: each_slice #--------------------------------------------------------------------------- unless method_defined?(:each_slice) def each_slice(n, &block) not_integer = "expected Integer for 1st argument" n.is_a?(Integer) || raise(TypeError,not_integer,caller(1)) n <= 0 && raise(ArgumentError, "invalid slice size",caller(1)) ary = [] self.each do |e| ary << e if ary.size == n block.call(ary) ary = [] end end block.call(ary) unless ary.empty? end end #--------------------------------------------------------------------------- # * Redefined method: minmax #--------------------------------------------------------------------------- unless method_defined?(:minmax) def minmax(&block) (a = sort(&block)) && [a.first,a.last] end end end #============================================================================== # ** Array #------------------------------------------------------------------------------ # #============================================================================== class Array #--------------------------------------------------------------------------- # * Define Secondary Listing #--------------------------------------------------------------------------- define_sec_method(:have_all?) { |*array| self & array == array } define_sec_method(:have_any?) { |*array| self - array != self } define_sec_method(:relay) { |type| map {|s| s.send(:"to_#{type}")}} #--------------------------------------------------------------------------- # * Redirect method #--------------------------------------------------------------------------- redirect_method :switch_on, 'self.switch = (true)' redirect_method :switch_off, 'self.switch = (false)' redirect_method :random, 'self.at(rand(size))' redirect_method :random!, 'self.delete_at(rand(size))' redirect_method :sum, 'self.inject(0) {|r, n| r += n}' redirect_method :prod, 'self.inject(1) {|r, n| r *= n}' redirect_method :next_item, '(item = shift) && push(item) && (item)' redirect_method :previous_item, '(item = pop) && unshift(item) && (item)' redirect_method :nitems, 'count {|x| x.not.nil?}' redirect_method :switch_reverse, 'switch=(:flip)' #--------------------------------------------------------------------------- # * New method: method_missing #--------------------------------------------------------------------------- def method_missing(val,*a,&b) en = self.entries.find_all {|s|s.respond_to?(val.to_sym)} if self.not.empty? && en.empty? text = "Undefined method #{val} for #{self.inspect}" raise(NoMethodError,text,caller(1)) end return en.map {|s| s.send(val.to_s,*a,&b)} end #------------------------------------------------------------------------- # * New method: each_ntuple #------------------------------------------------------------------------- unless method_defined?(:each_ntuple) def each_ntuple(number) 0.step(size - size % number - 1, number) {|i| yield(*self[i, number])} end end #------------------------------------------------------------------------- # * New method: each_pair #------------------------------------------------------------------------- unless method_defined?(:each_pair) def each_pair() each_ntuple(2) {|a,b| yield a, b } end end #--------------------------------------------------------------------------- # * New method: each_triple #--------------------------------------------------------------------------- unless method_defined?(:each_triple) def each_triple() each_ntuple(3) {|a,b,c| yield a, b, c } end end #--------------------------------------------------------------------------- # * Redefined method: shuffle! (for RMXP) #--------------------------------------------------------------------------- unless method_defined?(:shuffle!) def shuffle!() self.dup == replace(shuffle) ? nil : self end end #--------------------------------------------------------------------------- # * New method: sort_by! #--------------------------------------------------------------------------- unless method_defined?(:sort_by!) def sort_by!(*args,&block) self.dup == replace(sort_by(*args,&block)) ? nil : self end end #--------------------------------------------------------------------------- # * New method: recursive_clone #--------------------------------------------------------------------------- unless method_defined?(:rclone) def recursive_clone (clon = self.clone).each_index do |i| clon[i] = clon[i].recursive_clone rescue clon[i].clone rescue clon[i] end clon end alias_method(:rclone, :recursive_clone) end #--------------------------------------------------------------------------- # * New method: to_hash #--------------------------------------------------------------------------- unless method_defined?(:to_hash) def to_hash (hash = Hash.new) && each_index {|i| hash[i] = self[i]} && hash end end #--------------------------------------------------------------------------- # * Redefined method: count #--------------------------------------------------------------------------- unless method_defined?(:count) def count(*args, &block) if block_given? find_all {|s| block.call(s)}.size else ary = args.empty? ? self : args.map {|a| find_all{|s| s == a}} ary.compact.size end end end #--------------------------------------------------------------------------- # * New method: each_with_next #--------------------------------------------------------------------------- unless method_defined?(:each_with_next) def each_with_next(num = 1) (size - num).times {|i| yield(*self[i..(i+num)])} end end #--------------------------------------------------------------------------- # * New method: switch= #--------------------------------------------------------------------------- unless method_defined?(:switch=) def switch=(value) integer = search_var_key[0] array = search_var_key[1] if value == :flip integer.each {|i| $game_switches[i] = !$game_switches[i] } array.each {|i| $game_self_switches[i] = !$game_self_switches[i] } else integer.each {|i| $game_switches[i] = value } array.each {|i| $game_self_switches[i] = value } end $game_map.need_refresh = true if $game_map.respond_to?(:need_refresh) end end #--------------------------------------------------------------------------- # * New method: variable #--------------------------------------------------------------------------- def variable(value = nil,method = "=") integer = search_var_key[0] integer += search_var_key[1] if $drago_game_variable return integer.map {|i| $game_variables[i]} if value.nil? result = integer.map {|i| eval("$game_variables[i] #{method} #{value}") } $game_map.need_refresh = true if $game_map.respond_to?(:need_refresh) result end #--------------------------------------------------------------------------- # * New method: search_var_key #--------------------------------------------------------------------------- def search_var_key integer = self.find_all {|s| s.is_a?(Integer)} range = self.find_all {|s| s.is_a?(Range) } array = self.find_all {|s| s.is_a?(Array) } string = self.find_all {|s| s.is_a?(String) } integer = integer + range.collect {|s| s.to_a }.flatten $game_switches ||= Game_Switches.new $game_self_switches ||= Game_SelfSwitches.new $game_variables ||= Game_Variables.new return [integer.sort.uniq, array.sort.uniq] end #--------------------------------------------------------------------------- # * New method: rindexes #--------------------------------------------------------------------------- unless method_defined?(:rindexes) def rindexes(*values) array = Array.new each_index {|i| values.include?(self[i]) && array.push(i)} array end end #--------------------------------------------------------------------------- # * New method: deep #--------------------------------------------------------------------------- unless method_defined?(:deep) def deep(deep = -1) tmp_deep = deep + 1 deep = tmp_deep self.each do |i| deep < i.deep(tmp_deep) && deep = i.deep(tmp_deep) rescue nil end deep end end #--------------------------------------------------------------------------- # * New method: recursive_flatten #--------------------------------------------------------------------------- unless method_defined?(:rflatten) def recursive_flatten (array = self.recursive_clone).each_index do |i| array[i] = array[i].to_a if array[i].is_a?(Hash) array[i] = array[i].recursive_flatten rescue array[i] end array.flatten! array end alias_method(:rflatten, :recursive_flatten) end #--------------------------------------------------------------------------- # * New method: recursive_flatten! #--------------------------------------------------------------------------- unless method_defined?(:rflatten!) def recursive_flatten! self.each_index do |i| self[i] = self[i].to_a if self[i].is_a?(Hash) self[i] = self[i].recursive_flatten! rescue self[i] end self.flatten! self end alias_method(:rflatten!, :recursive_flatten!) end #--------------------------------------------------------------------------- # * Redefined method: product #--------------------------------------------------------------------------- def dproduct(*arrays) (e = "(result = []) && self.each {|i0| ") && (a = arrays.size).times {|i| e += "arrays[#{i}].each {|i#{i+1}| " } (e += "result.push([i0,") && a.times {|i| e += "i#{i+1}," } (e += "])}" + "}" * a + " && result" ) return eval(e) end alias_sec_method(:product, :dproduct) #--------------------------------------------------------------------------- # * New method: geometric_average #--------------------------------------------------------------------------- unless method_defined?(:geometric_average) def geometric_average(float = false) average = empty? ? 0 : prod ** (1.0 / size) return (float ? average : average.to_i) end end #--------------------------------------------------------------------------- # * New method: average #--------------------------------------------------------------------------- unless method_defined?(:average) def average(float = false) sum / [(float ? size.to_f : size.to_i), 1].max end end #--------------------------------------------------------------------------- # * Alias method #--------------------------------------------------------------------------- alias_sec_method :has_all?, :have_all? alias_sec_method :has_any?, :have_any? end #============================================================================== # ** Hash #------------------------------------------------------------------------------ # #============================================================================== class Hash #-------------------------------------------------------------------------- # * Define Secondary Listing #-------------------------------------------------------------------------- define_sec_method(:reverse!) { self.dup == replace(reverse) ? nil : self } #-------------------------------------------------------------------------- # ● New method: reverse #-------------------------------------------------------------------------- unless method_defined?(:reverse) def reverse key, new_hash = self.keys, {} key.reverse.each_with_index {|k,i| new_hash[k] = self[key[i]]} new_hash end end #-------------------------------------------------------------------------- # ● New method: recursive_clone #-------------------------------------------------------------------------- unless method_defined?(:rclone) def recursive_clone (clon = self.clone).each_key do |i| clon[i] = clon[i].recursive_clone rescue clon[i].clone rescue clon[i] end clon end alias_method(:rclone, :recursive_clone) end #-------------------------------------------------------------------------- # ● New method: deep #-------------------------------------------------------------------------- unless method_defined?(:deep) def deep(deep = -1) key_deep = value_deep = tmp_deep = deep + 1 self.each do |k, v| key_deep = k.deep(tmp_deep) if key_deep < k.deep(tmp_deep) rescue nil value_deep = v.deep(tmp_deep)if value_deep< v.deep(tmp_deep) rescue nil end key_deep > value_deep ? key_deep : value_deep end end #-------------------------------------------------------------------------- # ● New method: fusion #-------------------------------------------------------------------------- unless method_defined?(:fusion) def fusion (array = sort).each_index do |i| array[i] = array[i][0] + array[i][1] rescue array[i] end array end end end #============================================================================== # ** Range #------------------------------------------------------------------------------ # #============================================================================== class Range #-------------------------------------------------------------------------- # * Include Comparable #-------------------------------------------------------------------------- include(Comparable) #------------------------------------------------------------------------- # ● New method: random #------------------------------------------------------------------------- define_sec_method(:random) { self.to_a.random } define_sec_method(:sum) { self.to_a.sum } define_sec_method(:prod) { self.to_a.prod } #------------------------------------------------------------------------- # ● New method: <=> #------------------------------------------------------------------------- unless method_defined?(:"<=>") def <=>(other) temp = first <=> other.first temp = last <=> other.last if temp = 0 return temp end end end #============================================================================== # ** NilClass #------------------------------------------------------------------------------ # #============================================================================== class NilClass #-------------------------------------------------------------------------- # ● Overwriten method: clone, dup #-------------------------------------------------------------------------- define_method(:clone) {|*a|} define_method(:dup) {|*a|} end #============================================================================== # ** Math #------------------------------------------------------------------------------ # #============================================================================== module Math #-------------------------------------------------------------------------- # ● New method: A (Ackermann function) #-------------------------------------------------------------------------- def self.A(m,n) text = 'Ackermann: No negative values allowed.' if m < 0 or n < 0 raise(ArgumentError.new(text)) if m < 0 or n < 0 return n + 1 if m == 0 return Math.A(m - 1, 1) if n == 0 return Math.A(m - 1, Math.A(m, n - 1)) end #-------------------------------------------------------------------------- # ● New method: percent #-------------------------------------------------------------------------- def self.percent(min,max=100) (min / max.to_f) * 100.0 end end #============================================================================== # ** Numeric #------------------------------------------------------------------------------ # #============================================================================== class Numeric #-------------------------------------------------------------------------- # ● Define Secondary Listing: clamp, sign #-------------------------------------------------------------------------- define_sec_method(:clamp) {|min,max| [[self, min].max, max].min} define_sec_method(:sign) { zero? ? 0 : (self / self.abs).to_i } #-------------------------------------------------------------------------- # ● New method: group #-------------------------------------------------------------------------- unless method_defined?(:group) def group self.to_s.gsub(/(\d)(?=\d{3}+(?:\.|$))(\d{3}\..*)?/,'\1,\2') end end end #============================================================================== # ** Integer #------------------------------------------------------------------------------ # #============================================================================== class Integer #-------------------------------------------------------------------------- # ● Define Secondary Listing: sum_to, factorial #-------------------------------------------------------------------------- define_sec_method(:sum_down) { sum_to(0)} define_sec_method(:factorial) {(sign * (1..(self.abs)).prod) } #-------------------------------------------------------------------------- # * New method: sum_to #-------------------------------------------------------------------------- unless method_defined?(:sum_to) def sum_to(v = self) (v > self ? (self..v) : (v..self)).sum end end end #============================================================================== # ** Float #------------------------------------------------------------------------------ # #============================================================================== class Float #-------------------------------------------------------------------------- # ● Overwriten method: =~ #-------------------------------------------------------------------------- # A close float comparison. Because of rounding errors, this comparison will # help compensate for that. Since 0 and 0.0001 are very close to each other, # it's best to use this custom comparison. define_method(:"=~") {|num| (self + 0.0001 >= num && self - 0.0001 <= num) } #-------------------------------------------------------------------------- # ● New method: float_points #-------------------------------------------------------------------------- unless method_defined?(:float_points) def float_points(points = 2) n = self * 10 ** points n = n.round.to_f / (10.0 ** points) return n end end end #============================================================================== # ** Color #------------------------------------------------------------------------------ # #============================================================================== class Color #-------------------------------------------------------------------------- # ● Define Secondary Listing #-------------------------------------------------------------------------- define_sec_method(:invert) { set(255-red, 255-green, 255-blue, alpha)} #---------------------------------------------------------------------------- # * New method: to_hex #---------------------------------------------------------------------------- def to_hex str = [self.blue.to_i, self.green.to_i, self.red.to_i].pack("C*") str.inspect.gsub('\\x','') end end class << Color #-------------------------------------------------------------------------- # ● Define Secondary Listing: red, green, blue, white, black... etc #-------------------------------------------------------------------------- define_sec_method(:red) {|*a| self.new(255, 0, 0,a.first||255)} define_sec_method(:green) {|*a| self.new( 0,255, 0,a.first||255)} define_sec_method(:blue) {|*a| self.new( 0, 0,255,a.first||255)} define_sec_method(:white) {|*a| self.new(255,255,255,a.first||255)} define_sec_method(:purple) {|*a| self.new(128, 0,128,a.first||255)} define_sec_method(:gray) {|*a| self.new(128,128,128,a.first||255)} define_sec_method(:lgray) {|*a| self.new(211,211,211,a.first||255)} define_sec_method(:dgray) {|*a| self.new( 64, 64, 64,a.first||255)} define_sec_method(:pink) {|*a| self.new(255,175,175,a.first||255)} define_sec_method(:orange) {|*a| self.new(255,165, 0,a.first||255)} define_sec_method(:brown) {|*a| self.new(128, 64, 0,a.first||255)} define_sec_method(:chocolate){|*a| self.new(210,105, 30,a.first||255)} define_sec_method(:golden) {|*a| self.new(218,165, 32,a.first||255)} define_sec_method(:silver) {|*a| self.new(192,192,192,a.first||255)} define_sec_method(:system) {|*a| self.new(192,224,255,a.first||255)} define_sec_method(:crisis) {|*a| self.new(255,255, 64,a.first||255)} define_sec_method(:knockout) {|*a| self.new(255, 64, 0,a.first||255)} #-------------------------------------------------------------------------- # ● Redirect Listing: cyan, magenta, yellow, black, disabled, erase #-------------------------------------------------------------------------- redirect_method :cyan, '(red(*args).invert )' redirect_method :magenta, '(green(*args).invert)' redirect_method :yellow, '(blue(*args).invert )' redirect_method :black, '(white(*args).invert)' redirect_method :disabled, '(black(128).invert )' redirect_method :erase, '(white(0).invert )' #-------------------------------------------------------------------------- # ● Alias method: grey, light_grey, dark_grey #-------------------------------------------------------------------------- alias_sec_method :normal, :white alias_sec_method :grey, :gray alias_sec_method :lightgrey, :lightgray, :light_grey, :light_gray, :lgray alias_sec_method :darkgrey, :darkgray, :dark_grey, :dark_gray, :dgray #-------------------------------------------------------------------------- # ● New method: method_missing #-------------------------------------------------------------------------- def method_missing(val,*a) val = "#{val}".gsub(/x/i,'') if "#{val}".size == 6 && "#{val}".gsub(/(\d+|[a-f])/i,'') r = "#{val}"[0..1].hex g = "#{val}"[2..3].hex b = "#{val}"[4..5].hex return self.new(r,g,b,a.first||255) end text = "Undefined method #{val} for #{self.inspect}" raise(NoMethodError, text, caller(1)) end end #============================================================================== # ** Viewport #------------------------------------------------------------------------------ # #============================================================================== class Viewport unless method_defined?(:disposed?) #-------------------------------------------------------------------------- # ● Alias Listing #-------------------------------------------------------------------------- alias_sec_method :d3x40932s2, :dispose #-------------------------------------------------------------------------- # ● New method: disposed? # help file is lying when says Viewport#disposed? is exist #-------------------------------------------------------------------------- define_method(:disposed?) { @disposed == true } #-------------------------------------------------------------------------- # ● Aliased method: dispose #-------------------------------------------------------------------------- def dispose(*a) (disposed? || d3x40932s2(*a) || 0) && @disposed = true end end #-------------------------------------------------------------------------- # ● New method: resize #-------------------------------------------------------------------------- define_sec_method(:resize) do |*a| self.rect = a.first.is_a?(Rect) ? a.first : Rect.new(*a) end #-------------------------------------------------------------------------- # * New method: update_viewport_sizes #-------------------------------------------------------------------------- define_sec_method(:update_viewport_sizes) do |*a| map = $game_map w, h = Graphics.width, Graphics.height hor = map.respond_to?(:loop_horizontal?) && map.loop_horizontal? ver = map.respond_to?(:loop_vertical?) && map.loop_vertical? dx = w > map.width * 32 && !hor ? (w - map.width * 32) / 2 : 0 dw = hor ? w : [w, map.width * 32].min dy = h > map.height * 32 && !ver ? (h - map.height * 32) / 2 : 0 dh = ver ? h : [h, map.height * 32].min resize(Rect.new(dx, dy, dw, dh)) end #-------------------------------------------------------------------------- # ● New method: x, y, width, height #-------------------------------------------------------------------------- define_sec_method(:x) { self.rect.x } define_sec_method(:y) { self.rect.y } define_sec_method(:width) { self.rect.width } define_sec_method(:height) { self.rect.height } define_sec_method(:x=) {|x2| resize(x2,y,width,height) } define_sec_method(:y=) {|y2| resize(x,y2,width,height) } define_sec_method(:width=) {|w1| resize(x,y,w1,height) } define_sec_method(:height=) {|h1| resize(x,y,width,h1) } end #============================================================================== # ** Graphics #------------------------------------------------------------------------------ # This module handles all Graphics #============================================================================== class << Graphics #------------------------------------------------------------------------ # ● Include AutoUpdate #------------------------------------------------------------------------ include_auto_update #------------------------------------------------------------------------ # ● Redirect Listing #------------------------------------------------------------------------ redirect_method :width, 'LiTTleDRAgo.client_size.at(0)' redirect_method :height, 'LiTTleDRAgo.client_size.at(1)' redirect_method :snap_to_bitmap, 'LiTTleDRAgo.snap_to_bitmap' redirect_method :disable_alt_enter, 'LiTTleDRAgo.disable_alt_enter' redirect_method :always_on_top, 'LiTTleDRAgo.always_on_top' redirect_method :show_fps, 'LiTTleDRAgo.show_fps' redirect_method :scale_screen, 'LiTTleDRAgo.scale_screen' redirect_method :fill_monitor, 'LiTTleDRAgo.fill_monitor' redirect_method :window, 'LiTTleDRAgo.window' redirect_method :toggle, 'LiTTleDRAgo.toggle' redirect_method :fullscreen, 'LiTTleDRAgo.fullscreen' redirect_method :fullscreen?, 'LiTTleDRAgo.fullscreen?' redirect_method :control_screen_size,'LiTTleDRAgo.control_screen_size' redirect_method :high_priority, 'LiTTleDRAgo.high_priority' redirect_method :high_priority=, 'LiTTleDRAgo.high_priority=args.at(0)' #------------------------------------------------------------------------ # ● Alias Listing #------------------------------------------------------------------------ alias_sec_method :resize_screen, :scale_screen #-------------------------------------------------------------------------- # * New method: fadeoutviewport #-------------------------------------------------------------------------- def fadeoutviewport @fadeoutviewport ||= ((v = Viewport.new(0,0,width,height)) (v.color = (v.z = 0x3FFFFFFF) && Color.new(0,0,0,0)) && v) end #-------------------------------------------------------------------------- # ● Redefined method: wait, brightness #-------------------------------------------------------------------------- define_sec_method(:wait) { |frame| frame.times {|i| update } } define_sec_method(:brightness) { (255 - fadeoutviewport.color.alpha) } #-------------------------------------------------------------------------- # * Redefined method: brightness= (Set Graphics Brightness) #-------------------------------------------------------------------------- unless method_defined?(:brightness=) def brightness=(value) fadeoutviewport.color.alpha = 255 - value.clamp(0,255) end end #-------------------------------------------------------------------------- # * Redefined method: fadein (Graphics Fade In) # frame : frame of fade #-------------------------------------------------------------------------- unless method_defined?(:fadein) def fadein(frames = 10) return if frames <= 0 curvalue, count = brightness, (255 - brightness) frames.times do |i| (self.brightness = curvalue + (count * i / frames)) && update end end end #-------------------------------------------------------------------------- # * Redefined method: fadeout (Graphics Fade Out) # frame : frame of fade #-------------------------------------------------------------------------- unless method_defined?(:fadeout) def fadeout(frames = 10) return if frames <= 0 curvalue = count = self.brightness frames.times do |i| (self.brightness = curvalue - (count * i / frames)) && update end end end #-------------------------------------------------------------------------- # * New method: wait_for_input #-------------------------------------------------------------------------- unless method_defined?(:wait_for_input) def wait_for_input [Input,self].update [Input,self].update until press_any_key end end end #============================================================================== # ** Input #------------------------------------------------------------------------------ # This module handles all Input #============================================================================== class << Input #------------------------------------------------------------------------ # ● Include AutoUpdate #------------------------------------------------------------------------ include_auto_update #-------------------------------------------------------------------------- # ● Aliased method: :press?, :repeat?, :trigger? #-------------------------------------------------------------------------- [:press?,:repeat?,:trigger?].each do |method| next unless method_defined?(:"#{method}") alias_sec_method(:"sym_#{method}", :"#{method}") define_method(:"#{method}") do |*args| if (b = args.first).is_a?(Symbol) || b.is_a?(String) args[0] = Input.const_get("#{b}") rescue nil end (args.first.not.nil?) && send(:"sym_#{method}", *args) end end end #============================================================================== # ** Sprite_Battler #------------------------------------------------------------------------------ # This sprite is used to display the battler.It observes the Game_Character # class and automatically changes sprite conditions. #============================================================================== class Sprite_Battler #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- define_pre_alias(:update) { @battler.nil? && @battler_name = nil } end #============================================================================== # ** Spriteset_Map #------------------------------------------------------------------------------ # This class brings together map screen sprites, tilemaps, etc. # It's used within the Scene_Map class. #============================================================================== class Spriteset_Map #-------------------------------------------------------------------------- # ● New method: sprite_player #-------------------------------------------------------------------------- define_sec_method(:sprite_player) { find_character($game_player) } #------------------------------------------------------------------------ # ● Public Instance Variables #------------------------------------------------------------------------ attr_sec_reader :character_sprites, 'Array.new' attr_reader :viewport1, :viewport2, :viewport3 #-------------------------------------------------------------------------- # * Aliased method: update #-------------------------------------------------------------------------- define_pre_alias(:update) { update_viewport_size_change } #-------------------------------------------------------------------------- # * New method: update_viewport_size_change #-------------------------------------------------------------------------- def update_viewport_size_change if viewport_size_change? @viewport_map_width = $game_map.width @viewport_map_height = $game_map.height @viewport_screen_width = Graphics.width @viewport_screen_height = Graphics.height [@viewport1,@viewport2,@viewport3].compact.update_viewport_sizes end end #-------------------------------------------------------------------------- # * New method: viewport_size_change? #-------------------------------------------------------------------------- unless method_defined?(:viewport_size_change?) def viewport_size_change? return true if @viewport_map_width != $game_map.width return true if @viewport_map_height != $game_map.height return true if @viewport_screen_width != Graphics.width return true if @viewport_screen_height != Graphics.height end end #-------------------------------------------------------------------------- # ● New method: redraw_character_sprites #-------------------------------------------------------------------------- unless method_defined?(:redraw_character_sprites) def redraw_character_sprites return refresh_characters if self.respond_to?(:refresh_characters) character_sprites.dispose @character_sprites = $game_map.events.keys.sort.map {|i| Sprite_Character.new(@viewport1, $game_map.events[i]) } @character_sprites.push(Sprite_Character.new(@viewport1, $game_player)) end end #-------------------------------------------------------------------------- # ● New method: find_character #-------------------------------------------------------------------------- unless method_defined?(:find_character) def find_character(char) character_sprites.detect { |s| s.character == char } end end #--------------------------------------------------------------------------- # * New method: viewport_sprite #--------------------------------------------------------------------------- def viewport_sprite(*v) v.collect! {|s| s.is_a?(Symbol) ? instance_variable_get(:"@#{s}") : s } v.reject! {|s| s.not.is_a?(Viewport)} all = instance_variables.map {|s| instance_variable_get("#{s}")}.flatten all.select {|s| s.respond_to?(:viewport) && v.include?(s.viewport)} end end #============================================================================== # ** Game_Battler #------------------------------------------------------------------------------ # This class deals with battlers. It's used as a superclass for the Game_Actor # and Game_Enemy classes. #============================================================================== class Game_Battler #-------------------------------------------------------------------------- # ● New method: alive? #-------------------------------------------------------------------------- define_sec_method(:alive?) { self.not.dead? } #-------------------------------------------------------------------------- # ● New method: hp_percent #-------------------------------------------------------------------------- unless method_defined?(:hp_percent) def hp_percent(integer = false, float_points = 2) n = Math.percent(hp,(respond_to?(:mhp) ? mhp : maxhp)) return integer ? Integer(n) : n.float_points(float_points) end end #-------------------------------------------------------------------------- # ● New method: sp_percent #-------------------------------------------------------------------------- unless method_defined?(:sp_percent) def sp_percent(integer = false, float_points = 2) n = Math.percent((respond_to?(:sp) ? sp : mp), ((respond_to?(:mmp) ? mmp : (respond_to?(:maxsp) ? maxsp : maxmp)))) return integer ? Integer(n) : n.float_points(float_points) end alias_method :mp_percent, :sp_percent end end #============================================================================== # ** Game_Character #------------------------------------------------------------------------------ # This class deals with characters. It's used as a superclass for the # Game_Player and Game_Event classes. #============================================================================== class Game_Character #-------------------------------------------------------------------------- # ● Redirect Listing #-------------------------------------------------------------------------- redirect_method :move_down, 'move_straight(2,*args)' redirect_method :move_left, 'move_straight(4,*args)' redirect_method :move_right, 'move_straight(6,*args)' redirect_method :move_up, 'move_straight(8,*args)' redirect_method :turn_down, 'set_direction(2,*args)' redirect_method :turn_left, 'set_direction(4,*args)' redirect_method :turn_right, 'set_direction(6,*args)' redirect_method :turn_up, 'set_direction(8,*args)' redirect_method :move_lower_left, 'move_diagonal(4, 2,*args)' redirect_method :move_lower_right, 'move_diagonal(6, 2,*args)' redirect_method :move_upper_left, 'move_diagonal(4, 8,*args)' redirect_method :move_upper_right, 'move_diagonal(6, 8,*args)' redirect_method :character_sprite, '$game_map.character_sprite(self)' redirect_method :character_above?, '(args.first.y > @y)' redirect_method :character_below?, '(args.first.y < @y)' redirect_method :character_right?, '(args.first.x < @x)' redirect_method :character_left?, '(args.first.x > @x)' redirect_method :pos, '[@x, @y]' redirect_method :pos_nt?, '!@through && pos?' redirect_method :normal_priority?, '@character_name != ""' redirect_method :map_passable?, '$game_map.passable?' redirect_method :map_terrain_tag, '$game_map.terrain_tag' #-------------------------------------------------------------------------- # * Redefined method: pos? # anime # reverse_dir #-------------------------------------------------------------------------- define_sec_method(:reverse_dir) {|dir| 10 - dir } define_sec_method(:pos?) {|x,y| @x == x && @y == y } define_sec_method(:anime) {|aid| @animation_id = aid } #-------------------------------------------------------------------------- # ● Redefined method: check_event_trigger_touch_front #-------------------------------------------------------------------------- unless method_defined?(:check_event_trigger_touch_front) def check_event_trigger_touch_front x2 = $game_map.round_x_with_direction(@x, @direction) y2 = $game_map.round_y_with_direction(@y, @direction) check_event_trigger_touch(x2, y2) end end #-------------------------------------------------------------------------- # ● Redefined method: move_straight #-------------------------------------------------------------------------- unless method_defined?(:move_straight) def move_straight(d, turn_ok = true) if passable?(@x, @y, d) set_direction(d) @x = $game_map.round_x_with_direction(@x, d) @y = $game_map.round_y_with_direction(@y, d) increase_steps elsif turn_ok set_direction(d) check_event_trigger_touch_front end end end #-------------------------------------------------------------------------- # ● Redefined method: set_direction #-------------------------------------------------------------------------- unless method_defined?(:set_direction) def set_direction(d) @direction = d unless @direction_fix || d == 0 @stop_count = 0 end end #-------------------------------------------------------------------------- # ● Redefined method: set_graphic #-------------------------------------------------------------------------- unless method_defined?(:set_graphic) def set_graphic(character_name, character_index = 0) @tile_id = 0 @character_name = character_name if self.respond_to?(:character_index) @character_index = character_index else @character_hue = character_index end @original_pattern = 1 end end #-------------------------------------------------------------------------- # ● Redefined method: swap #-------------------------------------------------------------------------- unless method_defined?(:swap) def swap(character) new_pos = character.pos character.moveto(x, y) moveto(*new_pos) end end #-------------------------------------------------------------------------- # ● Redefined method: rotate_swap_prev #-------------------------------------------------------------------------- unless method_defined?(:rotate_swap_prev) def rotate_swap_prev(*character) character.unshift(self) position = character.collect {|c| c.pos} character.each_with_index { |c,i| c.moveto(*position[i-1]) } end end #-------------------------------------------------------------------------- # ● Redefined method: rotate_swap_next #-------------------------------------------------------------------------- unless method_defined?(:rotate_swap_next) def rotate_swap_next(*character) character.unshift(self) position = character.collect {|c| c.pos} character.each_with_index do |char,index| char.moveto(*position[index + 1 >= position.size ? 0 : index + 1]) end end end #-------------------------------------------------------------------------- # ● New method: distance_from #-------------------------------------------------------------------------- unless method_defined?(:distance_from) def distance_from(character,type= 'xy') character = $game_map.events[character] if character.is_a?(Integer) return 0 if character.nil? return (@x - character.x).abs if type.to_s == 'x' return (@y - character.y).abs if type.to_s == 'y' return Math.hypot(@x - character.x, @y - character.y) end end #-------------------------------------------------------------------------- # * Redefined method: distance_x_from #-------------------------------------------------------------------------- unless method_defined?(:distance_x_from) def distance_x_from(x) result = @x - x if result.abs > $game_map.width / 2 result += result < 0 ? $game_map.width : -$game_map.width end result end end #-------------------------------------------------------------------------- # * Redefined method: distance_y_from #-------------------------------------------------------------------------- unless method_defined?(:distance_y_from) def distance_y_from(y) result = @y - y if result.abs > $game_map.height / 2 result += result < 0 ? $game_map.height : -$game_map.height end result end end #-------------------------------------------------------------------------- # ● New method: random_teleport #-------------------------------------------------------------------------- unless method_defined?(:random_teleport) def random_teleport 1000.times do moveto(rand($game_map.height), rand($game_map.width)) vx = LiTTleDRAgo::VX && !LiTTleDRAgo::VXA arg = vx ? [@x,@y] : [@x,@y,@direction] break if passable?(*arg) end || true end end #-------------------------------------------------------------------------- # * Redefined method: diagonal_passable? (for RMXP) # horz : Horizontal (4 or 6) # vert : Vertical (2 or 8) #-------------------------------------------------------------------------- unless method_defined?(:diagonal_passable?) def diagonal_passable?(x, y, horz, vert) x2 = $game_map.round_x_with_direction(x, horz) y2 = $game_map.round_y_with_direction(y, vert) (passable?(x, y, vert) && passable?(x, y2, horz)) || (passable?(x, y, horz) && passable?(x2, y, vert)) end end #-------------------------------------------------------------------------- # * Redefined method: collide_with_characters? (for RMXP) #-------------------------------------------------------------------------- unless method_defined?(:collide_with_characters?) def collide_with_characters?(x, y) collide_with_events?(x, y) end end #-------------------------------------------------------------------------- # * Redefined method: collide_with_events? (for RMXP) #-------------------------------------------------------------------------- unless method_defined?(:collide_with_events?) def collide_with_events?(x, y) $game_map.events_xy_nt(x, y).any? do |event| event.normal_priority? || self.is_a?(Game_Event) end end end #-------------------------------------------------------------------------- # * Redefined method: debug_through? #-------------------------------------------------------------------------- unless method_defined?(:debug_through?) def debug_through? debug = LiTTleDRAgo::VX ? $TEST : $DEBUG return debug && Input.press?(Input::CTRL) if self.is_a?(Game_Player) return false end end end #============================================================================== # ** Game_Actor #------------------------------------------------------------------------------ # This class handles actors. It is used within the Game_Actors class # ($game_actors), also referenced from the Game_Party class ($game_party). #============================================================================== class Game_Actor #-------------------------------------------------------------------------- # * Get Actor Object #-------------------------------------------------------------------------- define_sec_method(:actor) { $data_actors[@actor_id] } define_method(:class) { $data_classes[@class_id] } end #============================================================================== # ** Game_Enemy #------------------------------------------------------------------------------ # This class handles enemies. It used within the Game_Troop class # ($game_troop). #============================================================================== class Game_Enemy #-------------------------------------------------------------------------- # * Get Enemy Object #-------------------------------------------------------------------------- define_sec_method(:enemy) { $data_enemies[@enemy_id] } end #============================================================================== # ** Game_Player #------------------------------------------------------------------------------ # This class handles the player. It includes event starting determinants and # map scrolling functions. The instance of this class is referenced by # $game_player. #============================================================================== class Game_Player #-------------------------------------------------------------------------- # ● Redefined method: actor # name #-------------------------------------------------------------------------- define_sec_method(:actor) { $game_party.leader } define_sec_method(:name) { actor.name } #-------------------------------------------------------------------------- # ● New method: method_missing #-------------------------------------------------------------------------- def method_missing(val,*a,&b) return actor.send(val.to_s,*a,&b) if actor.respond_to?(val.to_sym) text = "Undefined method #{val} for #{self.inspect}" raise(NoMethodError, text, caller(1)) end end #============================================================================== # ** Game_Event #------------------------------------------------------------------------------ # This class deals with events. It handles functions including event page # switching via condition determinants, and running parallel process events. # It's used within the Game_Map class. #============================================================================== class Game_Event < Game_Character #-------------------------------------------------------------------------- # ● Public Instance Variables #-------------------------------------------------------------------------- method_defined?(:erased) || (attr_reader :erased) method_defined?(:id) || (attr_reader :id) method_defined?(:event) || (attr_reader :event) attr_accessor :loaded_event #-------------------------------------------------------------------------- # ● New method: name # ● New method: restore #-------------------------------------------------------------------------- define_sec_method(:name) { @event.name } define_sec_method(:restore) { (@erased = false) || refresh } #-------------------------------------------------------------------------- # ● New method: destroy #-------------------------------------------------------------------------- unless method_defined?(:destroy) def destroy event = $game_map.events.delete(@id) if (s = $game_map.spriteset).is_a?(Spriteset_Map) after = s.character_sprites.select { |e| e if e.character != event } (delet = character_sprite) && delet.dispose s.character_sprites.replace(after) end end end #-------------------------------------------------------------------------- # ● New method: eliminate #-------------------------------------------------------------------------- unless method_defined?(:eliminate) def eliminate return destroy if self.loaded_event (eliminate = $game_map.eliminate_event)[(id = $game_map.map_id)] ||= [] (eliminate[id].include?(@id) || eliminate[id].push(@id)) && destroy end end #-------------------------------------------------------------------------- # ● New method: note #-------------------------------------------------------------------------- unless method_defined?(:note) def note list = @page ? @page.list.select {|l| [108,408].include?(l.code)} : [] notes = list.collect {|l| l.parameters[0] }.join("\n") return notes end end #-------------------------------------------------------------------------- # ● New method: proper_page_index #-------------------------------------------------------------------------- unless method_defined?(:proper_page_index) def proper_page_index if respond_to?(:conditions_met?) page = respond_to?(:find_proper_page) ? find_proper_page : @event.pages.reverse.find {|page| conditions_met?(page)} (i = @event.pages.index(page)).is_a?(Integer) ? i + 1 : 0 end end end end #============================================================================== # ** Game_Party #------------------------------------------------------------------------------ # This class handles the party. It includes information on amount of gold # and items. Refer to "$game_party" for the instance of this class. #============================================================================== class Game_Party #-------------------------------------------------------------------------- # ● Alias Listing #-------------------------------------------------------------------------- alias_sec_method :drg_ce_item_number, :item_number #-------------------------------------------------------------------------- # ● Redirect Listing #-------------------------------------------------------------------------- redirect_method :player_pos, '($game_player.pos)' redirect_method :leader, '(members.first)' redirect_method :members, '(actors)' redirect_method :actors, '(members)' #-------------------------------------------------------------------------- # ● New method: existing_actors, recover_all #-------------------------------------------------------------------------- define_sec_method(:existing_actors) { members.find_all {|a| a.exist?} } define_sec_method(:recover_all) { members.each {|a| a.recover_all} } #-------------------------------------------------------------------------- # ● New method: has_actors? #-------------------------------------------------------------------------- unless method_defined?(:has_actors?) def has_actors?(*actors) party = @actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s } actor = actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s }.flatten return party.have_all?(*actor) end end #-------------------------------------------------------------------------- # ● New method: has_any_actors? #-------------------------------------------------------------------------- unless method_defined?(:has_any_actors?) def has_any_actors?(*actors) party = @actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s } actor = actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s }.flatten return party.have_any?(*actor) end end #-------------------------------------------------------------------------- # ● New method: swap_previous_actor #-------------------------------------------------------------------------- unless method_defined?(:swap_leader_prev) def swap_leader_prev(n = 1) n <= 0 || n.round.times { @actors.previous_item && drg_ce_refresh } n >= 0 || swap_leader_next(n.round.abs) end end #-------------------------------------------------------------------------- # ● New method: swap_next_actor #-------------------------------------------------------------------------- unless method_defined?(:swap_leader_next) def swap_leader_next(n = 1) n <= 0 || n.round.times { @actors.next_item && drg_ce_refresh } n >= 0 || swap_leader_prev(n.round.abs) end end #-------------------------------------------------------------------------- # ● New method: set_leader #-------------------------------------------------------------------------- unless method_defined?(:set_leader) def set_leader(id) actor = id.is_a?(Numeric) ? $game_actors[id.to_i] : id if actor.is_a?(Game_Actor) && has_actors?(actor.id) swap_leader_next until $game_party.leader.id == actor.id actor.id end end end #-------------------------------------------------------------------------- # ● New method: drg_ce_refresh #-------------------------------------------------------------------------- unless method_defined?(:drg_ce_refresh) def drg_ce_refresh return refresh if respond_to?(:refresh) return ($game_map.need_refresh = true) && $game_player.refresh end end #-------------------------------------------------------------------------- # * Get Party Name #-------------------------------------------------------------------------- unless method_defined?(:name) def name return "" if existing_actors.size == 0 return leader.name if existing_actors.size == 1 return "#{leader.name}'s Party" end end #-------------------------------------------------------------------------- # * Aliased method: item_number #-------------------------------------------------------------------------- def item_number(item) unless LiTTleDRAgo::VX return drg_ce_item_number(item.id) if item.is_a?(RPG::Item) return weapon_number(item.id) if item.is_a?(RPG::Weapon) return armor_number(item.id) if item.is_a?(RPG::Armor) else item = $data_items[item.to_i] if item.is_a?(Numeric) end return skill_number(item) if item.is_a?(RPG::Skill) return drg_ce_item_number(item) end #-------------------------------------------------------------------------- # * Redefined method: weapon_number #-------------------------------------------------------------------------- unless method_defined?(:weapon_number) def weapon_number(weapon) weapon = $data_weapons[weapon.to_i] if weapon.is_a?(Numeric) item_number(weapon) end end #-------------------------------------------------------------------------- # * Redefined method: armor_number #-------------------------------------------------------------------------- unless method_defined?(:armor_number) def armor_number(armor) armor = $data_armors[armor.to_i] if armor.is_a?(Numeric) item_number(armor) end end #-------------------------------------------------------------------------- # * New method: skill_number #-------------------------------------------------------------------------- unless method_defined?(:skill_number) def skill_number(skill) skill = $data_skills[skill.to_i] if skill.is_a?(Numeric) s1 = actors.select {|a| a.skill_learn?(skill) } s2 = actors.select {|a| a.skill_learn?(skill.id) } return s1.size + s2.size end end #-------------------------------------------------------------------------- # * New method: gain_all_items #-------------------------------------------------------------------------- def gain_all_items(ammount=1) (0..999).to_a.each do |s| next if $data_items[s].nil? || $data_items[s].name == '' $game_party.drg_ce_get_item($data_items[s],ammount) end end #-------------------------------------------------------------------------- # * New method: gain_all_weapons #-------------------------------------------------------------------------- def gain_all_weapons(ammount=1) (0..999).to_a.each do |s| next if $data_weapons[s].nil? || $data_weapons[s].name == '' drg_ce_get_item($data_weapons[s],ammount) end end #-------------------------------------------------------------------------- # * New method: gain_all_armors #-------------------------------------------------------------------------- def gain_all_armors(ammount=1) (0..999).to_a.each do |s| next if $data_armors[s].nil? || $data_armors[s].name == '' drg_ce_get_item($data_armors[s],ammount) end end #-------------------------------------------------------------------------- # * New method: drg_ce_get_item #-------------------------------------------------------------------------- def drg_ce_get_item(item,ammount) return gain_item(item,ammount) if LiTTleDRAgo::VX return gain_item(item.id,ammount) if item.is_a?(RPG::Item) return gain_weapon(item.id,ammount) if item.is_a?(RPG::Weapon) return gain_armor(item.id,ammount) if item.is_a?(RPG::Armor) end end #============================================================================== # ** Game_Follower #------------------------------------------------------------------------------ # This class handles followers. A follower is an allied character, other than # the front character, displayed in the party. It is referenced within the # Game_Followers class. #============================================================================== class Game_Follower < Game_Character #-------------------------------------------------------------------------- # * Redirect Listing #-------------------------------------------------------------------------- redirect_method :name, "(actor.nil? ? '' : actor.name)" end if defined?(Game_Follower) #============================================================================== # ** Game_Map #------------------------------------------------------------------------------ # This class handles maps. It includes scrolling and passage determination # functions. The instance of this class is referenced by $game_map. #============================================================================== class Game_Map #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_sec_reader :eliminate_event, 'Hash.new' #-------------------------------------------------------------------------- # ● New method: name, parent_id, base_parent_id # event_list , map_events #-------------------------------------------------------------------------- define_sec_method(:name) { mapInfo[@map_id].name } define_sec_method(:parent_id) { mapInfo[@map_id].parent_id } define_sec_method(:base_parent_id) { search_parent_id(mapInfo) } define_sec_method(:event_list) { events.values } define_sec_method(:map_events) { @map.events } define_sec_method(:screen) { $game_screen } define_sec_method(:loop_horizontal?) { false } define_sec_method(:loop_vertical?) { false } define_sec_method(:map_child?) { |*a| a & child_ids == a } #-------------------------------------------------------------------------- # * Aliased method: setup #-------------------------------------------------------------------------- define_post_alias(:setup) do eliminate_event[@map_id] ||= [] eliminate_event[@map_id].each { |s| events.delete(s) } end #-------------------------------------------------------------------------- # * Redefined method: any_event_strarting? (for RMXP) #-------------------------------------------------------------------------- unless method_defined?(:any_event_starting?) def any_event_starting? event_list.any? {|event| event.starting } end end #-------------------------------------------------------------------------- # * Redefined method: interpreter (for RMXP) #-------------------------------------------------------------------------- unless method_defined?(:interpreter) def interpreter return $game_system.map_interpreter if LiTTleDRAgo.scene.is_a?(Scene_Map) return $game_system.battle_interpreter end end #-------------------------------------------------------------------------- # * Redefined method: events_xy (for RMXP) #-------------------------------------------------------------------------- unless method_defined?(:events_xy) def events_xy(x, y) event_list.select {|event| event.x == x && event.y == y } end end #-------------------------------------------------------------------------- # * Redefined method: events_xy_nt (for RMXP) #-------------------------------------------------------------------------- unless method_defined?(:events_xy_nt) def events_xy_nt(x, y) event_list.select {|event| event.pos_nt?(x, y) } end end #-------------------------------------------------------------------------- # * Redefined method: round_x, round_y (for RMXP) #-------------------------------------------------------------------------- define_sec_method(:round_x) {|x| loop_horizontal? ? (x + width) % width : x } define_sec_method(:round_y) {|y| loop_vertical? ? (y + height) % height : y } #-------------------------------------------------------------------------- # * Redefined method: x_with_direction (for RMXP) #-------------------------------------------------------------------------- define_sec_method(:x_with_direction) {|x, d| x + (d==6 ? 1 : d==4 ? -1 : 0)} define_sec_method(:y_with_direction) {|y, d| y + (d==2 ? 1 : d==8 ? -1 : 0)} #-------------------------------------------------------------------------- # * Redefined method: round_x_with_direction (for RMXP) #-------------------------------------------------------------------------- unless method_defined?(:round_x_with_direction) def round_x_with_direction(x, d) round_x(x_with_direction(x, d)) end end #-------------------------------------------------------------------------- # * Redefined method: round_y_with_direction (for RMXP) #-------------------------------------------------------------------------- unless method_defined?(:round_y_with_direction) def round_y_with_direction(y, d) round_y(y_with_direction(y, d)) end end #-------------------------------------------------------------------------- # * New method: x_diagonal_with_direction (for RMXP) #-------------------------------------------------------------------------- unless method_defined?(:x_diagonal_with_direction) def x_diagonal_with_direction(x, d) x + ([9,6,3].include?(d) ? 1 : [7,4,1].include?(d) ? -1 : 0) end end #-------------------------------------------------------------------------- # * New method: y_with_direction (for RMXP) #-------------------------------------------------------------------------- unless method_defined?(:y_diagonal_with_direction) def y_diagonal_with_direction(y, d) y + ([1,2,3].include?(d) ? 1 : [7,8,9].include?(d) ? -1 : 0) end end #-------------------------------------------------------------------------- # ● New method: existing_events #-------------------------------------------------------------------------- unless method_defined?(:existing_events) def existing_events event_list.select {|e| e.not.erased } end end #-------------------------------------------------------------------------- # ● New method: map_info #-------------------------------------------------------------------------- unless method_defined?(:mapInfo) def mapInfo(ext = LiTTleDRAgo.data_default_extension) data = "Data/MapInfos.#{ext}" @mapinfo ||= load_data(sprintf("#{data}")) rescue draise( "Fail to load #{data}") return @mapinfo end end #-------------------------------------------------------------------------- # ● New method: search_parent_id #-------------------------------------------------------------------------- unless method_defined?(:search_parent_id) def search_parent_id(mapInfo, id = @map_id, ancestor = 0) m_id = id loop do _m_id = mapInfo[m_id] p_id = _m_id.respond_to?(:parent_id) ? _m_id.parent_id : nil return p_id if p_id == nil return m_id if p_id == ancestor m_id = p_id end end end #-------------------------------------------------------------------------- # ● New method: base_map_name #-------------------------------------------------------------------------- unless method_defined?(:base_map_name) def base_map_name map = mapInfo[search_parent_id(mapInfo)] name = map.respond_to?(:name) ? map.name : '' return name end end #-------------------------------------------------------------------------- # ● New method: child_ids #-------------------------------------------------------------------------- unless method_defined?(:child_ids) def child_ids mapInfo.keys.select {|map_id| mapInfo[map_id].parent_id == @map_id } end end #-------------------------------------------------------------------------- # ● New method: descendant? #-------------------------------------------------------------------------- unless method_defined?(:map_descendant?) def map_descendant?(*a) a.all? {|map_id| search_parent_id(mapInfo, map_id, @map_id)} end end #-------------------------------------------------------------------------- # ● New method: load_event #-------------------------------------------------------------------------- unless method_defined?(:load_event) def load_event(*a) case a.size when 5, 4 then (mapid, eventid, x, y = *a) when 3 then (mapid = @map_id) && (eventid, x, y = *a) when 2 then (mapid, y = @map_id, 0) && (eventid, x = *a) when 1 then (mapid, x, y = @map_id, 0,0) && (eventid = a.first) when 0 then return nil end map = load_map_data(mapid) event = map.events.values.detect { |event| event.id == eventid } unless event.nil? (a = a.at(4)) && (b = [a].flatten) && event.pages.reject! do |s| c = b.map {|i| i.is_a?(Range) ? i.to_a : i } c.flatten.not.include?(event.pages.index(s)+1) end return nil if event.pages.empty? c,r = [Array,Range], [] c.include?(x.class) && (x = x.to_a.map{|s|s.is_a?(Range) ? s.to_a : s}) c.include?(y.class) && (y = y.to_a.map{|s|s.is_a?(Range) ? s.to_a : s}) [x].flatten.dproduct([y].flatten).each do |x1,y1| event.instance_variable_set(:@id,(id = next_key_events)) r.push(@events[id] = e = Game_Event.new(@map_id, event.clone)) e.loaded_event = true e.moveto(x1,y1) end a = r.size == 1 ? r.first : r if r && (s = spriteset).is_a?(Spriteset_Map) sc = s.character_sprites after = sc.select { |e| e if e.character != $game_player } player = s.sprite_player sc.replace(after) r.each {|e| sc.push(Sprite_Character.new(s.viewport1, e)) } sc.push(player) end return a end end end #-------------------------------------------------------------------------- # ● New method: call_event #-------------------------------------------------------------------------- unless method_defined?(:call_event) def call_event(*a) case a.size when 3 then (mapid, eventid, page_id = *a) when 2 then (page_id = -1) && (mapid, eventid = *a) when 1 then (mapid, page_id = @map_id, -1) && (eventid = a.first) when 0 then return nil end map = load_map_data(mapid) event = map.events.values.detect { |event| event.id == eventid } unless event.nil? if page_id == -1 && event.respond_to?(:conditions_met?) pages = event.pages.reverse.find {|page| event.conditions_met?(page)} else pages = event.pages[[page_id,1].max-1] end klass = LiTTleDRAgo::VX ? Game_Interpreter : Interpreter child = klass.new(interpreter.instance_variable_get(:@depth) + 1) child.setup(pages.list, interpreter.same_map? ? event.id : 0) if LiTTleDRAgo::VXA child.run rescue FiberError else interpreter.instance_variable_set(:@child_interpreter, child) end end end end #-------------------------------------------------------------------------- # ● New method: load_map_data #-------------------------------------------------------------------------- unless method_defined?(:load_map_data) def load_map_data(mapid, ext = LiTTleDRAgo.data_default_extension) (map = sprintf("Data/Map%03d.#{ext}", mapid)) && load_data(map) end end #-------------------------------------------------------------------------- # ● New method: increment_key_events #-------------------------------------------------------------------------- unless method_defined?(:next_key_events) def next_key_events (@events.keys.max || 0) + 1 end end #-------------------------------------------------------------------------- # ● New method: unused_key_events #-------------------------------------------------------------------------- unless method_defined?(:unused_key_events) def unused_key_events(start = 1) start = [start, next_key_events].min (start..next_key_events).detect {|i| @events.keys.not.include?(i)} end end #-------------------------------------------------------------------------- # ● New method: spriteset #-------------------------------------------------------------------------- unless method_defined?(:spriteset) def spriteset LiTTleDRAgo.scene.instance_variable_get(:@spriteset) end end #-------------------------------------------------------------------------- # ● New method: character_sprite #-------------------------------------------------------------------------- unless method_defined?(:character_sprite) def character_sprite(id = 0) return unless spriteset.is_a?(Spriteset_Map) id = id.is_a?(Game_Character) ? id : id == 0 ? $game_player : events[id] spriteset.find_character(id) end end #-------------------------------------------------------------------------- # ● New method: picture_sprite #-------------------------------------------------------------------------- unless method_defined?(:picture_sprite) def picture_sprite(id = nil) return unless spriteset.is_a?(Spriteset_Map) spriteset.update_pictures if spriteset.respond_to?(:update_pictures) result = spriteset.instance_variable_get(:@picture_sprites) id.nil? ? result : result[id] end end end #============================================================================== # ■ RPG::Cache #------------------------------------------------------------------------------ # #============================================================================== ModCache = LiTTleDRAgo.cache class << ModCache #----------------------------------------------------------------------- # ● New method: self.draw_text #----------------------------------------------------------------------- unless method_defined?(:draw_text) def draw_text( width, height, text, font = Font.default_name, size = Font.default_size, bold = Font.default_bold, italic = Font.default_italic, color = Font.default_color, edging = false ) cache_index = "text_" + width.to_s + height.to_s + text font_text = "" font.size.times do |i| font_text += font[i].to_s end cache_index += font_text + size.to_s + bold.to_s + italic.to_s cache_index += "#{color.red}#{color.blue}#{color.green}#{color.alpha}" @cache ||= {} if @cache[cache_index].nil? or @cache[cache_index].disposed? bitmap = Bitmap.new(width, height) bitmap.font.name = font bitmap.font.size = size bitmap.font.bold = bold bitmap.font.italic = italic bitmap.font.color = color if edging bitmap.draw_edging_text(0, 0, width, height, text, 0) else bitmap.draw_text(0, 0, width, height, text, 0) end @cache[cache_index] = bitmap end return @cache[cache_index] end end #----------------------------------------------------------------------- # ● New method: self.method_missing #----------------------------------------------------------------------- def method_missing(val,*a,&b) if a.at(0).is_a?(String) && a.size <= 2 return load_bitmap("Graphics/#{val}/",*a,&b) end modified = [:invert,:brighten,:darken,:grayscale,:pixelate,:frost] if modified.include?(a.first) && a.at(1).is_a?(String) && a.size <= 3 method = a.shift filename = a.join + "-#{method}" unless drago_bitmap_exist?("Graphics/#{val}",filename) bitmap = load_bitmap("Graphics/#{val}/",*a,&b) drago_set_bitmap(bitmap.send(method),"Graphics/#{val}",filename) end return drago_get_bitmap("Graphics/#{val}",filename) end text = "Undefined method #{val} for #{self.inspect}" raise(NoMethodError, text, caller(1)) end #----------------------------------------------------------------------- # ● New method: drago_get_bitmap #----------------------------------------------------------------------- def drago_get_bitmap(folder_name, filename = '', hue = 0) return empty_bitmap if filename.not.is_a?(String) || filename.empty? path = LiTTleDRAgo::APPPATHDRAGO + "#{folder_name}/" path = path.gsub("\\","/").gsub("//","/") last = filename.split('.').last filename.gsub!(".png","") if last.is_a?(String) && last[/png/i] load_bitmap_no_rescue(path.downcase,filename.downcase,hue) end #----------------------------------------------------------------------- # ● New method: drago_set_bitmap #----------------------------------------------------------------------- def drago_set_bitmap(bitmap, folder_name = '', filename = 'bitmap') path = LiTTleDRAgo::APPPATHDRAGO + "#{folder_name}/" path = path.gsub("\\","/").gsub("//","/") last = filename.split('.').last filename += '.png' unless last.is_a?(String) && last[/png/i] Dir.make_dir(path) unless FileTest.directory?(path) bitmap.export(path + filename) drago_get_bitmap(folder_name, filename) end #----------------------------------------------------------------------- # ● New method: drago_bitmap_exist? #----------------------------------------------------------------------- def drago_bitmap_exist?(folder_name, filename) return false if filename.not.is_a?(String) || filename.empty? path = LiTTleDRAgo::APPPATHDRAGO + "#{folder_name}/" path = path.gsub("\\","/").gsub("//","/") last = filename.split('.').last filename += '.png' unless last.is_a?(String) && last[/png/i] FileTest.file?(path + filename) end #-------------------------------------------------------------------------- # * Load Bitmap #-------------------------------------------------------------------------- define_sec_method(:load_bitmap_no_rescue) do |folder, file, *a| @cache ||= {} if file.empty? empty_bitmap elsif (hue = a.first).is_a?(Numeric) && hue != 0 hue_changed_bitmap(folder + file, hue.round) else normal_bitmap(folder + file) end end #-------------------------------------------------------------------------- # * Create Empty Bitmap #-------------------------------------------------------------------------- define_sec_method(:empty_bitmap) { Bitmap.new(32, 32)} #-------------------------------------------------------------------------- # * Create/Get Normal Bitmap #-------------------------------------------------------------------------- define_sec_method(:normal_bitmap) do |path| @cache[path] = Bitmap.new(path) unless include?(path) @cache[path] end #-------------------------------------------------------------------------- # * Create/Get Hue-Changed Bitmap #-------------------------------------------------------------------------- define_sec_method(:hue_changed_bitmap) do |path, hue| key = [path, hue] unless include?(key) @cache[key] = normal_bitmap(path).clone @cache[key].hue_change(hue) end @cache[key] end #-------------------------------------------------------------------------- # * Check Cache Existence #-------------------------------------------------------------------------- def include?(key) @cache[key] && @cache[key].not.disposed? end end #============================================================================== # ** Window_Base #------------------------------------------------------------------------------ # This class is for all in-game windows. #============================================================================== class Window_Base < Window #-------------------------------------------------------------------------- # * Redirect Listing #-------------------------------------------------------------------------- redirect_method :draw_text, 'contents.draw_text' redirect_method :text_size, 'contents.text_size' redirect_method :change_color, 'contents.change_color' redirect_method :draw_picture, 'contents.draw_picture' redirect_method :draw_icon, 'contents.draw_icon' redirect_method :draw_battler, 'contents.draw_battler' #-------------------------------------------------------------------------- # * Redefined method: line_height, translucent_alpha # * New method: show, hide, activate, deactivate #-------------------------------------------------------------------------- define_sec_method(:line_height) { 32 } define_sec_method(:translucent_alpha) { 160 } define_sec_method(:show) { self.visible = true } define_sec_method(:hide) { self.visible = false } define_sec_method(:activate) { self.active = true } define_sec_method(:deactivate) { self.active = false } #-------------------------------------------------------------------------- # * New method: center_window #-------------------------------------------------------------------------- unless method_defined?(:center_window) def center_window self.x = Graphics.width/2 - self.width/2 self.y = Graphics.height/2 - self.height/2 end end #-------------------------------------------------------------------------- # * Redefined method: disabled_color #-------------------------------------------------------------------------- unless method_defined?(:disabled_color) def disabled_color color = normal_color color.alpha = 128 return color end end #-------------------------------------------------------------------------- # * Redefined method: draw_text_ex #-------------------------------------------------------------------------- unless method_defined?(:draw_text_ex) def draw_text_ex(x, y, text) reset_font_settings text = convert_escape_characters(text) pos = {:x => x, :y => y, :new_x => x, :height => calc_line_height(text)} process_character(text.slice!(0, 1), text, pos) until text.empty? end end #-------------------------------------------------------------------------- # * Redefined method: reset_font_settings #-------------------------------------------------------------------------- unless method_defined?(:reset_font_settings) def reset_font_settings change_color(normal_color) contents.font.size = Font.default_size contents.font.bold = Font.default_bold contents.font.italic = Font.default_italic end end #-------------------------------------------------------------------------- # * Redefined method: convert_escape_characters #-------------------------------------------------------------------------- unless method_defined?(:convert_escape_characters) def convert_escape_characters(text) result = text.to_s.clone result.gsub!(/\\/) { "\e" } result.gsub!(/\e\e/) { "\\" } result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] } result.gsub!(/\eN\[(\d+)\]/i) { actor_name($1.to_i) } result.gsub!(/\eP\[(\d+)\]/i) { party_member_name($1.to_i) } result.gsub!(/\eG/i) { currency_unit } result end end #-------------------------------------------------------------------------- # * Redefined method: actor_name #-------------------------------------------------------------------------- unless method_defined?(:actor_name) def actor_name(n) actor = n >= 1 ? $game_actors[n] : nil actor ? actor.name : "" end end #-------------------------------------------------------------------------- # * Redefined method: party_member_name #-------------------------------------------------------------------------- unless method_defined?(:party_member_name) def party_member_name(n) actor = n >= 1 ? $game_party.instance_variable_get(:@actors)[n - 1] : nil actor ? actor.name : "" end end #-------------------------------------------------------------------------- # * Redefined method: process_character #-------------------------------------------------------------------------- unless method_defined?(:process_character) def process_character(c, text, pos) case c when "\n" # New line process_new_line(text, pos) when "\f" # New page process_new_page(text, pos) when "\e" # Control character process_escape_character(obtain_escape_code(text), text, pos) else # Normal character process_normal_character(c, pos) end end end #-------------------------------------------------------------------------- # * Redefined method: process_normal_character #-------------------------------------------------------------------------- unless method_defined?(:process_normal_character) def process_normal_character(c, pos) text_width = text_size(c).width draw_text(pos[:x], pos[:y], text_width * 2, pos[:height], c) pos[:x] += text_width end end #-------------------------------------------------------------------------- # * Redefined method: process_new_line #-------------------------------------------------------------------------- unless method_defined?(:process_new_line) def process_new_line(text, pos) pos[:x] = pos[:new_x] pos[:y] += pos[:height] pos[:height] = calc_line_height(text) end end #-------------------------------------------------------------------------- # * Redefined method: process_new_page #-------------------------------------------------------------------------- unless method_defined?(:process_new_page) def process_new_page(text, pos) end end #-------------------------------------------------------------------------- # * Redefined method: obtain_escape_code #-------------------------------------------------------------------------- unless method_defined?(:obtain_escape_code) def obtain_escape_code(text) text.slice!(/^[\$\.\|\^!><\{\}\\]|^[\/\w+\/]+/i) end end #-------------------------------------------------------------------------- # * Redefined method: obtain_escape_param #-------------------------------------------------------------------------- unless method_defined?(:obtain_escape_param) def obtain_escape_param(text) text.slice!(/^\[\d+\]/)[/\d+/].to_i rescue 0 end end #-------------------------------------------------------------------------- # * Redefined method: process_escape_character #-------------------------------------------------------------------------- unless method_defined?(:process_escape_character) def process_escape_character(code, text, pos) case code.upcase when 'C' then change_color(text_color(obtain_escape_param(text))) when 'I' then process_draw_icon(obtain_escape_code(text), pos) when '{' then make_font_bigger when '}' then make_font_smaller end end end #-------------------------------------------------------------------------- # * Redefined method: process_draw_icon #-------------------------------------------------------------------------- unless method_defined?(:process_draw_icon) def process_draw_icon(icon_index, pos) icon_index = icon_index.to_i if icon_index.to_i.to_s == icon_index draw_icon(icon_index, pos[:x], pos[:y]) pos[:x] += 24 end end #-------------------------------------------------------------------------- # * Redefined method: make_font_bigger #-------------------------------------------------------------------------- unless method_defined?(:make_font_bigger) def make_font_bigger contents.font.size += 8 if contents.font.size <= 64 end end #-------------------------------------------------------------------------- # * Redefined method: make_font_smaller #-------------------------------------------------------------------------- unless method_defined?(:make_font_smaller) def make_font_smaller contents.font.size -= 8 if contents.font.size >= 16 end end #-------------------------------------------------------------------------- # * Redefined method: calc_line_height #-------------------------------------------------------------------------- unless method_defined?(:calc_line_height) def calc_line_height(text, restore_font_size = true) result = [line_height, contents.font.size].max last_font_size = contents.font.size text.slice(/^.*$/).scan(/\e[\{\}]/).each do |esc| make_font_bigger if esc == "\e{" make_font_smaller if esc == "\e}" result = [result, contents.font.size].max end contents.font.size = last_font_size if restore_font_size result end end #-------------------------------------------------------------------------- # * New method: currency_unit #-------------------------------------------------------------------------- unless method_defined?(:currency_unit) def currency_unit gold = $data_system.words.gold return gold end end #-------------------------------------------------------------------------- # ● New method: draw_map_name #-------------------------------------------------------------------------- unless method_defined?(:draw_map_name) def draw_map_name(x, y, width, height) map_id = $game_map.map_id mapInfo = $game_map.mapInfo draw_text(x, y, width, height, mapInfo[map_id].name.to_s) end end #-------------------------------------------------------------------------- # ● New method: draw_enter_text #-------------------------------------------------------------------------- unless method_defined?(:draw_enter_text) def draw_enter_text(x, y, width, height, text) info_box = text.split(/\n/) info_box.size.times do |i| draw_text( x, y + i * line_height, width, line_height, info_box[i]) break if (y + i * line_height) > (self.height - line_height) end end end #-------------------------------------------------------------------------- # ● New method: draw_picture_number #-------------------------------------------------------------------------- unless method_defined?(:draw_picture_number) def draw_picture_number(x, y, value, file_name,align = 0, space = 0, frame_max = 1,frame_index = 0) number_image = LiTTleDRAgo.cache.windowskin(file_name) frame_max = [frame_max, 1].max frame_index = frame_max - 1 if frame_index > frame_max - 1 align = [[align,2].min,0].max cw = number_image.width / 10 ch = number_image.height / frame_max h = ch * frame_index number = value.abs.to_s.split(//) case align when 0 then plus_x = (-cw + space) * number.size when 1 then plus_x = ((-cw + space) * number.size) / 2 when 2 then plus_x = 0 end for r in 0..number.size - 1 rect = Rect.new(cw * number[r].to_i, h, cw, ch) contents.blt(plus_x + x + ((cw - space) * r), y , number_image, rect) end number_image.dispose end end end #============================================================================== # ■ Bitmap #------------------------------------------------------------------------------ # #============================================================================== class Bitmap #---------------------------------------------------------------------------- # ● Constant #---------------------------------------------------------------------------- RtlMoveMemory_pi = LiTTleDRAgo.rtlmemory_pi RtlMoveMemory_ip = LiTTleDRAgo.rtlmemory_ip Blur_Setting = "{ 'offset' => 2, 'spacing' => 1, 'opacity' => 255 }" #---------------------------------------------------------------------------- # ● Public Instance Variables #---------------------------------------------------------------------------- attr_sec_accessor :blur_settings, Blur_Setting #---------------------------------------------------------------------------- # ● Redirect Listing #---------------------------------------------------------------------------- redirect_method :change_hue, :hue_change #------------------------------------------------------------------------- # ● Define Secondary Listing #------------------------------------------------------------------------- define_sec_method(:full_fill) { |color| fill_rect(rect, color) } #---------------------------------------------------------------------------- # ● Alias Listing #---------------------------------------------------------------------------- alias_sec_method :invert!, :reversing! alias_sec_method :grayscale!, :gray_scale! alias_sec_method :frost, :diffusion alias_sec_method :frost!, :diffusion! alias_sec_method :drg_ce_stretch_blt, :stretch_blt alias_method :drg_bitmap_load, :initialize #-------------------------------------------------------------------------- # * Object Initialization #---------------------------------------------------------------------------- def initialize(*args) if (a = args.flatten).size == 4 && a.all? {|s| s.is_a?(Table)} bitmap = BitmapDump.read_bitmap_data(*a) drg_bitmap_load(bitmap.width,bitmap.height) return blt(0,0,bitmap,rect) && bitmap.dispose end drg_bitmap_load(*args) end #---------------------------------------------------------------------------- # ● New method: address #---------------------------------------------------------------------------- unless method_defined?(:address) def address @address ||= ( RtlMoveMemory_pi.call(a="\0"*4, __id__*2+16, 4) RtlMoveMemory_pi.call(a, a.unpack('L')[0]+8, 4) RtlMoveMemory_pi.call(a, a.unpack('L')[0]+16, 4) a.unpack('L')[0] ) end end #---------------------------------------------------------------------------- # ● New method: export #---------------------------------------------------------------------------- unless method_defined?(:export) def export(filename) file = File.open(filename, 'wb') size, vxace = width * height * 4, LiTTleDRAgo::RGSS3 case format = File.extname(filename) when '.bmp' data = String.new RtlMoveMemory_pi.call(empty_rString_struct="\0"*16,data.__id__*2,16) flags = vxace ? 5267461 : 8199 klass = empty_rString_struct.unpack('@4L')[0] pack = [flags,klass,size,address].pack('L4') weiss = [size+54,0,54,40,width,height,1,32,0,size,0,0,0,0] RtlMoveMemory_ip.call(data.__id__*2, pack, 16) file.write("BM#{weiss.pack('L6S2L6')}") file.write(data) RtlMoveMemory_ip.call(data.__id__*2, empty_rString_struct, 16) when '.png' write_chunk = Proc.new do |chunk| file.write([(vxace ? chunk.bytesize : chunk.size)-4].pack('N')) file.write(chunk) file.write([Zlib.crc32(chunk)].pack('N')) end null_char, w4, i, byte = "\0", width*4, 0, (t_Fx = 0) RtlMoveMemory_pi.call(data=null_char*size, address, size) if vxace data.force_encoding('ASCII-8BIT') (0).step(size-4, 4) do |i| Graphics.update if (t_Fx += 1) % 10000 == 0 byte = data.getbyte(i) data.setbyte(i, data.getbyte(i+=2)) data.setbyte(i, byte) end else (0).step(size-4, 4) do |i| Graphics.update if (t_Fx += 1) % 10000 == 0 data[i,3] = data[i,3].reverse! end end deflate = Zlib::Deflate.new(9) (size-w4).step(0, -w4) {|i| deflate << null_char << data[i,w4]} file.write("\211PNG\r\n\32\n") write_chunk.call("IHDR#{[width,height,8,6,0,0,0].pack('N2C5')}") write_chunk.call("IDAT#{deflate.finish}") write_chunk.call('IEND') deflate.close when '' script_report("Error: Export Bitmap Failed\n"+ "Extension '#{filename}' is missing.") else script_report("Error: Export Bitmap Failed\n"+ "Extension '#{format}' is not supported.") end file.close end end #---------------------------------------------------------------------------- # ● New method: blt_cache #---------------------------------------------------------------------------- unless method_defined?(:blt_cache) def blt_cache(x, y, width, height, text, align, edging) cache_bitmap = LiTTleDRAgo.cache.draw_text( width, height, text, self.font.name, self.font.size, self.font.bold, self.font.italic, self.font.color, edging ) x_plus = uncache_align_exe(width, text, align) blt(x + x_plus , y , cache_bitmap, Rect.new(0, 0, width, height)) end end #---------------------------------------------------------------------------- # ● New method: uncache_align_exe #---------------------------------------------------------------------------- unless method_defined?(:uncache_align_exe) def uncache_align_exe(width, text, align) recter = self.text_size(text) case align when 0 then x_index = 0 when 1 then x_index = (width / 2) - recter.width / 2 when 2 then x_index = width - recter.width else raise "Text Cache : align is wrong" end return x_index end end #---------------------------------------------------------------------------- # ● New method: draw_cache_text #---------------------------------------------------------------------------- unless method_defined?(:draw_cache_text) def draw_cache_text(x, y, width, height, text, align = 0) blt_cache(x, y, width, height, text, align, false) end end #---------------------------------------------------------------------------- # ● New method: draw_edging_cache_text #---------------------------------------------------------------------------- unless method_defined?(:draw_edging_cache_text) def draw_edging_cache_text(x, y, width, height, text, align = 0) blt_cache(x, y, width, height, text, align, true) end end #---------------------------------------------------------------------------- # ● New method: draw_easy_cache_text #---------------------------------------------------------------------------- unless method_defined?(:draw_easy_cache_text) def draw_easy_cache_text(x, y, text) t_rect = text_size(text) blt_cache(x, y, t_rect.width, t_rect.height, text, 0, false) end end #---------------------------------------------------------------------------- # ● New method: draw_easy_edging_cache_text #---------------------------------------------------------------------------- unless method_defined?(:draw_easy_edging_cache_text) def draw_easy_edging_cache_text(x, y, text) t_rect = text_size(text) blt_cache(x, y, t_rect.width, t_rect.height, text, 0, true) end end #-------------------------------------------------------------------------- # * New method: change_color #-------------------------------------------------------------------------- unless method_defined?(:change_color) def change_color(color, enabled = true) font.color = color font.color.alpha = translucent_alpha unless enabled end end #-------------------------------------------------------------------------- # ● New method: draw_picture #-------------------------------------------------------------------------- unless method_defined?(:draw_picture) def draw_picture(file_name, x, y, opacity = 255) bitmap = LiTTleDRAgo.cache.picture(file_name) cw = bitmap.width ch = bitmap.height src_rect = Rect.new(0, 0, cw, ch) blt(x, y, bitmap, src_rect, opacity) end end #-------------------------------------------------------------------------- # ● New method: draw_icon #-------------------------------------------------------------------------- unless method_defined?(:draw_icon) def draw_icon(file_name, x, y, enabled = true) if file_name.is_a?(Numeric) bitmap = LiTTleDRAgo.cache.system("Iconset") src_rect = Rect.new(file_name % 16 * 24, file_name / 16 * 24, 24, 24) blt(x, y, bitmap, src_rect, enabled ? 255 : 160) elsif file_name.is_a?(String) bitmap = LiTTleDRAgo.cache.icon(file_name) src_rect = Rect.new(0, 0, 24, 24) blt(x, y, bitmap, bitmap.rect, enabled ? 255 : 160) end end end #-------------------------------------------------------------------------- # ● New method: draw_battler #-------------------------------------------------------------------------- unless method_defined?(:draw_battler) def draw_battler(file_name, x, y, hue = 0, enabled = true) bitmap = LiTTleDRAgo.cache.battler(file_name, hue) cw = bitmap.width ch = bitmap.height src_rect = Rect.new(0, 0, cw, ch) blt(x, y, bitmap, src_rect, enabled ? 255 : 160) end end #-------------------------------------------------------------------------- # ● New method: draw_bar #-------------------------------------------------------------------------- unless method_defined?(:draw_bar) def draw_bar(x, y, current, file) bitmap = LiTTleDRAgo.cache.picture(file) cw = bitmap.width * current / 100 ch = bitmap.height src_rect = Rect.new(0, 0, cw, ch) blt(x, y, bitmap, src_rect) end end #-------------------------------------------------------------------------- # ● New method: draw_edging_text #-------------------------------------------------------------------------- unless method_defined?(:draw_edging_text) def draw_edging_text(x, y, width, height, text, align=0) old_color = font.color.dup font.color = Color.new(0, 0, 0) draw_text(x-1, y-1, width, height, text, align) draw_text(x-1, y+1, width, height, text, align) draw_text(x+1, y-1, width, height, text, align) draw_text(x+1, y+1, width, height, text, align) font.color = old_color draw_text(x, y, width, height, text, align) end end #-------------------------------------------------------------------------- # ● New method: draw_enter_text #-------------------------------------------------------------------------- unless method_defined?(:draw_enter_text) def draw_enter_text(x, y, width, height, text, align=0) rect = text_size(text) info_box = text.split(/\n/) info_box.size.times do |i| draw_text( x, y+i*rect.height, width, height, info_box[i], align) break if (y+i*rect.height) > self.height end end end #-------------------------------------------------------------------------- # ● New method: draw_enter_edging_text #-------------------------------------------------------------------------- unless method_defined?(:draw_enter_edging_text) def draw_enter_edging_text(x, y, width, height, text, align=0) rect = text_size(text) info_box = text.split(/\n/) info_box.size.times do |i| draw_edging_text( x, y+i*rect.height,width,height,info_box[i],align) break if (y+i*rect.height) > self.height end end end #-------------------------------------------------------------------------- # ● New method: draw_easy_text #-------------------------------------------------------------------------- unless method_defined?(:draw_easy_text) def draw_easy_text(x, y, text) rect = text_size(text) draw_text(x, y, rect.width + rect.height/2, rect.height, text) end end #-------------------------------------------------------------------------- # ● New method: draw_auto_text #-------------------------------------------------------------------------- unless method_defined?(:draw_auto_text) def draw_auto_text(x, y, width, height, text) ini_x = 0 law = 0 text_box = [] text_box[law] = [] otxto = text.split(//) otxto.size.times do |i| text_rect = text_size(otxto[i]) if (x + ini_x + text_rect.width) < width ini_x += text_rect.width else law += 1 ini_x = text_rect.width text_box[law] = [] end text_box[law].push(otxto[i]) end for l in 0..law ini_x = 0 text_box[l].size.times do |i| rect = text_size(text_box[l][i]) draw_text(x + ini_x, y+l*height, rect.width, height, text_box[l][i]) ini_x += rect.width end end end end #------------------------------------------------------------------------- # ● New method: erase #------------------------------------------------------------------------- unless method_defined?(:erase) def erase(*a) rect = nil if a.at(0).is_a?(Rect) then rect = a.at(0) elsif a.size == 4 then rect = Rect.new(*a) elsif a.size == 0 then rect = Rect.new(0,0,width,height) end fill_rect(rect.x, rect.y, rect.width, rect.height, Color.erase) if rect end end #------------------------------------------------------------------------- # ● New method: stretch #------------------------------------------------------------------------- unless method_defined?(:stretch) def stretch(width, height) dummy = Bitmap.new(width, height) dummy.stretch_blt(*[dummy.rect, self, self.rect]) dummy end end #------------------------------------------------------------------------- # ● New method: crop #------------------------------------------------------------------------- unless method_defined?(:crop) def crop(*a) return unless a.size == 1 or a.size == 4 rect = rect.at(0) if a.size == 1 && a.at(0).is_a?(Rect) rect = Rect.new(*a) if a.size == 4 cropped = Bitmap.new([rect.width,width-rect.x].min, [rect.height,height-rect.y].min) cropped.blt(0,0,self,rect) cropped end end #------------------------------------------------------------------------- # ● Aliased method: stretch_blt #------------------------------------------------------------------------- def stretch_blt(*a) if respond_to?(:stretch_blend_blt) a = [a[0..2],0,1,a.at(3)||255].flatten stretch_blend_blt(*a) else drg_ce_stretch_blt(*a) end end #------------------------------------------------------------------------- # ● Aliased method: hue_change #------------------------------------------------------------------------- define_post_alias(:hue_change) { self } #-------------------------------------------------------------------------- # ● New method: invert, etc #-------------------------------------------------------------------------- [:invert, :brighten, :darken, :grayscale, :pixelate, :frost, :flip_horizontal, :flip_vertical, :rotate90, :rotate180, :rotate270].each do |meth| define_sec_method(meth) do |*args| bitmap = self.clone bitmap.send(:"#{meth}!",*args) return bitmap end end #------------------------------------------------------------------------- # ● New method: flip_horizontal! #------------------------------------------------------------------------- define_sec_method(:flip_horizontal!) do flipped = Bitmap.new(width, height) fliprect = Rect.new(width,0,-width,height) flipped.blt(0,0, self,fliprect) (clear || 0) && blt(0,0,flipped,rect) flipped.dispose end #------------------------------------------------------------------------- # ● New method: flip_vertical! #------------------------------------------------------------------------- define_sec_method(:flip_vertical!) do flipped = Bitmap.new(width, height) fliprect = Rect.new(0,height,width,-height) flipped.blt(0,0, self,fliprect) (clear || 0) && blt(0,0,flipped,rect) flipped.dispose end #------------------------------------------------------------------------- # ● New method: rotate90! (clockwise) #------------------------------------------------------------------------- define_sec_method(:rotate90!) do copy = self.clone (t_Fx = width).times do |i| height.times do |j| Graphics.update if (t_Fx += 1) % 10000 == 0 a = (clockwise = true) ? [width - i - 1, j] : [i, height - j - 1] self.set_pixel(a[0],a[1], copy.get_pixel(j, i)) end end copy.dispose end #------------------------------------------------------------------------- # ● New method: rotate180! #------------------------------------------------------------------------- define_sec_method(:rotate180!) do flip_vertical! flip_horizontal! end #------------------------------------------------------------------------- # ● New method: rotate270! #------------------------------------------------------------------------- define_sec_method(:rotate270!) do rotate90! rotate180! end #---------------------------------------------------------------------------- # ● New method: invert! #---------------------------------------------------------------------------- unless method_defined?(:invert!) def invert! (t_Fx = width).times do |i| height.times do |j| color = get_pixel(i, j) Graphics.update if (t_Fx += 1) % 10000 == 0 set_pixel(i, j, color.invert) if color.alpha > 0 end end end end #-------------------------------------------------------------------------- # * New method: brighten! #-------------------------------------------------------------------------- unless method_defined?(:brighten!) def brighten!(amount = 10) (t_Fx = width).times do |w| height.times do |h| color = get_pixel(w, h) Graphics.update if (t_Fx += 1) % 10000 == 0 set_pixel(w, h, Color.new([color.red + amount, 255].min, [color.green + amount, 255].min, [color.blue + amount, 255].min, color.alpha)) if color.alpha > 0 end end end end #-------------------------------------------------------------------------- # * New method: darken! #-------------------------------------------------------------------------- unless method_defined?(:darken!) def darken!(amount = 10) (t_Fx = width).times do |w| height.times do |h| color = get_pixel(w, h) Graphics.update if (t_Fx += 1) % 10000 == 0 set_pixel(w, h, Color.new([color.red - amount, 0].max, [color.green - amount, 0].max, [color.blue - amount, 0].max, color.alpha)) if color.alpha > 0 end end end end #-------------------------------------------------------------------------- # * New method: grayscale! # NOTE: calling this method repeatedly has no effect on the bitmap, but will # still waste processing power. Do not call it repeatedly. #-------------------------------------------------------------------------- unless method_defined?(:grayscale!) def grayscale! (t_Fx = width).times do |w| height.times do |h| color = get_pixel(w, h) if (a = color.alpha) > 0 Graphics.update if (t_Fx += 1) % 10000 == 0 num = (color.red + color.green + color.blue) / 3 set_pixel(w, h, Color.new(num, num, num, a)) end end end end end #-------------------------------------------------------------------------- # * New method: drg_pixelate! (0.2 second) # NOTE: Pixelateing bitmaps to a larger pixel size is less process consuming. # for best results, don't pixelate to numbers below four. # This works much better for solid images, due to bugs. #-------------------------------------------------------------------------- unless method_defined?(:drg_pixelate!) def drg_pixelate!(size = 10) return self if size <= (t_Fx = 1) c = lambda {|a,b| (a / b**2) * Math.sqrt(b) } for w in 0..((width - 1) / size) w *= size for h in 0..((height - 1) / size) h *= size r, g, b, a = 0, 0, 0, 0 size.times do |i| color = get_pixel(w, h) r += color.red g += color.green b += color.blue a += color.alpha color = get_pixel(w + i, h) r += color.red g += color.green b += color.blue a += color.alpha color = get_pixel(w, h + i) r += color.red g += color.green b += color.blue a += color.alpha end Graphics.update if (t_Fx += 1) % 10000 == 0 fill_rect(w, h, size, size, Color.new(c.call(r,size),c.call(g,size), c.call(b,size),c.call(a,size))) end end end end #-------------------------------------------------------------------------- # * New method: pixelate! #-------------------------------------------------------------------------- unless method_defined?(:pixelate!) def pixelate!(size = 10) return mosaic!(size,size) if respond_to?(:mosaic!) return drg_pixelate!(size) end end #-------------------------------------------------------------------------- # * New method: drg_frost! (5 second) # NOTE: Frosting a bitmap randomly scatters its pixels. As such, Consistant # results are impossible to get. # Frosting a bitmap beyond eight won't result in a more scattered image #-------------------------------------------------------------------------- unless method_defined?(:drg_frost!) def drg_frost!(noise = 10) for pass in 1..noise (t_Fx = width).times do |w| height.times do |h| Graphics.update if (t_Fx += 1) % 10000 == 0 set_pixel(w, h, get_pixel(w + rand(3) - 1, h + rand(3) - 1)) end end end end end #------------------------------------------------------------------------- # ● New method: bltapiinit #------------------------------------------------------------------------- unless method_defined?(:bltapiinit) def bltapiinit info = [40,width,height,1,32,0,0,0,0,0,0].pack('LllSSLLllLL') hWndDC = LiTTleDRAgo.getdc.call(LiTTleDRAgo.hwnd) hMemDC = LiTTleDRAgo.ccdc.call(hWndDC) hMemBM = LiTTleDRAgo.ccbitmap.call(hWndDC, width, height) LiTTleDRAgo.releasedc.call(LiTTleDRAgo.hwnd, hWndDC) LiTTleDRAgo.selectobject.call(hMemDC, hMemBM) LiTTleDRAgo.setdibits.call(hMemDC, hMemBM, 0, height, address, info, 0) return hMemDC, hMemBM, info end end #------------------------------------------------------------------------- # ● New method: bit_blt #------------------------------------------------------------------------- unless method_defined?(:bit_blt) def bit_blt(x, y, src_bmp, src_rect, rastor_operation = 0xCC0020) hDC1, hBM1, info = *self.bltapiinit hDC2, hBM2 = *src_bmp.bltapiinit LiTTleDRAgo.bitblt.call(hDC1, x, y, src_rect.width, src_rect.height, hDC2, src_rect.x, src_rect.y, rastor_operation) LiTTleDRAgo.getdibits.call(hDC1, hBM1, 0, height, address, info, 0) LiTTleDRAgo.deleteobject.call(hBM1) LiTTleDRAgo.deleteobject.call(hDC1) LiTTleDRAgo.deleteobject.call(hBM2) LiTTleDRAgo.deleteobject.call(hDC2) end end #------------------------------------------------------------------------- # ● New method: crop_blt #------------------------------------------------------------------------- unless method_defined?(:crop_blt) def crop_blt(x, y, width, height, bitmap, dir = 1, align = 1, opacity = 255) w, h = bitmap.width, bitmap.height if w < width and h < height x += (width - w) / 2 if align == 1 x += width - w if align == 2 return full_blt(x, y, bitmap, opacity) end i, j = dir % 3, dir / 3 crop_x, crop_y = 0, 0 crop_x = (w - width) / 2 if i == 1 crop_x = w - width if i == 2 crop_y = (h - height) / 2 if j == 1 crop_y = h - height if j == 2 blt(x, y, bitmap, Rect.new(crop_x, crop_y, width, height), opacity) end end #------------------------------------------------------------------------- # ● New method: fit_blt #------------------------------------------------------------------------- unless method_defined?(:fit_blt) def fit_blt(x, y, width, height, bitmap, opacity = 255, align = 1) w, h = bitmap.width, bitmap.height if w > width or h > height conversion = w / h.to_f zoom_x, zoom_y = width * conversion, height if conversion <= 1 zoom_x, zoom_y = width, height / conversion unless conversion <= 1 x += (width - zoom_x) / 2 if align == 1 x += width - zoom_x if align == 2 dest_rect = Rect.new(x, y, zoom_x, zoom_y) stretch_blt(dest_rect, bitmap, bitmap.rect, opacity) else x += (width - w) / 2 if align == 1 x += width - w if align == 2 full_blt(x, y, bitmap, opacity) end end end #------------------------------------------------------------------------- # ● New method: full_blt #------------------------------------------------------------------------- unless method_defined?(:full_blt) def full_blt(x, y, bitmap, opacity = 255) blt(x, y, bitmap, bitmap.rect, opacity) end end #------------------------------------------------------------------------- # ● New method: scale_blt #------------------------------------------------------------------------- unless method_defined?(:scale_blt) def scale_blt(dest_rect, src_bitmap, src_rect = src_bitmap.rect, o = 255) w, h = src_rect.width, src_rect.height scale = [w / dest_rect.width.to_f, h / dest_rect.height.to_f].max ow, oh = (w / scale).to_i, (h / scale).to_i ox, oy = (dest_rect.width - ow) / 2, (dest_rect.height - oh) / 2 stretch_blt(Rect.new(ox + dest_rect.x, oy + dest_rect.y, ow, oh), src_bitmap, src_rect, o) end end #------------------------------------------------------------------------- # ● New method: frames_flip_horizontal #------------------------------------------------------------------------- unless method_defined?(:frames_flip_horizontal) def frames_flip_horizontal(frames) frame_width = width / frames frame_bitmap = Bitmap.new(frame_width, height) rect = Rect.new(0, 0, frame_width, height) frames.times do |i| frame_bitmap.clear rect.x = (x = i * frame_width) frame_bitmap.blt(0, 0, self, rect) frame_bitmap.flip_horizontal! blt(x, 0, frame_bitmap, frame_bitmap.rect) end frame_bitmap.dispose end end #------------------------------------------------------------------------- # ● New method: frames_flip_vertical #------------------------------------------------------------------------- unless method_defined?(:frames_flip_vertical) def frames_flip_vertical(frames) frame_height = height / frames frame_bitmap = Bitmap.new(width, frame_height) rect = Rect.new(0, 0, width, frame_height) frames.times do |i| frame_bitmap.clear rect.y = (y = i * frame_height) frame_bitmap.blt(0, 0, self, rect) frame_bitmap.flip_vertical! blt(0, y, frame_bitmap, frame_bitmap.rect) end frame_bitmap.dispose end end #------------------------------------------------------------------------- # ● New method: blur_area #------------------------------------------------------------------------- unless method_defined?(:blur_area) def blur_area(settings = {}) blur_settings.each do |default, setting| settings[default] = setting unless settings.has_key?(default) end keys = settings.keys rect_defined = keys.include?('rect') rect_p_defined = keys.include?('x') && keys.include?('y') && keys.include?('w') && keys.include?('h') if rect_defined rect = settings['rect'] x, y, w, h = rect.x, rect.y, rect.width, rect.height elsif rect_p_defined x, y, w, h = settings['x'], settings['y'], settings['w'], settings['h'] else x, y, w, h = 0, 0, self.width, self.height end dummy = self.dup spacing = settings['spacing'] opacity = settings['opacity'] settings['offset'].times do |i| src_rects = [] src_rects << Rect.new(x + i * spacing, y + i * spacing, w, h) src_rects << Rect.new(x - i * spacing, y + i * spacing, w, h) src_rects << Rect.new(x + i * spacing, y - i * spacing, w, h) src_rects << Rect.new(x - i * spacing, y - i * spacing, w, h) o = Integer(opacity * (settings['offset'] - i) / (settings['offset'])) src_rects.each { |src_rect| blt(x, y, dummy, src_rect, o)} end dummy.dispose self end end #------------------------------------------------------------------------- # ● New method: sub_bitmap_blend #------------------------------------------------------------------------- unless method_defined?(:sub_bitmap_blend) def sub_bitmap_blend(x = 0, y = 0, bitmap = self, src_rect = bitmap.rect) src_rect.width.times do |i| src_rect.height.times do |j| c1 = get_pixel(x + i, y + j) c2 = bitmap.get_pixel(src_rect.x + i, src_rect.y + j) nc = Color.new(c1.red-c2.red, c1.green-c2.green, c1.blue-c2.blue) set_pixel(x + i, y + j, nc) if c2.alpha > 0 end end end end #------------------------------------------------------------------------- # ● New method: add_bitmap_blend #------------------------------------------------------------------------- unless method_defined?(:add_bitmap_blend) def add_bitmap_blend(x = 0, y = 0, bitmap = self, src_rect = bitmap.rect) src_rect.width.times do |i| src_rect.height.times do |j| c1 = get_pixel(x + i, y + j) c2 = bitmap.get_pixel(src_rect.x + i, src_rect.y + j) nc = Color.new(c1.red+c2.red, c1.green+c2.green, c1.blue+c2.blue) set_pixel(x + i, y + j, nc) if c2.alpha > 0 end end end end #-------------------------------------------------------------------------- # * Alias Listing #-------------------------------------------------------------------------- alias_sec_method :frost!, :drg_frost! alias_sec_method :blur, :blur_area alias_sec_method :entire_fill, :full_fill #-------------------------------------------------------------------------- # * Replicated method: gradient_fill_rect #-------------------------------------------------------------------------- unless method_defined?(:gradient_fill_rect) def gradient_fill_rect(*a) if a.first.is_a?(Rect) x, y, width, height = a[0].x, a[0].y, a[0].width, a[0].height color1 = a.at(1).dup color2 = a.at(2) vertical = a.at(3) else x, y, width, height = a[0..3] color1 = a.at(4).dup color2 = a.at(5) vertical = a.at(6) end dr = color2.red - color1.red dg = color2.green - color1.green db = color2.blue - color1.blue da = color2.alpha - color1.alpha start_rgba = [color1.red, color1.green, color1.blue, color1.alpha] if vertical dr, dg, db, da = dr / height, dg / height, db / height, da / height for i in (y.round...(y + height).round) fill_rect(x, i, width, 1, color1) start_rgba[0] = [start_rgba.at(0) + dr, 0].max.round start_rgba[1] = [start_rgba.at(1) + dg, 0].max.round start_rgba[2] = [start_rgba.at(2) + db, 0].max.round start_rgba[3] = [start_rgba.at(3) + da, 0].max.round color1.set(*start_rgba) end else dr, dg, db, da = dr / width, dg / width, db / width, da / width for i in (x.round...(x + width).round) fill_rect(i, y, 1, height, color1) start_rgba[0] = [start_rgba.at(0) + dr, 0].max.round start_rgba[1] = [start_rgba.at(1) + dg, 0].max.round start_rgba[2] = [start_rgba.at(2) + db, 0].max.round start_rgba[3] = [start_rgba.at(3) + da, 0].max.round color1.set(*start_rgba) end end end end end #============================================================================== # ** String #------------------------------------------------------------------------------ # #============================================================================== class String #------------------------------------------------------------------------- # ● New method: get_int #------------------------------------------------------------------------- unless method_defined?(:get_int) def get_int m = self.scan(/([-]?\d+)/i).flatten return m.join.to_i end end #------------------------------------------------------------------------- # ● New method: get_ints #------------------------------------------------------------------------- unless method_defined?(:get_ints) def get_ints array = self.scan(/([-]?\d+)/i).flatten.relay(:i) return array end end #------------------------------------------------------------------------- # ● New method: encrypt #------------------------------------------------------------------------- unless method_defined?(:encrypt) def encrypt(encryption_string = 'encrypt') encryption_bytes = [] encryption_string.each_byte {|c| encryption_bytes << c} string = '' self.size.times do |i| byte = self[i] * encryption_bytes[i % encryption_bytes.size] base, mod = byte / 255, byte % 255 string += base.chr + mod.chr end return string end end #------------------------------------------------------------------------- # ● New method: encrypt! #------------------------------------------------------------------------- unless method_defined?(:encrypt!) def encrypt!(encryption_string = 'encrypt') replace(encrypt(encryption_string)) end end #------------------------------------------------------------------------- # ● New method: decrypt #------------------------------------------------------------------------- unless method_defined?(:decrypt) def decrypt(encryption_string = 'encrypt') encryption_bytes = [] encryption_string.each_byte {|c| encryption_bytes << c} string = '' (self.size / 2).times do |i| b, m = self[i * 2] * 255, self[i * 2 + 1] string += ((b + m) / encryption_bytes[i % encryption_bytes.size]).chr end return string end end #------------------------------------------------------------------------- # ● New method: decrypt! #------------------------------------------------------------------------- unless method_defined?(:decrypt!) def decrypt!(encryption_string = 'encrypt') replace(decrypt(encryption_string)) end end #------------------------------------------------------------------------- # ● New method: clear, words, characters #------------------------------------------------------------------------- define_sec_method(:clear) { replace('') } define_sec_method(:words) { split(' ') } define_sec_method(:characters) { split('') } define_sec_method(:last) { characters.last } define_sec_method(:first) { characters.first } end #============================================================================== # ** Game_Interpreter #------------------------------------------------------------------------------ # An interpreter for executing event commands. This class is used within the # Game_Map, Game_Troop, and Game_Event classes. #============================================================================== Klass = LiTTleDRAgo::VX ? Game_Interpreter : Interpreter class Klass #-------------------------------------------------------------------------- # * Constant #-------------------------------------------------------------------------- SCRIPT_WAIT_RESULTS = [:wait, FalseClass] #-------------------------------------------------------------------------- # ● Redirect Listing #-------------------------------------------------------------------------- redirect_method :picture_sprite, '$game_map.picture_sprite' #-------------------------------------------------------------------------- # ● New method: random_teleport #-------------------------------------------------------------------------- unless method_defined?(:random_teleport) def random_teleport(id = 0) character = id.is_a?(Game_Character) ? id : get_character(id) character.random_teleport if character.is_a?(Game_Character) end end #-------------------------------------------------------------------------- # ● Redefined method: same_map?, next_event_code #-------------------------------------------------------------------------- define_sec_method(:same_map?) { @map_id == $game_map.map_id } define_sec_method(:next_event_code) { @list[@index + 1].code } #-------------------------------------------------------------------------- # * Overwriten method: command_355 #-------------------------------------------------------------------------- def command_355 script = @list[index = @index].parameters[0] + "\n" while [655, 355].include?(next_event_code) do script += @list[@index+=1].parameters[0] + "\n" end wait = SCRIPT_WAIT_RESULTS.include?(eval(script)) && LiTTleDRAgo::XP return wait ? !(@index = index) : true end end #============================================================================== # ** Sprite #------------------------------------------------------------------------------ # A sprite class for bitmap processing. #============================================================================== class Sprite #--------------------------------------------------------------------------- # * Alias Listing #--------------------------------------------------------------------------- alias_sec_method(:angle_fix_alias, :"angle=") alias_sec_method(:drg_core_dispose,:"dispose") alias_sec_method(:set_x_alias, :"x=") alias_sec_method(:set_y_alias, :"y=") alias_sec_method(:get_x_alias, :"x") alias_sec_method(:get_y_alias, :"y") #--------------------------------------------------------------------------- # * New method: method_missing #--------------------------------------------------------------------------- def method_missing(val,*a,&b) return bitmap.send(val.to_s,*a,&b) if bitmap.respond_to?(val.to_sym) text = "Undefined method #{val} for #{self.inspect}" raise(NoMethodError, text, caller(1)) end #--------------------------------------------------------------------------- # * Aliased method: x=, y= #--------------------------------------------------------------------------- define_method(:x=) {|amt| set_x_alias((@intfloat_x = amt).to_i) } define_method(:y=) {|amt| set_y_alias((@intfloat_y = amt).to_i) } define_method(:x) { @intfloat_x ||= get_x_alias } define_method(:y) { @intfloat_y ||= get_y_alias } define_method(:dispose) { disposed? || drg_core_dispose } define_method(:rotate_correction) { self.ox,self.oy = width/2, height/2 } #--------------------------------------------------------------------------- # * Aliased method: angle= #--------------------------------------------------------------------------- def angle=(v) return if @angle == v sign = (v % 360 == 180 || v % 180 == 90) ? 1.00001 : 1 angle_fix_alias((@angle = v) * sign) end #-------------------------------------------------------------------------- # ● Redefined method: width, height #-------------------------------------------------------------------------- define_sec_method(:width) { src_rect.width } define_sec_method(:height) { src_rect.height } #-------------------------------------------------------------------------- # ● Overwriten method: dup #-------------------------------------------------------------------------- def dup sprite = self.class.new(self.viewport) sprite.bitmap = self.bitmap.clone sprite.zoom_x, sprite.zoom_y = self.zoom_x, self.zoom_y sprite.x, sprite.y = self.x, self.y sprite.ox, sprite.oy = self.ox, self.oy sprite.color, sprite.tone = self.color.dup, self.tone.dup sprite.src_rect,sprite.angle = self.src_rect, self.angle return sprite end #-------------------------------------------------------------------------- # ● Overwriten method: clone #-------------------------------------------------------------------------- def clone (sprite = self.dup) && instance_variables.each do |var| temp = instance_variable_get("#{var}") sprite.instance_variable_set("#{var}",temp) rescue nil end (frozen? && sprite.freeze) return sprite end #-------------------------------------------------------------------------- # ● New method: scale #-------------------------------------------------------------------------- unless method_defined?(:scale) def scale(w, h) tmp = self.bitmap.clone self.bitmap = Bitmap.new(w, h) self.bitmap.stretch_blt(Rect.new(0, 0, w, h), tmp, tmp.rect) tmp.dispose end end #-------------------------------------------------------------------------- # ● New method: in_rect? #-------------------------------------------------------------------------- unless method_defined?(:in_rect?) def in_rect?(*rect) if rect.size == 1 x, y, w, h = rect[0].x, rect[0].y, rect[0].width, rect[0].height return self.x.between?(x, x + w) && self.y.between?(y, y + h) elsif rect.size == 4 x, y, w, h = rect return self.x.between?(x, x + w) && self.y.between?(y, y + h) end return false end end end #============================================================================== # ** Scheduler #------------------------------------------------------------------------------ # This class allows to schedule a proc or method call a given amount of frames # into the future with any amount of arguments #============================================================================== unless defined?(Scheduler) class Scheduler #========================================================================== # ** Order #-------------------------------------------------------------------------- # An order is a proc, method or something else which has 'call' as a # method, and the arguments to pass along. #========================================================================== unless method_defined?(:update) Order = Struct.new(:callable, :arguments) class Order #---------------------------------------------------------------------- # * New Methods: call #---------------------------------------------------------------------- define_method(:call) { callable.call(*arguments) } end #======================================================================== # ** RecurringOrder #------------------------------------------------------------------------ # An order which is recurring every specified amount of time until # FalseClass is returned from the call. # Note that arguments remain the same for each call #======================================================================== RecurringOrder = Struct.new(:callable, :arguments, :frames) class RecurringOrder #---------------------------------------------------------------------- # * New Methods: call #---------------------------------------------------------------------- def call result = callable.call(*arguments) unless result == FalseClass Scheduler.schedule_recurring(frames, frames, callable, *arguments) end end end #======================================================================== # ** Mapping #------------------------------------------------------------------------ # Maps an index to an array. Values can be added to these value. # Each array starts empty. #======================================================================== class Mapping #---------------------------------------------------------------------- # * New method: add, get, empty #---------------------------------------------------------------------- define_method(:add) { |i, v| ((@mapping ||= {})[i] ||=[]) << v } define_method(:get) { |i| ((@mapping ||= {})[i] || []) } define_method(:empty) { |i| (@mapping ||= {}).delete(i) } end #------------------------------------------------------------------------ # * New method: schedule #------------------------------------------------------------------------ def schedule(frames, callable, *arguments) order = Order.new(callable, arguments) (@mapping ||= Mapping.new).add(frames + (@tick||=0), order) end #------------------------------------------------------------------------ # * New method: schedule_recurring #------------------------------------------------------------------------ def schedule_recurring(frames, frames_to_wait, callable, *arguments) order = RecurringOrder.new(callable, arguments, frames_to_wait) (@mapping ||= Mapping.new).add(frames + (@tick||=0), order) end #------------------------------------------------------------------------ # * New method: update #------------------------------------------------------------------------ def update orders = (@mapping ||= Mapping.new).get((@tick||=0)) @mapping.empty(@tick) orders.each {|s| s.call } @tick += 1 end #------------------------------------------------------------------------ # * Self #------------------------------------------------------------------------ @@instance = self.new class << self define_method(:instance) { @@instance } redirect_method :schedule_recurring, 'instance.schedule_recurring' redirect_method :schedule, 'instance.schedule' redirect_method :update, 'instance.update' end end end Graphics.auto_update.push([Scheduler,:update]) end #============================================================================== # ** Dir #------------------------------------------------------------------------------ # #============================================================================== class << Dir #-------------------------------------------------------------------------- # ● New method: make_dir #-------------------------------------------------------------------------- def make_dir(path) (dir = path.split("/")).size.times do |i| next if dir == "." Dir.mkdir(dir[0..i].join("/")) rescue nil end end #-------------------------------------------------------------------------- # ● New method: files_with_extension #-------------------------------------------------------------------------- def files_with_extension(directory, extension) entries(directory).select{|file| File.extname(file) == extension} end end #============================================================================== # ** BitmapDump #------------------------------------------------------------------------------ # #============================================================================== module BitmapDump; end class << BitmapDump #-------------------------------------------------------------------------- # ● New method: self.bitmap_data #-------------------------------------------------------------------------- unless method_defined?(:bitmap_data) def bitmap_data(bitmap) red = Table.new(bitmap.width, bitmap.height) green, blue, alpha = red.clone, red.clone, red.clone bitmap.width.times do |i| bitmap.height.times do |j| color = bitmap.get_pixel(i, j) red[i, j], green[i, j] = color.red, color.green blue[i, j], alpha[i, j] = color.blue, color.alpha end end return [red, green, blue, alpha] end end #-------------------------------------------------------------------------- # ● New method: self.read_bitmap_data #-------------------------------------------------------------------------- unless method_defined?(:read_bitmap_data) def read_bitmap_data(red, green, blue, alpha) bitmap = Bitmap.new(red.xsize, red.ysize) bitmap.width.times do |i| bitmap.height.times do |j| color_table = [red[i, j], green[i, j], blue[i, j], alpha[i, j]] bitmap.set_pixel(i, j, Color.new(*color_table)) end end return bitmap end end #-------------------------------------------------------------------------- # ● New method: self.save_bitmap #-------------------------------------------------------------------------- unless method_defined?(:save_bitmap) def save_bitmap(bitmap, filename, folder = '') bitmap_data = bitmap_data(bitmap) if folder && folder != '' Dir.make_dir(folder) unless FileTest.directory?(folder) filename = "#{folder}/#{filename}" end filename = filename.gsub("\\","/").gsub("//","/") file = File.open(filename,'wb') Marshal.dump(bitmap_data, file) file.close end end #-------------------------------------------------------------------------- # ● New method: self.load_bitmap #-------------------------------------------------------------------------- unless method_defined?(:load_bitmap) def load_bitmap(filename, folder = '') if folder && folder != '' Dir.make_dir(folder) unless FileTest.directory?(folder) filename = "#{folder}/#{filename}" end filename = filename.gsub("\\","/").gsub("//","/") file = File.open(filename,"rb") colors = Marshal.load(file) file.close bitmap = read_bitmap_data(colors) return bitmap end end end
#==============================================================================
# ** Drago - Core Engine
# Version : 1.59
# Contact : littledrago.blogspot.com / forum.chaos-project.com
#==============================================================================
($imported ||= {})[:drg_core_engine] = 1.59
# =============================================================================
# NOTE:
# -----------------------------------------------------------------------------
# This is a devtool for me to make me easier for scripting
# If you want to use this, put above all custom script & below Scene_Debug
#
# =============================================================================
# DOCUMENTATION:
# -----------------------------------------------------------------------------
=begin
Version History
1.57 -
▼ Overhaul script (108 minor modification)
▼ Fixed glitch on BitmapDump method
▼ Added Bitmap#rotate90
▼ Added Bitmap#rotate180
▼ Added Bitmap#rotate270
1.50 -
▼ Overhaul script (71 minor modification)
▼ Longer script call (RMXP script call bug fix)
1.42 -
▼ Fixed Graphics.fullscreen?
1.40 -
▼ Modified Game_Map#load_event
1.39 -
▼ Fixed glitch at Bitmap#draw_icon
▼ Added Fiber class
▼ Added Game_Map#load_event
▼ Added Game_Map#call_event
1.36 -
▼ Added Color class library
1.34 -
▼ Added Module#define_third_method(sym = nil, _alias = nil,
prevent_stack = true, *a, &block)
▼ Added Bitmap#blur
1.31 -
▼ Added Module#attr_sec_reader(symbol, default=0)
▼ Added Module#attr_sec_accessor(symbol, *a, &block)
▼ Added Module#alias_sec_method(sym = nil, *a, &block)
▼ Added Module#define_sec_method(sym = nil, *a, &block)
1.29 -
▼ Added Array#have_all?(array)
▼ Added Array#have_any?(array)
1.27 -
▼ Added Added Graphics.brightness
▼ Added Graphics.wait(frames = 10)
▼ Added Graphics.fadein(frames = 10)
▼ Added Graphics.fadeout(frames = 10)
▼ Added Bitmap#invert
▼ Added Bitmap#invert!
▼ Added Bitmap#brighten(amount = 10)
▼ Added Bitmap#brighten!(amount = 10)
▼ Added Bitmap#darken(amount = 10)
▼ Added Bitmap#darken!(amount = 10)
▼ Added Bitmap#grayscale
▼ Added Bitmap#grayscale!
▼ Added Bitmap#pixelate(size = 10)
▼ Added Bitmap#pixelate!(size = 10)
▼ Added Bitmap#frost(noise = 10)
▼ Added Bitmap#frost!(noise = 10)
1.24 -
▼ Added Viewport#x
▼ Added Viewport#y
▼ Added Viewport#width
▼ Added Viewport#height
▼ Added Viewport#disposed?
1.23 -
▼ Added Window_Base#draw_text (same as Bitmap#draw_text)
▼ Added Window_Base#draw_icon
▼ Added Window_Base#draw_battler
▼ Added Window_Base#draw_picture
1.22 -
▼ Added Game_Map#load_map_data
▼ Added Game_Map#load_event
▼ Rename Array#product => Array#prod (because of conflict with RGSS3)
1.21 -
▼ Fixed Glitch at Bitmap#crop
1.20 -
▼ Fixed Script Hanging Error at Bitmap#export
1.19 -
▼ Added some of RMXP method - Game_System#play_bgm
▼ Added some of RMXP method - Game_System#play_bgs
▼ Added some of RMXP method - Game_System#play_me
▼ Added some of RMXP method - Game_System#play_se
1.18 -
▼ Fixing Backtrace at Array#method_missing
1.17 -
▼ Added Bitmap#flip_vertical
▼ Added Bitmap#flip_vertical!
▼ Added Bitmap#flip_horizontal
▼ Added Bitmap#flip_horizontal!
1.16 -
▼ Added Bitmap#export (dump bitmap into .png files)
1.15 -
▼ Added Game_Characters#character_above?
▼ Added Game_Characters#character_below?
▼ Added Game_Characters#character_right?
▼ Added Game_Characters#character_left?
1.11 -
▼ Fixing Bug at changing screen size
1.10 -
▼ Added Graphics.scale_screen(width, height)
1.00 -
▼ Original Release
# -----------------------------------------------------------------------------
# Below is the available command in this script
# -----------------------------------------------------------------------------
# * Graphics
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
This command is not recommended to used in RMXP
Graphics.scale_screen(width,height)
- Resize the screen and stretched it (if not RMXP) into new resolution
Graphics.fill_monitor
- Maximize the screen and stretched it (if not RMXP) to fill the monitor
Graphics.control_screen_size(enable = true)
- Enable or disable screen size control by mouse.
Resized screen will be stretched (if not RMXP)
# -----------------------------------------------------------------------------
Graphics.width - Returns screen width
Graphics.height - Returns screen height
Graphics.fullscreen? - Returns true if Game in fullscreen mode, else false
Graphics.fullscreen - Switch to fullscreen mode
Graphics.window - Switch to windowed mode
Graphics.toggle - Switch between fullscreen mode and windowed mode
Graphics.wait(frame) - Wait for frame
Graphics.wait_for_input - Wait until input is pressed
Graphics.fadein(frame) - Fade in the screen
Graphics.fadeout(frame) - Fade out the screen
Graphics.snap_to_bitmap - Snap screen to a bitmap object
Graphics.high_priority = true/false - Change process priority to high / normal
Graphics.disable_alt_enter - Disable input ALT+Enter (until game is closed)
# -----------------------------------------------------------------------------
# * Module
# -----------------------------------------------------------------------------
Module#attr_sec_reader(symbol, default=0)
- Create attr_reader with default value
Example : attr_sec_reader :something, "Sprite.new"
Equal : def something
@something ||= Sprite.new
end
Module#attr_sec_accessor(symbol, *a, &block)
- Create (sheer of) attr_accessor with default value
Example : attr_sec_accessor :sprite1, :sprite2, :sprite3, "Sprite.new"
Equal : attr_writer :sprite1, :sprite2, :sprite3
attr_sec_reader :sprite1, "Sprite.new"
attr_sec_reader :sprite2, "Sprite.new"
attr_sec_reader :sprite3, "Sprite.new"
Module#alias_sec_method(sym = nil, *a, &block)
- Create alias only if alias name is not defined and target method is exist
Example : alias_sec_method :alias_method, :target_method
Equal : if method_defined?(:target) && !method_defined?(:alias)
alias_method :alias, :target
end
Module#define_sec_method(sym = nil, *a, &block)
- Define method only if the method is not defined
Example : define_sec_method(:some_method) { |*a| block }
Equal : unless method_defined?(:some_method)
def some_method(*a)
block
end
end
# -----------------------------------------------------------------------------
# * Array
# -----------------------------------------------------------------------------
Array Method Distributor
- Distribute unexisted method in array into each variable
(will work only if the method isn't exist in Array)
Example : [Graphics,Input].update
# equal => Graphics.update ; Input.update
[@string1,@string2,@integer1,@sprite].dispose
# equal => @sprite.dispose
# (all variable without dispose method is ignored)
[@string1,@string2,@integer1].dispose
# Throws NoMethodError if all method didn't have dispose method
Array#random_each / Array#random_each_with_index
Example : a = [1,2,3,4,5,6,7]
a.random_each {|i| puts i} # 4,5,3,2,7,1,6
Array#sum
Array#prod
Array#average
Example : [1,2,3,4].sum # 10 (1+2+3+4)
[1,2,3,4].average # 2.5 (10 / 4)
[1,2,3,4].prod # 24 (1*2*3*4)
Array#shuffle / Array#shuffle!
Example : [1,2,3,4].shuffle # [3,2,4,1]
Array#random / Array#random!
Example : [1,2,3,4].random # 3
Array#switch=(true/false)
Array#switch_reverse
- Turn on / off switches all variable in the array
(will ignored if variable not integer or not an array)
Example : [1,2,[3,2,'A'],5].switch = true
# equal => $game_switches[1] = true
$game_switches[2] = true
$game_self_switches[[3,2,'A']] = true
$game_switches[5] = true
Array#variable(value = nil, method = "=")
- Change all variable value in the array (ignored if variable not integer)
Example : [1,2,5].variable(10)
# equal => $game_variables[1] = 10
$game_variables[2] = 10
$game_variables[5] = 10
Example : [1,2,5].variable(10, "+=")
# equal => $game_variables[1] += 10
$game_variables[2] += 10
$game_variables[5] += 10
Array#have_all?(array)
- returns true if contains all elements of the array
Array#have_any?(array)
- returns true if contains any elements of the array
# -----------------------------------------------------------------------------
# * Sprite
# -----------------------------------------------------------------------------
Sprite#clone
Sprite#dup
- Clone sprite without "can't clone sprite error"
Example : a = Sprite.new
b = a.clone
a.dispose
print a.disposed? # true
print b.disposed? # false
# -----------------------------------------------------------------------------
# * Spriteset_Map
# -----------------------------------------------------------------------------
Spriteset_Map#sprite_player
- returns sprite player at @character_sprites in Spriteset_Map
Spriteset_Map#find_character(character)
- returns character sprite at @character_sprites in Spriteset_Map
# -----------------------------------------------------------------------------
# * Game Battler
# -----------------------------------------------------------------------------
Game_Battler#hp_percent(integer = false, float_points = 2)
Game_Battler#sp_percent(integer = false, float_points = 2)
Example : $game_actors[1].hp_percent
# returns 0 - 100 based on percentage hp
# -----------------------------------------------------------------------------
# * Bitmap
# -----------------------------------------------------------------------------
Bitmap#export(filename)
- exporting bitmap into a file (only support bmp and png)
Example : bitmap = Bitmap.new(50,20)
bitmap.export('empty.png')
Bitmap#flip_vertical
Bitmap#flip_vertical!
Bitmap#flip_horizontal
Bitmap#flip_horizontal!
- flip the bitmap vertically or horizontally (using ! will modify self)
Example : bitmap = Bitmap.new(50,20)
bitmap.flip_vertical!
Bitmap#rotate90
Bitmap#rotate90!
Bitmap#rotate180
Bitmap#rotate180!
Bitmap#rotate270
Bitmap#rotate270!
Additional Bitmap Effects
Note : calling this method is process consuming, use with caution
Bitmap#invert
Bitmap#invert!
Bitmap#brighten(amount = 10)
Bitmap#brighten!(amount = 10)
Bitmap#darken(amount = 10)
Bitmap#darken!(amount = 10)
Bitmap#grayscale
Bitmap#grayscale!
Bitmap#pixelate(size = 10)
Bitmap#pixelate!(size = 10)
Bitmap#frost(noise = 10)
Bitmap#frost!(noise = 10)
# -----------------------------------------------------------------------------
# * Color
# -----------------------------------------------------------------------------
Color RGB value shortcut
List :
Color.red
Color.green
Color.blue
Color.white
Color.black
Color.yellow
Color.magenta
Color.cyan
Color.purple
Color.gray
Color.lightgray
Color.darkgray
Color.pink
Color.orange
Color.brown
Color.golden
Color.invert
Color Hex
- You can use hex value as method in color class (not case sensitive)
(need to include 'x' in front)
Example : Color.xffffff, Color.x04dacf, etc
# -----------------------------------------------------------------------------
# * Game_Map
# -----------------------------------------------------------------------------
Game_Map#load_event(mapid, eventid, x, y, page_id)
Game_Map#load_event(mapid, eventid, x, y)
Game_Map#load_event(eventid, x, y) # map_id will be assumed as current map
- Duplicate an event from another map to current map at position (x, y)
Game_Map#call_event(mapid, eventid, page_id)
Game_Map#call_event(mapid, eventid) # page_id will be assumed as -1
Game_Map#call_event(eventid) # map_id will be assumed as current map
- Call an event from another map to current map
Note that page_id is start from 1, not 0
If you're using RMVX or RMVXA, setting page_id to -1 will bring you to
the page with met condition.
# -----------------------------------------------------------------------------
# * RTP fix
# -----------------------------------------------------------------------------
Longer script call
- You can stack script call next to each other as many as possible and they
will be connected.
- In addition, this also fixes the Interpreter Script call bug when if you
use $game_system..... = false, game would freeze. This will prevent that.
# -----------------------------------------------------------------------------
# * End Documentation
# -----------------------------------------------------------------------------
=end
# =============================================================================
#==============================================================================
# ** Module
#------------------------------------------------------------------------------
#
#==============================================================================
class Module
#-------------------------------------------------------------------------
# * New method: attr_sec_reader (Attr Secondary Reader)
#-------------------------------------------------------------------------
unless method_defined?(:attr_sec_reader)
def attr_sec_reader(*sym)
if (1..2) === sym.size
module_eval("define_method(:#{sym[0]}) { @#{sym[0]} ||= #{sym[1]||0}}")
elsif sym.size > 2
(default = sym.pop) && sym.each {|s| attr_sec_reader(s,default)}
end
end
end
#-------------------------------------------------------------------------
# * New method: attr_sec_accessor (Attr Secondary Accessor)
#-------------------------------------------------------------------------
def attr_sec_accessor(sym = nil, *args)
(args.size > 0) | sym.nil? || args.push(0)
(default = args.pop) && (b = [sym].concat(args).compact)
(b).each {|a| (attr_writer(a) || 0) && attr_sec_reader(a,default)}
end
#-------------------------------------------------------------------------
# * New method: alias_sec_method (Alias Secondary Method)
# Note : This method will create alias only if alias name is not defined
# and target alias is exist
#-------------------------------------------------------------------------
unless method_defined?(:alias_sec_method)
private
def alias_sec_method(sym = nil, *args)
(args.size > 0) | sym.nil? || args.clear
(t = args.pop) && (b = [sym].concat(args).compact).each do |a|
c = (t == :initialize ? true : method_defined?(t))
method_defined?(a) || (c && alias_method(a, t))
end
end
end
#-------------------------------------------------------------------------
# * New method: redirect_method
#-------------------------------------------------------------------------
unless method_defined?(:redirect_method)
private
def redirect_method(sym = nil, *args, &block)
(args.size > 0) | sym.nil? || args.clear
(t = args.pop) && (b = [sym].concat(args).compact).each do |a|
meth = "def #{a}[*args] #{t}(*args) end"
meth.gsub!(/(['")}\](\d+)])\(\*args\)/i) { $1 }#'
meth.gsub!(/\[\*args\]/i) { '(*args)' }
method_defined?(a) || module_eval(meth)
end
end
end
#-------------------------------------------------------------------------
# * New method: define_sec_method
# Note : This method will not defining method if method name already
# exist
#-------------------------------------------------------------------------
unless method_defined?(:define_sec_method)
private
def define_sec_method(sym = nil, *args, &block)
sym && (method_defined?(s = sym.to_sym) || define_method(s,*args,&block))
end
end
#-------------------------------------------------------------------------
# * New method: define_third_method
# Note : After aliasing, define a method
#-------------------------------------------------------------------------
unless method_defined?(:define_third_method)
private
def define_third_method(sym = nil, _alias = nil, *args, &block)
unless sym.nil? || _alias.nil?
stack = _alias.to_s =~ /stack/i || sym.to_s == 'initialize'
stack = (!stack && method_defined?(_alias.to_sym))
stack || alias_method(_alias.to_sym, sym.to_sym)
define_method(sym.to_sym,*args,&block)
end
end
end
#--------------------------------------------------------------------------
# ● New method: define_pre_alias
#--------------------------------------------------------------------------
unless method_defined?(:define_pre_method)
private
def define_pre_alias(sym = nil, *args, &block)
_time = Time.now
_alias = :"#{sym}_#{_time.to_i}_#{_time.usec}"
define_third_method(:"#{sym}",_alias) do |*args|
block.bind(self).call
send(_alias,*args)
end
end
private
def define_post_alias(sym = nil, *args, &block)
_time = Time.now
_alias = :"#{sym}_#{_time.to_i}_#{_time.usec}"
define_third_method(:"#{sym}",_alias) do |*args|
send(_alias,*args)
block.bind(self).call
end
end
end
#--------------------------------------------------------------------------
# ● New method: include_auto_update
#--------------------------------------------------------------------------
unless method_defined?(:include_auto_update)
private
def include_auto_update
return if method_defined?(:update_auto_update)
attr_sec_accessor(:auto_update, "[]")
define_method(:update_auto_update) do
return if auto_update.empty?
auto_update.each do |x|
(x[1].nil? ? send(x[0]) : (x[2].nil? ? x[0].method(x[1]).call :
(x[0].method(x[1]).call(*x[2]))))
(x[3].is_a?(Numeric) && (x[3] -= 1))
end
auto_update.reject! {|x| x[3].is_a?(Numeric) && x[3] <= 0 }
end
_time = Time.now
_alias = :"update_#{_time.to_i}_#{_time.usec}"
define_third_method(:update,_alias) do |*args|
send(_alias,*args)
update_auto_update
end
end
end
end
#==============================================================================
# ** LiTTleDRAgo
#------------------------------------------------------------------------------
#
#==============================================================================
module LiTTleDRAgo
#-------------------------------------------------------------------------
# * Constant
#-------------------------------------------------------------------------
VX = defined?(Window_ActorCommand)
VXA = defined?(Window_BattleActor)
XP = !VX
RGSS1 = defined?(Hangup)
RGSS2 = RUBY_VERSION == '1.8.1' && !RGSS1
RGSS3 = RUBY_VERSION == '1.9.2'
APPPATHDRAGO = "#{ENV['APPDATA']}/Drago/"
end
#==============================================================================
# ** CoreDLL
#------------------------------------------------------------------------------
#
#==============================================================================
module CoreDLL
#-------------------------------------------------------------------------
# * Constant
#-------------------------------------------------------------------------
DLL_USED = ['kernel32','msvcrt','user32','gdi32']
SCENEVXA = "SceneManager.send(:instance_variable_set,:@scene,args.at(0))"
L = LiTTleDRAgo
#-------------------------------------------------------------------------
# * Public Instance Variables
#-------------------------------------------------------------------------
attr_sec_reader :rtlmemory_pi, "winapi(0,'RtlMoveMemory','pii','i')"
attr_sec_reader :rtlmemory_ip, "winapi(0,'RtlMoveMemory','ipi','i')"
attr_sec_reader :setpriority, "winapi(0,'SetPriorityClass','pi','i')"
attr_sec_reader :getprocesstime,"winapi(0,'GetProcessTimes','ipppp','i')"
attr_sec_reader :getdc, "winapi(2,'GetDC','i','i')"
attr_sec_reader :releasedc, "winapi(2,'ReleaseDC','ii','i')"
attr_sec_reader :reghotkey, "winapi(2,'RegisterHotKey', 'liii', 'i')"
attr_sec_reader :sendinput, "winapi(2,'SendInput','ipi','i')"
attr_sec_reader :setwindowlong, "winapi(2,'SetWindowLong','lll','l')"
attr_sec_reader :getkeysta, "winapi(2,'GetKeyboardState','p','i')"
attr_sec_reader :getkeylay, "winapi(2,'GetKeyboardLayout','l','l')"
attr_sec_reader :mapvirkey, "winapi(2,'MapVirtualKeyEx','iil','i')"
attr_sec_reader :tounicode, "winapi(2,'ToUnicodeEx','llppill','l')"
attr_sec_reader :screentoclient,"winapi(2,'ScreenToClient', 'lp', 'i')"
attr_sec_reader :cursorposition,"winapi(2,'GetCursorPos', 'p', 'i')"
attr_sec_reader :systemmetrix, "winapi(2,'GetSystemMetrics', %w(i), 'i')"
attr_sec_reader :bitblt, "winapi(3,'BitBlt','iiiiiiiii','i')"
attr_sec_reader :ccdc, "winapi(3,'CreateCompatibleDC','i','i')"
attr_sec_reader :ccbitmap, "winapi(3,'CreateCompatibleBitmap','iii','i')"
attr_sec_reader :deleteobject, "winapi(3,'DeleteObject','i','i')"
attr_sec_reader :getbitmapbits, "winapi(3,'GetBitmapBits','llp','l')"
attr_sec_reader :getdibits, "winapi(3,'GetDIBits','iiiiipi','i')"
attr_sec_reader :setdibits, "winapi(3,'SetDIBits','iiiiipi','i')"
attr_sec_reader :selectobject, "winapi(3,'SelectObject','ii','i')"
attr_sec_reader :getpixel, "winapi(3,'GetPixel','iii','i')"
attr_sec_reader :setpixel, "winapi(3,'SetPixel','liil','l')"
attr_sec_reader :disabled_key, "Array.new"
attr_sec_reader :high_priority, 'false'
#-------------------------------------------------------------------------
# * Define Secondary Listing
#-------------------------------------------------------------------------
define_sec_method(:disable_alt_enter) { disable_keys(0x0D) }
define_sec_method(:fullscreen?) { systemmetrix.call(0) == Graphics.width }
define_sec_method(:fullscreen) { self.fullscreen? || toggle }
define_sec_method(:window) { self.fullscreen? && toggle }
#-------------------------------------------------------------------------
# * Redirect Listing
#-------------------------------------------------------------------------
redirect_method :cache, L::VX ? '(Cache)' : '(RPG::Cache)'
redirect_method :scene, L::VXA ? '(SceneManager.scene)':'($scene)'
redirect_method :scene=, L::VXA ? SCENEVXA : '($scene = args[0])'
#-------------------------------------------------------------------------
# * Enable change window size via mouse (border required)
# Screen will not resized if RMXP
#-------------------------------------------------------------------------
def control_screen_size(enable = true)
hid = @hide_border ? 0x14000000 : 0x14CA0000
set = enable ? (0x10C70000|0x00080000) : hid
self.setwindowlong.call(self.hwnd,-16, set)
end
#-------------------------------------------------------------------------
# * Hide window border
# Screen size can't be controlled via mouse
#-------------------------------------------------------------------------
def hide_borders
control_screen_size((@hide_border = true) && false)
end
#-------------------------------------------------------------------------
# * Show window border
# Screen size can't be controlled via mouse
#-------------------------------------------------------------------------
def show_borders
control_screen_size((@hide_border = false))
end
#-------------------------------------------------------------------------
# * Disable Key
#-------------------------------------------------------------------------
def disable_keys(*keys)
keys.each do |key|
disabled_key.include?(key) || disabled_key.push(key)
self.reghotkey.call(self.hwnd, 1, 0x0001, key)
end
end
#-------------------------------------------------------------------------
# * Resize the screen (scaled)
# Screen will not resized if RMXP
#-------------------------------------------------------------------------
def scale_screen(width, height)
width += ((res = self.systemmetrix).call(5) + (res.call(45))) * 2
height += (res.call(6) + (res.call(46))) * 2 + res.call(4)
x = [(res.call(0) - width) / 2, 0].max
y = [(res.call(1) - height) / 2, 0].max
self.setwindowpos(self.hwnd,0,x,y,width,height,0)
end
#-------------------------------------------------------------------------
# * Scale the game.exe to fill the monitor
# Screen will not resized if RMXP
#-------------------------------------------------------------------------
def fill_monitor
setwindowpos(hwnd,0,0,0,(res = systemmetrix).call(0),res.call(1),0)
end
#-------------------------------------------------------------------------
# * setwindowpos
#-------------------------------------------------------------------------
def setwindowpos(hwnd = self.hwnd,at = 0,x = 0,y = 0,
width = 640, height = 480, ni = 0)
@setwindowpos ||= winapi(2, 'SetWindowPos', 'liiiiip','i')
@setwindowpos.call(hwnd, at, x, y, width, height, ni)
end
#-------------------------------------------------------------------------
# * Toggle between fullscreen and windowed
#-------------------------------------------------------------------------
def toggle
@keybd ||= winapi(2, 'keybd_event', %w(i i l l), 'v')
[@keybd.call(0xA4, 0, 0, 0), @keybd.call(13, 0, 0, 0) ]
[@keybd.call(13, 0, 2, 0), @keybd.call(0xA4, 0, 2, 0)]
end
#-------------------------------------------------------------------------
# * Show FPS
#-------------------------------------------------------------------------
def show_fps
@show_fps ||= winapi(2, 'keybd_event', %w(l l l l), '')
@show_fps.call(0x71,0,0,0)
sleep(0.1)
@show_fps.call(0x71,0,2,0)
end
#-------------------------------------------------------------------------
# * Get the Game Window's width and height
#-------------------------------------------------------------------------
def client_size
@window_c_rect ||= winapi(2, 'GetClientRect', %w(l p), 'i')
@window_c_rect.call(self.hwnd, (rect = [0, 0, 0, 0].pack('l4')))
right, bottom = rect.unpack('l4')[2..3]
return right, bottom
end
#-------------------------------------------------------------------------
# * Get the game window handle (specific to game)
#-------------------------------------------------------------------------
def hwnd
@game_window ||= winapi(2, 'FindWindowEx', %w(l l p p), 'i').
call(0,0,"RGSS Player",0)
end
#-------------------------------------------------------------------------
# * always_on_top (cannot be undone)
#-------------------------------------------------------------------------
def always_on_top
res = self.systemmetrix
width = Graphics.width + (res.call(5) + (res.call(45))) * 2
height = Graphics.height + (res.call(6) + (res.call(46))) * 2 + res.call(4)
x = [(res.call(0) - width) / 2, 0].max
y = [(res.call(1) - height) / 2, 0].max
self.setwindowpos(self.hwnd,-1,x,y,width,height,0x0200)
end
#-------------------------------------------------------------------------
# * Get the value of game.ini
#-------------------------------------------------------------------------
def read_ini(field, key, ini = 'Game.ini')
@gpps ||= winapi(0, 'GetPrivateProfileString', 'pppplp', 'l')
@gpps.call(field,key,"",result="\0"*256,256,".//#{ini}") rescue return ""
return result.delete!("\0")
end
#-------------------------------------------------------------------------
# * Data default extension
#-------------------------------------------------------------------------
def data_default_extension
data = read_ini('Game','Scripts')
data = data.split('.').last || 'rxdata'
return data
end
#-------------------------------------------------------------------------
# * High Priority (true/false)
#-------------------------------------------------------------------------
def high_priority=(value)
@high_priority = value && true
setpriority.call(-1, @high_priority ? 0x00000080 : 0x00000020)
end
#--------------------------------------------------------------------------
# * snap_to_bitmap
#--------------------------------------------------------------------------
def snap_to_bitmap
bitmap = Bitmap.new((w = client_size.at(0)),(h = client_size.at(1)))
info = [40,w,h,1,32,0,0,0,0,0,0].pack('LllSSLLllLL')
hDC = ccdc.call((dc = getdc.call(hwnd)))
deleteobject.call(selectobject.call(hDC, (hBM = ccbitmap.call(dc, w, h))))
setdibits.call(hDC, hBM, 0, h, (a = bitmap.address), info, 0)
bitblt.call(hDC, 0, 0, w, h, dc, 0, 0, 0xCC0020)
getdibits.call(hDC, hBM, 0, h, a, info, 0)
deleteobject.call(hBM)
deleteobject.call(hDC)
return bitmap
end
#-------------------------------------------------------------------------
# * Execute Win32API
#-------------------------------------------------------------------------
def winapi(*a)
Win32API.new(*((a[0].is_a?(Integer) ? a[0] = DLL_USED[a[0]] : a) && a))
end
#----------------------------------------------------------------------------
# * unicode_to_utf8
# string - string in Unicode format
# Converts a string from Unicode format to UTF-8 format as RGSS does not
# support Unicode.
#----------------------------------------------------------------------------
def unicode_to_utf8(string)
result = ''
string.unpack('L*').each do |c|
if (c1 = c < 0x0080) || (c2 = c < 0x0800) || (c3 = c < 0x10000) ||
(c4 = c < 0x200000)|| (c5 = c < 0x4000000) || (c6 = c < 0x80000000)
result += c.chr if c1
result += (0xC0 | (c >> 6)).chr if c2
result += (0xE0 | (c >> 12)).chr if c3
result += (0xF0 | (c >> 18)).chr if c4
result += (0xF8 | (c >> 24)).chr if c5
result += (0xFC | (c >> 30)).chr if c6
result += (0x80 | ((c >> 24) & 0x3F)).chr if c6
result += (0x80 | ((c >> 18) & 0x3F)).chr if c5 || c6
result += (0x80 | ((c >> 12) & 0x3F)).chr if c4 || c5 || c6
result += (0x80 | ((c >> 6) & 0x3F)).chr if c3 || c4 || c5 || c6
result += (0x80 | (c & 0x3F)).chr if c2 || c3 || c4 || c5 || c6
end
end
return result
end
end
LiTTleDRAgo.extend(CoreDLL)
#==============================================================================
# ** RPG
#------------------------------------------------------------------------------
#
#==============================================================================
module RPG
#============================================================================
# ** System
#----------------------------------------------------------------------------
#
#============================================================================
class System
#----------------------------------------------------------------------
# ● Class Variables
#----------------------------------------------------------------------
if (VX = LiTTleDRAgo::VX)
#------------------------------------------------------------------------
# ● Public Instance Variables
#------------------------------------------------------------------------
attr_accessor :magic_number, :windowskin_name, :gameover_name
attr_accessor :battle_transition, :battleback_name, :title_name
#------------------------------------------------------------------------
# ● Redefined Methods
#------------------------------------------------------------------------
redirect_method :sounds, "$data_system.sounds"
redirect_method :cursor_se, "sounds[0]"
redirect_method :decision_se, "sounds[1]"
redirect_method :cancel_se, "sounds[2]"
redirect_method :buzzer_se, "sounds[3]"
redirect_method :equip_se, "sounds[4]"
redirect_method :save_se, "sounds[5]"
redirect_method :load_se, "sounds[6]"
redirect_method :battle_start_se, "sounds[7]"
redirect_method :escape_se, "sounds[8]"
if (VXA = LiTTleDRAgo::VXA)
redirect_method :shop_se, "sounds[21]"
redirect_method :actor_collapse_se, "sounds[15]"
else
redirect_method :shop_se, "sounds[17]"
redirect_method :actor_collapse_se, "sounds[13]"
end
redirect_method :enemy_collapse_se, "sounds[11]"
redirect_method :words, "@words ||= RPG::System::Words.new()"
#------------------------------------------------------------------------
# ● Aliased Methods
#------------------------------------------------------------------------
alias_sec_method :battleback_name, :battleback1_name
alias_sec_method :title_name, :title1_name
end
#========================================================================
# ** Words
#------------------------------------------------------------------------
#
#========================================================================
class Words
#----------------------------------------------------------------------
# ● New Methods
#----------------------------------------------------------------------
attr_sec_accessor :params, !(VXA = LiTTleDRAgo::VXA) ? !VX ?
'[hp,sp,str,dex,agi,int]' : # XP
'[hp,sp,atk,pdef,int,agi]' : # VX
'[hp,sp,atk,pdef,int,mdef,agi,luk]' # VXA
attr_sec_accessor :weapon1, VX && !VXA ? 'Vocab.weapon1' : "'Weapon 1'"
attr_sec_accessor :weapon2, VX && !VXA ? 'Vocab.weapon2' : "'Weapon 2'"
attr_sec_accessor :status, VX ? 'Vocab.status' : "'Status' "
attr_sec_accessor :save, VX ? 'Vocab.save' : "'Save' "
attr_sec_accessor :game_end, VX ? 'Vocab.game_end' : "'Game End'"
attr_sec_accessor :fight, VX ? 'Vocab.fight' : "'Fight' "
attr_sec_accessor :escape, VX ? 'Vocab.escape' : "'Escape' "
attr_sec_accessor :new_game, VX ? 'Vocab.new_game' : "'New Game'"
attr_sec_accessor :continue, VX ? 'Vocab.continue' : "'Continue'"
attr_sec_accessor :shutdown, VX ? 'Vocab.shutdown' : "'Shutdown'"
attr_sec_accessor :to_title, VX ? 'Vocab.to_title' : "'To Title'"
attr_sec_accessor :cancel, VX ? 'Vocab.cancel' : "'Cancel' "
#----------------------------------------------------------------------
# ● Redirect Listings
#----------------------------------------------------------------------
redirect_method :gold, (VXA ? 'Vocab.currency_unit' : 'Vocab.gold')
redirect_method :hp, 'Vocab.hp'
redirect_method :sp, 'Vocab.mp'
redirect_method :str, 'String.new()'
redirect_method :dex, 'String.new()'
redirect_method :luk, (VXA ? 'Vocab.param(7)' : 'String.new()')
redirect_method :agi, (VXA ? 'Vocab.param(6)' : 'Vocab.agi')
redirect_method :int, (VXA ? 'Vocab.param(4)' : 'Vocab.spi')
redirect_method :atk, (VXA ? 'Vocab.param(2)' : 'Vocab.atk')
redirect_method :pdef, (VXA ? 'Vocab.param(3)' : 'Vocab.def')
redirect_method :mdef, (VXA ? 'Vocab.param(5)' : 'String.new()')
redirect_method :weapon, (VXA ? 'Vocab.etype(0)' : 'Vocab.weapon')
redirect_method :armor1, (VXA ? 'Vocab.etype(1)' : 'Vocab.armor1')
redirect_method :armor2, (VXA ? 'Vocab.etype(2)' : 'Vocab.armor2')
redirect_method :armor3, (VXA ? 'Vocab.etype(3)' : 'Vocab.armor3')
redirect_method :armor4, (VXA ? 'Vocab.etype(4)' : 'Vocab.armor4')
redirect_method :attack, 'Vocab.attack'
redirect_method :skill, 'Vocab.skill'
redirect_method :guard, 'Vocab.guard'
redirect_method :item, 'Vocab.item'
redirect_method :equip, 'Vocab.equip'
end
end
end
#==============================================================================
# ** RPG_FileTest
#------------------------------------------------------------------------------
#
#==============================================================================
module RPG_FileTest
#--------------------------------------------------------------------------
# ● New method: self.exist?
#--------------------------------------------------------------------------
def self.exist?(filename)
dir,ext = File.dirname(filename) + '/', File.extname(filename)
base = File.basename(filename, ext)
if ['.png','.jpg','.bmp'].include?(ext.downcase)
cache = defined?(Cache) ? Cache : RPG::Cache
(cache.load_bitmap(dir,base) && true) rescue false
elsif ['.rxdata','.rvdata','.rvdata2','.rb','.txt'].include?(ext.downcase)
(load_data(filename) && true) rescue false
else
File.exist?(filename)
end
end
end
#==============================================================================
# ** Sound
#------------------------------------------------------------------------------
# This module plays sound effects. It obtains sound effects specified in the
# database from the global variable $data_system, and plays them.
#==============================================================================
module Sound; end
class << Sound
#------------------------------------------------------------------------
# ● New Method :se_play
#------------------------------------------------------------------------
unless method_defined?(:se_play)
def se_play(type)
system = ($game_system ||= Game_System.new)
case type
when :cursor then system.se_play($data_system.cursor_se)
when :decision then system.se_play($data_system.decision_se)
when :cancel then system.se_play($data_system.cancel_se)
when :buzzer then system.se_play($data_system.buzzer_se)
when :shop then system.se_play($data_system.shop_se)
when :equip then system.se_play($data_system.equip_se)
when :save then system.se_play($data_system.save_se)
when :load then system.se_play($data_system.load_se)
when :battle_start then system.se_play($data_system.battle_start_se)
when :escape then system.se_play($data_system.escape_se)
when :actor_collapse then system.se_play($data_system.actor_collapse_se)
when :enemy_collapse then system.se_play($data_system.enemy_collapse_se)
end
end
end
#--------------------------------------------------------------------------
# * Redefined Method
#--------------------------------------------------------------------------
define_sec_method(:play_cursor) { se_play(:cursor) }
define_sec_method(:play_decision) { se_play(:decision) }
define_sec_method(:play_cancel) { se_play(:cancel) }
define_sec_method(:play_buzzer) { se_play(:buzzer) }
define_sec_method(:play_equip) { se_play(:equip) }
define_sec_method(:play_save) { se_play(:save) }
define_sec_method(:play_load) { se_play(:load) }
define_sec_method(:play_battle_start) { se_play(:battle_start) }
define_sec_method(:play_escape) { se_play(:escape) }
define_sec_method(:play_enemy_collapse) { se_play(:enemy_collapse) }
define_sec_method(:play_actor_collapse) { se_play(:actor_collapse) }
define_sec_method(:play_shop) { se_play(:shop) }
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_sec_method :play_ok, :play_decision
end
#==============================================================================
# ** Game_System
#------------------------------------------------------------------------------
# This class handles data surrounding the system. Backround music, etc.
# is managed here as well. Refer to "$game_system" for the instance of
# this class.
#==============================================================================
class Game_System
#--------------------------------------------------------------------------
# * Constant
#--------------------------------------------------------------------------
VX = LiTTleDRAgo::VX && !LiTTleDRAgo::VXA
#--------------------------------------------------------------------------
# * Public Instance Variable
#--------------------------------------------------------------------------
attr_sec_accessor :bgm_volume , 100
attr_sec_accessor :bgs_volume , 100
attr_sec_accessor :me_volume , 100
attr_sec_accessor :se_volume , 100
attr_sec_accessor :bgm_pitch , 100
attr_sec_accessor :bgs_pitch , 100
attr_sec_accessor :me_pitch , 100
attr_sec_accessor :se_pitch , 100
attr_sec_accessor :volume_control, 'false'
#--------------------------------------------------------------------------
# * Redefined method: bgm_memorize, bgm_restore
#--------------------------------------------------------------------------
VX && define_sec_method(:bgm_memorize) { @memorized_bgm = @playing_bgm }
VX && define_sec_method(:bgm_restore) { bgm_play(@memorized_bgm) }
#--------------------------------------------------------------------------
# * Redirect Listing
#--------------------------------------------------------------------------
redirect_method :bgm_stop, 'Audio.bgm_stop'
redirect_method :bgs_stop, 'Audio.bgs_stop'
redirect_method :se_stop, 'Audio.se_stop'
redirect_method :me_stop, 'Audio.me_stop'
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_sec_method :bgm_memorize, :save_bgm
alias_sec_method :bgm_restore, :replay_bgm
alias_sec_method :save_bgm, :bgm_memorize
alias_sec_method :replay_bgm, :bgm_restore
#--------------------------------------------------------------------------
# * Aliased method: bgm_play, bgs_play, me_play, se_play
#--------------------------------------------------------------------------
[:bgm,:bgs,:me,:se].each do |sa|
next unless method_defined?(:"#{sa}_play")
alias_sec_method(:"drg_#{sa}_play", :"#{sa}_play")
define_method(:"#{sa}_play") do |bgm,*a|
if bgm.is_a?(String) && bgm != ''
bgm = RPG::AudioFile.new(bgm,send(:"#{sa}_volume"),send(:"#{sa}_pitch"))
elsif volume_control && bgm.is_a?(RPG::AudioFile) && bgm.name != ""
bgm = bgm.clone
bgm.volume = Math.percent(bgm.volume,send(:"#{sa}_volume"))
bgm.pitch = Math.percent(bgm.pitch,send(:"#{sa}_pitch"))
end
@playing_bgm = bgm if "#{sa}" == 'bgm'
@playing_bgs = bgm if "#{sa}" == 'bgs'
if respond_to?(:"drg_#{sa}_play")
send(:"drg_#{sa}_play", bgm,*a)
else
if bgm.is_a?(RPG::AudioFile) && bgm.name != ''
Audio.send(:"#{sa}_play","Audio/#{sa}/" + bgm.name,
bgm.volume.round, bgm.pitch.round,*a)
else
send(:"#{sa}_stop")
end
Graphics.frame_reset
end
end
end
end
#==============================================================================
# ** Object
#------------------------------------------------------------------------------
# This class is superclass for all class
#==============================================================================
class Object
#-------------------------------------------------------------------------
# * New method: all_variable_dispose
#-------------------------------------------------------------------------
def all_variable_dispose
all = instance_variables.map {|s| instance_variable_get("#{s}")}.flatten
all.delete_if {|s| s.not.respond_to?(:dispose) }
all.delete_if {|s| s.respond_to?(:disposed?) && s.disposed?}
all.dispose
end
#-------------------------------------------------------------------------
# * New method: rand_between
#-------------------------------------------------------------------------
unless method_defined?(:rand_between)
def rand_between(min, max)
min + rand(max - min + 1) if min.is_a?(Numeric) && max.is_a?(Numeric)
end
end
#-------------------------------------------------------------------------
# * New method: get_note
#-------------------------------------------------------------------------
unless method_defined?(:get_note)
def get_note
respond_to?(:note) ? note : ""
end
end
#-------------------------------------------------------------------------
# * New method: screen_rect
#-------------------------------------------------------------------------
unless method_defined?(:screen_rect)
def screen_rect(as_rect = true)
array = [0,0,Graphics.width,Graphics.height]
as_rect ? Rect.new(*array) : array
end
end
#-------------------------------------------------------------------------
# * New method: forcesave
#-------------------------------------------------------------------------
unless method_defined?(:forcesave)
def forcesave(index)
return DataManager.save_game(index) if defined?(DataManager)
save = LiTTleDRAgo::VX ? Scene_File.new(0,nil,0) : Scene_Save.new
begin
file = File.open(save.make_filename(index), "wb")
(save.write_save_data(file) && file.close) || true
rescue
File.delete(save.make_filename(index)) rescue nil
(Sound.play_buzzer) && false
end
end
end
#--------------------------------------------------------------------------
# * sprite_report
#--------------------------------------------------------------------------
unless method_defined?(:script_report)
def script_report(text,font = nil)
s = (text.is_a?(String) || (text = text.inspect)) && Sprite.new
s.opacity = (s.bitmap = Bitmap.new((g = Graphics).width,g.height)) && 0
s.bitmap.font.name = ['Georgia',Font.default_name].flatten
s.bitmap.font = (s.z += 9999) && (font || s.bitmap.font)
y = (text.split(/\n/).size * s.bitmap.text_size(text).height) / 2
s.bitmap.draw_enter_edging_text(0,0-y,g.width,g.height,text,1)
(s.opacity += 10) && g.update until s.opacity >= 255
g.wait_for_input
(s.opacity -= 10) && g.update until s.opacity <= 0
s.dispose
end
end
#-------------------------------------------------------------------------
# * New method: not
#-------------------------------------------------------------------------
define_sec_method(:not) { Not.new(self) }
#============================================================================
# ** Not
#----------------------------------------------------------------------------
#
#============================================================================
class Not
#-------------------------------------------------------------------------
# * Private
#-------------------------------------------------------------------------
private *instance_methods.select { |m| m !~ /(^__|^\W|^binding$)/ }
#-------------------------------------------------------------------------
# * Object Initialization
#-------------------------------------------------------------------------
define_method(:initialize) {|original| @original = original }
#-------------------------------------------------------------------------
# * New method: method_missing
#-------------------------------------------------------------------------
def method_missing(sym, *a, &blk)
!@original.send(sym, *a, &blk)
end
end
end
#==============================================================================
# ** Kernel
#------------------------------------------------------------------------------
#
#==============================================================================
module Kernel
#-------------------------------------------------------------------------
# * Alias Listing
#-------------------------------------------------------------------------
$@ || alias_method(:carrot, :proc)
#-------------------------------------------------------------------------
# * Script Check
#-------------------------------------------------------------------------
if LiTTleDRAgo::XP && LiTTleDRAgo::RGSS3 && !defined?(XPA_CONFIG)
$@ || alias_method(:last_before_p, :p)
$@ || alias_method(:last_before_print, :print)
$@ || alias_method(:last_before_msgbox, :msgbox)
$@ || alias_method(:last_before_msgbox_p, :msgbox_p)
define_method(:p) {|*args| last_before_msgbox_p(*args)}
define_method(:print) {|*args| last_before_msgbox(*args) }
define_method(:msgbox) {|*args| last_before_print(*args) }
define_method(:msgbox_p){|*args| last_before_p(*args) }
end
define_method(:draise) {|*args| (dp(*args) && !1) || exit }
define_method(:dp) {|*a| script_report(a.map {|i| i.inspect}.join("\n"))}
#-------------------------------------------------------------------------
# * New method: dprint
#-------------------------------------------------------------------------
def dprint(*args)
script_report(args.map {|i| i.is_a?(String) ? i : i.inspect}.join)
end
#-------------------------------------------------------------------------
# * New method: press_any_key
#-------------------------------------------------------------------------
unless method_defined?(:press_any_key)
def press_any_key
return false if Input.nil?
return true if Input.trigger?(Input::A) ||Input.trigger?(Input::B)
return true if Input.trigger?(Input::C) ||Input.trigger?(Input::X)
return true if Input.trigger?(Input::Y) ||Input.trigger?(Input::Z)
return true if Input.trigger?(Input::L) ||Input.trigger?(Input::R)
return true if Input.trigger?(Input::UP) ||Input.trigger?(Input::DOWN)
return true if Input.trigger?(Input::LEFT) ||Input.trigger?(Input::RIGHT)
return true if Input.trigger?(Input::SHIFT)||Input.trigger?(Input::CTRL)
return true if Input.trigger?(Input::ALT) ||Input.trigger?(Input::F5)
return true if Input.trigger?(Input::F6) ||Input.trigger?(Input::F7)
return true if Input.trigger?(Input::F8) ||Input.trigger?(Input::F9)
end
end
#-------------------------------------------------------------------------
# * New method: inspect_instance_variable
#-------------------------------------------------------------------------
unless method_defined?(:inspect_instance_variable)
def inspect_instance_variable(class_name, variable)
Module.const_get(class_name).new.instance_variable_get(:"@#{variable}")
end
end
end
#==============================================================================
# ** Proc
#------------------------------------------------------------------------------
#
#==============================================================================
class Proc
#-------------------------------------------------------------------------
# * New method: bind
#-------------------------------------------------------------------------
unless method_defined?(:bind)
def bind(object)
block, time = self, Time.now
class << object
self
end.class_eval do
define_method((name = "__bind_#{time.to_i}_#{time.usec}"), &block)
remove_method((method = instance_method(name)) && name)
method
end.bind(object)
end
end
end
#==============================================================================
# ** Enumerable
#------------------------------------------------------------------------------
#
#==============================================================================
module Enumerable
#---------------------------------------------------------------------------
# * Redefined method: shuffle
#---------------------------------------------------------------------------
define_sec_method(:shuffle) {(a = entries) && Array.new(size){ a.random!}}
#---------------------------------------------------------------------------
# * New method: random_each
#---------------------------------------------------------------------------
unless method_defined?(:random_each)
def random_each() (block_given? ? shuffle.each {|s| yield s } : random) end
end
#---------------------------------------------------------------------------
# * New method: random_each_with_index
#---------------------------------------------------------------------------
unless method_defined?(:random_each_with_index)
def random_each_with_index
block_given? ? self.shuffle.each_with_index {|obj, i| yield obj,i } :
self.random
end
end
#---------------------------------------------------------------------------
# * Redefined method: drop_while
#---------------------------------------------------------------------------
unless method_defined?(:drop_while)
def drop_while(&block)
ary, state = [], false
self.each do |e|
state = true if !state and !block.call(e)
ary << e if state
end
ary
end
end
#---------------------------------------------------------------------------
# * Redefined method: take_while
#---------------------------------------------------------------------------
unless method_defined?(:take_while)
def take_while(&block)
ary = []
self.each do |e|
return ary unless block.call(e)
ary << e
end
ary
end
end
#---------------------------------------------------------------------------
# * Redefined method: partition
#---------------------------------------------------------------------------
unless method_defined?(:partition)
def partition(&block)
ary_T, ary_F = [], []
self.each {|val| block.call(val) ? ary_T.push(val) : ary_F.push(val)}
return ary_T, ary_F
end
end
#---------------------------------------------------------------------------
# * Redefined method: grep
#---------------------------------------------------------------------------
unless method_defined?(:grep)
def grep(pattern, &block)
collect {|v| pattern === v && ary.push((block)? block.call(v): v)}
end
end
#---------------------------------------------------------------------------
# * Redefined method: each_slice
#---------------------------------------------------------------------------
unless method_defined?(:each_slice)
def each_slice(n, &block)
not_integer = "expected Integer for 1st argument"
n.is_a?(Integer) || raise(TypeError,not_integer,caller(1))
n <= 0 && raise(ArgumentError, "invalid slice size",caller(1))
ary = []
self.each do |e|
ary << e
if ary.size == n
block.call(ary)
ary = []
end
end
block.call(ary) unless ary.empty?
end
end
#---------------------------------------------------------------------------
# * Redefined method: minmax
#---------------------------------------------------------------------------
unless method_defined?(:minmax)
def minmax(&block) (a = sort(&block)) && [a.first,a.last] end
end
end
#==============================================================================
# ** Array
#------------------------------------------------------------------------------
#
#==============================================================================
class Array
#---------------------------------------------------------------------------
# * Define Secondary Listing
#---------------------------------------------------------------------------
define_sec_method(:have_all?) { |*array| self & array == array }
define_sec_method(:have_any?) { |*array| self - array != self }
define_sec_method(:relay) { |type| map {|s| s.send(:"to_#{type}")}}
#---------------------------------------------------------------------------
# * Redirect method
#---------------------------------------------------------------------------
redirect_method :switch_on, 'self.switch = (true)'
redirect_method :switch_off, 'self.switch = (false)'
redirect_method :random, 'self.at(rand(size))'
redirect_method :random!, 'self.delete_at(rand(size))'
redirect_method :sum, 'self.inject(0) {|r, n| r += n}'
redirect_method :prod, 'self.inject(1) {|r, n| r *= n}'
redirect_method :next_item, '(item = shift) && push(item) && (item)'
redirect_method :previous_item, '(item = pop) && unshift(item) && (item)'
redirect_method :nitems, 'count {|x| x.not.nil?}'
redirect_method :switch_reverse, 'switch=(:flip)'
#---------------------------------------------------------------------------
# * New method: method_missing
#---------------------------------------------------------------------------
def method_missing(val,*a,&b)
en = self.entries.find_all {|s|s.respond_to?(val.to_sym)}
if self.not.empty? && en.empty?
text = "Undefined method #{val} for #{self.inspect}"
raise(NoMethodError,text,caller(1))
end
return en.map {|s| s.send(val.to_s,*a,&b)}
end
#-------------------------------------------------------------------------
# * New method: each_ntuple
#-------------------------------------------------------------------------
unless method_defined?(:each_ntuple)
def each_ntuple(number)
0.step(size - size % number - 1, number) {|i| yield(*self[i, number])}
end
end
#-------------------------------------------------------------------------
# * New method: each_pair
#-------------------------------------------------------------------------
unless method_defined?(:each_pair)
def each_pair() each_ntuple(2) {|a,b| yield a, b } end
end
#---------------------------------------------------------------------------
# * New method: each_triple
#---------------------------------------------------------------------------
unless method_defined?(:each_triple)
def each_triple() each_ntuple(3) {|a,b,c| yield a, b, c } end
end
#---------------------------------------------------------------------------
# * Redefined method: shuffle! (for RMXP)
#---------------------------------------------------------------------------
unless method_defined?(:shuffle!)
def shuffle!() self.dup == replace(shuffle) ? nil : self end
end
#---------------------------------------------------------------------------
# * New method: sort_by!
#---------------------------------------------------------------------------
unless method_defined?(:sort_by!)
def sort_by!(*args,&block)
self.dup == replace(sort_by(*args,&block)) ? nil : self
end
end
#---------------------------------------------------------------------------
# * New method: recursive_clone
#---------------------------------------------------------------------------
unless method_defined?(:rclone)
def recursive_clone
(clon = self.clone).each_index do |i|
clon[i] = clon[i].recursive_clone rescue clon[i].clone rescue clon[i]
end
clon
end
alias_method(:rclone, :recursive_clone)
end
#---------------------------------------------------------------------------
# * New method: to_hash
#---------------------------------------------------------------------------
unless method_defined?(:to_hash)
def to_hash
(hash = Hash.new) && each_index {|i| hash[i] = self[i]} && hash
end
end
#---------------------------------------------------------------------------
# * Redefined method: count
#---------------------------------------------------------------------------
unless method_defined?(:count)
def count(*args, &block)
if block_given?
find_all {|s| block.call(s)}.size
else
ary = args.empty? ? self : args.map {|a| find_all{|s| s == a}}
ary.compact.size
end
end
end
#---------------------------------------------------------------------------
# * New method: each_with_next
#---------------------------------------------------------------------------
unless method_defined?(:each_with_next)
def each_with_next(num = 1)
(size - num).times {|i| yield(*self[i..(i+num)])}
end
end
#---------------------------------------------------------------------------
# * New method: switch=
#---------------------------------------------------------------------------
unless method_defined?(:switch=)
def switch=(value)
integer = search_var_key[0]
array = search_var_key[1]
if value == :flip
integer.each {|i| $game_switches[i] = !$game_switches[i] }
array.each {|i| $game_self_switches[i] = !$game_self_switches[i] }
else
integer.each {|i| $game_switches[i] = value }
array.each {|i| $game_self_switches[i] = value }
end
$game_map.need_refresh = true if $game_map.respond_to?(:need_refresh)
end
end
#---------------------------------------------------------------------------
# * New method: variable
#---------------------------------------------------------------------------
def variable(value = nil,method = "=")
integer = search_var_key[0]
integer += search_var_key[1] if $drago_game_variable
return integer.map {|i| $game_variables[i]} if value.nil?
result = integer.map {|i| eval("$game_variables[i] #{method} #{value}") }
$game_map.need_refresh = true if $game_map.respond_to?(:need_refresh)
result
end
#---------------------------------------------------------------------------
# * New method: search_var_key
#---------------------------------------------------------------------------
def search_var_key
integer = self.find_all {|s| s.is_a?(Integer)}
range = self.find_all {|s| s.is_a?(Range) }
array = self.find_all {|s| s.is_a?(Array) }
string = self.find_all {|s| s.is_a?(String) }
integer = integer + range.collect {|s| s.to_a }.flatten
$game_switches ||= Game_Switches.new
$game_self_switches ||= Game_SelfSwitches.new
$game_variables ||= Game_Variables.new
return [integer.sort.uniq, array.sort.uniq]
end
#---------------------------------------------------------------------------
# * New method: rindexes
#---------------------------------------------------------------------------
unless method_defined?(:rindexes)
def rindexes(*values)
array = Array.new
each_index {|i| values.include?(self[i]) && array.push(i)}
array
end
end
#---------------------------------------------------------------------------
# * New method: deep
#---------------------------------------------------------------------------
unless method_defined?(:deep)
def deep(deep = -1)
tmp_deep = deep + 1
deep = tmp_deep
self.each do |i|
deep < i.deep(tmp_deep) && deep = i.deep(tmp_deep) rescue nil
end
deep
end
end
#---------------------------------------------------------------------------
# * New method: recursive_flatten
#---------------------------------------------------------------------------
unless method_defined?(:rflatten)
def recursive_flatten
(array = self.recursive_clone).each_index do |i|
array[i] = array[i].to_a if array[i].is_a?(Hash)
array[i] = array[i].recursive_flatten rescue array[i]
end
array.flatten!
array
end
alias_method(:rflatten, :recursive_flatten)
end
#---------------------------------------------------------------------------
# * New method: recursive_flatten!
#---------------------------------------------------------------------------
unless method_defined?(:rflatten!)
def recursive_flatten!
self.each_index do |i|
self[i] = self[i].to_a if self[i].is_a?(Hash)
self[i] = self[i].recursive_flatten! rescue self[i]
end
self.flatten!
self
end
alias_method(:rflatten!, :recursive_flatten!)
end
#---------------------------------------------------------------------------
# * Redefined method: product
#---------------------------------------------------------------------------
def dproduct(*arrays)
(e = "(result = []) && self.each {|i0| ") &&
(a = arrays.size).times {|i| e += "arrays[#{i}].each {|i#{i+1}| " }
(e += "result.push([i0,") && a.times {|i| e += "i#{i+1}," }
(e += "])}" + "}" * a + " && result" )
return eval(e)
end
alias_sec_method(:product, :dproduct)
#---------------------------------------------------------------------------
# * New method: geometric_average
#---------------------------------------------------------------------------
unless method_defined?(:geometric_average)
def geometric_average(float = false)
average = empty? ? 0 : prod ** (1.0 / size)
return (float ? average : average.to_i)
end
end
#---------------------------------------------------------------------------
# * New method: average
#---------------------------------------------------------------------------
unless method_defined?(:average)
def average(float = false)
sum / [(float ? size.to_f : size.to_i), 1].max
end
end
#---------------------------------------------------------------------------
# * Alias method
#---------------------------------------------------------------------------
alias_sec_method :has_all?, :have_all?
alias_sec_method :has_any?, :have_any?
end
#==============================================================================
# ** Hash
#------------------------------------------------------------------------------
#
#==============================================================================
class Hash
#--------------------------------------------------------------------------
# * Define Secondary Listing
#--------------------------------------------------------------------------
define_sec_method(:reverse!) { self.dup == replace(reverse) ? nil : self }
#--------------------------------------------------------------------------
# ● New method: reverse
#--------------------------------------------------------------------------
unless method_defined?(:reverse)
def reverse
key, new_hash = self.keys, {}
key.reverse.each_with_index {|k,i| new_hash[k] = self[key[i]]}
new_hash
end
end
#--------------------------------------------------------------------------
# ● New method: recursive_clone
#--------------------------------------------------------------------------
unless method_defined?(:rclone)
def recursive_clone
(clon = self.clone).each_key do |i|
clon[i] = clon[i].recursive_clone rescue clon[i].clone rescue clon[i]
end
clon
end
alias_method(:rclone, :recursive_clone)
end
#--------------------------------------------------------------------------
# ● New method: deep
#--------------------------------------------------------------------------
unless method_defined?(:deep)
def deep(deep = -1)
key_deep = value_deep = tmp_deep = deep + 1
self.each do |k, v|
key_deep = k.deep(tmp_deep) if key_deep < k.deep(tmp_deep) rescue nil
value_deep = v.deep(tmp_deep)if value_deep< v.deep(tmp_deep) rescue nil
end
key_deep > value_deep ? key_deep : value_deep
end
end
#--------------------------------------------------------------------------
# ● New method: fusion
#--------------------------------------------------------------------------
unless method_defined?(:fusion)
def fusion
(array = sort).each_index do |i|
array[i] = array[i][0] + array[i][1] rescue array[i]
end
array
end
end
end
#==============================================================================
# ** Range
#------------------------------------------------------------------------------
#
#==============================================================================
class Range
#--------------------------------------------------------------------------
# * Include Comparable
#--------------------------------------------------------------------------
include(Comparable)
#-------------------------------------------------------------------------
# ● New method: random
#-------------------------------------------------------------------------
define_sec_method(:random) { self.to_a.random }
define_sec_method(:sum) { self.to_a.sum }
define_sec_method(:prod) { self.to_a.prod }
#-------------------------------------------------------------------------
# ● New method: <=>
#-------------------------------------------------------------------------
unless method_defined?(:"<=>")
def <=>(other)
temp = first <=> other.first
temp = last <=> other.last if temp = 0
return temp
end
end
end
#==============================================================================
# ** NilClass
#------------------------------------------------------------------------------
#
#==============================================================================
class NilClass
#--------------------------------------------------------------------------
# ● Overwriten method: clone, dup
#--------------------------------------------------------------------------
define_method(:clone) {|*a|}
define_method(:dup) {|*a|}
end
#==============================================================================
# ** Math
#------------------------------------------------------------------------------
#
#==============================================================================
module Math
#--------------------------------------------------------------------------
# ● New method: A (Ackermann function)
#--------------------------------------------------------------------------
def self.A(m,n)
text = 'Ackermann: No negative values allowed.' if m < 0 or n < 0
raise(ArgumentError.new(text)) if m < 0 or n < 0
return n + 1 if m == 0
return Math.A(m - 1, 1) if n == 0
return Math.A(m - 1, Math.A(m, n - 1))
end
#--------------------------------------------------------------------------
# ● New method: percent
#--------------------------------------------------------------------------
def self.percent(min,max=100)
(min / max.to_f) * 100.0
end
end
#==============================================================================
# ** Numeric
#------------------------------------------------------------------------------
#
#==============================================================================
class Numeric
#--------------------------------------------------------------------------
# ● Define Secondary Listing: clamp, sign
#--------------------------------------------------------------------------
define_sec_method(:clamp) {|min,max| [[self, min].max, max].min}
define_sec_method(:sign) { zero? ? 0 : (self / self.abs).to_i }
#--------------------------------------------------------------------------
# ● New method: group
#--------------------------------------------------------------------------
unless method_defined?(:group)
def group
self.to_s.gsub(/(\d)(?=\d{3}+(?:\.|$))(\d{3}\..*)?/,'\1,\2')
end
end
end
#==============================================================================
# ** Integer
#------------------------------------------------------------------------------
#
#==============================================================================
class Integer
#--------------------------------------------------------------------------
# ● Define Secondary Listing: sum_to, factorial
#--------------------------------------------------------------------------
define_sec_method(:sum_down) { sum_to(0)}
define_sec_method(:factorial) {(sign * (1..(self.abs)).prod) }
#--------------------------------------------------------------------------
# * New method: sum_to
#--------------------------------------------------------------------------
unless method_defined?(:sum_to)
def sum_to(v = self) (v > self ? (self..v) : (v..self)).sum end
end
end
#==============================================================================
# ** Float
#------------------------------------------------------------------------------
#
#==============================================================================
class Float
#--------------------------------------------------------------------------
# ● Overwriten method: =~
#--------------------------------------------------------------------------
# A close float comparison. Because of rounding errors, this comparison will
# help compensate for that. Since 0 and 0.0001 are very close to each other,
# it's best to use this custom comparison.
define_method(:"=~") {|num| (self + 0.0001 >= num && self - 0.0001 <= num) }
#--------------------------------------------------------------------------
# ● New method: float_points
#--------------------------------------------------------------------------
unless method_defined?(:float_points)
def float_points(points = 2)
n = self * 10 ** points
n = n.round.to_f / (10.0 ** points)
return n
end
end
end
#==============================================================================
# ** Color
#------------------------------------------------------------------------------
#
#==============================================================================
class Color
#--------------------------------------------------------------------------
# ● Define Secondary Listing
#--------------------------------------------------------------------------
define_sec_method(:invert) { set(255-red, 255-green, 255-blue, alpha)}
#----------------------------------------------------------------------------
# * New method: to_hex
#----------------------------------------------------------------------------
def to_hex
str = [self.blue.to_i, self.green.to_i, self.red.to_i].pack("C*")
str.inspect.gsub('\\x','')
end
end
class << Color
#--------------------------------------------------------------------------
# ● Define Secondary Listing: red, green, blue, white, black... etc
#--------------------------------------------------------------------------
define_sec_method(:red) {|*a| self.new(255, 0, 0,a.first||255)}
define_sec_method(:green) {|*a| self.new( 0,255, 0,a.first||255)}
define_sec_method(:blue) {|*a| self.new( 0, 0,255,a.first||255)}
define_sec_method(:white) {|*a| self.new(255,255,255,a.first||255)}
define_sec_method(:purple) {|*a| self.new(128, 0,128,a.first||255)}
define_sec_method(:gray) {|*a| self.new(128,128,128,a.first||255)}
define_sec_method(:lgray) {|*a| self.new(211,211,211,a.first||255)}
define_sec_method(:dgray) {|*a| self.new( 64, 64, 64,a.first||255)}
define_sec_method(:pink) {|*a| self.new(255,175,175,a.first||255)}
define_sec_method(:orange) {|*a| self.new(255,165, 0,a.first||255)}
define_sec_method(:brown) {|*a| self.new(128, 64, 0,a.first||255)}
define_sec_method(:chocolate){|*a| self.new(210,105, 30,a.first||255)}
define_sec_method(:golden) {|*a| self.new(218,165, 32,a.first||255)}
define_sec_method(:silver) {|*a| self.new(192,192,192,a.first||255)}
define_sec_method(:system) {|*a| self.new(192,224,255,a.first||255)}
define_sec_method(:crisis) {|*a| self.new(255,255, 64,a.first||255)}
define_sec_method(:knockout) {|*a| self.new(255, 64, 0,a.first||255)}
#--------------------------------------------------------------------------
# ● Redirect Listing: cyan, magenta, yellow, black, disabled, erase
#--------------------------------------------------------------------------
redirect_method :cyan, '(red(*args).invert )'
redirect_method :magenta, '(green(*args).invert)'
redirect_method :yellow, '(blue(*args).invert )'
redirect_method :black, '(white(*args).invert)'
redirect_method :disabled, '(black(128).invert )'
redirect_method :erase, '(white(0).invert )'
#--------------------------------------------------------------------------
# ● Alias method: grey, light_grey, dark_grey
#--------------------------------------------------------------------------
alias_sec_method :normal, :white
alias_sec_method :grey, :gray
alias_sec_method :lightgrey, :lightgray, :light_grey, :light_gray, :lgray
alias_sec_method :darkgrey, :darkgray, :dark_grey, :dark_gray, :dgray
#--------------------------------------------------------------------------
# ● New method: method_missing
#--------------------------------------------------------------------------
def method_missing(val,*a)
val = "#{val}".gsub(/x/i,'')
if "#{val}".size == 6 && "#{val}".gsub(/(\d+|[a-f])/i,'')
r = "#{val}"[0..1].hex
g = "#{val}"[2..3].hex
b = "#{val}"[4..5].hex
return self.new(r,g,b,a.first||255)
end
text = "Undefined method #{val} for #{self.inspect}"
raise(NoMethodError, text, caller(1))
end
end
#==============================================================================
# ** Viewport
#------------------------------------------------------------------------------
#
#==============================================================================
class Viewport
unless method_defined?(:disposed?)
#--------------------------------------------------------------------------
# ● Alias Listing
#--------------------------------------------------------------------------
alias_sec_method :d3x40932s2, :dispose
#--------------------------------------------------------------------------
# ● New method: disposed?
# help file is lying when says Viewport#disposed? is exist
#--------------------------------------------------------------------------
define_method(:disposed?) { @disposed == true }
#--------------------------------------------------------------------------
# ● Aliased method: dispose
#--------------------------------------------------------------------------
def dispose(*a)
(disposed? || d3x40932s2(*a) || 0) && @disposed = true
end
end
#--------------------------------------------------------------------------
# ● New method: resize
#--------------------------------------------------------------------------
define_sec_method(:resize) do |*a|
self.rect = a.first.is_a?(Rect) ? a.first : Rect.new(*a)
end
#--------------------------------------------------------------------------
# * New method: update_viewport_sizes
#--------------------------------------------------------------------------
define_sec_method(:update_viewport_sizes) do |*a|
map = $game_map
w, h = Graphics.width, Graphics.height
hor = map.respond_to?(:loop_horizontal?) && map.loop_horizontal?
ver = map.respond_to?(:loop_vertical?) && map.loop_vertical?
dx = w > map.width * 32 && !hor ? (w - map.width * 32) / 2 : 0
dw = hor ? w : [w, map.width * 32].min
dy = h > map.height * 32 && !ver ? (h - map.height * 32) / 2 : 0
dh = ver ? h : [h, map.height * 32].min
resize(Rect.new(dx, dy, dw, dh))
end
#--------------------------------------------------------------------------
# ● New method: x, y, width, height
#--------------------------------------------------------------------------
define_sec_method(:x) { self.rect.x }
define_sec_method(:y) { self.rect.y }
define_sec_method(:width) { self.rect.width }
define_sec_method(:height) { self.rect.height }
define_sec_method(:x=) {|x2| resize(x2,y,width,height) }
define_sec_method(:y=) {|y2| resize(x,y2,width,height) }
define_sec_method(:width=) {|w1| resize(x,y,w1,height) }
define_sec_method(:height=) {|h1| resize(x,y,width,h1) }
end
#==============================================================================
# ** Graphics
#------------------------------------------------------------------------------
# This module handles all Graphics
#==============================================================================
class << Graphics
#------------------------------------------------------------------------
# ● Include AutoUpdate
#------------------------------------------------------------------------
include_auto_update
#------------------------------------------------------------------------
# ● Redirect Listing
#------------------------------------------------------------------------
redirect_method :width, 'LiTTleDRAgo.client_size.at(0)'
redirect_method :height, 'LiTTleDRAgo.client_size.at(1)'
redirect_method :snap_to_bitmap, 'LiTTleDRAgo.snap_to_bitmap'
redirect_method :disable_alt_enter, 'LiTTleDRAgo.disable_alt_enter'
redirect_method :always_on_top, 'LiTTleDRAgo.always_on_top'
redirect_method :show_fps, 'LiTTleDRAgo.show_fps'
redirect_method :scale_screen, 'LiTTleDRAgo.scale_screen'
redirect_method :fill_monitor, 'LiTTleDRAgo.fill_monitor'
redirect_method :window, 'LiTTleDRAgo.window'
redirect_method :toggle, 'LiTTleDRAgo.toggle'
redirect_method :fullscreen, 'LiTTleDRAgo.fullscreen'
redirect_method :fullscreen?, 'LiTTleDRAgo.fullscreen?'
redirect_method :control_screen_size,'LiTTleDRAgo.control_screen_size'
redirect_method :high_priority, 'LiTTleDRAgo.high_priority'
redirect_method :high_priority=, 'LiTTleDRAgo.high_priority=args.at(0)'
#------------------------------------------------------------------------
# ● Alias Listing
#------------------------------------------------------------------------
alias_sec_method :resize_screen, :scale_screen
#--------------------------------------------------------------------------
# * New method: fadeoutviewport
#--------------------------------------------------------------------------
def fadeoutviewport
@fadeoutviewport ||= ((v = Viewport.new(0,0,width,height))
(v.color = (v.z = 0x3FFFFFFF) && Color.new(0,0,0,0)) && v)
end
#--------------------------------------------------------------------------
# ● Redefined method: wait, brightness
#--------------------------------------------------------------------------
define_sec_method(:wait) { |frame| frame.times {|i| update } }
define_sec_method(:brightness) { (255 - fadeoutviewport.color.alpha) }
#--------------------------------------------------------------------------
# * Redefined method: brightness= (Set Graphics Brightness)
#--------------------------------------------------------------------------
unless method_defined?(:brightness=)
def brightness=(value)
fadeoutviewport.color.alpha = 255 - value.clamp(0,255)
end
end
#--------------------------------------------------------------------------
# * Redefined method: fadein (Graphics Fade In)
# frame : frame of fade
#--------------------------------------------------------------------------
unless method_defined?(:fadein)
def fadein(frames = 10)
return if frames <= 0
curvalue, count = brightness, (255 - brightness)
frames.times do |i|
(self.brightness = curvalue + (count * i / frames)) && update
end
end
end
#--------------------------------------------------------------------------
# * Redefined method: fadeout (Graphics Fade Out)
# frame : frame of fade
#--------------------------------------------------------------------------
unless method_defined?(:fadeout)
def fadeout(frames = 10)
return if frames <= 0
curvalue = count = self.brightness
frames.times do |i|
(self.brightness = curvalue - (count * i / frames)) && update
end
end
end
#--------------------------------------------------------------------------
# * New method: wait_for_input
#--------------------------------------------------------------------------
unless method_defined?(:wait_for_input)
def wait_for_input
[Input,self].update
[Input,self].update until press_any_key
end
end
end
#==============================================================================
# ** Input
#------------------------------------------------------------------------------
# This module handles all Input
#==============================================================================
class << Input
#------------------------------------------------------------------------
# ● Include AutoUpdate
#------------------------------------------------------------------------
include_auto_update
#--------------------------------------------------------------------------
# ● Aliased method: :press?, :repeat?, :trigger?
#--------------------------------------------------------------------------
[:press?,:repeat?,:trigger?].each do |method|
next unless method_defined?(:"#{method}")
alias_sec_method(:"sym_#{method}", :"#{method}")
define_method(:"#{method}") do |*args|
if (b = args.first).is_a?(Symbol) || b.is_a?(String)
args[0] = Input.const_get("#{b}") rescue nil
end
(args.first.not.nil?) && send(:"sym_#{method}", *args)
end
end
end
#==============================================================================
# ** Sprite_Battler
#------------------------------------------------------------------------------
# This sprite is used to display the battler.It observes the Game_Character
# class and automatically changes sprite conditions.
#==============================================================================
class Sprite_Battler
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
define_pre_alias(:update) { @battler.nil? && @battler_name = nil }
end
#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
# This class brings together map screen sprites, tilemaps, etc.
# It's used within the Scene_Map class.
#==============================================================================
class Spriteset_Map
#--------------------------------------------------------------------------
# ● New method: sprite_player
#--------------------------------------------------------------------------
define_sec_method(:sprite_player) { find_character($game_player) }
#------------------------------------------------------------------------
# ● Public Instance Variables
#------------------------------------------------------------------------
attr_sec_reader :character_sprites, 'Array.new'
attr_reader :viewport1, :viewport2, :viewport3
#--------------------------------------------------------------------------
# * Aliased method: update
#--------------------------------------------------------------------------
define_pre_alias(:update) { update_viewport_size_change }
#--------------------------------------------------------------------------
# * New method: update_viewport_size_change
#--------------------------------------------------------------------------
def update_viewport_size_change
if viewport_size_change?
@viewport_map_width = $game_map.width
@viewport_map_height = $game_map.height
@viewport_screen_width = Graphics.width
@viewport_screen_height = Graphics.height
[@viewport1,@viewport2,@viewport3].compact.update_viewport_sizes
end
end
#--------------------------------------------------------------------------
# * New method: viewport_size_change?
#--------------------------------------------------------------------------
unless method_defined?(:viewport_size_change?)
def viewport_size_change?
return true if @viewport_map_width != $game_map.width
return true if @viewport_map_height != $game_map.height
return true if @viewport_screen_width != Graphics.width
return true if @viewport_screen_height != Graphics.height
end
end
#--------------------------------------------------------------------------
# ● New method: redraw_character_sprites
#--------------------------------------------------------------------------
unless method_defined?(:redraw_character_sprites)
def redraw_character_sprites
return refresh_characters if self.respond_to?(:refresh_characters)
character_sprites.dispose
@character_sprites = $game_map.events.keys.sort.map {|i|
Sprite_Character.new(@viewport1, $game_map.events[i]) }
@character_sprites.push(Sprite_Character.new(@viewport1, $game_player))
end
end
#--------------------------------------------------------------------------
# ● New method: find_character
#--------------------------------------------------------------------------
unless method_defined?(:find_character)
def find_character(char)
character_sprites.detect { |s| s.character == char }
end
end
#---------------------------------------------------------------------------
# * New method: viewport_sprite
#---------------------------------------------------------------------------
def viewport_sprite(*v)
v.collect! {|s| s.is_a?(Symbol) ? instance_variable_get(:"@#{s}") : s }
v.reject! {|s| s.not.is_a?(Viewport)}
all = instance_variables.map {|s| instance_variable_get("#{s}")}.flatten
all.select {|s| s.respond_to?(:viewport) && v.include?(s.viewport)}
end
end
#==============================================================================
# ** Game_Battler
#------------------------------------------------------------------------------
# This class deals with battlers. It's used as a superclass for the Game_Actor
# and Game_Enemy classes.
#==============================================================================
class Game_Battler
#--------------------------------------------------------------------------
# ● New method: alive?
#--------------------------------------------------------------------------
define_sec_method(:alive?) { self.not.dead? }
#--------------------------------------------------------------------------
# ● New method: hp_percent
#--------------------------------------------------------------------------
unless method_defined?(:hp_percent)
def hp_percent(integer = false, float_points = 2)
n = Math.percent(hp,(respond_to?(:mhp) ? mhp : maxhp))
return integer ? Integer(n) : n.float_points(float_points)
end
end
#--------------------------------------------------------------------------
# ● New method: sp_percent
#--------------------------------------------------------------------------
unless method_defined?(:sp_percent)
def sp_percent(integer = false, float_points = 2)
n = Math.percent((respond_to?(:sp) ? sp : mp),
((respond_to?(:mmp) ? mmp : (respond_to?(:maxsp) ? maxsp : maxmp))))
return integer ? Integer(n) : n.float_points(float_points)
end
alias_method :mp_percent, :sp_percent
end
end
#==============================================================================
# ** Game_Character
#------------------------------------------------------------------------------
# This class deals with characters. It's used as a superclass for the
# Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# ● Redirect Listing
#--------------------------------------------------------------------------
redirect_method :move_down, 'move_straight(2,*args)'
redirect_method :move_left, 'move_straight(4,*args)'
redirect_method :move_right, 'move_straight(6,*args)'
redirect_method :move_up, 'move_straight(8,*args)'
redirect_method :turn_down, 'set_direction(2,*args)'
redirect_method :turn_left, 'set_direction(4,*args)'
redirect_method :turn_right, 'set_direction(6,*args)'
redirect_method :turn_up, 'set_direction(8,*args)'
redirect_method :move_lower_left, 'move_diagonal(4, 2,*args)'
redirect_method :move_lower_right, 'move_diagonal(6, 2,*args)'
redirect_method :move_upper_left, 'move_diagonal(4, 8,*args)'
redirect_method :move_upper_right, 'move_diagonal(6, 8,*args)'
redirect_method :character_sprite, '$game_map.character_sprite(self)'
redirect_method :character_above?, '(args.first.y > @y)'
redirect_method :character_below?, '(args.first.y < @y)'
redirect_method :character_right?, '(args.first.x < @x)'
redirect_method :character_left?, '(args.first.x > @x)'
redirect_method :pos, '[@x, @y]'
redirect_method :pos_nt?, '!@through && pos?'
redirect_method :normal_priority?, '@character_name != ""'
redirect_method :map_passable?, '$game_map.passable?'
redirect_method :map_terrain_tag, '$game_map.terrain_tag'
#--------------------------------------------------------------------------
# * Redefined method: pos?
# anime
# reverse_dir
#--------------------------------------------------------------------------
define_sec_method(:reverse_dir) {|dir| 10 - dir }
define_sec_method(:pos?) {|x,y| @x == x && @y == y }
define_sec_method(:anime) {|aid| @animation_id = aid }
#--------------------------------------------------------------------------
# ● Redefined method: check_event_trigger_touch_front
#--------------------------------------------------------------------------
unless method_defined?(:check_event_trigger_touch_front)
def check_event_trigger_touch_front
x2 = $game_map.round_x_with_direction(@x, @direction)
y2 = $game_map.round_y_with_direction(@y, @direction)
check_event_trigger_touch(x2, y2)
end
end
#--------------------------------------------------------------------------
# ● Redefined method: move_straight
#--------------------------------------------------------------------------
unless method_defined?(:move_straight)
def move_straight(d, turn_ok = true)
if passable?(@x, @y, d)
set_direction(d)
@x = $game_map.round_x_with_direction(@x, d)
@y = $game_map.round_y_with_direction(@y, d)
increase_steps
elsif turn_ok
set_direction(d)
check_event_trigger_touch_front
end
end
end
#--------------------------------------------------------------------------
# ● Redefined method: set_direction
#--------------------------------------------------------------------------
unless method_defined?(:set_direction)
def set_direction(d)
@direction = d unless @direction_fix || d == 0
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# ● Redefined method: set_graphic
#--------------------------------------------------------------------------
unless method_defined?(:set_graphic)
def set_graphic(character_name, character_index = 0)
@tile_id = 0
@character_name = character_name
if self.respond_to?(:character_index)
@character_index = character_index
else
@character_hue = character_index
end
@original_pattern = 1
end
end
#--------------------------------------------------------------------------
# ● Redefined method: swap
#--------------------------------------------------------------------------
unless method_defined?(:swap)
def swap(character)
new_pos = character.pos
character.moveto(x, y)
moveto(*new_pos)
end
end
#--------------------------------------------------------------------------
# ● Redefined method: rotate_swap_prev
#--------------------------------------------------------------------------
unless method_defined?(:rotate_swap_prev)
def rotate_swap_prev(*character)
character.unshift(self)
position = character.collect {|c| c.pos}
character.each_with_index { |c,i| c.moveto(*position[i-1]) }
end
end
#--------------------------------------------------------------------------
# ● Redefined method: rotate_swap_next
#--------------------------------------------------------------------------
unless method_defined?(:rotate_swap_next)
def rotate_swap_next(*character)
character.unshift(self)
position = character.collect {|c| c.pos}
character.each_with_index do |char,index|
char.moveto(*position[index + 1 >= position.size ? 0 : index + 1])
end
end
end
#--------------------------------------------------------------------------
# ● New method: distance_from
#--------------------------------------------------------------------------
unless method_defined?(:distance_from)
def distance_from(character,type= 'xy')
character = $game_map.events[character] if character.is_a?(Integer)
return 0 if character.nil?
return (@x - character.x).abs if type.to_s == 'x'
return (@y - character.y).abs if type.to_s == 'y'
return Math.hypot(@x - character.x, @y - character.y)
end
end
#--------------------------------------------------------------------------
# * Redefined method: distance_x_from
#--------------------------------------------------------------------------
unless method_defined?(:distance_x_from)
def distance_x_from(x)
result = @x - x
if result.abs > $game_map.width / 2
result += result < 0 ? $game_map.width : -$game_map.width
end
result
end
end
#--------------------------------------------------------------------------
# * Redefined method: distance_y_from
#--------------------------------------------------------------------------
unless method_defined?(:distance_y_from)
def distance_y_from(y)
result = @y - y
if result.abs > $game_map.height / 2
result += result < 0 ? $game_map.height : -$game_map.height
end
result
end
end
#--------------------------------------------------------------------------
# ● New method: random_teleport
#--------------------------------------------------------------------------
unless method_defined?(:random_teleport)
def random_teleport
1000.times do
moveto(rand($game_map.height), rand($game_map.width))
vx = LiTTleDRAgo::VX && !LiTTleDRAgo::VXA
arg = vx ? [@x,@y] : [@x,@y,@direction]
break if passable?(*arg)
end || true
end
end
#--------------------------------------------------------------------------
# * Redefined method: diagonal_passable? (for RMXP)
# horz : Horizontal (4 or 6)
# vert : Vertical (2 or 8)
#--------------------------------------------------------------------------
unless method_defined?(:diagonal_passable?)
def diagonal_passable?(x, y, horz, vert)
x2 = $game_map.round_x_with_direction(x, horz)
y2 = $game_map.round_y_with_direction(y, vert)
(passable?(x, y, vert) && passable?(x, y2, horz)) ||
(passable?(x, y, horz) && passable?(x2, y, vert))
end
end
#--------------------------------------------------------------------------
# * Redefined method: collide_with_characters? (for RMXP)
#--------------------------------------------------------------------------
unless method_defined?(:collide_with_characters?)
def collide_with_characters?(x, y)
collide_with_events?(x, y)
end
end
#--------------------------------------------------------------------------
# * Redefined method: collide_with_events? (for RMXP)
#--------------------------------------------------------------------------
unless method_defined?(:collide_with_events?)
def collide_with_events?(x, y)
$game_map.events_xy_nt(x, y).any? do |event|
event.normal_priority? || self.is_a?(Game_Event)
end
end
end
#--------------------------------------------------------------------------
# * Redefined method: debug_through?
#--------------------------------------------------------------------------
unless method_defined?(:debug_through?)
def debug_through?
debug = LiTTleDRAgo::VX ? $TEST : $DEBUG
return debug && Input.press?(Input::CTRL) if self.is_a?(Game_Player)
return false
end
end
end
#==============================================================================
# ** Game_Actor
#------------------------------------------------------------------------------
# This class handles actors. It is used within the Game_Actors class
# ($game_actors), also referenced from the Game_Party class ($game_party).
#==============================================================================
class Game_Actor
#--------------------------------------------------------------------------
# * Get Actor Object
#--------------------------------------------------------------------------
define_sec_method(:actor) { $data_actors[@actor_id] }
define_method(:class) { $data_classes[@class_id] }
end
#==============================================================================
# ** Game_Enemy
#------------------------------------------------------------------------------
# This class handles enemies. It used within the Game_Troop class
# ($game_troop).
#==============================================================================
class Game_Enemy
#--------------------------------------------------------------------------
# * Get Enemy Object
#--------------------------------------------------------------------------
define_sec_method(:enemy) { $data_enemies[@enemy_id] }
end
#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
# This class handles the player. It includes event starting determinants and
# map scrolling functions. The instance of this class is referenced by
# $game_player.
#==============================================================================
class Game_Player
#--------------------------------------------------------------------------
# ● Redefined method: actor
# name
#--------------------------------------------------------------------------
define_sec_method(:actor) { $game_party.leader }
define_sec_method(:name) { actor.name }
#--------------------------------------------------------------------------
# ● New method: method_missing
#--------------------------------------------------------------------------
def method_missing(val,*a,&b)
return actor.send(val.to_s,*a,&b) if actor.respond_to?(val.to_sym)
text = "Undefined method #{val} for #{self.inspect}"
raise(NoMethodError, text, caller(1))
end
end
#==============================================================================
# ** Game_Event
#------------------------------------------------------------------------------
# This class deals with events. It handles functions including event page
# switching via condition determinants, and running parallel process events.
# It's used within the Game_Map class.
#==============================================================================
class Game_Event < Game_Character
#--------------------------------------------------------------------------
# ● Public Instance Variables
#--------------------------------------------------------------------------
method_defined?(:erased) || (attr_reader :erased)
method_defined?(:id) || (attr_reader :id)
method_defined?(:event) || (attr_reader :event)
attr_accessor :loaded_event
#--------------------------------------------------------------------------
# ● New method: name
# ● New method: restore
#--------------------------------------------------------------------------
define_sec_method(:name) { @event.name }
define_sec_method(:restore) { (@erased = false) || refresh }
#--------------------------------------------------------------------------
# ● New method: destroy
#--------------------------------------------------------------------------
unless method_defined?(:destroy)
def destroy
event = $game_map.events.delete(@id)
if (s = $game_map.spriteset).is_a?(Spriteset_Map)
after = s.character_sprites.select { |e| e if e.character != event }
(delet = character_sprite) && delet.dispose
s.character_sprites.replace(after)
end
end
end
#--------------------------------------------------------------------------
# ● New method: eliminate
#--------------------------------------------------------------------------
unless method_defined?(:eliminate)
def eliminate
return destroy if self.loaded_event
(eliminate = $game_map.eliminate_event)[(id = $game_map.map_id)] ||= []
(eliminate[id].include?(@id) || eliminate[id].push(@id)) && destroy
end
end
#--------------------------------------------------------------------------
# ● New method: note
#--------------------------------------------------------------------------
unless method_defined?(:note)
def note
list = @page ? @page.list.select {|l| [108,408].include?(l.code)} : []
notes = list.collect {|l| l.parameters[0] }.join("\n")
return notes
end
end
#--------------------------------------------------------------------------
# ● New method: proper_page_index
#--------------------------------------------------------------------------
unless method_defined?(:proper_page_index)
def proper_page_index
if respond_to?(:conditions_met?)
page = respond_to?(:find_proper_page) ? find_proper_page :
@event.pages.reverse.find {|page| conditions_met?(page)}
(i = @event.pages.index(page)).is_a?(Integer) ? i + 1 : 0
end
end
end
end
#==============================================================================
# ** Game_Party
#------------------------------------------------------------------------------
# This class handles the party. It includes information on amount of gold
# and items. Refer to "$game_party" for the instance of this class.
#==============================================================================
class Game_Party
#--------------------------------------------------------------------------
# ● Alias Listing
#--------------------------------------------------------------------------
alias_sec_method :drg_ce_item_number, :item_number
#--------------------------------------------------------------------------
# ● Redirect Listing
#--------------------------------------------------------------------------
redirect_method :player_pos, '($game_player.pos)'
redirect_method :leader, '(members.first)'
redirect_method :members, '(actors)'
redirect_method :actors, '(members)'
#--------------------------------------------------------------------------
# ● New method: existing_actors, recover_all
#--------------------------------------------------------------------------
define_sec_method(:existing_actors) { members.find_all {|a| a.exist?} }
define_sec_method(:recover_all) { members.each {|a| a.recover_all} }
#--------------------------------------------------------------------------
# ● New method: has_actors?
#--------------------------------------------------------------------------
unless method_defined?(:has_actors?)
def has_actors?(*actors)
party = @actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s }
actor = actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s }.flatten
return party.have_all?(*actor)
end
end
#--------------------------------------------------------------------------
# ● New method: has_any_actors?
#--------------------------------------------------------------------------
unless method_defined?(:has_any_actors?)
def has_any_actors?(*actors)
party = @actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s }
actor = actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s }.flatten
return party.have_any?(*actor)
end
end
#--------------------------------------------------------------------------
# ● New method: swap_previous_actor
#--------------------------------------------------------------------------
unless method_defined?(:swap_leader_prev)
def swap_leader_prev(n = 1)
n <= 0 || n.round.times { @actors.previous_item && drg_ce_refresh }
n >= 0 || swap_leader_next(n.round.abs)
end
end
#--------------------------------------------------------------------------
# ● New method: swap_next_actor
#--------------------------------------------------------------------------
unless method_defined?(:swap_leader_next)
def swap_leader_next(n = 1)
n <= 0 || n.round.times { @actors.next_item && drg_ce_refresh }
n >= 0 || swap_leader_prev(n.round.abs)
end
end
#--------------------------------------------------------------------------
# ● New method: set_leader
#--------------------------------------------------------------------------
unless method_defined?(:set_leader)
def set_leader(id)
actor = id.is_a?(Numeric) ? $game_actors[id.to_i] : id
if actor.is_a?(Game_Actor) && has_actors?(actor.id)
swap_leader_next until $game_party.leader.id == actor.id
actor.id
end
end
end
#--------------------------------------------------------------------------
# ● New method: drg_ce_refresh
#--------------------------------------------------------------------------
unless method_defined?(:drg_ce_refresh)
def drg_ce_refresh
return refresh if respond_to?(:refresh)
return ($game_map.need_refresh = true) && $game_player.refresh
end
end
#--------------------------------------------------------------------------
# * Get Party Name
#--------------------------------------------------------------------------
unless method_defined?(:name)
def name
return "" if existing_actors.size == 0
return leader.name if existing_actors.size == 1
return "#{leader.name}'s Party"
end
end
#--------------------------------------------------------------------------
# * Aliased method: item_number
#--------------------------------------------------------------------------
def item_number(item)
unless LiTTleDRAgo::VX
return drg_ce_item_number(item.id) if item.is_a?(RPG::Item)
return weapon_number(item.id) if item.is_a?(RPG::Weapon)
return armor_number(item.id) if item.is_a?(RPG::Armor)
else
item = $data_items[item.to_i] if item.is_a?(Numeric)
end
return skill_number(item) if item.is_a?(RPG::Skill)
return drg_ce_item_number(item)
end
#--------------------------------------------------------------------------
# * Redefined method: weapon_number
#--------------------------------------------------------------------------
unless method_defined?(:weapon_number)
def weapon_number(weapon)
weapon = $data_weapons[weapon.to_i] if weapon.is_a?(Numeric)
item_number(weapon)
end
end
#--------------------------------------------------------------------------
# * Redefined method: armor_number
#--------------------------------------------------------------------------
unless method_defined?(:armor_number)
def armor_number(armor)
armor = $data_armors[armor.to_i] if armor.is_a?(Numeric)
item_number(armor)
end
end
#--------------------------------------------------------------------------
# * New method: skill_number
#--------------------------------------------------------------------------
unless method_defined?(:skill_number)
def skill_number(skill)
skill = $data_skills[skill.to_i] if skill.is_a?(Numeric)
s1 = actors.select {|a| a.skill_learn?(skill) }
s2 = actors.select {|a| a.skill_learn?(skill.id) }
return s1.size + s2.size
end
end
#--------------------------------------------------------------------------
# * New method: gain_all_items
#--------------------------------------------------------------------------
def gain_all_items(ammount=1)
(0..999).to_a.each do |s|
next if $data_items[s].nil? || $data_items[s].name == ''
$game_party.drg_ce_get_item($data_items[s],ammount)
end
end
#--------------------------------------------------------------------------
# * New method: gain_all_weapons
#--------------------------------------------------------------------------
def gain_all_weapons(ammount=1)
(0..999).to_a.each do |s|
next if $data_weapons[s].nil? || $data_weapons[s].name == ''
drg_ce_get_item($data_weapons[s],ammount)
end
end
#--------------------------------------------------------------------------
# * New method: gain_all_armors
#--------------------------------------------------------------------------
def gain_all_armors(ammount=1)
(0..999).to_a.each do |s|
next if $data_armors[s].nil? || $data_armors[s].name == ''
drg_ce_get_item($data_armors[s],ammount)
end
end
#--------------------------------------------------------------------------
# * New method: drg_ce_get_item
#--------------------------------------------------------------------------
def drg_ce_get_item(item,ammount)
return gain_item(item,ammount) if LiTTleDRAgo::VX
return gain_item(item.id,ammount) if item.is_a?(RPG::Item)
return gain_weapon(item.id,ammount) if item.is_a?(RPG::Weapon)
return gain_armor(item.id,ammount) if item.is_a?(RPG::Armor)
end
end
#==============================================================================
# ** Game_Follower
#------------------------------------------------------------------------------
# This class handles followers. A follower is an allied character, other than
# the front character, displayed in the party. It is referenced within the
# Game_Followers class.
#==============================================================================
class Game_Follower < Game_Character
#--------------------------------------------------------------------------
# * Redirect Listing
#--------------------------------------------------------------------------
redirect_method :name, "(actor.nil? ? '' : actor.name)"
end if defined?(Game_Follower)
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
# This class handles maps. It includes scrolling and passage determination
# functions. The instance of this class is referenced by $game_map.
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_sec_reader :eliminate_event, 'Hash.new'
#--------------------------------------------------------------------------
# ● New method: name, parent_id, base_parent_id
# event_list , map_events
#--------------------------------------------------------------------------
define_sec_method(:name) { mapInfo[@map_id].name }
define_sec_method(:parent_id) { mapInfo[@map_id].parent_id }
define_sec_method(:base_parent_id) { search_parent_id(mapInfo) }
define_sec_method(:event_list) { events.values }
define_sec_method(:map_events) { @map.events }
define_sec_method(:screen) { $game_screen }
define_sec_method(:loop_horizontal?) { false }
define_sec_method(:loop_vertical?) { false }
define_sec_method(:map_child?) { |*a| a & child_ids == a }
#--------------------------------------------------------------------------
# * Aliased method: setup
#--------------------------------------------------------------------------
define_post_alias(:setup) do
eliminate_event[@map_id] ||= []
eliminate_event[@map_id].each { |s| events.delete(s) }
end
#--------------------------------------------------------------------------
# * Redefined method: any_event_strarting? (for RMXP)
#--------------------------------------------------------------------------
unless method_defined?(:any_event_starting?)
def any_event_starting?
event_list.any? {|event| event.starting }
end
end
#--------------------------------------------------------------------------
# * Redefined method: interpreter (for RMXP)
#--------------------------------------------------------------------------
unless method_defined?(:interpreter)
def interpreter
return $game_system.map_interpreter if LiTTleDRAgo.scene.is_a?(Scene_Map)
return $game_system.battle_interpreter
end
end
#--------------------------------------------------------------------------
# * Redefined method: events_xy (for RMXP)
#--------------------------------------------------------------------------
unless method_defined?(:events_xy)
def events_xy(x, y)
event_list.select {|event| event.x == x && event.y == y }
end
end
#--------------------------------------------------------------------------
# * Redefined method: events_xy_nt (for RMXP)
#--------------------------------------------------------------------------
unless method_defined?(:events_xy_nt)
def events_xy_nt(x, y)
event_list.select {|event| event.pos_nt?(x, y) }
end
end
#--------------------------------------------------------------------------
# * Redefined method: round_x, round_y (for RMXP)
#--------------------------------------------------------------------------
define_sec_method(:round_x) {|x| loop_horizontal? ? (x + width) % width : x }
define_sec_method(:round_y) {|y| loop_vertical? ? (y + height) % height : y }
#--------------------------------------------------------------------------
# * Redefined method: x_with_direction (for RMXP)
#--------------------------------------------------------------------------
define_sec_method(:x_with_direction) {|x, d| x + (d==6 ? 1 : d==4 ? -1 : 0)}
define_sec_method(:y_with_direction) {|y, d| y + (d==2 ? 1 : d==8 ? -1 : 0)}
#--------------------------------------------------------------------------
# * Redefined method: round_x_with_direction (for RMXP)
#--------------------------------------------------------------------------
unless method_defined?(:round_x_with_direction)
def round_x_with_direction(x, d)
round_x(x_with_direction(x, d))
end
end
#--------------------------------------------------------------------------
# * Redefined method: round_y_with_direction (for RMXP)
#--------------------------------------------------------------------------
unless method_defined?(:round_y_with_direction)
def round_y_with_direction(y, d)
round_y(y_with_direction(y, d))
end
end
#--------------------------------------------------------------------------
# * New method: x_diagonal_with_direction (for RMXP)
#--------------------------------------------------------------------------
unless method_defined?(:x_diagonal_with_direction)
def x_diagonal_with_direction(x, d)
x + ([9,6,3].include?(d) ? 1 : [7,4,1].include?(d) ? -1 : 0)
end
end
#--------------------------------------------------------------------------
# * New method: y_with_direction (for RMXP)
#--------------------------------------------------------------------------
unless method_defined?(:y_diagonal_with_direction)
def y_diagonal_with_direction(y, d)
y + ([1,2,3].include?(d) ? 1 : [7,8,9].include?(d) ? -1 : 0)
end
end
#--------------------------------------------------------------------------
# ● New method: existing_events
#--------------------------------------------------------------------------
unless method_defined?(:existing_events)
def existing_events
event_list.select {|e| e.not.erased }
end
end
#--------------------------------------------------------------------------
# ● New method: map_info
#--------------------------------------------------------------------------
unless method_defined?(:mapInfo)
def mapInfo(ext = LiTTleDRAgo.data_default_extension)
data = "Data/MapInfos.#{ext}"
@mapinfo ||= load_data(sprintf("#{data}")) rescue draise(
"Fail to load #{data}")
return @mapinfo
end
end
#--------------------------------------------------------------------------
# ● New method: search_parent_id
#--------------------------------------------------------------------------
unless method_defined?(:search_parent_id)
def search_parent_id(mapInfo, id = @map_id, ancestor = 0)
m_id = id
loop do
_m_id = mapInfo[m_id]
p_id = _m_id.respond_to?(:parent_id) ? _m_id.parent_id : nil
return p_id if p_id == nil
return m_id if p_id == ancestor
m_id = p_id
end
end
end
#--------------------------------------------------------------------------
# ● New method: base_map_name
#--------------------------------------------------------------------------
unless method_defined?(:base_map_name)
def base_map_name
map = mapInfo[search_parent_id(mapInfo)]
name = map.respond_to?(:name) ? map.name : ''
return name
end
end
#--------------------------------------------------------------------------
# ● New method: child_ids
#--------------------------------------------------------------------------
unless method_defined?(:child_ids)
def child_ids
mapInfo.keys.select {|map_id| mapInfo[map_id].parent_id == @map_id }
end
end
#--------------------------------------------------------------------------
# ● New method: descendant?
#--------------------------------------------------------------------------
unless method_defined?(:map_descendant?)
def map_descendant?(*a)
a.all? {|map_id| search_parent_id(mapInfo, map_id, @map_id)}
end
end
#--------------------------------------------------------------------------
# ● New method: load_event
#--------------------------------------------------------------------------
unless method_defined?(:load_event)
def load_event(*a)
case a.size
when 5, 4 then (mapid, eventid, x, y = *a)
when 3 then (mapid = @map_id) && (eventid, x, y = *a)
when 2 then (mapid, y = @map_id, 0) && (eventid, x = *a)
when 1 then (mapid, x, y = @map_id, 0,0) && (eventid = a.first)
when 0 then return nil
end
map = load_map_data(mapid)
event = map.events.values.detect { |event| event.id == eventid }
unless event.nil?
(a = a.at(4)) && (b = [a].flatten) && event.pages.reject! do |s|
c = b.map {|i| i.is_a?(Range) ? i.to_a : i }
c.flatten.not.include?(event.pages.index(s)+1)
end
return nil if event.pages.empty?
c,r = [Array,Range], []
c.include?(x.class) && (x = x.to_a.map{|s|s.is_a?(Range) ? s.to_a : s})
c.include?(y.class) && (y = y.to_a.map{|s|s.is_a?(Range) ? s.to_a : s})
[x].flatten.dproduct([y].flatten).each do |x1,y1|
event.instance_variable_set(:@id,(id = next_key_events))
r.push(@events[id] = e = Game_Event.new(@map_id, event.clone))
e.loaded_event = true
e.moveto(x1,y1)
end
a = r.size == 1 ? r.first : r
if r && (s = spriteset).is_a?(Spriteset_Map)
sc = s.character_sprites
after = sc.select { |e| e if e.character != $game_player }
player = s.sprite_player
sc.replace(after)
r.each {|e| sc.push(Sprite_Character.new(s.viewport1, e)) }
sc.push(player)
end
return a
end
end
end
#--------------------------------------------------------------------------
# ● New method: call_event
#--------------------------------------------------------------------------
unless method_defined?(:call_event)
def call_event(*a)
case a.size
when 3 then (mapid, eventid, page_id = *a)
when 2 then (page_id = -1) && (mapid, eventid = *a)
when 1 then (mapid, page_id = @map_id, -1) && (eventid = a.first)
when 0 then return nil
end
map = load_map_data(mapid)
event = map.events.values.detect { |event| event.id == eventid }
unless event.nil?
if page_id == -1 && event.respond_to?(:conditions_met?)
pages = event.pages.reverse.find {|page| event.conditions_met?(page)}
else
pages = event.pages[[page_id,1].max-1]
end
klass = LiTTleDRAgo::VX ? Game_Interpreter : Interpreter
child = klass.new(interpreter.instance_variable_get(:@depth) + 1)
child.setup(pages.list, interpreter.same_map? ? event.id : 0)
if LiTTleDRAgo::VXA
child.run rescue FiberError
else
interpreter.instance_variable_set(:@child_interpreter, child)
end
end
end
end
#--------------------------------------------------------------------------
# ● New method: load_map_data
#--------------------------------------------------------------------------
unless method_defined?(:load_map_data)
def load_map_data(mapid, ext = LiTTleDRAgo.data_default_extension)
(map = sprintf("Data/Map%03d.#{ext}", mapid)) && load_data(map)
end
end
#--------------------------------------------------------------------------
# ● New method: increment_key_events
#--------------------------------------------------------------------------
unless method_defined?(:next_key_events)
def next_key_events
(@events.keys.max || 0) + 1
end
end
#--------------------------------------------------------------------------
# ● New method: unused_key_events
#--------------------------------------------------------------------------
unless method_defined?(:unused_key_events)
def unused_key_events(start = 1)
start = [start, next_key_events].min
(start..next_key_events).detect {|i| @events.keys.not.include?(i)}
end
end
#--------------------------------------------------------------------------
# ● New method: spriteset
#--------------------------------------------------------------------------
unless method_defined?(:spriteset)
def spriteset
LiTTleDRAgo.scene.instance_variable_get(:@spriteset)
end
end
#--------------------------------------------------------------------------
# ● New method: character_sprite
#--------------------------------------------------------------------------
unless method_defined?(:character_sprite)
def character_sprite(id = 0)
return unless spriteset.is_a?(Spriteset_Map)
id = id.is_a?(Game_Character) ? id : id == 0 ? $game_player : events[id]
spriteset.find_character(id)
end
end
#--------------------------------------------------------------------------
# ● New method: picture_sprite
#--------------------------------------------------------------------------
unless method_defined?(:picture_sprite)
def picture_sprite(id = nil)
return unless spriteset.is_a?(Spriteset_Map)
spriteset.update_pictures if spriteset.respond_to?(:update_pictures)
result = spriteset.instance_variable_get(:@picture_sprites)
id.nil? ? result : result[id]
end
end
end
#==============================================================================
# ■ RPG::Cache
#------------------------------------------------------------------------------
#
#==============================================================================
ModCache = LiTTleDRAgo.cache
class << ModCache
#-----------------------------------------------------------------------
# ● New method: self.draw_text
#-----------------------------------------------------------------------
unless method_defined?(:draw_text)
def draw_text(
width, height, text,
font = Font.default_name,
size = Font.default_size,
bold = Font.default_bold,
italic = Font.default_italic,
color = Font.default_color,
edging = false
)
cache_index = "text_" + width.to_s + height.to_s + text
font_text = ""
font.size.times do |i|
font_text += font[i].to_s
end
cache_index += font_text + size.to_s + bold.to_s + italic.to_s
cache_index += "#{color.red}#{color.blue}#{color.green}#{color.alpha}"
@cache ||= {}
if @cache[cache_index].nil? or @cache[cache_index].disposed?
bitmap = Bitmap.new(width, height)
bitmap.font.name = font
bitmap.font.size = size
bitmap.font.bold = bold
bitmap.font.italic = italic
bitmap.font.color = color
if edging
bitmap.draw_edging_text(0, 0, width, height, text, 0)
else
bitmap.draw_text(0, 0, width, height, text, 0)
end
@cache[cache_index] = bitmap
end
return @cache[cache_index]
end
end
#-----------------------------------------------------------------------
# ● New method: self.method_missing
#-----------------------------------------------------------------------
def method_missing(val,*a,&b)
if a.at(0).is_a?(String) && a.size <= 2
return load_bitmap("Graphics/#{val}/",*a,&b)
end
modified = [:invert,:brighten,:darken,:grayscale,:pixelate,:frost]
if modified.include?(a.first) && a.at(1).is_a?(String) && a.size <= 3
method = a.shift
filename = a.join + "-#{method}"
unless drago_bitmap_exist?("Graphics/#{val}",filename)
bitmap = load_bitmap("Graphics/#{val}/",*a,&b)
drago_set_bitmap(bitmap.send(method),"Graphics/#{val}",filename)
end
return drago_get_bitmap("Graphics/#{val}",filename)
end
text = "Undefined method #{val} for #{self.inspect}"
raise(NoMethodError, text, caller(1))
end
#-----------------------------------------------------------------------
# ● New method: drago_get_bitmap
#-----------------------------------------------------------------------
def drago_get_bitmap(folder_name, filename = '', hue = 0)
return empty_bitmap if filename.not.is_a?(String) || filename.empty?
path = LiTTleDRAgo::APPPATHDRAGO + "#{folder_name}/"
path = path.gsub("\\","/").gsub("//","/")
last = filename.split('.').last
filename.gsub!(".png","") if last.is_a?(String) && last[/png/i]
load_bitmap_no_rescue(path.downcase,filename.downcase,hue)
end
#-----------------------------------------------------------------------
# ● New method: drago_set_bitmap
#-----------------------------------------------------------------------
def drago_set_bitmap(bitmap, folder_name = '', filename = 'bitmap')
path = LiTTleDRAgo::APPPATHDRAGO + "#{folder_name}/"
path = path.gsub("\\","/").gsub("//","/")
last = filename.split('.').last
filename += '.png' unless last.is_a?(String) && last[/png/i]
Dir.make_dir(path) unless FileTest.directory?(path)
bitmap.export(path + filename)
drago_get_bitmap(folder_name, filename)
end
#-----------------------------------------------------------------------
# ● New method: drago_bitmap_exist?
#-----------------------------------------------------------------------
def drago_bitmap_exist?(folder_name, filename)
return false if filename.not.is_a?(String) || filename.empty?
path = LiTTleDRAgo::APPPATHDRAGO + "#{folder_name}/"
path = path.gsub("\\","/").gsub("//","/")
last = filename.split('.').last
filename += '.png' unless last.is_a?(String) && last[/png/i]
FileTest.file?(path + filename)
end
#--------------------------------------------------------------------------
# * Load Bitmap
#--------------------------------------------------------------------------
define_sec_method(:load_bitmap_no_rescue) do |folder, file, *a|
@cache ||= {}
if file.empty?
empty_bitmap
elsif (hue = a.first).is_a?(Numeric) && hue != 0
hue_changed_bitmap(folder + file, hue.round)
else
normal_bitmap(folder + file)
end
end
#--------------------------------------------------------------------------
# * Create Empty Bitmap
#--------------------------------------------------------------------------
define_sec_method(:empty_bitmap) { Bitmap.new(32, 32)}
#--------------------------------------------------------------------------
# * Create/Get Normal Bitmap
#--------------------------------------------------------------------------
define_sec_method(:normal_bitmap) do |path|
@cache[path] = Bitmap.new(path) unless include?(path)
@cache[path]
end
#--------------------------------------------------------------------------
# * Create/Get Hue-Changed Bitmap
#--------------------------------------------------------------------------
define_sec_method(:hue_changed_bitmap) do |path, hue|
key = [path, hue]
unless include?(key)
@cache[key] = normal_bitmap(path).clone
@cache[key].hue_change(hue)
end
@cache[key]
end
#--------------------------------------------------------------------------
# * Check Cache Existence
#--------------------------------------------------------------------------
def include?(key)
@cache[key] && @cache[key].not.disposed?
end
end
#==============================================================================
# ** Window_Base
#------------------------------------------------------------------------------
# This class is for all in-game windows.
#==============================================================================
class Window_Base < Window
#--------------------------------------------------------------------------
# * Redirect Listing
#--------------------------------------------------------------------------
redirect_method :draw_text, 'contents.draw_text'
redirect_method :text_size, 'contents.text_size'
redirect_method :change_color, 'contents.change_color'
redirect_method :draw_picture, 'contents.draw_picture'
redirect_method :draw_icon, 'contents.draw_icon'
redirect_method :draw_battler, 'contents.draw_battler'
#--------------------------------------------------------------------------
# * Redefined method: line_height, translucent_alpha
# * New method: show, hide, activate, deactivate
#--------------------------------------------------------------------------
define_sec_method(:line_height) { 32 }
define_sec_method(:translucent_alpha) { 160 }
define_sec_method(:show) { self.visible = true }
define_sec_method(:hide) { self.visible = false }
define_sec_method(:activate) { self.active = true }
define_sec_method(:deactivate) { self.active = false }
#--------------------------------------------------------------------------
# * New method: center_window
#--------------------------------------------------------------------------
unless method_defined?(:center_window)
def center_window
self.x = Graphics.width/2 - self.width/2
self.y = Graphics.height/2 - self.height/2
end
end
#--------------------------------------------------------------------------
# * Redefined method: disabled_color
#--------------------------------------------------------------------------
unless method_defined?(:disabled_color)
def disabled_color
color = normal_color
color.alpha = 128
return color
end
end
#--------------------------------------------------------------------------
# * Redefined method: draw_text_ex
#--------------------------------------------------------------------------
unless method_defined?(:draw_text_ex)
def draw_text_ex(x, y, text)
reset_font_settings
text = convert_escape_characters(text)
pos = {:x => x, :y => y, :new_x => x, :height => calc_line_height(text)}
process_character(text.slice!(0, 1), text, pos) until text.empty?
end
end
#--------------------------------------------------------------------------
# * Redefined method: reset_font_settings
#--------------------------------------------------------------------------
unless method_defined?(:reset_font_settings)
def reset_font_settings
change_color(normal_color)
contents.font.size = Font.default_size
contents.font.bold = Font.default_bold
contents.font.italic = Font.default_italic
end
end
#--------------------------------------------------------------------------
# * Redefined method: convert_escape_characters
#--------------------------------------------------------------------------
unless method_defined?(:convert_escape_characters)
def convert_escape_characters(text)
result = text.to_s.clone
result.gsub!(/\\/) { "\e" }
result.gsub!(/\e\e/) { "\\" }
result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }
result.gsub!(/\eN\[(\d+)\]/i) { actor_name($1.to_i) }
result.gsub!(/\eP\[(\d+)\]/i) { party_member_name($1.to_i) }
result.gsub!(/\eG/i) { currency_unit }
result
end
end
#--------------------------------------------------------------------------
# * Redefined method: actor_name
#--------------------------------------------------------------------------
unless method_defined?(:actor_name)
def actor_name(n)
actor = n >= 1 ? $game_actors[n] : nil
actor ? actor.name : ""
end
end
#--------------------------------------------------------------------------
# * Redefined method: party_member_name
#--------------------------------------------------------------------------
unless method_defined?(:party_member_name)
def party_member_name(n)
actor = n >= 1 ? $game_party.instance_variable_get(:@actors)[n - 1] : nil
actor ? actor.name : ""
end
end
#--------------------------------------------------------------------------
# * Redefined method: process_character
#--------------------------------------------------------------------------
unless method_defined?(:process_character)
def process_character(c, text, pos)
case c
when "\n" # New line
process_new_line(text, pos)
when "\f" # New page
process_new_page(text, pos)
when "\e" # Control character
process_escape_character(obtain_escape_code(text), text, pos)
else # Normal character
process_normal_character(c, pos)
end
end
end
#--------------------------------------------------------------------------
# * Redefined method: process_normal_character
#--------------------------------------------------------------------------
unless method_defined?(:process_normal_character)
def process_normal_character(c, pos)
text_width = text_size(c).width
draw_text(pos[:x], pos[:y], text_width * 2, pos[:height], c)
pos[:x] += text_width
end
end
#--------------------------------------------------------------------------
# * Redefined method: process_new_line
#--------------------------------------------------------------------------
unless method_defined?(:process_new_line)
def process_new_line(text, pos)
pos[:x] = pos[:new_x]
pos[:y] += pos[:height]
pos[:height] = calc_line_height(text)
end
end
#--------------------------------------------------------------------------
# * Redefined method: process_new_page
#--------------------------------------------------------------------------
unless method_defined?(:process_new_page)
def process_new_page(text, pos)
end
end
#--------------------------------------------------------------------------
# * Redefined method: obtain_escape_code
#--------------------------------------------------------------------------
unless method_defined?(:obtain_escape_code)
def obtain_escape_code(text)
text.slice!(/^[\$\.\|\^!><\{\}\\]|^[\/\w+\/]+/i)
end
end
#--------------------------------------------------------------------------
# * Redefined method: obtain_escape_param
#--------------------------------------------------------------------------
unless method_defined?(:obtain_escape_param)
def obtain_escape_param(text)
text.slice!(/^\[\d+\]/)[/\d+/].to_i rescue 0
end
end
#--------------------------------------------------------------------------
# * Redefined method: process_escape_character
#--------------------------------------------------------------------------
unless method_defined?(:process_escape_character)
def process_escape_character(code, text, pos)
case code.upcase
when 'C' then change_color(text_color(obtain_escape_param(text)))
when 'I' then process_draw_icon(obtain_escape_code(text), pos)
when '{' then make_font_bigger
when '}' then make_font_smaller
end
end
end
#--------------------------------------------------------------------------
# * Redefined method: process_draw_icon
#--------------------------------------------------------------------------
unless method_defined?(:process_draw_icon)
def process_draw_icon(icon_index, pos)
icon_index = icon_index.to_i if icon_index.to_i.to_s == icon_index
draw_icon(icon_index, pos[:x], pos[:y])
pos[:x] += 24
end
end
#--------------------------------------------------------------------------
# * Redefined method: make_font_bigger
#--------------------------------------------------------------------------
unless method_defined?(:make_font_bigger)
def make_font_bigger
contents.font.size += 8 if contents.font.size <= 64
end
end
#--------------------------------------------------------------------------
# * Redefined method: make_font_smaller
#--------------------------------------------------------------------------
unless method_defined?(:make_font_smaller)
def make_font_smaller
contents.font.size -= 8 if contents.font.size >= 16
end
end
#--------------------------------------------------------------------------
# * Redefined method: calc_line_height
#--------------------------------------------------------------------------
unless method_defined?(:calc_line_height)
def calc_line_height(text, restore_font_size = true)
result = [line_height, contents.font.size].max
last_font_size = contents.font.size
text.slice(/^.*$/).scan(/\e[\{\}]/).each do |esc|
make_font_bigger if esc == "\e{"
make_font_smaller if esc == "\e}"
result = [result, contents.font.size].max
end
contents.font.size = last_font_size if restore_font_size
result
end
end
#--------------------------------------------------------------------------
# * New method: currency_unit
#--------------------------------------------------------------------------
unless method_defined?(:currency_unit)
def currency_unit
gold = $data_system.words.gold
return gold
end
end
#--------------------------------------------------------------------------
# ● New method: draw_map_name
#--------------------------------------------------------------------------
unless method_defined?(:draw_map_name)
def draw_map_name(x, y, width, height)
map_id = $game_map.map_id
mapInfo = $game_map.mapInfo
draw_text(x, y, width, height, mapInfo[map_id].name.to_s)
end
end
#--------------------------------------------------------------------------
# ● New method: draw_enter_text
#--------------------------------------------------------------------------
unless method_defined?(:draw_enter_text)
def draw_enter_text(x, y, width, height, text)
info_box = text.split(/\n/)
info_box.size.times do |i|
draw_text( x, y + i * line_height, width, line_height, info_box[i])
break if (y + i * line_height) > (self.height - line_height)
end
end
end
#--------------------------------------------------------------------------
# ● New method: draw_picture_number
#--------------------------------------------------------------------------
unless method_defined?(:draw_picture_number)
def draw_picture_number(x, y, value, file_name,align = 0,
space = 0, frame_max = 1,frame_index = 0)
number_image = LiTTleDRAgo.cache.windowskin(file_name)
frame_max = [frame_max, 1].max
frame_index = frame_max - 1 if frame_index > frame_max - 1
align = [[align,2].min,0].max
cw = number_image.width / 10
ch = number_image.height / frame_max
h = ch * frame_index
number = value.abs.to_s.split(//)
case align
when 0 then plus_x = (-cw + space) * number.size
when 1 then plus_x = ((-cw + space) * number.size) / 2
when 2 then plus_x = 0
end
for r in 0..number.size - 1
rect = Rect.new(cw * number[r].to_i, h, cw, ch)
contents.blt(plus_x + x + ((cw - space) * r), y , number_image, rect)
end
number_image.dispose
end
end
end
#==============================================================================
# ■ Bitmap
#------------------------------------------------------------------------------
#
#==============================================================================
class Bitmap
#----------------------------------------------------------------------------
# ● Constant
#----------------------------------------------------------------------------
RtlMoveMemory_pi = LiTTleDRAgo.rtlmemory_pi
RtlMoveMemory_ip = LiTTleDRAgo.rtlmemory_ip
Blur_Setting = "{ 'offset' => 2, 'spacing' => 1, 'opacity' => 255 }"
#----------------------------------------------------------------------------
# ● Public Instance Variables
#----------------------------------------------------------------------------
attr_sec_accessor :blur_settings, Blur_Setting
#----------------------------------------------------------------------------
# ● Redirect Listing
#----------------------------------------------------------------------------
redirect_method :change_hue, :hue_change
#-------------------------------------------------------------------------
# ● Define Secondary Listing
#-------------------------------------------------------------------------
define_sec_method(:full_fill) { |color| fill_rect(rect, color) }
#----------------------------------------------------------------------------
# ● Alias Listing
#----------------------------------------------------------------------------
alias_sec_method :invert!, :reversing!
alias_sec_method :grayscale!, :gray_scale!
alias_sec_method :frost, :diffusion
alias_sec_method :frost!, :diffusion!
alias_sec_method :drg_ce_stretch_blt, :stretch_blt
alias_method :drg_bitmap_load, :initialize
#--------------------------------------------------------------------------
# * Object Initialization
#----------------------------------------------------------------------------
def initialize(*args)
if (a = args.flatten).size == 4 && a.all? {|s| s.is_a?(Table)}
bitmap = BitmapDump.read_bitmap_data(*a)
drg_bitmap_load(bitmap.width,bitmap.height)
return blt(0,0,bitmap,rect) && bitmap.dispose
end
drg_bitmap_load(*args)
end
#----------------------------------------------------------------------------
# ● New method: address
#----------------------------------------------------------------------------
unless method_defined?(:address)
def address
@address ||= ( RtlMoveMemory_pi.call(a="\0"*4, __id__*2+16, 4)
RtlMoveMemory_pi.call(a, a.unpack('L')[0]+8, 4)
RtlMoveMemory_pi.call(a, a.unpack('L')[0]+16, 4)
a.unpack('L')[0] )
end
end
#----------------------------------------------------------------------------
# ● New method: export
#----------------------------------------------------------------------------
unless method_defined?(:export)
def export(filename)
file = File.open(filename, 'wb')
size, vxace = width * height * 4, LiTTleDRAgo::RGSS3
case format = File.extname(filename)
when '.bmp'
data = String.new
RtlMoveMemory_pi.call(empty_rString_struct="\0"*16,data.__id__*2,16)
flags = vxace ? 5267461 : 8199
klass = empty_rString_struct.unpack('@4L')[0]
pack = [flags,klass,size,address].pack('L4')
weiss = [size+54,0,54,40,width,height,1,32,0,size,0,0,0,0]
RtlMoveMemory_ip.call(data.__id__*2, pack, 16)
file.write("BM#{weiss.pack('L6S2L6')}")
file.write(data)
RtlMoveMemory_ip.call(data.__id__*2, empty_rString_struct, 16)
when '.png'
write_chunk = Proc.new do |chunk|
file.write([(vxace ? chunk.bytesize : chunk.size)-4].pack('N'))
file.write(chunk)
file.write([Zlib.crc32(chunk)].pack('N'))
end
null_char, w4, i, byte = "\0", width*4, 0, (t_Fx = 0)
RtlMoveMemory_pi.call(data=null_char*size, address, size)
if vxace
data.force_encoding('ASCII-8BIT')
(0).step(size-4, 4) do |i|
Graphics.update if (t_Fx += 1) % 10000 == 0
byte = data.getbyte(i)
data.setbyte(i, data.getbyte(i+=2))
data.setbyte(i, byte)
end
else
(0).step(size-4, 4) do |i|
Graphics.update if (t_Fx += 1) % 10000 == 0
data[i,3] = data[i,3].reverse!
end
end
deflate = Zlib::Deflate.new(9)
(size-w4).step(0, -w4) {|i| deflate << null_char << data[i,w4]}
file.write("\211PNG\r\n\32\n")
write_chunk.call("IHDR#{[width,height,8,6,0,0,0].pack('N2C5')}")
write_chunk.call("IDAT#{deflate.finish}")
write_chunk.call('IEND')
deflate.close
when ''
script_report("Error: Export Bitmap Failed\n"+
"Extension '#{filename}' is missing.")
else
script_report("Error: Export Bitmap Failed\n"+
"Extension '#{format}' is not supported.")
end
file.close
end
end
#----------------------------------------------------------------------------
# ● New method: blt_cache
#----------------------------------------------------------------------------
unless method_defined?(:blt_cache)
def blt_cache(x, y, width, height, text, align, edging)
cache_bitmap = LiTTleDRAgo.cache.draw_text(
width, height, text, self.font.name, self.font.size,
self.font.bold, self.font.italic, self.font.color, edging
)
x_plus = uncache_align_exe(width, text, align)
blt(x + x_plus , y , cache_bitmap, Rect.new(0, 0, width, height))
end
end
#----------------------------------------------------------------------------
# ● New method: uncache_align_exe
#----------------------------------------------------------------------------
unless method_defined?(:uncache_align_exe)
def uncache_align_exe(width, text, align)
recter = self.text_size(text)
case align
when 0 then x_index = 0
when 1 then x_index = (width / 2) - recter.width / 2
when 2 then x_index = width - recter.width
else
raise "Text Cache : align is wrong"
end
return x_index
end
end
#----------------------------------------------------------------------------
# ● New method: draw_cache_text
#----------------------------------------------------------------------------
unless method_defined?(:draw_cache_text)
def draw_cache_text(x, y, width, height, text, align = 0)
blt_cache(x, y, width, height, text, align, false)
end
end
#----------------------------------------------------------------------------
# ● New method: draw_edging_cache_text
#----------------------------------------------------------------------------
unless method_defined?(:draw_edging_cache_text)
def draw_edging_cache_text(x, y, width, height, text, align = 0)
blt_cache(x, y, width, height, text, align, true)
end
end
#----------------------------------------------------------------------------
# ● New method: draw_easy_cache_text
#----------------------------------------------------------------------------
unless method_defined?(:draw_easy_cache_text)
def draw_easy_cache_text(x, y, text)
t_rect = text_size(text)
blt_cache(x, y, t_rect.width, t_rect.height, text, 0, false)
end
end
#----------------------------------------------------------------------------
# ● New method: draw_easy_edging_cache_text
#----------------------------------------------------------------------------
unless method_defined?(:draw_easy_edging_cache_text)
def draw_easy_edging_cache_text(x, y, text)
t_rect = text_size(text)
blt_cache(x, y, t_rect.width, t_rect.height, text, 0, true)
end
end
#--------------------------------------------------------------------------
# * New method: change_color
#--------------------------------------------------------------------------
unless method_defined?(:change_color)
def change_color(color, enabled = true)
font.color = color
font.color.alpha = translucent_alpha unless enabled
end
end
#--------------------------------------------------------------------------
# ● New method: draw_picture
#--------------------------------------------------------------------------
unless method_defined?(:draw_picture)
def draw_picture(file_name, x, y, opacity = 255)
bitmap = LiTTleDRAgo.cache.picture(file_name)
cw = bitmap.width
ch = bitmap.height
src_rect = Rect.new(0, 0, cw, ch)
blt(x, y, bitmap, src_rect, opacity)
end
end
#--------------------------------------------------------------------------
# ● New method: draw_icon
#--------------------------------------------------------------------------
unless method_defined?(:draw_icon)
def draw_icon(file_name, x, y, enabled = true)
if file_name.is_a?(Numeric)
bitmap = LiTTleDRAgo.cache.system("Iconset")
src_rect = Rect.new(file_name % 16 * 24, file_name / 16 * 24, 24, 24)
blt(x, y, bitmap, src_rect, enabled ? 255 : 160)
elsif file_name.is_a?(String)
bitmap = LiTTleDRAgo.cache.icon(file_name)
src_rect = Rect.new(0, 0, 24, 24)
blt(x, y, bitmap, bitmap.rect, enabled ? 255 : 160)
end
end
end
#--------------------------------------------------------------------------
# ● New method: draw_battler
#--------------------------------------------------------------------------
unless method_defined?(:draw_battler)
def draw_battler(file_name, x, y, hue = 0, enabled = true)
bitmap = LiTTleDRAgo.cache.battler(file_name, hue)
cw = bitmap.width
ch = bitmap.height
src_rect = Rect.new(0, 0, cw, ch)
blt(x, y, bitmap, src_rect, enabled ? 255 : 160)
end
end
#--------------------------------------------------------------------------
# ● New method: draw_bar
#--------------------------------------------------------------------------
unless method_defined?(:draw_bar)
def draw_bar(x, y, current, file)
bitmap = LiTTleDRAgo.cache.picture(file)
cw = bitmap.width * current / 100
ch = bitmap.height
src_rect = Rect.new(0, 0, cw, ch)
blt(x, y, bitmap, src_rect)
end
end
#--------------------------------------------------------------------------
# ● New method: draw_edging_text
#--------------------------------------------------------------------------
unless method_defined?(:draw_edging_text)
def draw_edging_text(x, y, width, height, text, align=0)
old_color = font.color.dup
font.color = Color.new(0, 0, 0)
draw_text(x-1, y-1, width, height, text, align)
draw_text(x-1, y+1, width, height, text, align)
draw_text(x+1, y-1, width, height, text, align)
draw_text(x+1, y+1, width, height, text, align)
font.color = old_color
draw_text(x, y, width, height, text, align)
end
end
#--------------------------------------------------------------------------
# ● New method: draw_enter_text
#--------------------------------------------------------------------------
unless method_defined?(:draw_enter_text)
def draw_enter_text(x, y, width, height, text, align=0)
rect = text_size(text)
info_box = text.split(/\n/)
info_box.size.times do |i|
draw_text( x, y+i*rect.height, width, height, info_box[i], align)
break if (y+i*rect.height) > self.height
end
end
end
#--------------------------------------------------------------------------
# ● New method: draw_enter_edging_text
#--------------------------------------------------------------------------
unless method_defined?(:draw_enter_edging_text)
def draw_enter_edging_text(x, y, width, height, text, align=0)
rect = text_size(text)
info_box = text.split(/\n/)
info_box.size.times do |i|
draw_edging_text( x, y+i*rect.height,width,height,info_box[i],align)
break if (y+i*rect.height) > self.height
end
end
end
#--------------------------------------------------------------------------
# ● New method: draw_easy_text
#--------------------------------------------------------------------------
unless method_defined?(:draw_easy_text)
def draw_easy_text(x, y, text)
rect = text_size(text)
draw_text(x, y, rect.width + rect.height/2, rect.height, text)
end
end
#--------------------------------------------------------------------------
# ● New method: draw_auto_text
#--------------------------------------------------------------------------
unless method_defined?(:draw_auto_text)
def draw_auto_text(x, y, width, height, text)
ini_x = 0
law = 0
text_box = []
text_box[law] = []
otxto = text.split(//)
otxto.size.times do |i|
text_rect = text_size(otxto[i])
if (x + ini_x + text_rect.width) < width
ini_x += text_rect.width
else
law += 1
ini_x = text_rect.width
text_box[law] = []
end
text_box[law].push(otxto[i])
end
for l in 0..law
ini_x = 0
text_box[l].size.times do |i|
rect = text_size(text_box[l][i])
draw_text(x + ini_x, y+l*height, rect.width, height, text_box[l][i])
ini_x += rect.width
end
end
end
end
#-------------------------------------------------------------------------
# ● New method: erase
#-------------------------------------------------------------------------
unless method_defined?(:erase)
def erase(*a)
rect = nil
if a.at(0).is_a?(Rect) then rect = a.at(0)
elsif a.size == 4 then rect = Rect.new(*a)
elsif a.size == 0 then rect = Rect.new(0,0,width,height)
end
fill_rect(rect.x, rect.y, rect.width, rect.height, Color.erase) if rect
end
end
#-------------------------------------------------------------------------
# ● New method: stretch
#-------------------------------------------------------------------------
unless method_defined?(:stretch)
def stretch(width, height)
dummy = Bitmap.new(width, height)
dummy.stretch_blt(*[dummy.rect, self, self.rect])
dummy
end
end
#-------------------------------------------------------------------------
# ● New method: crop
#-------------------------------------------------------------------------
unless method_defined?(:crop)
def crop(*a)
return unless a.size == 1 or a.size == 4
rect = rect.at(0) if a.size == 1 && a.at(0).is_a?(Rect)
rect = Rect.new(*a) if a.size == 4
cropped = Bitmap.new([rect.width,width-rect.x].min,
[rect.height,height-rect.y].min)
cropped.blt(0,0,self,rect)
cropped
end
end
#-------------------------------------------------------------------------
# ● Aliased method: stretch_blt
#-------------------------------------------------------------------------
def stretch_blt(*a)
if respond_to?(:stretch_blend_blt)
a = [a[0..2],0,1,a.at(3)||255].flatten
stretch_blend_blt(*a)
else
drg_ce_stretch_blt(*a)
end
end
#-------------------------------------------------------------------------
# ● Aliased method: hue_change
#-------------------------------------------------------------------------
define_post_alias(:hue_change) { self }
#--------------------------------------------------------------------------
# ● New method: invert, etc
#--------------------------------------------------------------------------
[:invert, :brighten, :darken, :grayscale, :pixelate, :frost, :flip_horizontal,
:flip_vertical, :rotate90, :rotate180, :rotate270].each do |meth|
define_sec_method(meth) do |*args|
bitmap = self.clone
bitmap.send(:"#{meth}!",*args)
return bitmap
end
end
#-------------------------------------------------------------------------
# ● New method: flip_horizontal!
#-------------------------------------------------------------------------
define_sec_method(:flip_horizontal!) do
flipped = Bitmap.new(width, height)
fliprect = Rect.new(width,0,-width,height)
flipped.blt(0,0, self,fliprect)
(clear || 0) && blt(0,0,flipped,rect)
flipped.dispose
end
#-------------------------------------------------------------------------
# ● New method: flip_vertical!
#-------------------------------------------------------------------------
define_sec_method(:flip_vertical!) do
flipped = Bitmap.new(width, height)
fliprect = Rect.new(0,height,width,-height)
flipped.blt(0,0, self,fliprect)
(clear || 0) && blt(0,0,flipped,rect)
flipped.dispose
end
#-------------------------------------------------------------------------
# ● New method: rotate90! (clockwise)
#-------------------------------------------------------------------------
define_sec_method(:rotate90!) do
copy = self.clone
(t_Fx = width).times do |i|
height.times do |j|
Graphics.update if (t_Fx += 1) % 10000 == 0
a = (clockwise = true) ? [width - i - 1, j] : [i, height - j - 1]
self.set_pixel(a[0],a[1], copy.get_pixel(j, i))
end
end
copy.dispose
end
#-------------------------------------------------------------------------
# ● New method: rotate180!
#-------------------------------------------------------------------------
define_sec_method(:rotate180!) do
flip_vertical!
flip_horizontal!
end
#-------------------------------------------------------------------------
# ● New method: rotate270!
#-------------------------------------------------------------------------
define_sec_method(:rotate270!) do
rotate90!
rotate180!
end
#----------------------------------------------------------------------------
# ● New method: invert!
#----------------------------------------------------------------------------
unless method_defined?(:invert!)
def invert!
(t_Fx = width).times do |i|
height.times do |j|
color = get_pixel(i, j)
Graphics.update if (t_Fx += 1) % 10000 == 0
set_pixel(i, j, color.invert) if color.alpha > 0
end
end
end
end
#--------------------------------------------------------------------------
# * New method: brighten!
#--------------------------------------------------------------------------
unless method_defined?(:brighten!)
def brighten!(amount = 10)
(t_Fx = width).times do |w|
height.times do |h|
color = get_pixel(w, h)
Graphics.update if (t_Fx += 1) % 10000 == 0
set_pixel(w, h, Color.new([color.red + amount, 255].min,
[color.green + amount, 255].min,
[color.blue + amount, 255].min,
color.alpha)) if color.alpha > 0
end
end
end
end
#--------------------------------------------------------------------------
# * New method: darken!
#--------------------------------------------------------------------------
unless method_defined?(:darken!)
def darken!(amount = 10)
(t_Fx = width).times do |w|
height.times do |h|
color = get_pixel(w, h)
Graphics.update if (t_Fx += 1) % 10000 == 0
set_pixel(w, h, Color.new([color.red - amount, 0].max,
[color.green - amount, 0].max,
[color.blue - amount, 0].max,
color.alpha)) if color.alpha > 0
end
end
end
end
#--------------------------------------------------------------------------
# * New method: grayscale!
# NOTE: calling this method repeatedly has no effect on the bitmap, but will
# still waste processing power. Do not call it repeatedly.
#--------------------------------------------------------------------------
unless method_defined?(:grayscale!)
def grayscale!
(t_Fx = width).times do |w|
height.times do |h|
color = get_pixel(w, h)
if (a = color.alpha) > 0
Graphics.update if (t_Fx += 1) % 10000 == 0
num = (color.red + color.green + color.blue) / 3
set_pixel(w, h, Color.new(num, num, num, a))
end
end
end
end
end
#--------------------------------------------------------------------------
# * New method: drg_pixelate! (0.2 second)
# NOTE: Pixelateing bitmaps to a larger pixel size is less process consuming.
# for best results, don't pixelate to numbers below four.
# This works much better for solid images, due to bugs.
#--------------------------------------------------------------------------
unless method_defined?(:drg_pixelate!)
def drg_pixelate!(size = 10)
return self if size <= (t_Fx = 1)
c = lambda {|a,b| (a / b**2) * Math.sqrt(b) }
for w in 0..((width - 1) / size)
w *= size
for h in 0..((height - 1) / size)
h *= size
r, g, b, a = 0, 0, 0, 0
size.times do |i|
color = get_pixel(w, h)
r += color.red
g += color.green
b += color.blue
a += color.alpha
color = get_pixel(w + i, h)
r += color.red
g += color.green
b += color.blue
a += color.alpha
color = get_pixel(w, h + i)
r += color.red
g += color.green
b += color.blue
a += color.alpha
end
Graphics.update if (t_Fx += 1) % 10000 == 0
fill_rect(w, h, size, size, Color.new(c.call(r,size),c.call(g,size),
c.call(b,size),c.call(a,size)))
end
end
end
end
#--------------------------------------------------------------------------
# * New method: pixelate!
#--------------------------------------------------------------------------
unless method_defined?(:pixelate!)
def pixelate!(size = 10)
return mosaic!(size,size) if respond_to?(:mosaic!)
return drg_pixelate!(size)
end
end
#--------------------------------------------------------------------------
# * New method: drg_frost! (5 second)
# NOTE: Frosting a bitmap randomly scatters its pixels. As such, Consistant
# results are impossible to get.
# Frosting a bitmap beyond eight won't result in a more scattered image
#--------------------------------------------------------------------------
unless method_defined?(:drg_frost!)
def drg_frost!(noise = 10)
for pass in 1..noise
(t_Fx = width).times do |w|
height.times do |h|
Graphics.update if (t_Fx += 1) % 10000 == 0
set_pixel(w, h, get_pixel(w + rand(3) - 1, h + rand(3) - 1))
end
end
end
end
end
#-------------------------------------------------------------------------
# ● New method: bltapiinit
#-------------------------------------------------------------------------
unless method_defined?(:bltapiinit)
def bltapiinit
info = [40,width,height,1,32,0,0,0,0,0,0].pack('LllSSLLllLL')
hWndDC = LiTTleDRAgo.getdc.call(LiTTleDRAgo.hwnd)
hMemDC = LiTTleDRAgo.ccdc.call(hWndDC)
hMemBM = LiTTleDRAgo.ccbitmap.call(hWndDC, width, height)
LiTTleDRAgo.releasedc.call(LiTTleDRAgo.hwnd, hWndDC)
LiTTleDRAgo.selectobject.call(hMemDC, hMemBM)
LiTTleDRAgo.setdibits.call(hMemDC, hMemBM, 0, height, address, info, 0)
return hMemDC, hMemBM, info
end
end
#-------------------------------------------------------------------------
# ● New method: bit_blt
#-------------------------------------------------------------------------
unless method_defined?(:bit_blt)
def bit_blt(x, y, src_bmp, src_rect, rastor_operation = 0xCC0020)
hDC1, hBM1, info = *self.bltapiinit
hDC2, hBM2 = *src_bmp.bltapiinit
LiTTleDRAgo.bitblt.call(hDC1, x, y, src_rect.width, src_rect.height,
hDC2, src_rect.x, src_rect.y, rastor_operation)
LiTTleDRAgo.getdibits.call(hDC1, hBM1, 0, height, address, info, 0)
LiTTleDRAgo.deleteobject.call(hBM1)
LiTTleDRAgo.deleteobject.call(hDC1)
LiTTleDRAgo.deleteobject.call(hBM2)
LiTTleDRAgo.deleteobject.call(hDC2)
end
end
#-------------------------------------------------------------------------
# ● New method: crop_blt
#-------------------------------------------------------------------------
unless method_defined?(:crop_blt)
def crop_blt(x, y, width, height, bitmap, dir = 1, align = 1, opacity = 255)
w, h = bitmap.width, bitmap.height
if w < width and h < height
x += (width - w) / 2 if align == 1
x += width - w if align == 2
return full_blt(x, y, bitmap, opacity)
end
i, j = dir % 3, dir / 3
crop_x, crop_y = 0, 0
crop_x = (w - width) / 2 if i == 1
crop_x = w - width if i == 2
crop_y = (h - height) / 2 if j == 1
crop_y = h - height if j == 2
blt(x, y, bitmap, Rect.new(crop_x, crop_y, width, height), opacity)
end
end
#-------------------------------------------------------------------------
# ● New method: fit_blt
#-------------------------------------------------------------------------
unless method_defined?(:fit_blt)
def fit_blt(x, y, width, height, bitmap, opacity = 255, align = 1)
w, h = bitmap.width, bitmap.height
if w > width or h > height
conversion = w / h.to_f
zoom_x, zoom_y = width * conversion, height if conversion <= 1
zoom_x, zoom_y = width, height / conversion unless conversion <= 1
x += (width - zoom_x) / 2 if align == 1
x += width - zoom_x if align == 2
dest_rect = Rect.new(x, y, zoom_x, zoom_y)
stretch_blt(dest_rect, bitmap, bitmap.rect, opacity)
else
x += (width - w) / 2 if align == 1
x += width - w if align == 2
full_blt(x, y, bitmap, opacity)
end
end
end
#-------------------------------------------------------------------------
# ● New method: full_blt
#-------------------------------------------------------------------------
unless method_defined?(:full_blt)
def full_blt(x, y, bitmap, opacity = 255)
blt(x, y, bitmap, bitmap.rect, opacity)
end
end
#-------------------------------------------------------------------------
# ● New method: scale_blt
#-------------------------------------------------------------------------
unless method_defined?(:scale_blt)
def scale_blt(dest_rect, src_bitmap, src_rect = src_bitmap.rect, o = 255)
w, h = src_rect.width, src_rect.height
scale = [w / dest_rect.width.to_f, h / dest_rect.height.to_f].max
ow, oh = (w / scale).to_i, (h / scale).to_i
ox, oy = (dest_rect.width - ow) / 2, (dest_rect.height - oh) / 2
stretch_blt(Rect.new(ox + dest_rect.x, oy + dest_rect.y, ow, oh),
src_bitmap, src_rect, o)
end
end
#-------------------------------------------------------------------------
# ● New method: frames_flip_horizontal
#-------------------------------------------------------------------------
unless method_defined?(:frames_flip_horizontal)
def frames_flip_horizontal(frames)
frame_width = width / frames
frame_bitmap = Bitmap.new(frame_width, height)
rect = Rect.new(0, 0, frame_width, height)
frames.times do |i|
frame_bitmap.clear
rect.x = (x = i * frame_width)
frame_bitmap.blt(0, 0, self, rect)
frame_bitmap.flip_horizontal!
blt(x, 0, frame_bitmap, frame_bitmap.rect)
end
frame_bitmap.dispose
end
end
#-------------------------------------------------------------------------
# ● New method: frames_flip_vertical
#-------------------------------------------------------------------------
unless method_defined?(:frames_flip_vertical)
def frames_flip_vertical(frames)
frame_height = height / frames
frame_bitmap = Bitmap.new(width, frame_height)
rect = Rect.new(0, 0, width, frame_height)
frames.times do |i|
frame_bitmap.clear
rect.y = (y = i * frame_height)
frame_bitmap.blt(0, 0, self, rect)
frame_bitmap.flip_vertical!
blt(0, y, frame_bitmap, frame_bitmap.rect)
end
frame_bitmap.dispose
end
end
#-------------------------------------------------------------------------
# ● New method: blur_area
#-------------------------------------------------------------------------
unless method_defined?(:blur_area)
def blur_area(settings = {})
blur_settings.each do |default, setting|
settings[default] = setting unless settings.has_key?(default)
end
keys = settings.keys
rect_defined = keys.include?('rect')
rect_p_defined = keys.include?('x') && keys.include?('y') &&
keys.include?('w') && keys.include?('h')
if rect_defined
rect = settings['rect']
x, y, w, h = rect.x, rect.y, rect.width, rect.height
elsif rect_p_defined
x, y, w, h = settings['x'], settings['y'], settings['w'], settings['h']
else
x, y, w, h = 0, 0, self.width, self.height
end
dummy = self.dup
spacing = settings['spacing']
opacity = settings['opacity']
settings['offset'].times do |i|
src_rects = []
src_rects << Rect.new(x + i * spacing, y + i * spacing, w, h)
src_rects << Rect.new(x - i * spacing, y + i * spacing, w, h)
src_rects << Rect.new(x + i * spacing, y - i * spacing, w, h)
src_rects << Rect.new(x - i * spacing, y - i * spacing, w, h)
o = Integer(opacity * (settings['offset'] - i) / (settings['offset']))
src_rects.each { |src_rect| blt(x, y, dummy, src_rect, o)}
end
dummy.dispose
self
end
end
#-------------------------------------------------------------------------
# ● New method: sub_bitmap_blend
#-------------------------------------------------------------------------
unless method_defined?(:sub_bitmap_blend)
def sub_bitmap_blend(x = 0, y = 0, bitmap = self, src_rect = bitmap.rect)
src_rect.width.times do |i|
src_rect.height.times do |j|
c1 = get_pixel(x + i, y + j)
c2 = bitmap.get_pixel(src_rect.x + i, src_rect.y + j)
nc = Color.new(c1.red-c2.red, c1.green-c2.green, c1.blue-c2.blue)
set_pixel(x + i, y + j, nc) if c2.alpha > 0
end
end
end
end
#-------------------------------------------------------------------------
# ● New method: add_bitmap_blend
#-------------------------------------------------------------------------
unless method_defined?(:add_bitmap_blend)
def add_bitmap_blend(x = 0, y = 0, bitmap = self, src_rect = bitmap.rect)
src_rect.width.times do |i|
src_rect.height.times do |j|
c1 = get_pixel(x + i, y + j)
c2 = bitmap.get_pixel(src_rect.x + i, src_rect.y + j)
nc = Color.new(c1.red+c2.red, c1.green+c2.green, c1.blue+c2.blue)
set_pixel(x + i, y + j, nc) if c2.alpha > 0
end
end
end
end
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_sec_method :frost!, :drg_frost!
alias_sec_method :blur, :blur_area
alias_sec_method :entire_fill, :full_fill
#--------------------------------------------------------------------------
# * Replicated method: gradient_fill_rect
#--------------------------------------------------------------------------
unless method_defined?(:gradient_fill_rect)
def gradient_fill_rect(*a)
if a.first.is_a?(Rect)
x, y, width, height = a[0].x, a[0].y, a[0].width, a[0].height
color1 = a.at(1).dup
color2 = a.at(2)
vertical = a.at(3)
else
x, y, width, height = a[0..3]
color1 = a.at(4).dup
color2 = a.at(5)
vertical = a.at(6)
end
dr = color2.red - color1.red
dg = color2.green - color1.green
db = color2.blue - color1.blue
da = color2.alpha - color1.alpha
start_rgba = [color1.red, color1.green, color1.blue, color1.alpha]
if vertical
dr, dg, db, da = dr / height, dg / height, db / height, da / height
for i in (y.round...(y + height).round)
fill_rect(x, i, width, 1, color1)
start_rgba[0] = [start_rgba.at(0) + dr, 0].max.round
start_rgba[1] = [start_rgba.at(1) + dg, 0].max.round
start_rgba[2] = [start_rgba.at(2) + db, 0].max.round
start_rgba[3] = [start_rgba.at(3) + da, 0].max.round
color1.set(*start_rgba)
end
else
dr, dg, db, da = dr / width, dg / width, db / width, da / width
for i in (x.round...(x + width).round)
fill_rect(i, y, 1, height, color1)
start_rgba[0] = [start_rgba.at(0) + dr, 0].max.round
start_rgba[1] = [start_rgba.at(1) + dg, 0].max.round
start_rgba[2] = [start_rgba.at(2) + db, 0].max.round
start_rgba[3] = [start_rgba.at(3) + da, 0].max.round
color1.set(*start_rgba)
end
end
end
end
end
#==============================================================================
# ** String
#------------------------------------------------------------------------------
#
#==============================================================================
class String
#-------------------------------------------------------------------------
# ● New method: get_int
#-------------------------------------------------------------------------
unless method_defined?(:get_int)
def get_int
m = self.scan(/([-]?\d+)/i).flatten
return m.join.to_i
end
end
#-------------------------------------------------------------------------
# ● New method: get_ints
#-------------------------------------------------------------------------
unless method_defined?(:get_ints)
def get_ints
array = self.scan(/([-]?\d+)/i).flatten.relay(:i)
return array
end
end
#-------------------------------------------------------------------------
# ● New method: encrypt
#-------------------------------------------------------------------------
unless method_defined?(:encrypt)
def encrypt(encryption_string = 'encrypt')
encryption_bytes = []
encryption_string.each_byte {|c| encryption_bytes << c}
string = ''
self.size.times do |i|
byte = self[i] * encryption_bytes[i % encryption_bytes.size]
base, mod = byte / 255, byte % 255
string += base.chr + mod.chr
end
return string
end
end
#-------------------------------------------------------------------------
# ● New method: encrypt!
#-------------------------------------------------------------------------
unless method_defined?(:encrypt!)
def encrypt!(encryption_string = 'encrypt')
replace(encrypt(encryption_string))
end
end
#-------------------------------------------------------------------------
# ● New method: decrypt
#-------------------------------------------------------------------------
unless method_defined?(:decrypt)
def decrypt(encryption_string = 'encrypt')
encryption_bytes = []
encryption_string.each_byte {|c| encryption_bytes << c}
string = ''
(self.size / 2).times do |i|
b, m = self[i * 2] * 255, self[i * 2 + 1]
string += ((b + m) / encryption_bytes[i % encryption_bytes.size]).chr
end
return string
end
end
#-------------------------------------------------------------------------
# ● New method: decrypt!
#-------------------------------------------------------------------------
unless method_defined?(:decrypt!)
def decrypt!(encryption_string = 'encrypt')
replace(decrypt(encryption_string))
end
end
#-------------------------------------------------------------------------
# ● New method: clear, words, characters
#-------------------------------------------------------------------------
define_sec_method(:clear) { replace('') }
define_sec_method(:words) { split(' ') }
define_sec_method(:characters) { split('') }
define_sec_method(:last) { characters.last }
define_sec_method(:first) { characters.first }
end
#==============================================================================
# ** Game_Interpreter
#------------------------------------------------------------------------------
# An interpreter for executing event commands. This class is used within the
# Game_Map, Game_Troop, and Game_Event classes.
#==============================================================================
Klass = LiTTleDRAgo::VX ? Game_Interpreter : Interpreter
class Klass
#--------------------------------------------------------------------------
# * Constant
#--------------------------------------------------------------------------
SCRIPT_WAIT_RESULTS = [:wait, FalseClass]
#--------------------------------------------------------------------------
# ● Redirect Listing
#--------------------------------------------------------------------------
redirect_method :picture_sprite, '$game_map.picture_sprite'
#--------------------------------------------------------------------------
# ● New method: random_teleport
#--------------------------------------------------------------------------
unless method_defined?(:random_teleport)
def random_teleport(id = 0)
character = id.is_a?(Game_Character) ? id : get_character(id)
character.random_teleport if character.is_a?(Game_Character)
end
end
#--------------------------------------------------------------------------
# ● Redefined method: same_map?, next_event_code
#--------------------------------------------------------------------------
define_sec_method(:same_map?) { @map_id == $game_map.map_id }
define_sec_method(:next_event_code) { @list[@index + 1].code }
#--------------------------------------------------------------------------
# * Overwriten method: command_355
#--------------------------------------------------------------------------
def command_355
script = @list[index = @index].parameters[0] + "\n"
while [655, 355].include?(next_event_code) do
script += @list[@index+=1].parameters[0] + "\n"
end
wait = SCRIPT_WAIT_RESULTS.include?(eval(script)) && LiTTleDRAgo::XP
return wait ? !(@index = index) : true
end
end
#==============================================================================
# ** Sprite
#------------------------------------------------------------------------------
# A sprite class for bitmap processing.
#==============================================================================
class Sprite
#---------------------------------------------------------------------------
# * Alias Listing
#---------------------------------------------------------------------------
alias_sec_method(:angle_fix_alias, :"angle=")
alias_sec_method(:drg_core_dispose,:"dispose")
alias_sec_method(:set_x_alias, :"x=")
alias_sec_method(:set_y_alias, :"y=")
alias_sec_method(:get_x_alias, :"x")
alias_sec_method(:get_y_alias, :"y")
#---------------------------------------------------------------------------
# * New method: method_missing
#---------------------------------------------------------------------------
def method_missing(val,*a,&b)
return bitmap.send(val.to_s,*a,&b) if bitmap.respond_to?(val.to_sym)
text = "Undefined method #{val} for #{self.inspect}"
raise(NoMethodError, text, caller(1))
end
#---------------------------------------------------------------------------
# * Aliased method: x=, y=
#---------------------------------------------------------------------------
define_method(:x=) {|amt| set_x_alias((@intfloat_x = amt).to_i) }
define_method(:y=) {|amt| set_y_alias((@intfloat_y = amt).to_i) }
define_method(:x) { @intfloat_x ||= get_x_alias }
define_method(:y) { @intfloat_y ||= get_y_alias }
define_method(:dispose) { disposed? || drg_core_dispose }
define_method(:rotate_correction) { self.ox,self.oy = width/2, height/2 }
#---------------------------------------------------------------------------
# * Aliased method: angle=
#---------------------------------------------------------------------------
def angle=(v)
return if @angle == v
sign = (v % 360 == 180 || v % 180 == 90) ? 1.00001 : 1
angle_fix_alias((@angle = v) * sign)
end
#--------------------------------------------------------------------------
# ● Redefined method: width, height
#--------------------------------------------------------------------------
define_sec_method(:width) { src_rect.width }
define_sec_method(:height) { src_rect.height }
#--------------------------------------------------------------------------
# ● Overwriten method: dup
#--------------------------------------------------------------------------
def dup
sprite = self.class.new(self.viewport)
sprite.bitmap = self.bitmap.clone
sprite.zoom_x, sprite.zoom_y = self.zoom_x, self.zoom_y
sprite.x, sprite.y = self.x, self.y
sprite.ox, sprite.oy = self.ox, self.oy
sprite.color, sprite.tone = self.color.dup, self.tone.dup
sprite.src_rect,sprite.angle = self.src_rect, self.angle
return sprite
end
#--------------------------------------------------------------------------
# ● Overwriten method: clone
#--------------------------------------------------------------------------
def clone
(sprite = self.dup) && instance_variables.each do |var|
temp = instance_variable_get("#{var}")
sprite.instance_variable_set("#{var}",temp) rescue nil
end
(frozen? && sprite.freeze)
return sprite
end
#--------------------------------------------------------------------------
# ● New method: scale
#--------------------------------------------------------------------------
unless method_defined?(:scale)
def scale(w, h)
tmp = self.bitmap.clone
self.bitmap = Bitmap.new(w, h)
self.bitmap.stretch_blt(Rect.new(0, 0, w, h), tmp, tmp.rect)
tmp.dispose
end
end
#--------------------------------------------------------------------------
# ● New method: in_rect?
#--------------------------------------------------------------------------
unless method_defined?(:in_rect?)
def in_rect?(*rect)
if rect.size == 1
x, y, w, h = rect[0].x, rect[0].y, rect[0].width, rect[0].height
return self.x.between?(x, x + w) && self.y.between?(y, y + h)
elsif rect.size == 4
x, y, w, h = rect
return self.x.between?(x, x + w) && self.y.between?(y, y + h)
end
return false
end
end
end
#==============================================================================
# ** Scheduler
#------------------------------------------------------------------------------
# This class allows to schedule a proc or method call a given amount of frames
# into the future with any amount of arguments
#==============================================================================
unless defined?(Scheduler)
class Scheduler
#==========================================================================
# ** Order
#--------------------------------------------------------------------------
# An order is a proc, method or something else which has 'call' as a
# method, and the arguments to pass along.
#==========================================================================
unless method_defined?(:update)
Order = Struct.new(:callable, :arguments)
class Order
#----------------------------------------------------------------------
# * New Methods: call
#----------------------------------------------------------------------
define_method(:call) { callable.call(*arguments) }
end
#========================================================================
# ** RecurringOrder
#------------------------------------------------------------------------
# An order which is recurring every specified amount of time until
# FalseClass is returned from the call.
# Note that arguments remain the same for each call
#========================================================================
RecurringOrder = Struct.new(:callable, :arguments, :frames)
class RecurringOrder
#----------------------------------------------------------------------
# * New Methods: call
#----------------------------------------------------------------------
def call
result = callable.call(*arguments)
unless result == FalseClass
Scheduler.schedule_recurring(frames, frames, callable, *arguments)
end
end
end
#========================================================================
# ** Mapping
#------------------------------------------------------------------------
# Maps an index to an array. Values can be added to these value.
# Each array starts empty.
#========================================================================
class Mapping
#----------------------------------------------------------------------
# * New method: add, get, empty
#----------------------------------------------------------------------
define_method(:add) { |i, v| ((@mapping ||= {})[i] ||=[]) << v }
define_method(:get) { |i| ((@mapping ||= {})[i] || []) }
define_method(:empty) { |i| (@mapping ||= {}).delete(i) }
end
#------------------------------------------------------------------------
# * New method: schedule
#------------------------------------------------------------------------
def schedule(frames, callable, *arguments)
order = Order.new(callable, arguments)
(@mapping ||= Mapping.new).add(frames + (@tick||=0), order)
end
#------------------------------------------------------------------------
# * New method: schedule_recurring
#------------------------------------------------------------------------
def schedule_recurring(frames, frames_to_wait, callable, *arguments)
order = RecurringOrder.new(callable, arguments, frames_to_wait)
(@mapping ||= Mapping.new).add(frames + (@tick||=0), order)
end
#------------------------------------------------------------------------
# * New method: update
#------------------------------------------------------------------------
def update
orders = (@mapping ||= Mapping.new).get((@tick||=0))
@mapping.empty(@tick)
orders.each {|s| s.call }
@tick += 1
end
#------------------------------------------------------------------------
# * Self
#------------------------------------------------------------------------
@@instance = self.new
class << self
define_method(:instance) { @@instance }
redirect_method :schedule_recurring, 'instance.schedule_recurring'
redirect_method :schedule, 'instance.schedule'
redirect_method :update, 'instance.update'
end
end
end
Graphics.auto_update.push([Scheduler,:update])
end
#==============================================================================
# ** Dir
#------------------------------------------------------------------------------
#
#==============================================================================
class << Dir
#--------------------------------------------------------------------------
# ● New method: make_dir
#--------------------------------------------------------------------------
def make_dir(path)
(dir = path.split("/")).size.times do |i|
next if dir == "."
Dir.mkdir(dir[0..i].join("/")) rescue nil
end
end
#--------------------------------------------------------------------------
# ● New method: files_with_extension
#--------------------------------------------------------------------------
def files_with_extension(directory, extension)
entries(directory).select{|file| File.extname(file) == extension}
end
end
#==============================================================================
# ** BitmapDump
#------------------------------------------------------------------------------
#
#==============================================================================
module BitmapDump; end
class << BitmapDump
#--------------------------------------------------------------------------
# ● New method: self.bitmap_data
#--------------------------------------------------------------------------
unless method_defined?(:bitmap_data)
def bitmap_data(bitmap)
red = Table.new(bitmap.width, bitmap.height)
green, blue, alpha = red.clone, red.clone, red.clone
bitmap.width.times do |i|
bitmap.height.times do |j|
color = bitmap.get_pixel(i, j)
red[i, j], green[i, j] = color.red, color.green
blue[i, j], alpha[i, j] = color.blue, color.alpha
end
end
return [red, green, blue, alpha]
end
end
#--------------------------------------------------------------------------
# ● New method: self.read_bitmap_data
#--------------------------------------------------------------------------
unless method_defined?(:read_bitmap_data)
def read_bitmap_data(red, green, blue, alpha)
bitmap = Bitmap.new(red.xsize, red.ysize)
bitmap.width.times do |i|
bitmap.height.times do |j|
color_table = [red[i, j], green[i, j], blue[i, j], alpha[i, j]]
bitmap.set_pixel(i, j, Color.new(*color_table))
end
end
return bitmap
end
end
#--------------------------------------------------------------------------
# ● New method: self.save_bitmap
#--------------------------------------------------------------------------
unless method_defined?(:save_bitmap)
def save_bitmap(bitmap, filename, folder = '')
bitmap_data = bitmap_data(bitmap)
if folder && folder != ''
Dir.make_dir(folder) unless FileTest.directory?(folder)
filename = "#{folder}/#{filename}"
end
filename = filename.gsub("\\","/").gsub("//","/")
file = File.open(filename,'wb')
Marshal.dump(bitmap_data, file)
file.close
end
end
#--------------------------------------------------------------------------
# ● New method: self.load_bitmap
#--------------------------------------------------------------------------
unless method_defined?(:load_bitmap)
def load_bitmap(filename, folder = '')
if folder && folder != ''
Dir.make_dir(folder) unless FileTest.directory?(folder)
filename = "#{folder}/#{filename}"
end
filename = filename.gsub("\\","/").gsub("//","/")
file = File.open(filename,"rb")
colors = Marshal.load(file)
file.close
bitmap = read_bitmap_data(colors)
return bitmap
end
end
end
#============================================================================== # ** Drago - Custom Resolution # Version : 2.17 # Contact : littledrago.blogspot.com / forum.chaos-project.com #============================================================================== ($imported ||= {})[:drg_custom_resolution] = 2.17 #============================================================================== # # Introduction : # # Version 2 from previous Drago - Custom Resolution # # Issue : # # - Normal transition didn't work when resolution is more than 640x480 # - ALT+Enter is disabled by default # - Custom menu system will require an edit to match the new resolution # - Anything that modify Sprite_Character & Spriteset_Map will require an edit # # Script Call : # # Graphics.window # Graphics.fullscreen # Graphics.fullscreen? # returns true if game is fullscreen # # $game_map.start_zoom(X, Y, ZOOM_VALUE, DURATION = 20) # $game_map.zoom(X = nil, Y = nil, ZOOM_VALUE) # $game_map.zoom_in(X = nil, Y = nil, DURATION = 20) # $game_map.zoom_out(X = nil, Y = nil, DURATION = 20) # # $game_map.reverse(true / false) # Flip the map # # $game_map.start_tilemap_opacity(OPACITY = 255, DURATION = 20) # $game_map.start_tilemap_tone(TONE = Tone.new(0,0,0,0), DURATION = 0) # # # change_tilemap_tone(TONE,*CHARACTER) # change tilemap tone # change_character_tone(TONE,*CHARACTER) # change character tone without # changing the tilemap # # X, Y = Zoom focus # # ZOOM_VALUE = Integer from 1-12 # # OPACITY = Integer from 0-255 # # TONE = [R,G,B,A] or Tone.new(R,G,B,A) # # CHARACTER = $game_map.events.values # all events # = $game_map.events.keys # all events # = $game_player # player # = -1 # player # = 0 # this event # = [2,3,4,6] # events with selected id # = [-1,2,3,4,6] # player & events with selected id # = [0,2,3,4,6] # this event & events with selected id # = (1..99) # events in range # = [(1..8),20,25,(30..42)] # events in range # # * will not change the character tone if left out # # Links : # # - Fantasist's Transitions Pack # [url]http://forum.chaos-project.com/index.php/topic[/url],1390.0.html # - ForeverZer0's Add-ons # [url]http://forum.chaos-project.com/index.php/topic[/url],7862.0.html # - ThallionDarkshine's Add-ons # [url]http://forum.chaos-project.com/index.php/topic[/url],12655.0.html # - Drago Transition Pack # [url]http://forum.chaos-project.com/index.php/topic[/url],13488.0.html # # - Adjust Menu Position # [url]http://forum.chaos-project.com/index.php/topic[/url],13781.0.html # # - ThallionDarkshine's F12 Fix # [url]http://forum.chaos-project.com/index.php/topic[/url],13629.0.html # - Zeriab's F12 Pause with images # [url]http://forum.chaos-project.com/index.php/topic[/url],3613.0.html # # Special Thanks : # # - ForeverZer0 & KK20 for method used in this script # - Wecoc for autotile addon # #============================================================================== module LiTTleDRAgo SCREEN_SIZE = [640,490] # Define the resolution of the game screen. These values can be anything # within reason. Centering, viewports, etc. will all be taken care of, but it # is recommended that you use values divisible by 32 for best results. AUTOTILE_SPEED = {} AUTOTILE_SPEED[:map_id] = :speed AUTOTILE_SPEED[0] = 6 # default speed #AUTOTILE_SPEED[35] = 0 # unchanged autotile #AUTOTILE_SPEED[159] = 16 # Speed of the autotile based on map_id CONTROL_SCREEN_SIZE = false # Control screen size with a mouse HIGH_PRIORITY = true # Change Game process priority to high SPRITE_COMPACT = true # Keep the sprite to the very minimum number CHARACTER_Z_FIX = { '178-Switch01' => 0, '180-Switch03' => 0, '181-Switch04' => 0, '199-Support07' => 0, } # Fix the screen_z value for events based on Graphic name. # You can also define z value for event by inserting <z: Z_VALUE> # on event name. # This way, flat events such as pitfall won't overlap with player z value. end core = "This script needs Drago - Core Engine ver 1.47 or above" rmvx = "This script not for RMVX" implemented = "%1$s has already implemented, Please remove the %1$s script" zoom = sprintf(implemented,"Map Zoom") tone = sprintf(implemented,"Tilemap Tone Changer" ) ($imported[:drg_core_engine] || 0) >= 1.47 || raise(core) LiTTleDRAgo::XP || LiTTleDRAgo::VXA || raise(rmvx) $imported[:drg_cr_map_zoom] && raise(zoom) $imported[:drg_tilemap_tone_changer] && raise(tone) #============================================================================== # ** Graphics #------------------------------------------------------------------------------ # This module handles all Graphics #============================================================================== class << Graphics #------------------------------------------------------------------------- # * Alias Listing #------------------------------------------------------------------------- alias_sec_method :zer0_graphics_transition, :transition alias_sec_method :drg_resolution_change_resize_screen, :resize_screen alias_sec_method :drg_resolution_change_update, :update #------------------------------------------------------------------------- # * Aliased method: resize_screen #------------------------------------------------------------------------- def resize_screen(width, height) width = (width / 32.0).round * 32 height = (height / 32.0).round * 32 if $game_map.respond_to?(:screen_size) $game_map.screen_size[0] = width $game_map.screen_size[1] = height end drg_resolution_change_resize_screen(width, height) end #------------------------------------------------------------------------- # * Aliased method: transition #------------------------------------------------------------------------- def transition(duration = 8, *args) if width <= 640 && height <= 480 return zer0_graphics_transition(duration, *args) end if duration > 0 viewport = Viewport.new(0,0,width,height) sprite = Sprite.new(viewport) sprite.bitmap = Graphics.snap_to_bitmap sprite2 = Sprite.new(viewport) sprite2.z = sprite.z - 10 sprite2.blend_type = 1 zer0_graphics_transition(0) fade = 255 / duration if (file = args.at(0)).is_a?(String) bitmap = Bitmap.new(file) sprite2.bitmap = bitmap.stretch(width,height) bitmap.dispose end duration.times {[sprite,sprite2].each {|s|s.opacity -= fade} && update } [sprite.bitmap, sprite2.bitmap, sprite, sprite2, viewport].dispose end zer0_graphics_transition(0) end #------------------------------------------------------------------------- # * Aliased method: update #------------------------------------------------------------------------- def update drg_resolution_change_update update_resolution_adjust end #------------------------------------------------------------------------- # * New method: update_resolution_adjust #------------------------------------------------------------------------- def update_resolution_adjust return unless LiTTleDRAgo::XP && $game_player return unless Game_Player.const_defined?(:CENTER_X) change = Game_Player.const_get(:CENTER_X) != $game_player.center_x change ||= Game_Player.const_get(:CENTER_Y) != $game_player.center_y return unless change resize_screen(width,height) $game_player.center($game_player.x,$game_player.y) end #------------------------------------------------------------------------- # * Overwriten method: fullscreen #------------------------------------------------------------------------- def fullscreen @fullscreen = true fill_monitor LiTTleDRAgo.hide_borders end #------------------------------------------------------------------------- # * Overwriten method: window #------------------------------------------------------------------------- def window @fullscreen = false LiTTleDRAgo.show_borders if $game_map && $game_map.screen_size.all? {|s| s.is_a?(Numeric)} x,y = $game_map.screen_size[0..1] x += ($game_map.screen_size[2] ||= 1) $game_map.screen_size[2] *= -1 drg_resolution_change_resize_screen(x,y) else x,y = LiTTleDRAgo::SCREEN_SIZE end resize_screen(x,y) end #------------------------------------------------------------------------- # * Overwriten method: fullscreen? #------------------------------------------------------------------------- define_method(:fullscreen?) { @fullscreen == true } end Graphics.window Graphics.disable_alt_enter Graphics.control_screen_size LiTTleDRAgo::CONTROL_SCREEN_SIZE Graphics.high_priority = LiTTleDRAgo::HIGH_PRIORITY GC.start #============================================================================== # ** Game_Map #------------------------------------------------------------------------------ # This class handles the map. It includes scrolling and passable determining # functions. Refer to "$game_map" for the instance of this class. #============================================================================== class Game_Map #-------------------------------------------------------------------------- # * Public Instance Variable #-------------------------------------------------------------------------- attr_sec_accessor :zoom_x, :zoom_y, 'Integer(1)' attr_sec_accessor :screen_size, 'LiTTleDRAgo::SCREEN_SIZE' attr_sec_accessor :tilemap_tone, 'Tone.new(0,0,0)' attr_sec_accessor :tilemap_opacity, 'Integer(255)' attr_sec_accessor :tilemap_hue, 'Integer(0)' #--------------------------------------------------------------------------- # * Redirect Listing #--------------------------------------------------------------------------- [:tilemap_tone,:tilemap_opacity].each do |meth| redirect_method :"#{meth}_changing?", "(@#{meth}_duration ||= 0) > 0" end #--------------------------------------------------------------------------- # * Define Sec Listing #--------------------------------------------------------------------------- define_sec_method(:zooming?) {(@zoom_duration ||= 0) > 0} define_sec_method(:screen_tile_x) {(Graphics.width / 32.0).ceil} define_sec_method(:screen_tile_y) {(Graphics.height / 32.0).ceil} #------------------------------------------------------------------------- # * Alias Listing #------------------------------------------------------------------------- alias_sec_method(:drg_scroll_right_adjust, :scroll_right) alias_sec_method(:drg_scroll_down_adjust, :scroll_down) alias_sec_method(:tilemap_effect_update, :update) alias_sec_method(:get_map_data, :data) #-------------------------------------------------------------------------- # * Aliased method: Scroll Down #-------------------------------------------------------------------------- def scroll_down(distance) times = vxa_map_multiplier if loop_vertical? @display_y += distance @display_y %= height * times @parallax_y += distance if @parallax_y && @parallax_loop_y else last_y = @display_y result = [@display_y + distance, (map_edge.at(1) / zoom_y)].min drg_scroll_down_adjust(distance) @display_y = result end end #-------------------------------------------------------------------------- # * Aliased method: Scroll Right #-------------------------------------------------------------------------- def scroll_right(distance) times = vxa_map_multiplier if loop_horizontal? @display_x += distance @display_x %= width * times @parallax_x += distance if @parallax_x && @parallax_loop_x else last_x = @display_x result = [@display_x + distance, (map_edge.at(0) / zoom_x)].min drg_scroll_right_adjust(distance) @display_x = result end end #-------------------------------------------------------------------------- # * New method: zoom #-------------------------------------------------------------------------- def zoom(*zoom) if zoom.size == 1 zoom = (zoom.first) elsif zoom.size == 3 x,y,zoom = zoom[0..2] end return unless zoom.is_a?(Numeric) old_zoom = @zoom_x @zoom_x = [[zoom,12].min, 1].max @zoom_y = [[zoom,12].min, 1].max $game_player.center(x,y) if x && y end #-------------------------------------------------------------------------- # * New method: zoom_in #-------------------------------------------------------------------------- def zoom_in(x = nil,y = nil, duration = 20) start_zoom(x,y, zoom_x >= 1 ? zoom_x + 1 : 1, duration) end #-------------------------------------------------------------------------- # * New method: zoom_out #-------------------------------------------------------------------------- def zoom_out(x = nil,y = nil,duration = 20) start_zoom(x,y, zoom_x - 1 >= 1 ? zoom_x - 1 : zoom_x - 0.5, duration) end #-------------------------------------------------------------------------- # * New method: map_edge #-------------------------------------------------------------------------- def map_edge times = vxa_map_multiplier [_w = [(width * zoom_x - screen_tile_x).ceil * times, 0].max, _h = [(height * zoom_y - screen_tile_y).ceil * times, 0].max] end #-------------------------------------------------------------------------- # * New method: autotile_speed #-------------------------------------------------------------------------- def autotile_speed(id = @map_id) speed = LiTTleDRAgo::AUTOTILE_SPEED @autotile_speed.is_a?(Array) || @autotile_speed = [] @autotile_speed[id] ||= (speed[id] || speed[0] || 0) end #-------------------------------------------------------------------------- # * New method: autotile_speed= #-------------------------------------------------------------------------- def autotile_speed=(*value) @autotile_speed.is_a?(Array) || @autotile_speed = [] @autotile_speed[@map_id] = [value.first,0].max if value.size == 1 @autotile_speed[value.first] = [value.at(1),0].max if value.size > 1 end #-------------------------------------------------------------------------- # * New method: vxa_map_multiplier #-------------------------------------------------------------------------- def vxa_map_multiplier LiTTleDRAgo::VXA ? 1 : 128 end #-------------------------------------------------------------------------- # * New method: screen_is_solid? #-------------------------------------------------------------------------- def screen_is_solid? tone = screen.tone.to_s.gsub(/([(),0 ])/i){''} return true if tone['255.255.255.'] return true if tone['255.-255.-255.'] return true if tone['-255.255.-255.'] return true if tone['-255.-255.255.'] return true if tone['255.255.-255.'] return true if tone['255.-255.255.'] return true if tone['-255.255.255.'] return true if tone['-255.-255.-255.'] end #-------------------------------------------------------------------------- # * Aliased method: data #-------------------------------------------------------------------------- def data data = self.reverse ? reverse_data : get_map_data data.make_changes = true data end #-------------------------------------------------------------------------- # * New method: reverse_data #-------------------------------------------------------------------------- def reverse_data @reverse_data ||= [] @reverse_data[@map_id] ||= get_map_data.reverse(true,false,false) end #-------------------------------------------------------------------------- # * New method: reverse= #-------------------------------------------------------------------------- def reverse=(val) return val if @reverse == val @reverse = ((@reverse_data||=[])[@map_id] = nil) || val spriteset && spriteset.reload_tilemap @reverse end #-------------------------------------------------------------------------- # * New method: reverse #-------------------------------------------------------------------------- def reverse @reverse && LiTTleDRAgo::XP end #-------------------------------------------------------------------------- # * New method: start_tilemap_tone #-------------------------------------------------------------------------- def start_tilemap_tone(tone = Tone.new(0,0,0,0), duration = 0) @tilemap_tone_target = tone.is_a?(Array) ? Tone.new(*tone) : tone.clone @tilemap_tone_duration = duration tilemap_tone_changing? || @tilemap_tone = @tilemap_tone_target.clone end #-------------------------------------------------------------------------- # * New method: start_tilemap_opacity #-------------------------------------------------------------------------- def start_tilemap_opacity(opacity = 255, duration = 0) @tilemap_opacity_target = opacity * 1.0 @tilemap_opacity_duration = duration tilemap_opacity_changing? || @tilemap_opacity = @tilemap_opacity_target end #-------------------------------------------------------------------------- # * New method: update_tilemap_tone #-------------------------------------------------------------------------- def update_tilemap_tone if tilemap_tone_changing? d = @tilemap_tone_duration target = @tilemap_tone_target @tilemap_tone.red = (@tilemap_tone.red * (d - 1) + target.red) / d @tilemap_tone.green = (@tilemap_tone.green * (d - 1) + target.green) / d @tilemap_tone.blue = (@tilemap_tone.blue * (d - 1) + target.blue) / d @tilemap_tone.gray = (@tilemap_tone.gray * (d - 1) + target.gray) / d @tilemap_tone_duration -= 1 tilemap_tone_changing? || @tilemap_tone = @tilemap_tone_target.clone end end #-------------------------------------------------------------------------- # * New method: update_tilemap_opacity #-------------------------------------------------------------------------- def update_tilemap_opacity if tilemap_opacity_changing? d = @tilemap_opacity_duration @tilemap_opacity = (@tilemap_opacity * (d - 1) + @tilemap_opacity_target) / d @tilemap_opacity_duration -= 1 tilemap_opacity_changing? || @tilemap_opacity = @tilemap_opacity_target end end #-------------------------------------------------------------------------- # * New method: start_zoom #-------------------------------------------------------------------------- def start_zoom(x,y, zoom_target, duration=20) @x_zoom = x @y_zoom = y @zoom_target = zoom_target * 1.0 @zoom_duration = @zoom_x == @zoom_target ? 0 : duration zooming? || zoom(@x_zoom,@y_zoom,@zoom_target) end #-------------------------------------------------------------------------- # * New method: update_zooming #-------------------------------------------------------------------------- def update_zooming if zooming? d = @zoom_duration power = (@zoom_x * (d - 1) + @zoom_target) / d @zoom_duration -= 1 zoom(@x_zoom,@y_zoom,power) zoom(@x_zoom,@y_zoom,@zoom_target) unless zooming? end end #-------------------------------------------------------------------------- # * Aliased method: update #-------------------------------------------------------------------------- def update(*args) tilemap_effect_update(*args) update_tilemap_tone update_tilemap_opacity update_zooming end end #============================================================================== # ** Interpreter #------------------------------------------------------------------------------ # This interpreter runs event commands. This class is used within the # Game_System class and the Game_Event class. #============================================================================== unless LiTTleDRAgo::VX class Interpreter #--------------------------------------------------------------------------- # * Redirect Listing #--------------------------------------------------------------------------- redirect_method :zoom, '$game_map.zoom' redirect_method :zoom_in, '$game_map.zoom_in' redirect_method :zoom_out, '$game_map.zoom_out' redirect_method :start_zoom, '$game_map.start_zoom' redirect_method :start_tilemap_opacity, '$game_map.start_tilemap_opacity' redirect_method :start_tilemap_tone, '$game_map.start_tilemap_tone' [:change_tilemap_tone,:change_character_tone].each do |meth| redirect_method :"#{meth}", :"$game_map.spriteset.#{meth}" end end end #============================================================================== # ** Game_Player #------------------------------------------------------------------------------ # This class handles the player. Its functions include event starting # determinants and map scrolling. Refer to "$game_player" for the one # instance of this class. #============================================================================== class Game_Player #--------------------------------------------------------------------------- # * Define Sec Listing #--------------------------------------------------------------------------- define_sec_method(:center_x) {((Graphics.width/2) / $game_map.zoom_x-16) * 4} define_sec_method(:center_y) {((Graphics.height/2) / $game_map.zoom_y-16) * 4} #------------------------------------------------------------------------- # * Alias Listing #------------------------------------------------------------------------- alias_sec_method(:drg_adjust_viewport_center, :center) #------------------------------------------------------------------------- # * Aliased method: center #------------------------------------------------------------------------- def center(x, y) if LiTTleDRAgo::XP Game_Player.const_set(:CENTER_X, center_x) Game_Player.const_set(:CENTER_Y, center_y) end drg_adjust_viewport_center(x, y) max_x = $game_map.map_edge.at(0) / $game_map.zoom_x max_y = $game_map.map_edge.at(1) / $game_map.zoom_y if LiTTleDRAgo::XP $game_map.display_x = [0, [(x * 32*4) - center_x, max_x.ceil].min].max $game_map.display_y = [0, [(y * 32*4) - center_y, max_y.ceil].min].max elsif $game_map.respond_to?(:set_display_pos) $game_map.set_display_pos(x - center_x, y - center_y) end end end #============================================================================== # ** Tilemap #------------------------------------------------------------------------------ # #============================================================================== class Tilemap #--------------------------------------------------------------------------- # * Public Instance Variables #--------------------------------------------------------------------------- method_defined?(:tileset) || attr_accessor(:tileset) method_defined?(:priorities)|| attr_accessor(:priorities) method_defined?(:autotiles) || attr_sec_accessor(:autotiles,'Array.new') end #============================================================================== # ** Table #------------------------------------------------------------------------------ # #============================================================================== class Table #-------------------------------------------------------------------------- # * Public Instance Variable #-------------------------------------------------------------------------- attr_sec_accessor :table_changes, :orig_value, 'Array.new' attr_accessor :make_changes #-------------------------------------------------------------------------- # * Alias Listing #-------------------------------------------------------------------------- alias_sec_method :set_method, :"[]=" #-------------------------------------------------------------------------- # * Set Data #-------------------------------------------------------------------------- def []=(*args) if @make_changes table_changes.push([*args]) && orig_value.push(self[*args[0..-2]]) @make_changes = false end set_method(*args) end #-------------------------------------------------------------------------- # * Reverse #-------------------------------------------------------------------------- def reverse(rx=true,ry=true,rz=true) reverse = self.clone _x = (0...xsize).to_a _y = (0...ysize).to_a _z = (0...zsize).to_a _x.each do |x| _rx = rx ? _x[-1-x] : x ysize == 1 && (reverse[x] = self[_rx]) && next _y.each do |y| _ry = ry ? _y[-1-y] : y zsize == 1 && (reverse[x,y] = self[_rx,_ry]) && next _z.each do |z| _rz = rz ? _z[-1-z] : z reverse[x,y,z] = self[_rx,_ry,_rz] end end end reverse end end #============================================================================== # ** RPG::Cache #============================================================================== ModCache = LiTTleDRAgo.cache module ModCache #---------------------------------------------------------------------------- # * Self #---------------------------------------------------------------------------- class << self #-------------------------------------------------------------------------- # * Constant #-------------------------------------------------------------------------- AUTO_INDEX = [[ [27,28,33,34], [ 5,28,33,34], [27, 6,33,34], [ 5, 6,33,34], [27,28,33,12], [ 5,28,33,12], [27, 6,33,12], [ 5, 6,33,12], [27,28,11,34], [ 5,28,11,34], [27, 6,11,34], [ 5, 6,11,34], [27,28,11,12], [ 5,28,11,12], [27, 6,11,12], [ 5, 6,11,12], [25,26,31,32], [25, 6,31,32], [25,26,31,12], [25, 6,31,12], [15,16,21,22], [15,16,21,12], [15,16,11,22], [15,16,11,12], [29,30,35,36], [29,30,11,36], [ 5,30,35,36], [ 5,30,11,36], [39,40,45,46], [ 5,40,45,46], [39, 6,45,46], [ 5, 6,45,46], [25,30,31,36], [15,16,45,46], [13,14,19,20], [13,14,19,12], [17,18,23,24], [17,18,11,24], [41,42,47,48], [ 5,42,47,48], [37,38,43,44], [37, 6,43,44], [13,18,19,24], [13,14,43,44], [37,42,43,48], [17,18,47,48], [13,18,43,48], [ 1, 2, 7, 8]], [[27,28,33,34], [49,50,55,56], [51,52,57,58], [49,52,55,58], [63,64,69,70], [65,66,71,72], [51,52,69,70], [ 5, 6,33,12], [61,62,67,68], [49,50,67,68], [53,54,59,60], [ 5, 6,11,34], [61,64,67,70], [ 5,28,11,12], [27, 6,11,12], [ 5, 6,11,12], [25,26,31,32], [25, 6,31,32], [25,26,31,12], [25, 6,31,12], [15,16,21,22], [15,16,21,12], [15,16,11,22], [15,16,11,12], [29,30,35,36], [29,30,11,36], [ 5,30,35,36], [ 5,30,11,36], [39,40,45,46], [ 5,40,45,46], [39, 6,45,46], [ 5, 6,45,46], [25,30,31,36], [15,16,45,46], [13,14,19,20], [13,14,19,12], [17,18,23,24], [17,18,11,24], [41,42,47,48], [ 5,42,47,48], [37,38,43,44], [37, 6,43,44], [13,18,19,24], [13,14,43,44], [37,42,43,48], [17,18,47,48], [13,18,43,48], [ 1, 2, 7, 8]] ].freeze #-------------------------------------------------------------------------- # * Public Instance Variable #-------------------------------------------------------------------------- attr_sec_reader :cache, 'Hash.new' #-------------------------------------------------------------------------- # * New method: autotile_cr_tilemap #-------------------------------------------------------------------------- def autotile_cr_tilemap(filename) key = "Graphics/Autotiles/CR#{filename}" if !@cache.include?(key) || @cache[key].disposed? @cache[key] = (filename=='') ? Bitmap.new(128,96) : autotile(filename) new_bm = self.format_autotiles(@cache[key], filename) @cache[key].dispose @cache[key] = new_bm @cache[key].instance_variable_set(:@autotile_name, filename) end return @cache[key] end #-------------------------------------------------------------------------- # * New method: include? #-------------------------------------------------------------------------- unless method_defined?(:include?) def include?(key) @cache[key] && !@cache[key].disposed? end end #-------------------------------------------------------------------------- # * New method: format_autotiles #-------------------------------------------------------------------------- def format_autotiles(bitmap, filename) if bitmap.height > 32 frames = bitmap.width / 96 index = bitmap.height == 192 ? AUTO_INDEX[1] : AUTO_INDEX[0] template = Bitmap.new(256*frames,192) frames.times {|a| (0...6).each { |i| (0...8).each { |j| index[8*i+j].each { |number| number -= 1 x, y = 16 * (number % 6), 16 * (number / 6) ox, oy = (32 * j + x % 32) + (a * 256), 32 * i + y % 32 rect = Rect.new(x + (a * 96), y, 16, 16) template.blt(ox, oy, bitmap, rect) }}}} return template else return bitmap end end #-------------------------------------------------------------------------- # * New method: tile #-------------------------------------------------------------------------- unless method_defined?(:format_tile) def format_tile(bitmap, tile_id, hue) filename = bitmap.pathname key = [filename, tile_id, hue] unless include?(key) @cache[key] = empty_bitmap x = (tile_id - 384) % 8 * 32 y = (tile_id - 384) / 8 * 32 rect = Rect.new(x, y, 32, 32) @cache[key].blt(0, 0, bitmap, rect) @cache[key].hue_change(hue) end @cache[key] end end #-------------------------------------------------------------------------- # * New method: clear_tile_cache #-------------------------------------------------------------------------- def clear_tile_cache @cache ||= {} @cache.reject! do |keys| keys.is_a?(Array) && keys.size == 3 && keys[0].is_a?(String) && keys[0].downcase["tilemap"] end GC.start end end end #============================================================================== # ** Bitmap #------------------------------------------------------------------------------ # #============================================================================== class Bitmap #-------------------------------------------------------------------------- # * Public Instance Variable #-------------------------------------------------------------------------- attr_sec_accessor :pathname, 'String.new' #-------------------------------------------------------------------------- # ● Alias Method #-------------------------------------------------------------------------- $@ || alias_method(:cr_path_init, :initialize) #-------------------------------------------------------------------------- # ● Object Initialization #-------------------------------------------------------------------------- def initialize(*args) @pathname = args.at(0) if args.at(0).is_a?(String) cr_path_init(*args) end end #============================================================================== # ** RPG::Weather #------------------------------------------------------------------------------ # A class for weather effects (rain, storm, and snow). It is used within the # Spriteset_Map class. #============================================================================== CRWeather = LiTTleDRAgo::VX ? Spriteset_Weather : RPG::Weather class CRWeather #-------------------------------------------------------------------------- # * Public Instance Variable #-------------------------------------------------------------------------- attr_reader :viewport attr_accessor :zoom_x, :zoom_y #-------------------------------------------------------------------------- # * Alias Listing #-------------------------------------------------------------------------- $@ || alias_method(:init_custom_resolution, :initialize) #-------------------------------------------------------------------------- # * Aliased method: initialize #-------------------------------------------------------------------------- def initialize(viewport) @viewport = viewport init_custom_resolution(@viewport) end #-------------------------------------------------------------------------- # * Overwriten method: update #-------------------------------------------------------------------------- def update return if @type == 0 return if $game_map && $game_map.screen_is_solid? update_screen if respond_to?(:update_screen) @sprites.each {|sprite| update_sprite(sprite) } end #-------------------------------------------------------------------------- # * Update Sprite #-------------------------------------------------------------------------- def update_sprite(sprite) sprite.ox = @ox sprite.oy = @oy case @type when 1, :rain then update_sprite_rain(sprite) when 2, :storm then update_sprite_storm(sprite) when 3, :snow then update_sprite_snow(sprite) end create_new_particle(sprite) if sprite.opacity < 64 end #-------------------------------------------------------------------------- # * Update Sprite [Rain] #-------------------------------------------------------------------------- def update_sprite_rain(sprite) sprite.bitmap = @rain_bitmap sprite.x -= 2 * sprite.zoom_x sprite.y += 16 * sprite.zoom_y sprite.opacity -= 8 end #-------------------------------------------------------------------------- # * Update Sprite [Storm] #-------------------------------------------------------------------------- def update_sprite_storm(sprite) sprite.bitmap = @storm_bitmap sprite.x -= 8 * sprite.zoom_x sprite.y += 16 * sprite.zoom_y sprite.opacity -= 12 end #-------------------------------------------------------------------------- # * Update Sprite [Snow] #-------------------------------------------------------------------------- def update_sprite_snow(sprite) sprite.bitmap = @snow_bitmap sprite.x -= 2 * sprite.zoom_x sprite.y += 8 * sprite.zoom_y sprite.opacity -= 8 end #-------------------------------------------------------------------------- # * Create New Particle #-------------------------------------------------------------------------- def create_new_particle(sprite) sprite.x = rand(Graphics.width + 100) - 100 + @ox sprite.y = rand(Graphics.height + 200) - 200 + @oy sprite.zoom_x = @zoom_x || 1 sprite.zoom_y = @zoom_y || 1 sprite.x *= sprite.zoom_x sprite.y *= sprite.zoom_y sprite.opacity = 160 + rand(96) end #--------------------------------------------------------------------------- # * New method: method_missing #--------------------------------------------------------------------------- def method_missing(val,*a,&b) en = @sprites.flatten.find_all {|s|s.respond_to?(val.to_sym)} if en.empty? text = "Undefined method #{val} at #{self.inspect}" raise(NoMethodError,text,caller(1)) end return en.map {|s| s.send(val.to_sym,*a,&b)} end end #============================================================================== # ** Plane #------------------------------------------------------------------------------ # This class is the rewrite of the default plane class #============================================================================== class CRPlane < Sprite #--------------------------------------------------------------------------- # * Public Instance Variable #--------------------------------------------------------------------------- attr_reader :bitmap #--------------------------------------------------------------------------- # * New method: z= #--------------------------------------------------------------------------- def z=(z) super(z * 1000) end #--------------------------------------------------------------------------- # * New method: ox= #--------------------------------------------------------------------------- def ox=(ox) return if $game_map && $game_map.screen_is_solid? return if bitmap.nil? || bitmap.disposed? super(ox % bitmap.width) if bitmap.is_a?(Bitmap) end #--------------------------------------------------------------------------- # * New method: oy= #--------------------------------------------------------------------------- def oy=(oy) return if $game_map && $game_map.screen_is_solid? return if bitmap.nil? || bitmap.disposed? super(oy % bitmap.height) if bitmap.is_a?(Bitmap) end #--------------------------------------------------------------------------- # * New method: dispose #--------------------------------------------------------------------------- def dispose @plane && (@plane.disposed? || @plane.dispose) super unless disposed? end #--------------------------------------------------------------------------- # * New method: bitmap= #--------------------------------------------------------------------------- def bitmap=(tile) return if @bitmap == tile @bitmap = tile if @bitmap.is_a?(Bitmap) xx = 1 + (Graphics.width.to_f / tile.width).ceil yy = 1 + (Graphics.height.to_f / tile.height).ceil @plane.dispose if @plane.respond_to?(:dispose) && @plane.not.disposed? @plane = Bitmap.new(@bitmap.width * xx, @bitmap.height * yy) (0..xx).each {|x| (0..yy).each {|y| @plane.blt(x * @bitmap.width, y * @bitmap.height, @bitmap, @bitmap.rect) }} super(@plane) else super(nil) end end #--------------------------------------------------------------------------- # * Undefine methods dealing with coordinates to do nothing. #--------------------------------------------------------------------------- undef :x, :x=, :y, :y= if method_defined?(:x) end #============================================================================== # ** Viewport #------------------------------------------------------------------------------ # #============================================================================== class Viewport #-------------------------------------------------------------------------- # * Overwriten method: update_viewport_sizes #-------------------------------------------------------------------------- def update_viewport_sizes map = $game_map w, h = Graphics.width, Graphics.height hor = $game_map.loop_horizontal? ver = $game_map.loop_vertical? _w = ($game_map.width * 32 * $game_map.zoom_x).floor _h = ($game_map.height * 32 * $game_map.zoom_y).floor dx = w > _w && !hor ? ((w - _w).floor.abs / 32) * 16 : 0 dw = hor ? w : [w, $game_map.width * 32 * $game_map.zoom_x].min dy = h > _h && !ver ? ((h - _h).floor.abs / 32) * 16 : 0 dh = ver ? h : [h, $game_map.height * 32 * $game_map.zoom_y].min resize(Rect.new(dx, dy, dw, dh)) end end #============================================================================== # ** ZTilemap #------------------------------------------------------------------------------ # This class is the rewrite of the default tilemap class #============================================================================== class ZTilemap #--------------------------------------------------------------------------- # * Public Instance Variables #--------------------------------------------------------------------------- attr_reader :map_data, :viewport attr_accessor :tileset, :tone, :priorities, :sprite_compact attr_sec_accessor :autotiles, 'Array.new' attr_sec_accessor :ox, :oy, :zoom_x, :zoom_y, :hue, 'Integer(1)' attr_sec_accessor :opacity, 'Integer(255)' attr_sec_reader :layers, :bitmap_layers, :extra_map_data, 'Array.new' #--------------------------------------------------------------------------- # * Redirect Listing #--------------------------------------------------------------------------- redirect_method :width, '$game_map.screen_tile_x + 2' redirect_method :height, '$game_map.screen_tile_y + 2' #--------------------------------------------------------------------------- # * Define Sec Listing #--------------------------------------------------------------------------- define_sec_method(:all_sprites) { layers.flatten.select {|s| is_sprite?(s)}} define_sec_method(:is_sprite?) { |s| s.is_a?(Sprite) && s.not.disposed? } #--------------------------------------------------------------------------- # * Alias Listing #--------------------------------------------------------------------------- alias_method :bitmaps, :autotiles #--------------------------------------------------------------------------- # * Object Initialization #--------------------------------------------------------------------------- def initialize(viewport) @viewport = viewport @sprite_compact = false#LiTTleDRAgo::SPRITE_COMPACT create_sprites create_carrot end #--------------------------------------------------------------------------- # * New method: create_sprites #--------------------------------------------------------------------------- def create_sprites 6.times do |i| layers[i] ||= [] (i % 6 == 0 ? 1 : height).times do |s| layers[i][s] = Sprite.new(@viewport) unless is_sprite?(layers[i][s]) end layers[i].each_with_index do |s,r| next unless is_sprite?(s) s.y = r * 32 * zoom_y s.z = (i % 6 == 0) ? 0 : (r * 32 + 32 + (i % 6) * 32) s.mirror = $game_map.reverse end end end #--------------------------------------------------------------------------- # * New method: create_carrot #--------------------------------------------------------------------------- def create_carrot @draw_tiles = carrot do |x,y,data,prio| [0,1,2].each do |r| if (id = data[x,y,r]).to_i == 0 || (layer = prio[id]).nil? next elsif @layer_clear && @layer_clear.not.include?(layer) @bitmap_layers[layer].fill_rect(x*32,y*32,32,32,Color.erase) @layer_clear.push(layer) end refresh_tiles(x,y,r,id) end end @change_tone = carrot {|s| all_sprites.tone = (@tone = s) } @change_opacity = carrot {|s| all_sprites.opacity = (@opacity = s)} @change_autotile_hue = carrot do |a,old,hue| [old.to_i != 0 && a.hue_change((old - 360).abs)] && a.hue_change(hue) end end #--------------------------------------------------------------------------- # * New method: ox=, oy=, zoom_x=, zoom_y= #--------------------------------------------------------------------------- [:ox, :oy, :zoom_x, :zoom_y].each do |a| meth = "def %1$s=(%1$s) (@%1$s != %1$s) && (@%1$s = %1$s) && %2$s end" module_eval(sprintf(meth, a ,'adjust_sprites')) end #--------------------------------------------------------------------------- # * New method: tone= #--------------------------------------------------------------------------- def tone=(*tone) new_tone = tone.flatten.size == 4 ? Tone.new(*tone.flatten) : tone.first.is_a?(Tone) ? tone.first : nil @tone.to_s == new_tone.to_s || @change_tone.call(new_tone.clone) end #--------------------------------------------------------------------------- # * New method: opacity= #--------------------------------------------------------------------------- def opacity=(opacity) opacity = [[opacity.round,255].min,0].max @opacity == opacity || @change_opacity.call(opacity) end #--------------------------------------------------------------------------- # * New method: hue= #--------------------------------------------------------------------------- def hue=(hue) return if @hue == (hue % 360) old = self.hue @hue = hue % 360 all_autotiles = @autotiles + extra_map_data.map {|m| m[:autotiles]}.flatten @change_autotile_hue.call(all_autotiles.uniq, old, @hue) refresh end #--------------------------------------------------------------------------- # * New method: Adjust Sprites #--------------------------------------------------------------------------- def adjust_sprites @times_compact ||= [] @layers_used && @layers.size.times do |i| layer = @layers[i] (i % 6 == 0 ? 1 : height).times do |r| sprite = layer[r] d = 32 _r = 32 + (i % 6) * 32 _y = r * 32 * zoom_y _z = i % 6 == 0 ? 0 : r * d + _r # (r * d + _r) unless is_sprite?(sprite) change = _y <= @viewport.height if @sprite_compact change &&= !char_out_range?(_r, (height-1)*d+_r) change &&= @layers_used[i] > 0 end change || next sprite = (layer[r] = Sprite.new(@viewport)) sprite.bitmap = bitmap_layers[i] sprite.tone = tone if tone sprite.opacity = opacity sprite.mirror = $game_map.reverse sprite.zoom_x, sprite.zoom_y = zoom_x, zoom_y else change = _y > @viewport.height if (@times_compact[i] ||= 0) < 10 && @sprite_compact change ||= (r > 0 && char_out_range?(_r, (height-1)*d+_r)) change ||= (r > 0 && @layers_used[i] == 0) end sprite.y, sprite.z = _y, _z.ceil change && [sprite.dispose, @times_compact[i] += 1] && next end sprite.y, sprite.z = _y, _z.ceil _wd = @viewport.width/zoom_x _ox = sprite.mirror ? (sprite.bitmap.width-ox)-_wd : (_wd+=10) && ox if layer.select { |s| is_sprite?(s) }.size == 1 sprite.src_rect.set(_ox, oy, _wd, @viewport.height/zoom_x + 10) else sprite.src_rect.set(_ox, (oy + r*32), _wd, 33) end sprite.zoom_x, sprite.zoom_y = zoom_x, zoom_y end end end #--------------------------------------------------------------------------- # * New method: char_out_range? #--------------------------------------------------------------------------- def char_out_range?(z1,z2) return false unless (s = $game_map.spriteset).is_a?(Spriteset_Map) s.character_sprites.all? do |d| d.not.disposed? && d.opacity > 0 && d.visible && (d.z).not.between?(z1,z2) end end #--------------------------------------------------------------------------- # * New method: Frame Dispose #--------------------------------------------------------------------------- def dispose all_sprites.each { |s| s.dispose } bitmap = bitmap_layers bitmap += extra_map_data.map {|m| m[:autotiles]}.flatten - @autotiles bitmap += extra_map_data.map {|m| m[:tileset]}.flatten bitmap.compact.each { |s| s.disposed? || s.dispose } @layers.clear GC.start end #--------------------------------------------------------------------------- # * New method: Change Map Data #--------------------------------------------------------------------------- def map_data=(data) return if @map_data == data @map_data = data @map_data_reverse = data.reverse(true,false,false) 6.times do |i| bitmap_layers[i].dispose if bitmap_layers[i] && bitmap_layers[i].disposed? bitmap_layers[i] = Bitmap.new($game_map.width*32,$game_map.height*32) layers[i].each { |s| is_sprite?(s) && s.bitmap = bitmap_layers[i] } end refresh end #--------------------------------------------------------------------------- # * New method: Map Data #--------------------------------------------------------------------------- def map_data $game_map.reverse ? @map_data_reverse : @map_data end #--------------------------------------------------------------------------- # * New method: Change priorities #--------------------------------------------------------------------------- def priorities=(priorities) return if @priorities == priorities @priorities = priorities refresh end #--------------------------------------------------------------------------- # * New method: Frame Refresh #--------------------------------------------------------------------------- def refresh return unless @priorities && @map_data LiTTleDRAgo.cache.clear_tile_cache @animated_tiles = [] @unrefreshed_tile = [] @layers_used = [] 7.times do |i| @total_frames = [] if i == 0 @current_frame = [] if i == 0 bm = (@current_frame[i] = @layers_used[i] = 0) && autotiles[i] bm.nil? && @total_frames[i] = 1 bm.nil? || @total_frames[i] = bm.width / (bm.height > 32 ? 256 : 32) extra_map_data.each do |data| data[:total_frames] = [] if i == 0 data[:current_frame] = [] if i == 0 bm = (data[:current_frame][i] = 0) && data[:autotiles][i] bm.nil? && data[:total_frames][i] = 1 bm.nil? || data[:total_frames][i] = bm.width / (bm.height>32 ? 256 : 32) end end _w = @viewport.width _h = @viewport.height layers[0][0].src_rect.set(ox, oy, _w/zoom_x, _h/zoom_y ) (0...map_data.xsize).each do |x| (0...map_data.ysize).each do |y| if in_range?(x,y) update_map_changes(x,y) else next if @unrefreshed_tile.include?([x,y]) @unrefreshed_tile.push([x,y]) @unrefreshed_tile.uniq! end end end adjust_sprites end #--------------------------------------------------------------------------- # * New method: Refresh Tiles #--------------------------------------------------------------------------- def refresh_tiles(x,y,z,i,d = nil) return if i.nil? || i == 0 i < 384 ? refresh_autotile(x,y,z,i,d) : refresh_regular_tile(x,y,z,i,d) end #--------------------------------------------------------------------------- # * New method: Refresh Autotile #--------------------------------------------------------------------------- def refresh_autotile(x,y,z,id,data) layer = data.nil? ? @priorities[id] : data[:priorities][id] tframe = data.nil? ? @total_frames : data[:total_frames] cframe = data.nil? ? @current_frame : data[:current_frame] bitmap = data.nil? ? @autotiles.at(id/48-1) : data[:autotiles].at(id/48-1) return if bitmap.nil? || layer.nil? div = (fid = id / 48 - 1) &&(id % 48) if @animated_tiles.not.include?([x,y]) && tframe[fid] > 1 @animated_tiles.push([x,y]) @animated_tiles.uniq! end rect = Rect.new((div % 8)*32 + cframe[fid] * 256, (div / 8)*32, 32, 32) bitmap_layers[layer].blt(x*32, y*32, bitmap, rect) @layers_used[layer] = [(@layers_used[layer] + 1) % 10000,1].max end #--------------------------------------------------------------------------- # * New method: Refresh Regular Tile #--------------------------------------------------------------------------- def refresh_regular_tile(x,y,z,id,data) tileset = data.nil? ? @tileset : data[:tileset] layer = data.nil? ? @priorities[id] : data[:priorities][id] return if layer.nil? || tileset.not.is_a?(Bitmap) bitmap = LiTTleDRAgo.cache.format_tile(tileset, id, hue) bitmap_layers[layer].blt(x*32, y*32, bitmap, Rect.new(0, 0, 32, 32)) @layers_used[layer] = [(@layers_used[layer] + 1) % 10000, 1].max end #--------------------------------------------------------------------------- # * New method: force_refresh #--------------------------------------------------------------------------- def force_refresh refresh (@unrefreshed_tile ||= []).each {|x,y| update_map_changes(x,y)} (@unrefreshed_tile.clear) end #--------------------------------------------------------------------------- # * New method: Frame Update #--------------------------------------------------------------------------- def update update_map_data update_autotile update_unrefreshed_tile end #--------------------------------------------------------------------------- # * New method: Update Unrefreshed Tile #--------------------------------------------------------------------------- def update_unrefreshed_tile if @unrefreshed_tile && @unrefreshed_tile.not.empty? unrefreshed = @unrefreshed_tile.select { |x,y| in_range?(x,y) } if unrefreshed.not.empty? (unrefreshed).each {|x,y| update_map_changes(x,y)} (@unrefreshed_tile -= unrefreshed) && adjust_sprites end end end #--------------------------------------------------------------------------- # * New method: Update Map Data #--------------------------------------------------------------------------- def update_map_data if map_data.table_changes.not.empty? map_data.table_changes.each do|item| x,y,z,tile_id = item update_map_changes(x,y) end map_data.table_changes.clear map_data.make_changes = false adjust_sprites end end #--------------------------------------------------------------------------- # * New method: Update the autotile #--------------------------------------------------------------------------- def update_autotile return if $game_map.screen_is_solid? speed = $game_map.autotile_speed total = [(@autotile_total || 0) / 10, 0].max if speed > 0 && Graphics.frame_count % (speed + total) == 0 7.times do |i| extra_map_data.each do |data| next if (total = data[:total_frames].at(i)) == 0 data[:current_frame][i] = (data[:current_frame].at(i) + 1) % total end next if (total = @total_frames.at(i)) == 0 @current_frame[i] = (@current_frame.at(i) + 1) % total end animated = @animated_tiles.select { |x,y| in_range?(x,y) } animated.each {|x,y| update_map_changes(x,y) } @autotile_total = animated.size end end #--------------------------------------------------------------------------- # * New method: in_range? #--------------------------------------------------------------------------- def in_range?(x=nil,y=nil) return false if layers[0].nil? || layers[0][0].nil? rect = @layers[0][0].src_rect _x = x && (x * 32).between?(rect.x-32, rect.x + rect.width) _y = y && (y * 32).between?(rect.y-32, rect.y + rect.height) return _x && _y if x && y return _x if x return _y if y return false end #--------------------------------------------------------------------------- # * New method: Update Map Changes #--------------------------------------------------------------------------- def update_map_changes(x,y) @layer_clear ||= [] @layer_clear.clear draw = [[x,y,map_data,priorities]] draw += extra_map_data.map {|data|[x,y,data[:map].data,data[:priorities]]} draw.each {|data| @draw_tiles.call(*data)} end end #============================================================================== # ** Game_Character #------------------------------------------------------------------------------ # This class deals with characters. It's used as a superclass for the # determinants and map scrolling. Refer to "$game_player" for the one # Game_Player and Game_Event classes. #============================================================================== class Game_Character #-------------------------------------------------------------------------- # * Alias Listing #-------------------------------------------------------------------------- alias_sec_method(:screen_x_before_zoom, :screen_x) alias_sec_method(:screen_y_before_zoom, :screen_y) alias_sec_method(:screen_z_before_zoom, :screen_z) #-------------------------------------------------------------------------- # * Aliased method: screen_x #-------------------------------------------------------------------------- def screen_x(*args) screen_x_before_zoom(*args) * $game_map.zoom_x end #-------------------------------------------------------------------------- # * Aliased method: screen_y #-------------------------------------------------------------------------- def screen_y(*args) screen_y_before_zoom(*args) * $game_map.zoom_y end #-------------------------------------------------------------------------- # * Aliased method: screen_z #-------------------------------------------------------------------------- def screen_z(*args) if self.is_a?(Game_Event) return 999 if @always_on_top return $1.to_i if self.name[/\<Z:\s*([-]?\d+)\s*\>/i] return screen_z_tilemap_fix if screen_z_tilemap_fix.is_a?(Integer) end return screen_z_before_zoom(*args) end #-------------------------------------------------------------------------- # * New method: screen_z_tilemap_fix #-------------------------------------------------------------------------- def screen_z_tilemap_fix LiTTleDRAgo::CHARACTER_Z_FIX.each do |key,value| if value.is_a?(Array) && key.is_a?(Integer) return key if value.any?{|v|"#{v}".downcase == @character_name.downcase} elsif key.is_a?(Array) && value.is_a?(Integer) return value if key.any?{|v|"#{v}".downcase == @character_name.downcase} elsif (key.is_a?(String) || key.is_a?(Symbol)) && value.is_a?(Integer) return value if "#{key}".downcase == @character_name.downcase end end return nil end end #============================================================================== # ** Sprite_Character #------------------------------------------------------------------------------ # This sprite is used to display the character.It observes the Game_Character # class and automatically changes sprite conditions. #============================================================================== class Sprite_Character #-------------------------------------------------------------------------- # * Alias Listing #-------------------------------------------------------------------------- alias_sec_method(:zoom_update_scrolling, :update) #-------------------------------------------------------------------------- # * Aliased method: update #-------------------------------------------------------------------------- def update(*args) if @old_character_zoom_x self.zoom_x = @old_character_zoom_x self.zoom_y = @old_character_zoom_y end zoom_update_scrolling(*args) @old_character_zoom_x = self.zoom_x @old_character_zoom_y = self.zoom_y self.zoom_x *= $game_map.zoom_x self.zoom_y *= $game_map.zoom_y end #-------------------------------------------------------------------------- # * New method: in_range? #-------------------------------------------------------------------------- unless method_defined?(:in_range?) def in_range? cw = self.src_rect ? self.src_rect.width : 32 ch = self.src_rect ? self.src_rect.height : 32 return @character.screen_x.round.between?(self.viewport.x - cw, self.viewport.x + self.viewport.width) && @character.screen_y.round.between?(self.viewport.y - ch, self.viewport.y + self.viewport.height) end end end #============================================================================== # ** Spriteset_Map #------------------------------------------------------------------------------ # This class brings together map screen sprites, tilemaps, etc. # It's used within the Scene_Map class. #============================================================================== class Spriteset_Map #--------------------------------------------------------------------------- # * Public Instance Variables #--------------------------------------------------------------------------- attr_reader :character_sprites, :tilemap attr_reader :viewport1, :viewport2, :viewport3 #-------------------------------------------------------------------------- # * Alias Listing #-------------------------------------------------------------------------- $@ || alias_method(:init_drgcr_tilemap, :initialize) alias_sec_method(:update_drgcr_tilemap, :update) #-------------------------------------------------------------------------- # * Aliased method: initialize #-------------------------------------------------------------------------- def initialize(*args) check_autotile_height init_drgcr_tilemap(*args) end #--------------------------------------------------------------------------- # * New method: check_autotile_height #--------------------------------------------------------------------------- def check_autotile_height return unless LiTTleDRAgo::XP $game_map.autotile_names.each do |autotile_name| bitmap = ModCache.autotile(autotile_name) [@force_tilemap_enabled = true] && break if bitmap.height == 192 end end #-------------------------------------------------------------------------- # * Aliased method: update #-------------------------------------------------------------------------- def update(*args) adjust_viewport adjust_tilemap adjust_old_zoom update_drgcr_tilemap(*args) update_tilemap_zoom end #--------------------------------------------------------------------------- # * New method: adjust_old_zoom #--------------------------------------------------------------------------- def adjust_old_zoom if @old_fog_zoom_x @fog.zoom_x = @old_fog_zoom_x @fog.zoom_y = @old_fog_zoom_y @panorama.zoom_x = @old_panorama_zoom_x @panorama.zoom_y = @old_panorama_zoom_y end end #--------------------------------------------------------------------------- # * New method: viewport_sprite #--------------------------------------------------------------------------- def viewport_sprite(*v) v.collect! {|s| s.is_a?(Symbol) ? instance_variable_get(:"@#{s}") : s } v.reject! {|s| s.not.is_a?(Viewport)} all = instance_variables.map {|s| instance_variable_get("#{s}")}.flatten all.select {|s| s.respond_to?(:viewport) && v.include?(s.viewport)} end #--------------------------------------------------------------------------- # * New method: change_tilemap_tone #--------------------------------------------------------------------------- def change_tilemap_tone(tone = Tone.new(0,0,0,0), *char) if tone.is_a?(Array) && (3..4) === tone.size result = $game_map.tilemap_tone = Tone.new(*tone) elsif tone.is_a?(Tone) result = $game_map.tilemap_tone = tone else return end sprite = viewport_sprite(:viewport1) sprite.reject! {|s| s.is_a?(Sprite_Character)} sprite.each {|s| s.tone = result if s.respond_to?(:tone=) } change_character_tone(tone, *char) unless char.empty? end #--------------------------------------------------------------------------- # * New method: change_character_tone #--------------------------------------------------------------------------- def change_character_tone(tone = Tone.new(0,0,0,0), *char) char = char.collect {|c| c.is_a?(Range) ? c.to_a : c}.flatten char = char.collect {|c| c.is_a?(Range) ? c.to_a : c}.flatten char.collect! {|c| c.is_a?(Game_Character) ? c : $game_map.interpreter.get_character(c)} sprite = viewport_sprite(:viewport1) sprite.reject! {|s| s.not.is_a?(Sprite_Character) } sprite.reject! {|s| char.not.include?(s.character)} if tone.is_a?(Array) && (3..4) === tone.size sprite.tone(:tone=, Tone.new(*tone)) elsif tone.is_a?(Tone) sprite.send(:tone=, tone) end end #-------------------------------------------------------------------------- # * New method: reload_tilemap #-------------------------------------------------------------------------- def reload_tilemap return [dispose_tilemap, create_tilemap] if LiTTleDRAgo::VXA @tilemap.respond_to?(:dispose) && @tilemap.dispose 7.times do |i| auto = @tilemap.autotiles[i] auto.respond_to?(:dispose) && (auto.disposed? || auto.dispose) end res = tilemap_enabled? ? ZTilemap : Tilemap @tilemap = res.new(@viewport1) @tilemap.tileset = ModCache.tileset($game_map.tileset_name) 7.times do |i| autotile_name = $game_map.autotile_names[i] @tilemap.autotiles[i] = @tilemap.is_a?(ZTilemap) ? ModCache.autotile_cr_tilemap(autotile_name) : ModCache.autotile(autotile_name) end update_tilemap_effect @tilemap.priorities = $game_map.priorities @tilemap.map_data = $game_map.data @tilemap.update @viewport_screen_width = 0 end #-------------------------------------------------------------------------- # * New method: reload_plane #-------------------------------------------------------------------------- def reload_plane z1 = @panorama.respond_to?(:z) ? @panorama.z : -1000 z2 = @fog.respond_to?(:z) ? @fog.z : 5000 z1 /= 1000 if @panorama.is_a?(CRPlane) z2 /= 1000 if @fog.is_a?(CRPlane) res = plane_enabled? ? CRPlane : Plane bitmap1 = @panorama.respond_to?(:bitmap) ? @panorama.bitmap : nil bitmap2 = @fog.respond_to?(:bitmap) ? @fog.bitmap : nil @panorama.respond_to?(:dispose) && @panorama.dispose @fog.respond_to?(:dispose) && @fog.dispose @panorama = res.new(@viewport1) @fog = res.new(@viewport1) @panorama.bitmap = bitmap1 if bitmap1.is_a?(Bitmap) @fog.bitmap = bitmap2 if bitmap2.is_a?(Bitmap) @panorama.z, @fog.z = z1, z2 @viewport_screen_width = 0 end #-------------------------------------------------------------------------- # * New method: update_tilemap_zoom #-------------------------------------------------------------------------- def update_tilemap_zoom @weather.zoom_x = $game_map.zoom_x @weather.zoom_y = $game_map.zoom_y @old_fog_zoom_x = @fog.zoom_x @old_fog_zoom_y = @fog.zoom_y @old_panorama_zoom_x = @panorama.zoom_x @old_panorama_zoom_y = @panorama.zoom_y @fog.zoom_x *= $game_map.zoom_x @fog.zoom_y *= $game_map.zoom_y @panorama.zoom_x *= $game_map.zoom_x @panorama.zoom_y *= $game_map.zoom_y update_tilemap_effect end #-------------------------------------------------------------------------- # * New method: update_tilemap_effect #-------------------------------------------------------------------------- def update_tilemap_effect return if @tilemap.not.is_a?(ZTilemap) @tilemap.zoom_x = $game_map.zoom_x @tilemap.zoom_y = $game_map.zoom_y @tilemap.opacity = $game_map.tilemap_opacity @tilemap.hue = $game_map.tilemap_hue @tilemap.tone = $game_map.tilemap_tone end #-------------------------------------------------------------------------- # * Overwriten method: viewport_size_change? #-------------------------------------------------------------------------- def viewport_size_change? return true if @viewport_map_width != $game_map.width * $game_map.zoom_x return true if @viewport_map_height != $game_map.height * $game_map.zoom_y return true if @viewport_screen_width != Graphics.width return true if @viewport_screen_height != Graphics.height end #-------------------------------------------------------------------------- # * New method: adjust_viewport #-------------------------------------------------------------------------- def adjust_viewport if viewport_size_change? @viewport_map_width = $game_map.width * $game_map.zoom_x @viewport_map_height = $game_map.height * $game_map.zoom_y @viewport_screen_width = Graphics.width @viewport_screen_height = Graphics.height [@viewport1,@viewport2,@viewport3].compact.update_viewport_sizes end end #-------------------------------------------------------------------------- # * New method: adjust_tilemap #-------------------------------------------------------------------------- def adjust_tilemap if LiTTleDRAgo::XP if tilemap_enabled? reload_tilemap if @tilemap.is_a?(Tilemap) else reload_tilemap if @tilemap.is_a?(ZTilemap) end end if plane_enabled? reload_plane if @panorama.is_a?(Plane) || @fog.is_a?(Plane) else reload_plane if @panorama.is_a?(CRPlane) || @fog.is_a?(CRPlane) end end #-------------------------------------------------------------------------- # * New method: tilemap_enabled? #-------------------------------------------------------------------------- def tilemap_enabled? return true if @force_tilemap_enabled return true unless LiTTleDRAgo::RGSS1 return true unless @viewport1.width <= 640 && @viewport1.height <= 480 return true unless (map = $game_map) && map.zoom_x * map.zoom_y == 1 return true unless map.tilemap_opacity >= 255 return true unless map.tilemap_hue <= 0 return true unless map.tilemap_tone.to_s.get_int == 0 return true if map.reverse return false end #-------------------------------------------------------------------------- # * New method: plane_enabled? #-------------------------------------------------------------------------- def plane_enabled? return true unless LiTTleDRAgo::RGSS1 return true unless @viewport1.width <= 640 && @viewport1.height <= 480 return false end end
#==============================================================================
# ** Drago - Custom Resolution
# Version : 2.17
# Contact : littledrago.blogspot.com / forum.chaos-project.com
#==============================================================================
($imported ||= {})[:drg_custom_resolution] = 2.17
#==============================================================================
#
# Introduction :
#
# Version 2 from previous Drago - Custom Resolution
#
# Issue :
#
# - Normal transition didn't work when resolution is more than 640x480
# - ALT+Enter is disabled by default
# - Custom menu system will require an edit to match the new resolution
# - Anything that modify Sprite_Character & Spriteset_Map will require an edit
#
# Script Call :
#
# Graphics.window
# Graphics.fullscreen
# Graphics.fullscreen? # returns true if game is fullscreen
#
# $game_map.start_zoom(X, Y, ZOOM_VALUE, DURATION = 20)
# $game_map.zoom(X = nil, Y = nil, ZOOM_VALUE)
# $game_map.zoom_in(X = nil, Y = nil, DURATION = 20)
# $game_map.zoom_out(X = nil, Y = nil, DURATION = 20)
#
# $game_map.reverse(true / false) # Flip the map
#
# $game_map.start_tilemap_opacity(OPACITY = 255, DURATION = 20)
# $game_map.start_tilemap_tone(TONE = Tone.new(0,0,0,0), DURATION = 0)
#
#
# change_tilemap_tone(TONE,*CHARACTER) # change tilemap tone
# change_character_tone(TONE,*CHARACTER) # change character tone without
# changing the tilemap
#
# X, Y = Zoom focus
#
# ZOOM_VALUE = Integer from 1-12
#
# OPACITY = Integer from 0-255
#
# TONE = [R,G,B,A] or Tone.new(R,G,B,A)
#
# CHARACTER = $game_map.events.values # all events
# = $game_map.events.keys # all events
# = $game_player # player
# = -1 # player
# = 0 # this event
# = [2,3,4,6] # events with selected id
# = [-1,2,3,4,6] # player & events with selected id
# = [0,2,3,4,6] # this event & events with selected id
# = (1..99) # events in range
# = [(1..8),20,25,(30..42)] # events in range
#
# * will not change the character tone if left out
#
# Links :
#
# - Fantasist's Transitions Pack
# [url]http://forum.chaos-project.com/index.php/topic[/url],1390.0.html
# - ForeverZer0's Add-ons
# [url]http://forum.chaos-project.com/index.php/topic[/url],7862.0.html
# - ThallionDarkshine's Add-ons
# [url]http://forum.chaos-project.com/index.php/topic[/url],12655.0.html
# - Drago Transition Pack
# [url]http://forum.chaos-project.com/index.php/topic[/url],13488.0.html
#
# - Adjust Menu Position
# [url]http://forum.chaos-project.com/index.php/topic[/url],13781.0.html
#
# - ThallionDarkshine's F12 Fix
# [url]http://forum.chaos-project.com/index.php/topic[/url],13629.0.html
# - Zeriab's F12 Pause with images
# [url]http://forum.chaos-project.com/index.php/topic[/url],3613.0.html
#
# Special Thanks :
#
# - ForeverZer0 & KK20 for method used in this script
# - Wecoc for autotile addon
#
#==============================================================================
module LiTTleDRAgo
SCREEN_SIZE = [640,490]
# Define the resolution of the game screen. These values can be anything
# within reason. Centering, viewports, etc. will all be taken care of, but it
# is recommended that you use values divisible by 32 for best results.
AUTOTILE_SPEED = {}
AUTOTILE_SPEED[:map_id] = :speed
AUTOTILE_SPEED[0] = 6 # default speed
#AUTOTILE_SPEED[35] = 0 # unchanged autotile
#AUTOTILE_SPEED[159] = 16
# Speed of the autotile based on map_id
CONTROL_SCREEN_SIZE = false
# Control screen size with a mouse
HIGH_PRIORITY = true
# Change Game process priority to high
SPRITE_COMPACT = true
# Keep the sprite to the very minimum number
CHARACTER_Z_FIX = {
'178-Switch01' => 0,
'180-Switch03' => 0,
'181-Switch04' => 0,
'199-Support07' => 0,
}
# Fix the screen_z value for events based on Graphic name.
# You can also define z value for event by inserting <z: Z_VALUE>
# on event name.
# This way, flat events such as pitfall won't overlap with player z value.
end
core = "This script needs Drago - Core Engine ver 1.47 or above"
rmvx = "This script not for RMVX"
implemented = "%1$s has already implemented, Please remove the %1$s script"
zoom = sprintf(implemented,"Map Zoom")
tone = sprintf(implemented,"Tilemap Tone Changer" )
($imported[:drg_core_engine] || 0) >= 1.47 || raise(core)
LiTTleDRAgo::XP || LiTTleDRAgo::VXA || raise(rmvx)
$imported[:drg_cr_map_zoom] && raise(zoom)
$imported[:drg_tilemap_tone_changer] && raise(tone)
#==============================================================================
# ** Graphics
#------------------------------------------------------------------------------
# This module handles all Graphics
#==============================================================================
class << Graphics
#-------------------------------------------------------------------------
# * Alias Listing
#-------------------------------------------------------------------------
alias_sec_method :zer0_graphics_transition, :transition
alias_sec_method :drg_resolution_change_resize_screen, :resize_screen
alias_sec_method :drg_resolution_change_update, :update
#-------------------------------------------------------------------------
# * Aliased method: resize_screen
#-------------------------------------------------------------------------
def resize_screen(width, height)
width = (width / 32.0).round * 32
height = (height / 32.0).round * 32
if $game_map.respond_to?(:screen_size)
$game_map.screen_size[0] = width
$game_map.screen_size[1] = height
end
drg_resolution_change_resize_screen(width, height)
end
#-------------------------------------------------------------------------
# * Aliased method: transition
#-------------------------------------------------------------------------
def transition(duration = 8, *args)
if width <= 640 && height <= 480
return zer0_graphics_transition(duration, *args)
end
if duration > 0
viewport = Viewport.new(0,0,width,height)
sprite = Sprite.new(viewport)
sprite.bitmap = Graphics.snap_to_bitmap
sprite2 = Sprite.new(viewport)
sprite2.z = sprite.z - 10
sprite2.blend_type = 1
zer0_graphics_transition(0)
fade = 255 / duration
if (file = args.at(0)).is_a?(String)
bitmap = Bitmap.new(file)
sprite2.bitmap = bitmap.stretch(width,height)
bitmap.dispose
end
duration.times {[sprite,sprite2].each {|s|s.opacity -= fade} && update }
[sprite.bitmap, sprite2.bitmap, sprite, sprite2, viewport].dispose
end
zer0_graphics_transition(0)
end
#-------------------------------------------------------------------------
# * Aliased method: update
#-------------------------------------------------------------------------
def update
drg_resolution_change_update
update_resolution_adjust
end
#-------------------------------------------------------------------------
# * New method: update_resolution_adjust
#-------------------------------------------------------------------------
def update_resolution_adjust
return unless LiTTleDRAgo::XP && $game_player
return unless Game_Player.const_defined?(:CENTER_X)
change = Game_Player.const_get(:CENTER_X) != $game_player.center_x
change ||= Game_Player.const_get(:CENTER_Y) != $game_player.center_y
return unless change
resize_screen(width,height)
$game_player.center($game_player.x,$game_player.y)
end
#-------------------------------------------------------------------------
# * Overwriten method: fullscreen
#-------------------------------------------------------------------------
def fullscreen
@fullscreen = true
fill_monitor
LiTTleDRAgo.hide_borders
end
#-------------------------------------------------------------------------
# * Overwriten method: window
#-------------------------------------------------------------------------
def window
@fullscreen = false
LiTTleDRAgo.show_borders
if $game_map && $game_map.screen_size.all? {|s| s.is_a?(Numeric)}
x,y = $game_map.screen_size[0..1]
x += ($game_map.screen_size[2] ||= 1)
$game_map.screen_size[2] *= -1
drg_resolution_change_resize_screen(x,y)
else
x,y = LiTTleDRAgo::SCREEN_SIZE
end
resize_screen(x,y)
end
#-------------------------------------------------------------------------
# * Overwriten method: fullscreen?
#-------------------------------------------------------------------------
define_method(:fullscreen?) { @fullscreen == true }
end
Graphics.window
Graphics.disable_alt_enter
Graphics.control_screen_size LiTTleDRAgo::CONTROL_SCREEN_SIZE
Graphics.high_priority = LiTTleDRAgo::HIGH_PRIORITY
GC.start
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
# This class handles the map. It includes scrolling and passable determining
# functions. Refer to "$game_map" for the instance of this class.
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Public Instance Variable
#--------------------------------------------------------------------------
attr_sec_accessor :zoom_x, :zoom_y, 'Integer(1)'
attr_sec_accessor :screen_size, 'LiTTleDRAgo::SCREEN_SIZE'
attr_sec_accessor :tilemap_tone, 'Tone.new(0,0,0)'
attr_sec_accessor :tilemap_opacity, 'Integer(255)'
attr_sec_accessor :tilemap_hue, 'Integer(0)'
#---------------------------------------------------------------------------
# * Redirect Listing
#---------------------------------------------------------------------------
[:tilemap_tone,:tilemap_opacity].each do |meth|
redirect_method :"#{meth}_changing?", "(@#{meth}_duration ||= 0) > 0"
end
#---------------------------------------------------------------------------
# * Define Sec Listing
#---------------------------------------------------------------------------
define_sec_method(:zooming?) {(@zoom_duration ||= 0) > 0}
define_sec_method(:screen_tile_x) {(Graphics.width / 32.0).ceil}
define_sec_method(:screen_tile_y) {(Graphics.height / 32.0).ceil}
#-------------------------------------------------------------------------
# * Alias Listing
#-------------------------------------------------------------------------
alias_sec_method(:drg_scroll_right_adjust, :scroll_right)
alias_sec_method(:drg_scroll_down_adjust, :scroll_down)
alias_sec_method(:tilemap_effect_update, :update)
alias_sec_method(:get_map_data, :data)
#--------------------------------------------------------------------------
# * Aliased method: Scroll Down
#--------------------------------------------------------------------------
def scroll_down(distance)
times = vxa_map_multiplier
if loop_vertical?
@display_y += distance
@display_y %= height * times
@parallax_y += distance if @parallax_y && @parallax_loop_y
else
last_y = @display_y
result = [@display_y + distance, (map_edge.at(1) / zoom_y)].min
drg_scroll_down_adjust(distance)
@display_y = result
end
end
#--------------------------------------------------------------------------
# * Aliased method: Scroll Right
#--------------------------------------------------------------------------
def scroll_right(distance)
times = vxa_map_multiplier
if loop_horizontal?
@display_x += distance
@display_x %= width * times
@parallax_x += distance if @parallax_x && @parallax_loop_x
else
last_x = @display_x
result = [@display_x + distance, (map_edge.at(0) / zoom_x)].min
drg_scroll_right_adjust(distance)
@display_x = result
end
end
#--------------------------------------------------------------------------
# * New method: zoom
#--------------------------------------------------------------------------
def zoom(*zoom)
if zoom.size == 1
zoom = (zoom.first)
elsif zoom.size == 3
x,y,zoom = zoom[0..2]
end
return unless zoom.is_a?(Numeric)
old_zoom = @zoom_x
@zoom_x = [[zoom,12].min, 1].max
@zoom_y = [[zoom,12].min, 1].max
$game_player.center(x,y) if x && y
end
#--------------------------------------------------------------------------
# * New method: zoom_in
#--------------------------------------------------------------------------
def zoom_in(x = nil,y = nil, duration = 20)
start_zoom(x,y, zoom_x >= 1 ? zoom_x + 1 : 1, duration)
end
#--------------------------------------------------------------------------
# * New method: zoom_out
#--------------------------------------------------------------------------
def zoom_out(x = nil,y = nil,duration = 20)
start_zoom(x,y, zoom_x - 1 >= 1 ? zoom_x - 1 : zoom_x - 0.5, duration)
end
#--------------------------------------------------------------------------
# * New method: map_edge
#--------------------------------------------------------------------------
def map_edge
times = vxa_map_multiplier
[_w = [(width * zoom_x - screen_tile_x).ceil * times, 0].max,
_h = [(height * zoom_y - screen_tile_y).ceil * times, 0].max]
end
#--------------------------------------------------------------------------
# * New method: autotile_speed
#--------------------------------------------------------------------------
def autotile_speed(id = @map_id)
speed = LiTTleDRAgo::AUTOTILE_SPEED
@autotile_speed.is_a?(Array) || @autotile_speed = []
@autotile_speed[id] ||= (speed[id] || speed[0] || 0)
end
#--------------------------------------------------------------------------
# * New method: autotile_speed=
#--------------------------------------------------------------------------
def autotile_speed=(*value)
@autotile_speed.is_a?(Array) || @autotile_speed = []
@autotile_speed[@map_id] = [value.first,0].max if value.size == 1
@autotile_speed[value.first] = [value.at(1),0].max if value.size > 1
end
#--------------------------------------------------------------------------
# * New method: vxa_map_multiplier
#--------------------------------------------------------------------------
def vxa_map_multiplier
LiTTleDRAgo::VXA ? 1 : 128
end
#--------------------------------------------------------------------------
# * New method: screen_is_solid?
#--------------------------------------------------------------------------
def screen_is_solid?
tone = screen.tone.to_s.gsub(/([(),0 ])/i){''}
return true if tone['255.255.255.']
return true if tone['255.-255.-255.']
return true if tone['-255.255.-255.']
return true if tone['-255.-255.255.']
return true if tone['255.255.-255.']
return true if tone['255.-255.255.']
return true if tone['-255.255.255.']
return true if tone['-255.-255.-255.']
end
#--------------------------------------------------------------------------
# * Aliased method: data
#--------------------------------------------------------------------------
def data
data = self.reverse ? reverse_data : get_map_data
data.make_changes = true
data
end
#--------------------------------------------------------------------------
# * New method: reverse_data
#--------------------------------------------------------------------------
def reverse_data
@reverse_data ||= []
@reverse_data[@map_id] ||= get_map_data.reverse(true,false,false)
end
#--------------------------------------------------------------------------
# * New method: reverse=
#--------------------------------------------------------------------------
def reverse=(val)
return val if @reverse == val
@reverse = ((@reverse_data||=[])[@map_id] = nil) || val
spriteset && spriteset.reload_tilemap
@reverse
end
#--------------------------------------------------------------------------
# * New method: reverse
#--------------------------------------------------------------------------
def reverse
@reverse && LiTTleDRAgo::XP
end
#--------------------------------------------------------------------------
# * New method: start_tilemap_tone
#--------------------------------------------------------------------------
def start_tilemap_tone(tone = Tone.new(0,0,0,0), duration = 0)
@tilemap_tone_target = tone.is_a?(Array) ? Tone.new(*tone) : tone.clone
@tilemap_tone_duration = duration
tilemap_tone_changing? || @tilemap_tone = @tilemap_tone_target.clone
end
#--------------------------------------------------------------------------
# * New method: start_tilemap_opacity
#--------------------------------------------------------------------------
def start_tilemap_opacity(opacity = 255, duration = 0)
@tilemap_opacity_target = opacity * 1.0
@tilemap_opacity_duration = duration
tilemap_opacity_changing? || @tilemap_opacity = @tilemap_opacity_target
end
#--------------------------------------------------------------------------
# * New method: update_tilemap_tone
#--------------------------------------------------------------------------
def update_tilemap_tone
if tilemap_tone_changing?
d = @tilemap_tone_duration
target = @tilemap_tone_target
@tilemap_tone.red = (@tilemap_tone.red * (d - 1) + target.red) / d
@tilemap_tone.green = (@tilemap_tone.green * (d - 1) + target.green) / d
@tilemap_tone.blue = (@tilemap_tone.blue * (d - 1) + target.blue) / d
@tilemap_tone.gray = (@tilemap_tone.gray * (d - 1) + target.gray) / d
@tilemap_tone_duration -= 1
tilemap_tone_changing? || @tilemap_tone = @tilemap_tone_target.clone
end
end
#--------------------------------------------------------------------------
# * New method: update_tilemap_opacity
#--------------------------------------------------------------------------
def update_tilemap_opacity
if tilemap_opacity_changing?
d = @tilemap_opacity_duration
@tilemap_opacity = (@tilemap_opacity * (d - 1) +
@tilemap_opacity_target) / d
@tilemap_opacity_duration -= 1
tilemap_opacity_changing? || @tilemap_opacity = @tilemap_opacity_target
end
end
#--------------------------------------------------------------------------
# * New method: start_zoom
#--------------------------------------------------------------------------
def start_zoom(x,y, zoom_target, duration=20)
@x_zoom = x
@y_zoom = y
@zoom_target = zoom_target * 1.0
@zoom_duration = @zoom_x == @zoom_target ? 0 : duration
zooming? || zoom(@x_zoom,@y_zoom,@zoom_target)
end
#--------------------------------------------------------------------------
# * New method: update_zooming
#--------------------------------------------------------------------------
def update_zooming
if zooming?
d = @zoom_duration
power = (@zoom_x * (d - 1) + @zoom_target) / d
@zoom_duration -= 1
zoom(@x_zoom,@y_zoom,power)
zoom(@x_zoom,@y_zoom,@zoom_target) unless zooming?
end
end
#--------------------------------------------------------------------------
# * Aliased method: update
#--------------------------------------------------------------------------
def update(*args)
tilemap_effect_update(*args)
update_tilemap_tone
update_tilemap_opacity
update_zooming
end
end
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
# This interpreter runs event commands. This class is used within the
# Game_System class and the Game_Event class.
#==============================================================================
unless LiTTleDRAgo::VX
class Interpreter
#---------------------------------------------------------------------------
# * Redirect Listing
#---------------------------------------------------------------------------
redirect_method :zoom, '$game_map.zoom'
redirect_method :zoom_in, '$game_map.zoom_in'
redirect_method :zoom_out, '$game_map.zoom_out'
redirect_method :start_zoom, '$game_map.start_zoom'
redirect_method :start_tilemap_opacity, '$game_map.start_tilemap_opacity'
redirect_method :start_tilemap_tone, '$game_map.start_tilemap_tone'
[:change_tilemap_tone,:change_character_tone].each do |meth|
redirect_method :"#{meth}", :"$game_map.spriteset.#{meth}"
end
end
end
#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
# This class handles the player. Its functions include event starting
# determinants and map scrolling. Refer to "$game_player" for the one
# instance of this class.
#==============================================================================
class Game_Player
#---------------------------------------------------------------------------
# * Define Sec Listing
#---------------------------------------------------------------------------
define_sec_method(:center_x) {((Graphics.width/2) / $game_map.zoom_x-16) * 4}
define_sec_method(:center_y) {((Graphics.height/2) / $game_map.zoom_y-16) * 4}
#-------------------------------------------------------------------------
# * Alias Listing
#-------------------------------------------------------------------------
alias_sec_method(:drg_adjust_viewport_center, :center)
#-------------------------------------------------------------------------
# * Aliased method: center
#-------------------------------------------------------------------------
def center(x, y)
if LiTTleDRAgo::XP
Game_Player.const_set(:CENTER_X, center_x)
Game_Player.const_set(:CENTER_Y, center_y)
end
drg_adjust_viewport_center(x, y)
max_x = $game_map.map_edge.at(0) / $game_map.zoom_x
max_y = $game_map.map_edge.at(1) / $game_map.zoom_y
if LiTTleDRAgo::XP
$game_map.display_x = [0, [(x * 32*4) - center_x, max_x.ceil].min].max
$game_map.display_y = [0, [(y * 32*4) - center_y, max_y.ceil].min].max
elsif $game_map.respond_to?(:set_display_pos)
$game_map.set_display_pos(x - center_x, y - center_y)
end
end
end
#==============================================================================
# ** Tilemap
#------------------------------------------------------------------------------
#
#==============================================================================
class Tilemap
#---------------------------------------------------------------------------
# * Public Instance Variables
#---------------------------------------------------------------------------
method_defined?(:tileset) || attr_accessor(:tileset)
method_defined?(:priorities)|| attr_accessor(:priorities)
method_defined?(:autotiles) || attr_sec_accessor(:autotiles,'Array.new')
end
#==============================================================================
# ** Table
#------------------------------------------------------------------------------
#
#==============================================================================
class Table
#--------------------------------------------------------------------------
# * Public Instance Variable
#--------------------------------------------------------------------------
attr_sec_accessor :table_changes, :orig_value, 'Array.new'
attr_accessor :make_changes
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_sec_method :set_method, :"[]="
#--------------------------------------------------------------------------
# * Set Data
#--------------------------------------------------------------------------
def []=(*args)
if @make_changes
table_changes.push([*args]) && orig_value.push(self[*args[0..-2]])
@make_changes = false
end
set_method(*args)
end
#--------------------------------------------------------------------------
# * Reverse
#--------------------------------------------------------------------------
def reverse(rx=true,ry=true,rz=true)
reverse = self.clone
_x = (0...xsize).to_a
_y = (0...ysize).to_a
_z = (0...zsize).to_a
_x.each do |x|
_rx = rx ? _x[-1-x] : x
ysize == 1 && (reverse[x] = self[_rx]) && next
_y.each do |y|
_ry = ry ? _y[-1-y] : y
zsize == 1 && (reverse[x,y] = self[_rx,_ry]) && next
_z.each do |z|
_rz = rz ? _z[-1-z] : z
reverse[x,y,z] = self[_rx,_ry,_rz]
end
end
end
reverse
end
end
#==============================================================================
# ** RPG::Cache
#==============================================================================
ModCache = LiTTleDRAgo.cache
module ModCache
#----------------------------------------------------------------------------
# * Self
#----------------------------------------------------------------------------
class << self
#--------------------------------------------------------------------------
# * Constant
#--------------------------------------------------------------------------
AUTO_INDEX = [[
[27,28,33,34], [ 5,28,33,34], [27, 6,33,34], [ 5, 6,33,34],
[27,28,33,12], [ 5,28,33,12], [27, 6,33,12], [ 5, 6,33,12],
[27,28,11,34], [ 5,28,11,34], [27, 6,11,34], [ 5, 6,11,34],
[27,28,11,12], [ 5,28,11,12], [27, 6,11,12], [ 5, 6,11,12],
[25,26,31,32], [25, 6,31,32], [25,26,31,12], [25, 6,31,12],
[15,16,21,22], [15,16,21,12], [15,16,11,22], [15,16,11,12],
[29,30,35,36], [29,30,11,36], [ 5,30,35,36], [ 5,30,11,36],
[39,40,45,46], [ 5,40,45,46], [39, 6,45,46], [ 5, 6,45,46],
[25,30,31,36], [15,16,45,46], [13,14,19,20], [13,14,19,12],
[17,18,23,24], [17,18,11,24], [41,42,47,48], [ 5,42,47,48],
[37,38,43,44], [37, 6,43,44], [13,18,19,24], [13,14,43,44],
[37,42,43,48], [17,18,47,48], [13,18,43,48], [ 1, 2, 7, 8]],
[[27,28,33,34], [49,50,55,56], [51,52,57,58], [49,52,55,58],
[63,64,69,70], [65,66,71,72], [51,52,69,70], [ 5, 6,33,12],
[61,62,67,68], [49,50,67,68], [53,54,59,60], [ 5, 6,11,34],
[61,64,67,70], [ 5,28,11,12], [27, 6,11,12], [ 5, 6,11,12],
[25,26,31,32], [25, 6,31,32], [25,26,31,12], [25, 6,31,12],
[15,16,21,22], [15,16,21,12], [15,16,11,22], [15,16,11,12],
[29,30,35,36], [29,30,11,36], [ 5,30,35,36], [ 5,30,11,36],
[39,40,45,46], [ 5,40,45,46], [39, 6,45,46], [ 5, 6,45,46],
[25,30,31,36], [15,16,45,46], [13,14,19,20], [13,14,19,12],
[17,18,23,24], [17,18,11,24], [41,42,47,48], [ 5,42,47,48],
[37,38,43,44], [37, 6,43,44], [13,18,19,24], [13,14,43,44],
[37,42,43,48], [17,18,47,48], [13,18,43,48], [ 1, 2, 7, 8]]
].freeze
#--------------------------------------------------------------------------
# * Public Instance Variable
#--------------------------------------------------------------------------
attr_sec_reader :cache, 'Hash.new'
#--------------------------------------------------------------------------
# * New method: autotile_cr_tilemap
#--------------------------------------------------------------------------
def autotile_cr_tilemap(filename)
key = "Graphics/Autotiles/CR#{filename}"
if !@cache.include?(key) || @cache[key].disposed?
@cache[key] = (filename=='') ? Bitmap.new(128,96) : autotile(filename)
new_bm = self.format_autotiles(@cache[key], filename)
@cache[key].dispose
@cache[key] = new_bm
@cache[key].instance_variable_set(:@autotile_name, filename)
end
return @cache[key]
end
#--------------------------------------------------------------------------
# * New method: include?
#--------------------------------------------------------------------------
unless method_defined?(:include?)
def include?(key)
@cache[key] && !@cache[key].disposed?
end
end
#--------------------------------------------------------------------------
# * New method: format_autotiles
#--------------------------------------------------------------------------
def format_autotiles(bitmap, filename)
if bitmap.height > 32
frames = bitmap.width / 96
index = bitmap.height == 192 ? AUTO_INDEX[1] : AUTO_INDEX[0]
template = Bitmap.new(256*frames,192)
frames.times {|a| (0...6).each { |i| (0...8).each { |j|
index[8*i+j].each { |number|
number -= 1
x, y = 16 * (number % 6), 16 * (number / 6)
ox, oy = (32 * j + x % 32) + (a * 256), 32 * i + y % 32
rect = Rect.new(x + (a * 96), y, 16, 16)
template.blt(ox, oy, bitmap, rect)
}}}}
return template
else
return bitmap
end
end
#--------------------------------------------------------------------------
# * New method: tile
#--------------------------------------------------------------------------
unless method_defined?(:format_tile)
def format_tile(bitmap, tile_id, hue)
filename = bitmap.pathname
key = [filename, tile_id, hue]
unless include?(key)
@cache[key] = empty_bitmap
x = (tile_id - 384) % 8 * 32
y = (tile_id - 384) / 8 * 32
rect = Rect.new(x, y, 32, 32)
@cache[key].blt(0, 0, bitmap, rect)
@cache[key].hue_change(hue)
end
@cache[key]
end
end
#--------------------------------------------------------------------------
# * New method: clear_tile_cache
#--------------------------------------------------------------------------
def clear_tile_cache
@cache ||= {}
@cache.reject! do |keys|
keys.is_a?(Array) && keys.size == 3 &&
keys[0].is_a?(String) && keys[0].downcase["tilemap"]
end
GC.start
end
end
end
#==============================================================================
# ** Bitmap
#------------------------------------------------------------------------------
#
#==============================================================================
class Bitmap
#--------------------------------------------------------------------------
# * Public Instance Variable
#--------------------------------------------------------------------------
attr_sec_accessor :pathname, 'String.new'
#--------------------------------------------------------------------------
# ● Alias Method
#--------------------------------------------------------------------------
$@ || alias_method(:cr_path_init, :initialize)
#--------------------------------------------------------------------------
# ● Object Initialization
#--------------------------------------------------------------------------
def initialize(*args)
@pathname = args.at(0) if args.at(0).is_a?(String)
cr_path_init(*args)
end
end
#==============================================================================
# ** RPG::Weather
#------------------------------------------------------------------------------
# A class for weather effects (rain, storm, and snow). It is used within the
# Spriteset_Map class.
#==============================================================================
CRWeather = LiTTleDRAgo::VX ? Spriteset_Weather : RPG::Weather
class CRWeather
#--------------------------------------------------------------------------
# * Public Instance Variable
#--------------------------------------------------------------------------
attr_reader :viewport
attr_accessor :zoom_x, :zoom_y
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:init_custom_resolution, :initialize)
#--------------------------------------------------------------------------
# * Aliased method: initialize
#--------------------------------------------------------------------------
def initialize(viewport)
@viewport = viewport
init_custom_resolution(@viewport)
end
#--------------------------------------------------------------------------
# * Overwriten method: update
#--------------------------------------------------------------------------
def update
return if @type == 0
return if $game_map && $game_map.screen_is_solid?
update_screen if respond_to?(:update_screen)
@sprites.each {|sprite| update_sprite(sprite) }
end
#--------------------------------------------------------------------------
# * Update Sprite
#--------------------------------------------------------------------------
def update_sprite(sprite)
sprite.ox = @ox
sprite.oy = @oy
case @type
when 1, :rain then update_sprite_rain(sprite)
when 2, :storm then update_sprite_storm(sprite)
when 3, :snow then update_sprite_snow(sprite)
end
create_new_particle(sprite) if sprite.opacity < 64
end
#--------------------------------------------------------------------------
# * Update Sprite [Rain]
#--------------------------------------------------------------------------
def update_sprite_rain(sprite)
sprite.bitmap = @rain_bitmap
sprite.x -= 2 * sprite.zoom_x
sprite.y += 16 * sprite.zoom_y
sprite.opacity -= 8
end
#--------------------------------------------------------------------------
# * Update Sprite [Storm]
#--------------------------------------------------------------------------
def update_sprite_storm(sprite)
sprite.bitmap = @storm_bitmap
sprite.x -= 8 * sprite.zoom_x
sprite.y += 16 * sprite.zoom_y
sprite.opacity -= 12
end
#--------------------------------------------------------------------------
# * Update Sprite [Snow]
#--------------------------------------------------------------------------
def update_sprite_snow(sprite)
sprite.bitmap = @snow_bitmap
sprite.x -= 2 * sprite.zoom_x
sprite.y += 8 * sprite.zoom_y
sprite.opacity -= 8
end
#--------------------------------------------------------------------------
# * Create New Particle
#--------------------------------------------------------------------------
def create_new_particle(sprite)
sprite.x = rand(Graphics.width + 100) - 100 + @ox
sprite.y = rand(Graphics.height + 200) - 200 + @oy
sprite.zoom_x = @zoom_x || 1
sprite.zoom_y = @zoom_y || 1
sprite.x *= sprite.zoom_x
sprite.y *= sprite.zoom_y
sprite.opacity = 160 + rand(96)
end
#---------------------------------------------------------------------------
# * New method: method_missing
#---------------------------------------------------------------------------
def method_missing(val,*a,&b)
en = @sprites.flatten.find_all {|s|s.respond_to?(val.to_sym)}
if en.empty?
text = "Undefined method #{val} at #{self.inspect}"
raise(NoMethodError,text,caller(1))
end
return en.map {|s| s.send(val.to_sym,*a,&b)}
end
end
#==============================================================================
# ** Plane
#------------------------------------------------------------------------------
# This class is the rewrite of the default plane class
#==============================================================================
class CRPlane < Sprite
#---------------------------------------------------------------------------
# * Public Instance Variable
#---------------------------------------------------------------------------
attr_reader :bitmap
#---------------------------------------------------------------------------
# * New method: z=
#---------------------------------------------------------------------------
def z=(z)
super(z * 1000)
end
#---------------------------------------------------------------------------
# * New method: ox=
#---------------------------------------------------------------------------
def ox=(ox)
return if $game_map && $game_map.screen_is_solid?
return if bitmap.nil? || bitmap.disposed?
super(ox % bitmap.width) if bitmap.is_a?(Bitmap)
end
#---------------------------------------------------------------------------
# * New method: oy=
#---------------------------------------------------------------------------
def oy=(oy)
return if $game_map && $game_map.screen_is_solid?
return if bitmap.nil? || bitmap.disposed?
super(oy % bitmap.height) if bitmap.is_a?(Bitmap)
end
#---------------------------------------------------------------------------
# * New method: dispose
#---------------------------------------------------------------------------
def dispose
@plane && (@plane.disposed? || @plane.dispose)
super unless disposed?
end
#---------------------------------------------------------------------------
# * New method: bitmap=
#---------------------------------------------------------------------------
def bitmap=(tile)
return if @bitmap == tile
@bitmap = tile
if @bitmap.is_a?(Bitmap)
xx = 1 + (Graphics.width.to_f / tile.width).ceil
yy = 1 + (Graphics.height.to_f / tile.height).ceil
@plane.dispose if @plane.respond_to?(:dispose) && @plane.not.disposed?
@plane = Bitmap.new(@bitmap.width * xx, @bitmap.height * yy)
(0..xx).each {|x| (0..yy).each {|y|
@plane.blt(x * @bitmap.width, y * @bitmap.height, @bitmap, @bitmap.rect)
}}
super(@plane)
else
super(nil)
end
end
#---------------------------------------------------------------------------
# * Undefine methods dealing with coordinates to do nothing.
#---------------------------------------------------------------------------
undef :x, :x=, :y, :y= if method_defined?(:x)
end
#==============================================================================
# ** Viewport
#------------------------------------------------------------------------------
#
#==============================================================================
class Viewport
#--------------------------------------------------------------------------
# * Overwriten method: update_viewport_sizes
#--------------------------------------------------------------------------
def update_viewport_sizes
map = $game_map
w, h = Graphics.width, Graphics.height
hor = $game_map.loop_horizontal?
ver = $game_map.loop_vertical?
_w = ($game_map.width * 32 * $game_map.zoom_x).floor
_h = ($game_map.height * 32 * $game_map.zoom_y).floor
dx = w > _w && !hor ? ((w - _w).floor.abs / 32) * 16 : 0
dw = hor ? w : [w, $game_map.width * 32 * $game_map.zoom_x].min
dy = h > _h && !ver ? ((h - _h).floor.abs / 32) * 16 : 0
dh = ver ? h : [h, $game_map.height * 32 * $game_map.zoom_y].min
resize(Rect.new(dx, dy, dw, dh))
end
end
#==============================================================================
# ** ZTilemap
#------------------------------------------------------------------------------
# This class is the rewrite of the default tilemap class
#==============================================================================
class ZTilemap
#---------------------------------------------------------------------------
# * Public Instance Variables
#---------------------------------------------------------------------------
attr_reader :map_data, :viewport
attr_accessor :tileset, :tone, :priorities, :sprite_compact
attr_sec_accessor :autotiles, 'Array.new'
attr_sec_accessor :ox, :oy, :zoom_x, :zoom_y, :hue, 'Integer(1)'
attr_sec_accessor :opacity, 'Integer(255)'
attr_sec_reader :layers, :bitmap_layers, :extra_map_data, 'Array.new'
#---------------------------------------------------------------------------
# * Redirect Listing
#---------------------------------------------------------------------------
redirect_method :width, '$game_map.screen_tile_x + 2'
redirect_method :height, '$game_map.screen_tile_y + 2'
#---------------------------------------------------------------------------
# * Define Sec Listing
#---------------------------------------------------------------------------
define_sec_method(:all_sprites) { layers.flatten.select {|s| is_sprite?(s)}}
define_sec_method(:is_sprite?) { |s| s.is_a?(Sprite) && s.not.disposed? }
#---------------------------------------------------------------------------
# * Alias Listing
#---------------------------------------------------------------------------
alias_method :bitmaps, :autotiles
#---------------------------------------------------------------------------
# * Object Initialization
#---------------------------------------------------------------------------
def initialize(viewport)
@viewport = viewport
@sprite_compact = false#LiTTleDRAgo::SPRITE_COMPACT
create_sprites
create_carrot
end
#---------------------------------------------------------------------------
# * New method: create_sprites
#---------------------------------------------------------------------------
def create_sprites
6.times do |i|
layers[i] ||= []
(i % 6 == 0 ? 1 : height).times do |s|
layers[i][s] = Sprite.new(@viewport) unless is_sprite?(layers[i][s])
end
layers[i].each_with_index do |s,r|
next unless is_sprite?(s)
s.y = r * 32 * zoom_y
s.z = (i % 6 == 0) ? 0 : (r * 32 + 32 + (i % 6) * 32)
s.mirror = $game_map.reverse
end
end
end
#---------------------------------------------------------------------------
# * New method: create_carrot
#---------------------------------------------------------------------------
def create_carrot
@draw_tiles = carrot do |x,y,data,prio|
[0,1,2].each do |r|
if (id = data[x,y,r]).to_i == 0 || (layer = prio[id]).nil?
next
elsif @layer_clear && @layer_clear.not.include?(layer)
@bitmap_layers[layer].fill_rect(x*32,y*32,32,32,Color.erase)
@layer_clear.push(layer)
end
refresh_tiles(x,y,r,id)
end
end
@change_tone = carrot {|s| all_sprites.tone = (@tone = s) }
@change_opacity = carrot {|s| all_sprites.opacity = (@opacity = s)}
@change_autotile_hue = carrot do |a,old,hue|
[old.to_i != 0 && a.hue_change((old - 360).abs)] && a.hue_change(hue)
end
end
#---------------------------------------------------------------------------
# * New method: ox=, oy=, zoom_x=, zoom_y=
#---------------------------------------------------------------------------
[:ox, :oy, :zoom_x, :zoom_y].each do |a|
meth = "def %1$s=(%1$s) (@%1$s != %1$s) && (@%1$s = %1$s) && %2$s end"
module_eval(sprintf(meth, a ,'adjust_sprites'))
end
#---------------------------------------------------------------------------
# * New method: tone=
#---------------------------------------------------------------------------
def tone=(*tone)
new_tone = tone.flatten.size == 4 ? Tone.new(*tone.flatten) :
tone.first.is_a?(Tone) ? tone.first : nil
@tone.to_s == new_tone.to_s || @change_tone.call(new_tone.clone)
end
#---------------------------------------------------------------------------
# * New method: opacity=
#---------------------------------------------------------------------------
def opacity=(opacity)
opacity = [[opacity.round,255].min,0].max
@opacity == opacity || @change_opacity.call(opacity)
end
#---------------------------------------------------------------------------
# * New method: hue=
#---------------------------------------------------------------------------
def hue=(hue)
return if @hue == (hue % 360)
old = self.hue
@hue = hue % 360
all_autotiles = @autotiles + extra_map_data.map {|m| m[:autotiles]}.flatten
@change_autotile_hue.call(all_autotiles.uniq, old, @hue)
refresh
end
#---------------------------------------------------------------------------
# * New method: Adjust Sprites
#---------------------------------------------------------------------------
def adjust_sprites
@times_compact ||= []
@layers_used && @layers.size.times do |i|
layer = @layers[i]
(i % 6 == 0 ? 1 : height).times do |r|
sprite = layer[r]
d = 32
_r = 32 + (i % 6) * 32
_y = r * 32 * zoom_y
_z = i % 6 == 0 ? 0 : r * d + _r # (r * d + _r)
unless is_sprite?(sprite)
change = _y <= @viewport.height
if @sprite_compact
change &&= !char_out_range?(_r, (height-1)*d+_r)
change &&= @layers_used[i] > 0
end
change || next
sprite = (layer[r] = Sprite.new(@viewport))
sprite.bitmap = bitmap_layers[i]
sprite.tone = tone if tone
sprite.opacity = opacity
sprite.mirror = $game_map.reverse
sprite.zoom_x, sprite.zoom_y = zoom_x, zoom_y
else
change = _y > @viewport.height
if (@times_compact[i] ||= 0) < 10 && @sprite_compact
change ||= (r > 0 && char_out_range?(_r, (height-1)*d+_r))
change ||= (r > 0 && @layers_used[i] == 0)
end
sprite.y, sprite.z = _y, _z.ceil
change && [sprite.dispose, @times_compact[i] += 1] && next
end
sprite.y, sprite.z = _y, _z.ceil
_wd = @viewport.width/zoom_x
_ox = sprite.mirror ? (sprite.bitmap.width-ox)-_wd : (_wd+=10) && ox
if layer.select { |s| is_sprite?(s) }.size == 1
sprite.src_rect.set(_ox, oy, _wd, @viewport.height/zoom_x + 10)
else
sprite.src_rect.set(_ox, (oy + r*32), _wd, 33)
end
sprite.zoom_x, sprite.zoom_y = zoom_x, zoom_y
end
end
end
#---------------------------------------------------------------------------
# * New method: char_out_range?
#---------------------------------------------------------------------------
def char_out_range?(z1,z2)
return false unless (s = $game_map.spriteset).is_a?(Spriteset_Map)
s.character_sprites.all? do |d|
d.not.disposed? && d.opacity > 0 && d.visible &&
(d.z).not.between?(z1,z2)
end
end
#---------------------------------------------------------------------------
# * New method: Frame Dispose
#---------------------------------------------------------------------------
def dispose
all_sprites.each { |s| s.dispose }
bitmap = bitmap_layers
bitmap += extra_map_data.map {|m| m[:autotiles]}.flatten - @autotiles
bitmap += extra_map_data.map {|m| m[:tileset]}.flatten
bitmap.compact.each { |s| s.disposed? || s.dispose }
@layers.clear
GC.start
end
#---------------------------------------------------------------------------
# * New method: Change Map Data
#---------------------------------------------------------------------------
def map_data=(data)
return if @map_data == data
@map_data = data
@map_data_reverse = data.reverse(true,false,false)
6.times do |i|
bitmap_layers[i].dispose if bitmap_layers[i] && bitmap_layers[i].disposed?
bitmap_layers[i] = Bitmap.new($game_map.width*32,$game_map.height*32)
layers[i].each { |s| is_sprite?(s) && s.bitmap = bitmap_layers[i] }
end
refresh
end
#---------------------------------------------------------------------------
# * New method: Map Data
#---------------------------------------------------------------------------
def map_data
$game_map.reverse ? @map_data_reverse : @map_data
end
#---------------------------------------------------------------------------
# * New method: Change priorities
#---------------------------------------------------------------------------
def priorities=(priorities)
return if @priorities == priorities
@priorities = priorities
refresh
end
#---------------------------------------------------------------------------
# * New method: Frame Refresh
#---------------------------------------------------------------------------
def refresh
return unless @priorities && @map_data
LiTTleDRAgo.cache.clear_tile_cache
@animated_tiles = []
@unrefreshed_tile = []
@layers_used = []
7.times do |i|
@total_frames = [] if i == 0
@current_frame = [] if i == 0
bm = (@current_frame[i] = @layers_used[i] = 0) && autotiles[i]
bm.nil? && @total_frames[i] = 1
bm.nil? || @total_frames[i] = bm.width / (bm.height > 32 ? 256 : 32)
extra_map_data.each do |data|
data[:total_frames] = [] if i == 0
data[:current_frame] = [] if i == 0
bm = (data[:current_frame][i] = 0) && data[:autotiles][i]
bm.nil? && data[:total_frames][i] = 1
bm.nil? || data[:total_frames][i] = bm.width / (bm.height>32 ? 256 : 32)
end
end
_w = @viewport.width
_h = @viewport.height
layers[0][0].src_rect.set(ox, oy, _w/zoom_x, _h/zoom_y )
(0...map_data.xsize).each do |x|
(0...map_data.ysize).each do |y|
if in_range?(x,y)
update_map_changes(x,y)
else
next if @unrefreshed_tile.include?([x,y])
@unrefreshed_tile.push([x,y])
@unrefreshed_tile.uniq!
end
end
end
adjust_sprites
end
#---------------------------------------------------------------------------
# * New method: Refresh Tiles
#---------------------------------------------------------------------------
def refresh_tiles(x,y,z,i,d = nil)
return if i.nil? || i == 0
i < 384 ? refresh_autotile(x,y,z,i,d) : refresh_regular_tile(x,y,z,i,d)
end
#---------------------------------------------------------------------------
# * New method: Refresh Autotile
#---------------------------------------------------------------------------
def refresh_autotile(x,y,z,id,data)
layer = data.nil? ? @priorities[id] : data[:priorities][id]
tframe = data.nil? ? @total_frames : data[:total_frames]
cframe = data.nil? ? @current_frame : data[:current_frame]
bitmap = data.nil? ? @autotiles.at(id/48-1) : data[:autotiles].at(id/48-1)
return if bitmap.nil? || layer.nil?
div = (fid = id / 48 - 1) &&(id % 48)
if @animated_tiles.not.include?([x,y]) && tframe[fid] > 1
@animated_tiles.push([x,y])
@animated_tiles.uniq!
end
rect = Rect.new((div % 8)*32 + cframe[fid] * 256, (div / 8)*32, 32, 32)
bitmap_layers[layer].blt(x*32, y*32, bitmap, rect)
@layers_used[layer] = [(@layers_used[layer] + 1) % 10000,1].max
end
#---------------------------------------------------------------------------
# * New method: Refresh Regular Tile
#---------------------------------------------------------------------------
def refresh_regular_tile(x,y,z,id,data)
tileset = data.nil? ? @tileset : data[:tileset]
layer = data.nil? ? @priorities[id] : data[:priorities][id]
return if layer.nil? || tileset.not.is_a?(Bitmap)
bitmap = LiTTleDRAgo.cache.format_tile(tileset, id, hue)
bitmap_layers[layer].blt(x*32, y*32, bitmap, Rect.new(0, 0, 32, 32))
@layers_used[layer] = [(@layers_used[layer] + 1) % 10000, 1].max
end
#---------------------------------------------------------------------------
# * New method: force_refresh
#---------------------------------------------------------------------------
def force_refresh
refresh
(@unrefreshed_tile ||= []).each {|x,y| update_map_changes(x,y)}
(@unrefreshed_tile.clear)
end
#---------------------------------------------------------------------------
# * New method: Frame Update
#---------------------------------------------------------------------------
def update
update_map_data
update_autotile
update_unrefreshed_tile
end
#---------------------------------------------------------------------------
# * New method: Update Unrefreshed Tile
#---------------------------------------------------------------------------
def update_unrefreshed_tile
if @unrefreshed_tile && @unrefreshed_tile.not.empty?
unrefreshed = @unrefreshed_tile.select { |x,y| in_range?(x,y) }
if unrefreshed.not.empty?
(unrefreshed).each {|x,y| update_map_changes(x,y)}
(@unrefreshed_tile -= unrefreshed) && adjust_sprites
end
end
end
#---------------------------------------------------------------------------
# * New method: Update Map Data
#---------------------------------------------------------------------------
def update_map_data
if map_data.table_changes.not.empty?
map_data.table_changes.each do|item|
x,y,z,tile_id = item
update_map_changes(x,y)
end
map_data.table_changes.clear
map_data.make_changes = false
adjust_sprites
end
end
#---------------------------------------------------------------------------
# * New method: Update the autotile
#---------------------------------------------------------------------------
def update_autotile
return if $game_map.screen_is_solid?
speed = $game_map.autotile_speed
total = [(@autotile_total || 0) / 10, 0].max
if speed > 0 && Graphics.frame_count % (speed + total) == 0
7.times do |i|
extra_map_data.each do |data|
next if (total = data[:total_frames].at(i)) == 0
data[:current_frame][i] = (data[:current_frame].at(i) + 1) % total
end
next if (total = @total_frames.at(i)) == 0
@current_frame[i] = (@current_frame.at(i) + 1) % total
end
animated = @animated_tiles.select { |x,y| in_range?(x,y) }
animated.each {|x,y| update_map_changes(x,y) }
@autotile_total = animated.size
end
end
#---------------------------------------------------------------------------
# * New method: in_range?
#---------------------------------------------------------------------------
def in_range?(x=nil,y=nil)
return false if layers[0].nil? || layers[0][0].nil?
rect = @layers[0][0].src_rect
_x = x && (x * 32).between?(rect.x-32, rect.x + rect.width)
_y = y && (y * 32).between?(rect.y-32, rect.y + rect.height)
return _x && _y if x && y
return _x if x
return _y if y
return false
end
#---------------------------------------------------------------------------
# * New method: Update Map Changes
#---------------------------------------------------------------------------
def update_map_changes(x,y)
@layer_clear ||= []
@layer_clear.clear
draw = [[x,y,map_data,priorities]]
draw += extra_map_data.map {|data|[x,y,data[:map].data,data[:priorities]]}
draw.each {|data| @draw_tiles.call(*data)}
end
end
#==============================================================================
# ** Game_Character
#------------------------------------------------------------------------------
# This class deals with characters. It's used as a superclass for the
# determinants and map scrolling. Refer to "$game_player" for the one
# Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_sec_method(:screen_x_before_zoom, :screen_x)
alias_sec_method(:screen_y_before_zoom, :screen_y)
alias_sec_method(:screen_z_before_zoom, :screen_z)
#--------------------------------------------------------------------------
# * Aliased method: screen_x
#--------------------------------------------------------------------------
def screen_x(*args)
screen_x_before_zoom(*args) * $game_map.zoom_x
end
#--------------------------------------------------------------------------
# * Aliased method: screen_y
#--------------------------------------------------------------------------
def screen_y(*args)
screen_y_before_zoom(*args) * $game_map.zoom_y
end
#--------------------------------------------------------------------------
# * Aliased method: screen_z
#--------------------------------------------------------------------------
def screen_z(*args)
if self.is_a?(Game_Event)
return 999 if @always_on_top
return $1.to_i if self.name[/\<Z:\s*([-]?\d+)\s*\>/i]
return screen_z_tilemap_fix if screen_z_tilemap_fix.is_a?(Integer)
end
return screen_z_before_zoom(*args)
end
#--------------------------------------------------------------------------
# * New method: screen_z_tilemap_fix
#--------------------------------------------------------------------------
def screen_z_tilemap_fix
LiTTleDRAgo::CHARACTER_Z_FIX.each do |key,value|
if value.is_a?(Array) && key.is_a?(Integer)
return key if value.any?{|v|"#{v}".downcase == @character_name.downcase}
elsif key.is_a?(Array) && value.is_a?(Integer)
return value if key.any?{|v|"#{v}".downcase == @character_name.downcase}
elsif (key.is_a?(String) || key.is_a?(Symbol)) && value.is_a?(Integer)
return value if "#{key}".downcase == @character_name.downcase
end
end
return nil
end
end
#==============================================================================
# ** Sprite_Character
#------------------------------------------------------------------------------
# This sprite is used to display the character.It observes the Game_Character
# class and automatically changes sprite conditions.
#==============================================================================
class Sprite_Character
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_sec_method(:zoom_update_scrolling, :update)
#--------------------------------------------------------------------------
# * Aliased method: update
#--------------------------------------------------------------------------
def update(*args)
if @old_character_zoom_x
self.zoom_x = @old_character_zoom_x
self.zoom_y = @old_character_zoom_y
end
zoom_update_scrolling(*args)
@old_character_zoom_x = self.zoom_x
@old_character_zoom_y = self.zoom_y
self.zoom_x *= $game_map.zoom_x
self.zoom_y *= $game_map.zoom_y
end
#--------------------------------------------------------------------------
# * New method: in_range?
#--------------------------------------------------------------------------
unless method_defined?(:in_range?)
def in_range?
cw = self.src_rect ? self.src_rect.width : 32
ch = self.src_rect ? self.src_rect.height : 32
return @character.screen_x.round.between?(self.viewport.x - cw,
self.viewport.x + self.viewport.width) &&
@character.screen_y.round.between?(self.viewport.y - ch,
self.viewport.y + self.viewport.height)
end
end
end
#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
# This class brings together map screen sprites, tilemaps, etc.
# It's used within the Scene_Map class.
#==============================================================================
class Spriteset_Map
#---------------------------------------------------------------------------
# * Public Instance Variables
#---------------------------------------------------------------------------
attr_reader :character_sprites, :tilemap
attr_reader :viewport1, :viewport2, :viewport3
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:init_drgcr_tilemap, :initialize)
alias_sec_method(:update_drgcr_tilemap, :update)
#--------------------------------------------------------------------------
# * Aliased method: initialize
#--------------------------------------------------------------------------
def initialize(*args)
check_autotile_height
init_drgcr_tilemap(*args)
end
#---------------------------------------------------------------------------
# * New method: check_autotile_height
#---------------------------------------------------------------------------
def check_autotile_height
return unless LiTTleDRAgo::XP
$game_map.autotile_names.each do |autotile_name|
bitmap = ModCache.autotile(autotile_name)
[@force_tilemap_enabled = true] && break if bitmap.height == 192
end
end
#--------------------------------------------------------------------------
# * Aliased method: update
#--------------------------------------------------------------------------
def update(*args)
adjust_viewport
adjust_tilemap
adjust_old_zoom
update_drgcr_tilemap(*args)
update_tilemap_zoom
end
#---------------------------------------------------------------------------
# * New method: adjust_old_zoom
#---------------------------------------------------------------------------
def adjust_old_zoom
if @old_fog_zoom_x
@fog.zoom_x = @old_fog_zoom_x
@fog.zoom_y = @old_fog_zoom_y
@panorama.zoom_x = @old_panorama_zoom_x
@panorama.zoom_y = @old_panorama_zoom_y
end
end
#---------------------------------------------------------------------------
# * New method: viewport_sprite
#---------------------------------------------------------------------------
def viewport_sprite(*v)
v.collect! {|s| s.is_a?(Symbol) ? instance_variable_get(:"@#{s}") : s }
v.reject! {|s| s.not.is_a?(Viewport)}
all = instance_variables.map {|s| instance_variable_get("#{s}")}.flatten
all.select {|s| s.respond_to?(:viewport) && v.include?(s.viewport)}
end
#---------------------------------------------------------------------------
# * New method: change_tilemap_tone
#---------------------------------------------------------------------------
def change_tilemap_tone(tone = Tone.new(0,0,0,0), *char)
if tone.is_a?(Array) && (3..4) === tone.size
result = $game_map.tilemap_tone = Tone.new(*tone)
elsif tone.is_a?(Tone)
result = $game_map.tilemap_tone = tone
else
return
end
sprite = viewport_sprite(:viewport1)
sprite.reject! {|s| s.is_a?(Sprite_Character)}
sprite.each {|s| s.tone = result if s.respond_to?(:tone=) }
change_character_tone(tone, *char) unless char.empty?
end
#---------------------------------------------------------------------------
# * New method: change_character_tone
#---------------------------------------------------------------------------
def change_character_tone(tone = Tone.new(0,0,0,0), *char)
char = char.collect {|c| c.is_a?(Range) ? c.to_a : c}.flatten
char = char.collect {|c| c.is_a?(Range) ? c.to_a : c}.flatten
char.collect! {|c| c.is_a?(Game_Character) ? c :
$game_map.interpreter.get_character(c)}
sprite = viewport_sprite(:viewport1)
sprite.reject! {|s| s.not.is_a?(Sprite_Character) }
sprite.reject! {|s| char.not.include?(s.character)}
if tone.is_a?(Array) && (3..4) === tone.size
sprite.tone(:tone=, Tone.new(*tone))
elsif tone.is_a?(Tone)
sprite.send(:tone=, tone)
end
end
#--------------------------------------------------------------------------
# * New method: reload_tilemap
#--------------------------------------------------------------------------
def reload_tilemap
return [dispose_tilemap, create_tilemap] if LiTTleDRAgo::VXA
@tilemap.respond_to?(:dispose) && @tilemap.dispose
7.times do |i|
auto = @tilemap.autotiles[i]
auto.respond_to?(:dispose) && (auto.disposed? || auto.dispose)
end
res = tilemap_enabled? ? ZTilemap : Tilemap
@tilemap = res.new(@viewport1)
@tilemap.tileset = ModCache.tileset($game_map.tileset_name)
7.times do |i|
autotile_name = $game_map.autotile_names[i]
@tilemap.autotiles[i] = @tilemap.is_a?(ZTilemap) ?
ModCache.autotile_cr_tilemap(autotile_name) :
ModCache.autotile(autotile_name)
end
update_tilemap_effect
@tilemap.priorities = $game_map.priorities
@tilemap.map_data = $game_map.data
@tilemap.update
@viewport_screen_width = 0
end
#--------------------------------------------------------------------------
# * New method: reload_plane
#--------------------------------------------------------------------------
def reload_plane
z1 = @panorama.respond_to?(:z) ? @panorama.z : -1000
z2 = @fog.respond_to?(:z) ? @fog.z : 5000
z1 /= 1000 if @panorama.is_a?(CRPlane)
z2 /= 1000 if @fog.is_a?(CRPlane)
res = plane_enabled? ? CRPlane : Plane
bitmap1 = @panorama.respond_to?(:bitmap) ? @panorama.bitmap : nil
bitmap2 = @fog.respond_to?(:bitmap) ? @fog.bitmap : nil
@panorama.respond_to?(:dispose) && @panorama.dispose
@fog.respond_to?(:dispose) && @fog.dispose
@panorama = res.new(@viewport1)
@fog = res.new(@viewport1)
@panorama.bitmap = bitmap1 if bitmap1.is_a?(Bitmap)
@fog.bitmap = bitmap2 if bitmap2.is_a?(Bitmap)
@panorama.z, @fog.z = z1, z2
@viewport_screen_width = 0
end
#--------------------------------------------------------------------------
# * New method: update_tilemap_zoom
#--------------------------------------------------------------------------
def update_tilemap_zoom
@weather.zoom_x = $game_map.zoom_x
@weather.zoom_y = $game_map.zoom_y
@old_fog_zoom_x = @fog.zoom_x
@old_fog_zoom_y = @fog.zoom_y
@old_panorama_zoom_x = @panorama.zoom_x
@old_panorama_zoom_y = @panorama.zoom_y
@fog.zoom_x *= $game_map.zoom_x
@fog.zoom_y *= $game_map.zoom_y
@panorama.zoom_x *= $game_map.zoom_x
@panorama.zoom_y *= $game_map.zoom_y
update_tilemap_effect
end
#--------------------------------------------------------------------------
# * New method: update_tilemap_effect
#--------------------------------------------------------------------------
def update_tilemap_effect
return if @tilemap.not.is_a?(ZTilemap)
@tilemap.zoom_x = $game_map.zoom_x
@tilemap.zoom_y = $game_map.zoom_y
@tilemap.opacity = $game_map.tilemap_opacity
@tilemap.hue = $game_map.tilemap_hue
@tilemap.tone = $game_map.tilemap_tone
end
#--------------------------------------------------------------------------
# * Overwriten method: viewport_size_change?
#--------------------------------------------------------------------------
def viewport_size_change?
return true if @viewport_map_width != $game_map.width * $game_map.zoom_x
return true if @viewport_map_height != $game_map.height * $game_map.zoom_y
return true if @viewport_screen_width != Graphics.width
return true if @viewport_screen_height != Graphics.height
end
#--------------------------------------------------------------------------
# * New method: adjust_viewport
#--------------------------------------------------------------------------
def adjust_viewport
if viewport_size_change?
@viewport_map_width = $game_map.width * $game_map.zoom_x
@viewport_map_height = $game_map.height * $game_map.zoom_y
@viewport_screen_width = Graphics.width
@viewport_screen_height = Graphics.height
[@viewport1,@viewport2,@viewport3].compact.update_viewport_sizes
end
end
#--------------------------------------------------------------------------
# * New method: adjust_tilemap
#--------------------------------------------------------------------------
def adjust_tilemap
if LiTTleDRAgo::XP
if tilemap_enabled?
reload_tilemap if @tilemap.is_a?(Tilemap)
else
reload_tilemap if @tilemap.is_a?(ZTilemap)
end
end
if plane_enabled?
reload_plane if @panorama.is_a?(Plane) || @fog.is_a?(Plane)
else
reload_plane if @panorama.is_a?(CRPlane) || @fog.is_a?(CRPlane)
end
end
#--------------------------------------------------------------------------
# * New method: tilemap_enabled?
#--------------------------------------------------------------------------
def tilemap_enabled?
return true if @force_tilemap_enabled
return true unless LiTTleDRAgo::RGSS1
return true unless @viewport1.width <= 640 && @viewport1.height <= 480
return true unless (map = $game_map) && map.zoom_x * map.zoom_y == 1
return true unless map.tilemap_opacity >= 255
return true unless map.tilemap_hue <= 0
return true unless map.tilemap_tone.to_s.get_int == 0
return true if map.reverse
return false
end
#--------------------------------------------------------------------------
# * New method: plane_enabled?
#--------------------------------------------------------------------------
def plane_enabled?
return true unless LiTTleDRAgo::RGSS1
return true unless @viewport1.width <= 640 && @viewport1.height <= 480
return false
end
end
|
评分
-
查看全部评分
|