For my benefit and others I think it would be a good idea to collect all the hidden classes known (not the ones layed out in the help doc) into one location on the web.
Audio
Bitmap
Color
Code:
#==============================================================================
# ■ Color
#------------------------------------------------------------------------------
# by vgvgf
#==============================================================================
class Color
def initialize(r, g, b, a = 255)
@red = r
@green = g
@blue = b
@alpha = a
end
def set(r, g, b, a = 255)
@red = r
@green = g
@blue = b
@alpha = a
end
def color
Color.new(@red, @green, @blue, @alpha)
end
def _dump(d = 0)
[@red, @green, @blue, @alpha].pack('d4')
end
def self._load(s)
Color.new(*s.unpack('d4'))
end
def inspect
sprintf("(%f, %f, %f, %f)", @red, @green, @blue, @alpha)
end
def to_s
self.inspect
end
attr_accessor(:red, :green, :blue, :alpha)
end
Font
Graphics
Input
Code:
# Found by Narzew
module Input
DOWN=2
LEFT=4
RIGHT=6
UP=8
A=11
B=12
C=13
X=14
Y=15
Z=16
L=17
R=18
SHIFT=21
CTRL=22
ALT=23
F5=25
F6=26
F7=27
F8=28
F9=29
# GetAsyncKeyState or GetKeyState will work here
@GetKeyState=Win32API.new("user32", "GetAsyncKeyState", "i", "i")
# Returns whether a key is being pressed
def self.getstate(key)
return (@GetKeyState.call(key)&0x8000)>0
end
def self.update
if @keystate
for i in 0...256
@newstate=self.getstate(i)
@triggerstate[i]=(@newstate&&@keystate[i]==0)
@releasestate[i]=(!@newstate&&@keystate[i]>0)
@keystate[i]=@newstate ? @keystate[i]+1 : 0
end
else
@keystate=[]
@triggerstate=[]
@releasestate=[]
for i in 0...256
@keystate[i]=self.getstate(i) ? 1 : 0
@triggerstate[i]=false
@releasestate[i]=false
end
end
end
def self.buttonToKey(button)
case button
when Input::DOWN
return [0x28] # Down
when Input::LEFT
return [0x25] # Left
when Input::RIGHT
return [0x27] # Right
when Input::UP
return [0x26] # Up
when Input::A
return [0x5A,0x10] # Z, Shift
when Input::B
return [0x58,0x1B] # X, ESC
when Input::C
return [0x43,0x0d,0x20] # C, ENTER, Space
when Input::X
return [0x41] # A
when Input::Y
return [0x53] # S
when Input::Z
return [0x44] # D
when Input::L
return [0x51,0x21] # Q, Page Up
when Input::R
return [0x57,0x22] # W, Page Up
when Input::SHIFT
return [0x10] # Shift
when Input::CTRL
return [0x11] # Ctrl
when Input::ALT
return [0x12] # Alt
when Input::F5
return [0x74] # F5
when Input::F6
return [0x75] # F6
when Input::F7
return [0x76] # F7
when Input::F8
return [0x77] # F8
when Input::F9
return [0x78] # F9
else
return []
end
end
def self.dir4
button=0
repeatcount=0
if self.press?(Input::DOWN) && self.press?(Input::UP)
return 0
end
if self.press?(Input::LEFT) && self.press?(Input::RIGHT)
return 0
end
for b in [Input::DOWN,Input::LEFT,Input::RIGHT,Input::UP]
rc=self.count(b)
if rc>0
if repeatcount==0 || rc<repeatcount
button=b
repeatcount=rc
end
end
end
return button
end
def self.dir8
buttons=[]
for b in [Input::DOWN,Input::LEFT,Input::RIGHT,Input::UP]
rc=self.count(b)
if rc>0
buttons.push([b,rc])
end
end
if buttons.length==0
return 0
elsif buttons.length==1
return buttons[0][0]
elsif buttons.length==2
# since buttons sorted by button, no need to sort here
if (buttons[0][0]==Input::DOWN && buttons[1][0]==Input::UP)
return 0
end
if (buttons[0][0]==Input::LEFT && buttons[1][0]==Input::RIGHT)
return 0
end
end
buttons.sort!{|a,b| a[1]<=>b[1]}
updown=0
leftright=0
for b in buttons
if updown==0 && (b[0]==Input::UP || b[0]==Input::DOWN)
updown=b[0]
end
if leftright==0 && (b[0]==Input::LEFT || b[0]==Input::RIGHT)
leftright=b[0]
end
end
if updown==Input::DOWN
return 1 if leftright==Input::LEFT
return 3 if leftright==Input::RIGHT
return 2
elsif updown==Input::UP
return 7 if leftright==Input::LEFT
return 9 if leftright==Input::RIGHT
return 8
else
return 4 if leftright==Input::LEFT
return 6 if leftright==Input::RIGHT
return 0
end
end
def self.count(button)
for btn in self.buttonToKey(button)
c=self.repeatcount(btn)
return c if c>0
end
return 0
end
def self.trigger?(button)
return self.buttonToKey(button).any? {|item| self.triggerex?(item) }
end
def self.repeat?(button)
return self.buttonToKey(button).any? {|item| self.repeatex?(item) }
end
def self.press?(button)
return self.count(button)>0
end
def self.repeatex?(key)
return false if !@keystate
return @keystate[key]==1 || (@keystate[key]>20 && (@keystate[key]&1)==0)
end
def self.releaseex?(key)
return false if !@releasestate
return @releasestate[key]
end
def self.triggerex?(key)
return false if !@triggerstate
return @triggerstate[key]
end
def self.repeatcount(key)
return 0 if !@keystate
return @keystate[key]
end
def self.pressex?(key)
return self.repeatcount(key)>0
end
end
class SG::Plane
attr_reader :ox, :oy
#--------------------------------------------------------------------------
# — initialize
#--------------------------------------------------------------------------
def initialize(viewport = nil)
@sprite = Sprite.new(viewport)
@max_width = 640
@max_height = 480
@bitmap = nil
@ox = 0
@oy = 0
end
#--------------------------------------------------------------------------
# ● z, zoom_x, zoom_y, opacity, blend_type, color, tone
# z=, zoom_x=, zoom_y=, opacity=, blend_type=, color=, tone=
#--------------------------------------------------------------------------
def method_missing(symbol, *args)
@sprite.method(symbol).call(*args)
end
#--------------------------------------------------------------------------
# ● bitmap=
#--------------------------------------------------------------------------
def bitmap=(bitmap)
@bitmap = bitmap
refresh
end
#--------------------------------------------------------------------------
# ● ox=
#--------------------------------------------------------------------------
def ox=(ox)
w = @sprite.viewport != nil ? @sprite.viewport.rect.width : @max_width
@ox = ox % w
@sprite.ox = @ox
end
#--------------------------------------------------------------------------
# ● oy=
#--------------------------------------------------------------------------
def oy=(oy)
h = @sprite.viewport != nil ? @sprite.viewport.rect.height : @max_height
@oy = oy % h
@sprite.oy = @oy
end
#--------------------------------------------------------------------------
# ● refresh
#--------------------------------------------------------------------------
def refresh
return if @bitmap.nil?
w = @sprite.viewport != nil ? @sprite.viewport.rect.width : @max_width
h = @sprite.viewport != nil ? @sprite.viewport.rect.height : @max_height
if @sprite.bitmap != nil
@sprite.bitmap.dispose
end
@sprite.bitmap = Bitmap.new(w * 2, h * 2)
max_x = w / @bitmap.width
max_y = h / @bitmap.height
for x in 0..max_x
for y in 0..max_y
@sprite.bitmap.blt(x * @bitmap.width, y * @bitmap.height,
@bitmap, Rect.new(0, 0, @bitmap.width, @bitmap.height))
end
end
for i in 1...4
x = i % 2 * w
y = i / 2 * h
@sprite.bitmap.blt(x, y, @sprite.bitmap, Rect.new(0, 0, w, h))
end
end
end
end
Rect
Sprite
Table
Code:
#==============================================================================
# ■ Table
#------------------------------------------------------------------------------
# by vgvgf
#==============================================================================
class Table
def initialize(x,y=1,z=1)
@xsize,@ysize,@zsize=x,y,z
@data=Array.new(x*y*z, 0)
end
def [](x,y=0,z=0)
@data[x+y*@xsize+z*@xsize*@ysize]
end
def []=(*args)
x=args[0]
y=args.size>2 ?args[1]:0
z=args.size>3 ?args[2]:0
v=args.pop
@data[x+y*@xsize+z*@xsize*@ysize]=v
end
def _dump(d=0)
s=[3].pack('L')
s+=[@xsize].pack('L')+[@ysize].pack('L')+[@zsize].pack('L')
s+=[@xsize*@ysize*@zsize].pack('L')
for z in 0...@zsize
for y in 0...@ysize
for x in 0...@xsize
s+=[@data[x+y*@xsize+z*@xsize*@ysize],0,0].pack('L')[0,2]
end
end
end
s
end
attr_reader(:xsize,:ysize,:zsize,:data)
class << self
def _load(s)
size=s[0,4].unpack('L')[0]
nx=s[4,4].unpack('L')[0]
ny=s[8,4].unpack('L')[0]
nz=s[12,4].unpack('L')[0]
data=[]
pointer=20
loop do
data.push((s[pointer,2]+"\000\000").unpack('L')[0])
pointer+=2
break if pointer > s.size-1
end
t=Table.new(nx,ny,nz)
n=0
for z in 0...nz
for y in 0...ny
for x in 0...nx
t[x,y,z]=data[n]
n+=1
end
end
end
t
end
end
end
Tilemap
Code:
#==============================================================================
# ** Tilemap (hidden class)
#------------------------------------------------------------------------------
# This class handles the map data to screen processing
#==============================================================================
#==============================================================================
#
# Yet another Tilemap Script (for any map size /w autotiles)
# by Meâ €žÂ¢ / Derk-Jan Karrenbeld (me@solarsoft.nl)
# version 1.0 released on 08 nov 08
# version 1.2
#
#==============================================================================
class Tilemap
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :tileset
attr_reader :autotiles
attr_reader :flash_data
attr_reader :priorities
attr_reader :visible
attr_reader :ox, :oy
attr_writer :autotiles
# Window Rect - the visible Area of the Map (default: 640 x 480)
# Bitmap Rect - the active drawing Area of the Map (window tiles + 2 tiles)
# BitmapWindow offset - the invisible tile count on one side
WindowRect = Rect.new(0,0,640,480)
BitmapRect = Rect.new(0,0,640 + 64, 480 + 64) # Recommended
BitmapWindowOffset = (BitmapRect.height-WindowRect.height)/2/32
# Length in frames of one frame showing from autotile
AutotileLength = 10
# KillOutScreenSprite - Kills priority and autotile sprites out of screen
# EnableFlashingData - If activated, enables updating flashing data
KillOutScreenSprite = true
EnableFlashingData = false
# SingleFlashingSprite - Uses one Flashing sprite, instead of many
# SinglePrioritySprite - Uses one Priority sprite, instead of many
# SingleAutotileSprite - Uses one Autotile sprite, instead of many
SingleFlashingSprite = false
SinglePrioritySprite = false
SingleAutotileSprite = false
# This is the Autotile animation graphical index array. It contains numbers
# that point to the graphic part of an animating autotile.
Autotiles = [
[ [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] ]
]
#--------------------------------------------------------------------------
# * Object Initialization
# viewport : the drawing viewport
# rpgmap : the rpgmap object
#--------------------------------------------------------------------------
def initialize(viewport = nil, rpgmap = nil)
# Autotiles Array
@autotiles = Array.new(6, nil)
@oldautotiles = Array.new(6, nil)
# Tilemap Viewport
@viewport = viewport ? viewport : Viewport.new(WindowRect)
# Showing Region Rectangle
@region = Rect.new(0,0,BitmapRect.width/32, BitmapRect.height/32)
# Old Region Rect
@oldregion = nil
# Set TilemapSprite
@sprite = Sprite.new(@viewport)
# Set Bitmap on Sprite
@sprite.bitmap = Bitmap.new(BitmapRect.width, BitmapRect.height)
# Set FlashingSprite and bitmap
if SingleFlashingSprite
@flashsprite = Sprite.new(@viewport)
@flashsprite.bitmap = Bitmap.new(BitmapRect.width, BitmapRect.height)
end
# Set Informational Arrays/Hashes
@priority_ids = {} # Priority ids
@normal_tiles = {} # Non-auto tile bitmaps
@auto_tiles = {} # Autotile bitmaps
@priority_sprites = [] # Priority Sprites
@autotile_sprites = [] # Autotile Sprites
@flashing_sprites = [] # Flashing Sprites
# Disposal Boolean
@disposed = false
# Visibility Boolean
@visible = true
# Flashing Boolean
@flashing = true
# Disable Drawing Boolean
@can_draw = true
# Set Coords
@ox, @oy = 0, 0
# Create TileMap if rpgmap is provided
create_tilemap(rpgmap) if !rpgmap.nil?
end
#--------------------------------------------------------------------------
# * Get Bitmap Sprite
#--------------------------------------------------------------------------
def sprite_bitmap
return @sprite.bitmap
end
#--------------------------------------------------------------------------
# * Data Tileset Referer - loads if needed
#--------------------------------------------------------------------------
def data_tilesets
$data_tilesets ||= load_data("Data/Tilesets.rxdata")
end
#--------------------------------------------------------------------------
# * Check: Disposed?
#--------------------------------------------------------------------------
def disposed?
@disposed
end
#--------------------------------------------------------------------------
# * Dispose
#--------------------------------------------------------------------------
def dispose
# Dispose all sprites (and cached bitmaps for quick memory clearing)
for sprite in [@sprite] + @normal_tiles.values + @auto_tiles.values + @priority_sprites + @autotile_sprites + (SingleFlashingSprite ? [@flashsprite] : @flashing_sprites)
sprite = sprite[0] if sprite.is_a?(Array)
sprite.dispose if sprite.is_a?(Bitmap)
end
# Set Informational Arrays/Hashes
@priority_ids = {} # Priority ids
@normal_tiles = {} # Non-auto tile bitmaps
@priority_sprites = [] # Priority Sprites
@autotile_sprites = [] # Autotile Sprites
@flashing_sprites = [] # Flashing Sprites
# I am disposed
@disposed = true
end
#--------------------------------------------------------------------------
# * Checking: Drawing Allowed
#--------------------------------------------------------------------------
def drawing?
@can_draw
end
#--------------------------------------------------------------------------
# * Enable Drawing
#--------------------------------------------------------------------------
def enable_drawing
@can_draw = true
end
#--------------------------------------------------------------------------
# * Disable Drawing
#--------------------------------------------------------------------------
def disable_drawing
@can_draw = true
end
#--------------------------------------------------------------------------
# * Enable Flashing
#--------------------------------------------------------------------------
def enable_flashing
@flashing = true
end
#--------------------------------------------------------------------------
# * Disable Flashing
#--------------------------------------------------------------------------
def disable_flashing
@flashing = false
end
#--------------------------------------------------------------------------
# * Check: Flashing
#--------------------------------------------------------------------------
def flashing?
EnableFlashingData and @flashing and @flashing_sprites.size
end
#--------------------------------------------------------------------------
# * Check: Visible
#--------------------------------------------------------------------------
def visible?
@visible
end
#--------------------------------------------------------------------------
# * Check: Autotiles Changed
#--------------------------------------------------------------------------
def autotiles_changed?
@oldautotiles != @autotiles
end
#--------------------------------------------------------------------------
# * Set Visibility
# value: new value
#--------------------------------------------------------------------------
def visible=(value)
# Set Visibility value
@visible = value
# Update all sprites
for sprite in [@sprite] + @priority_sprites + @autotile_sprites + (SingleFlashingSprite ? [@flashsprite] : @flashing_sprites)
sprite = sprite[0] if sprite.is_a?(Array)
sprite.visible = value
end
end
#--------------------------------------------------------------------------
# * Set Tileset
# value : new RPG::Tileset, String or Bitmap
#--------------------------------------------------------------------------
def tileset=(value)
# Return on equal data
return if @tileset == value
# Set TilesetName
value = value.tileset_name if value.is_a?(RPG::Tileset)
# Cache Tileset
@tileset = RPG::Cache.tileset(value) if value.is_a?(String)
# Set Tileset
@tileset = value if value.is_a?(Bitmap)
# Draw Tileset
redraw_tileset if @can_draw
end
#--------------------------------------------------------------------------
# * Set Priorities
# value : new value
#--------------------------------------------------------------------------
def priorities=(value)
# Return on equal data
return if @priorities == value
# Set Priorities
@priorities = value
# Draw Tileset
redraw_priorities if @can_draw
end
#--------------------------------------------------------------------------
# * Set flash data
# coord[0] : x
# coord[1] : y
# value : Color or Hex
#--------------------------------------------------------------------------
def flash_data=(*coord, &value)
# Return on equal data
return if @flash_data[coord[0],coord[1]] == value
# Already Flashing this tile?
flashing = !@flash_data[x,y].nil?
# Set Flash Data
@flash_data[x,y] = value
return if !EnableFlashingData
# Take action and remove/change/add flash
if value.nil?
remove_flash(x,y)
elsif flashing
change_flash(x,y,value)
else
add_flash(x,y,value)
end
end
#--------------------------------------------------------------------------
# * Map Data referer
#--------------------------------------------------------------------------
def map_data
@map_data
end
#--------------------------------------------------------------------------
# * Set Map Data
# value : new Table value
#--------------------------------------------------------------------------
def map_data=(value)
# Return on equal data
return if @map_data == value
# Set New Map Data
@map_data = value
# Flash Data Table
@flash_data = Table.new(@map_data.xsize, @map_data.ysize)
# Redraw Current Region
draw_region if @can_draw and @priorities and @tileset
end
#--------------------------------------------------------------------------
# * Get Map width (in tiles)
#--------------------------------------------------------------------------
def map_tile_width
map_data.xsize
end
#--------------------------------------------------------------------------
# * Get Map height (in tiles)
#--------------------------------------------------------------------------
def map_tile_height
map_data.ysize
end
#--------------------------------------------------------------------------
# * Create Tilemap
# rpgmap : base object
#--------------------------------------------------------------------------
def create_tilemap(rpgmap)
# Return on invalid data
return if rpgmap.is_a?(RPG::Map) == false
# Restrict drawing
@can_draw = false
# Set Local Tileset Object (RPG::Tileset)
_tileset = data_tilesets[rpgmap.tileset_id]
# Return on invalid data
return if _tileset.is_a?(RPG::Tileset) == false
# Set Informational Arrays/Hashes
@priority_ids = {} # Priority ids
@normal_tiles = {} # Non-auto tile bitmaps
@priority_sprites = [] # Priority Sprites
@autotile_sprites = [] # Autotile Sprites
@flashing_sprites = [] # Flashing Sprites
# Set Tileset
tileset = _tileset.tileset_name
# Set AutoTiles
(0..6).each { |i| autotiles[i] = _tileset.autotile_names[i] }
# Set Priorities
priorities = _tileset.priorities
# Set Mapdata
map_data = rpgmap.map_data
# Reset drawing
@can_draw = true
# Reset disposed (need to reinit info variables)
@disposed = false
# Draw Region
draw_region
end
#--------------------------------------------------------------------------
# * Get Tile id
# x : x tile coord
# y : y tile coord
# z : z layer coord
#--------------------------------------------------------------------------
def tile_id(x, y, z)
return map_data[x, y, z]
end
#--------------------------------------------------------------------------
# * Get Priority
# args (1) : tile_id
# args (3) : x, y, z coord
#--------------------------------------------------------------------------
def priority(*args)
return @priorities[args[0]] if args.size == 1
return @priorities[tile_id(args[0], args[1], args[2])]
end
#--------------------------------------------------------------------------
# * Redraw Tileset (on change)
#--------------------------------------------------------------------------
def redraw_tileset
# Kill current bitmap
sprite_bitmap.clear
# Get rid of tile bitmaps
@normal_tiles.clear
# Get rid of autotile bitmaps
@auto_tiles.clear
# Dispose current tiles in screen
(@autotile_sprites + @priority_sprites).each { |sprite| sprite[0].dispose if !sprite[0].disposed? }
# Clear disposed graphics
@autotile_sprites.clear; @priority_sprites.clear
# Draw if allowed
draw_region if @can_draw and @priorities and @tileset
end
#--------------------------------------------------------------------------
# * Redraw Priorities (on change)
#--------------------------------------------------------------------------
def redraw_priorities
# Dispose current tiles in screen
(@autotile_sprites + @priority_sprites).each { |sprite| sprite[0].dispose if !sprite[0].disposed? }
# Clear disposed graphics
@priority_sprites.clear; @autotile_sprites.clear
# Clear Priority id information
@priority_ids.clear
# Do a one time check for all priorities (can't do @tileset.priorities
# because RPG::Tilemap is normally not passed trough, but if it were, you
# can do the following - just uncomment this part and command the next for
# loop:
## for tile_id in 0...@tileset.priorities.xsize
## next if @tileset.priorities[tile_id] == 0
## @priority_ids[tile_id] = @tileset.priorities[tile_id]
## end
# But because we don't have that data, just iterate trough the map and
# get seperate priority data for each tile, and save if there is one.
for z in 0...3
for y in 0...map_tile_height
for x in 0...map_tile_width
next if (id = tile_id(x, y, z)) == 0
next if (p = priority(id)) == 0
@priority_ids[id] = p
end
end
end
# Draw if allowed
draw_region if @can_draw and @priorities and @tileset
end
#--------------------------------------------------------------------------
# * Redraw autotiles (on change)
#--------------------------------------------------------------------------
def redraw_autotiles
# Clear autotile bitmaps
@auto_tiles.clear
# Dispose current autotiles on screen
@autotile_sprites.each { |sprite| sprite[0].dispose if !sprite[0].disposed? }
# Get rid of disposed sprites
@autotile_sprites.clear
# Save changes aka don't call this method again
@oldautotiles = @autotiles
# Draw if allowed
draw_region if @can_draw and @priorities and @tileset
end
#--------------------------------------------------------------------------
# * Draw new Visible region
#--------------------------------------------------------------------------
def draw_current_region
# Determine x and y coords for tile top left
left_x = @ox / 32
top_y = @oy / 32
# Set origin for bitmap
@sprite.ox = @ox % 32 + BitmapWindowOffset * 32
@sprite.oy = @oy % 32 + BitmapWindowOffset * 32
# Set New Region
@region.x, @region.y = left_x, top_y
# Set New Sprite Positions (pray for non disposed sprites: checking = cpu cost)
(@priority_sprites + @autotile_sprites).each { |sprite| sprite[0].x = (sprite[1] - left_x) * 32 ;
sprite[0].ox = @ox % 32; sprite[0].y = (sprite[2] - top_y) * 32; sprite[0].oy = @oy % 32;
unless (priority = @priority_ids[tile_id(sprite[1], sprite[2], sprite[3])]).nil? then sprite[0].z = @viewport.z + sprite[0].y + priority * 32 + 32 end}
# Return on old data
return if @oldregion == @region
# Draw complete region if new?
return draw_region if @oldregion.nil?
# Determine missing rect
first_drawing_x = [((left_x - @oldregion.x) >= 0 ? @region.width : 0) - (left_x - @oldregion.x)].max
drawing_rect_x = Rect.new(first_drawing_x, 0, ((left_x - @oldregion.x).abs), @region.height)
first_drawing_y = [((top_y - @oldregion.y) >= 0 ? @region.height : 0) - (top_y - @oldregion.y)].max
drawing_rect_y = Rect.new(0, first_drawing_y, @region.width, ((top_y - @oldregion.y).abs))
# Determine Rect that is still visible
stay_rect = Rect.new([(left_x-@oldregion.x) * 32,0].max, [(top_y-@oldregion.y) * 32,0].max, (@region.width - (left_x-@oldregion.x).abs) * 32,(@region.height - (top_y-@oldregion.y).abs) * 32)
# Dumplicate bitmap and clear Original
dump_bitmap = sprite_bitmap.dup; sprite_bitmap.clear
# Place Old bitmap on screen
sprite_bitmap.blt([(@oldregion.x-left_x) * 32, 0].max, [(@oldregion.y-top_y) * 32, 0].max,dump_bitmap, stay_rect)
# Remove Out of Range Sprites
if KillOutScreenSprite
_prio, _auto = @priority_sprites.dup, @autotile_sprites.dup; @priority_sprites, @autotile_sprites = [], []
for sprite in _prio do if (sprite[1]) < @region.x - BitmapWindowOffset or (sprite[1] - BitmapWindowOffset) > @region.width + @region.x or sprite[2] < @region.y - BitmapWindowOffset or (sprite[2] - BitmapWindowOffset) > @region.height + @region.y then sprite[0].dispose else @priority_sprites << sprite end end
for sprite in _auto do if (sprite[1]) < @region.x - BitmapWindowOffset or (sprite[1] - BitmapWindowOffset) > @region.width + @region.x or sprite[2] < @region.y - BitmapWindowOffset or (sprite[2] - BitmapWindowOffset) > @region.height + @region.y then sprite[0].dispose else @autotile_sprites << sprite end end
# Remove nil elements (error prevention)
@priority_sprites.compact!; @autotile_sprites.compact!;
end
# Draw New Columns
for x in 0...drawing_rect_x.width
for y in 0...drawing_rect_x.height
for z in 0..2
draw_tile(drawing_rect_x.x + x , drawing_rect_x.y + y, tile_id(left_x + drawing_rect_x.x + x - BitmapWindowOffset, top_y + y - BitmapWindowOffset, z), left_x + drawing_rect_x.x + x - BitmapWindowOffset, top_y + y - BitmapWindowOffset, z)
end
end
end
# Draw New Rows
for x in 0...drawing_rect_y.width
for y in 0...drawing_rect_y.height
for z in 0..2
draw_tile(drawing_rect_y.x + x , drawing_rect_y.y + y, tile_id(left_x + x - BitmapWindowOffset, top_y + drawing_rect_y.y + y - BitmapWindowOffset, z), left_x + x - BitmapWindowOffset, top_y + drawing_rect_y.y + y - BitmapWindowOffset, z)
end
end
end
# Set region sprite coords
@oldregion = Rect.new(left_x, top_y, @region.width, @region.height)
end
#--------------------------------------------------------------------------
# * Draw complete visible region
#--------------------------------------------------------------------------
def draw_region
# Clear Sprites
sprite_bitmap.clear
(@priority_sprites + @autotile_sprites).each { |sprite| sprite[0].dispose }
@priority_sprites.clear; @autotile_sprites.clear
# Determine x and y coords for tile top left
left_x = @ox / 32
top_y = @oy / 32
# Set Sprite ox/oy
@sprite.ox = BitmapWindowOffset * 32
@sprite.oy = BitmapWindowOffset * 32
# Set New Region
@region.x, @region.y = left_x, top_y
# Iterate through new xses
for x in 0...(@region.width)
for y in 0...(@region.height)
for z in 0..2
# Draw new tiles
draw_tile(x, y , tile_id(x + left_x - BitmapWindowOffset,y + top_y - BitmapWindowOffset,z), x + left_x - BitmapWindowOffset , y + top_y - BitmapWindowOffset, z)
end
end
end
# Set oldregion (sprite coords)
@oldregion = Rect.new(left_x, top_y, @region.width, @region.height)
# Update Sprite
@sprite.update
# Prevent Frame Skipping
Graphics.frame_reset
end
#--------------------------------------------------------------------------
# * Draw a tile
# x : x coord in tiles on screen
# y : y coord in tiles on screen
# tile_id : tile id
# tx : x coord in tiles on map
# ty : y coord in tiles on map
# tx : z layer on map
# src_... : bitmap to draw on
#--------------------------------------------------------------------------
def draw_tile(x, y, tile_id, tx, ty, tz, src_bitmap = nil)
# Return on invalid data
#return if @region.x < x or @region.y < y
#return if @region.width + @region.x > x or @region.height + @region.y > y
return if x < 0 or y < 0
return if tile_id == nil
return draw_autotile(x, y, tile_id, tx, ty, tz, bitmap = bitmap) if tile_id < 384
# First, Get Bitmap
if (src_bitmap = @normal_tiles[tile_id]).nil?
# Get Bitmap
src_bitmap = Bitmap.new(32, 32)
src_rect = Rect.new((tile_id - 384) % 8 * 32, (tile_id - 384) / 8 * 32,32,32)
src_bitmap.blt(0, 0, @tileset, src_rect)
# Save Bitmap
@normal_tiles[tile_id] = src_bitmap
end
# Now, if tile is not a priority tile...
if @priority_ids[tile_id].nil?
sprite_bitmap.blt(x * 32, y * 32, src_bitmap, Rect.new(0,0,32,32))
else
# ... Set Sprite and bitmap
sprite = Sprite.new(@viewport)
sprite.visible = visible
sprite.bitmap = src_bitmap
sprite.x, sprite.y = (tx - (@ox/32)) * 32, (ty - (@oy/32)) * 32
sprite.ox, sprite.oy = @ox % 32, @oy % 32
# Priority matches 32 (above normal) + value * 32 (priority) + tile y * 32
sprite.z = @viewport.z + y * 32 + @priority_ids[tile_id] * 32 + 32
# Add to sprites Array
@priority_sprites << [sprite, tx, ty, tz]
end
end
#--------------------------------------------------------------------------
# * Draw an autotile
# x : x coord in tiles on screen
# y : y coord in tiles on screen
# tile_id : tile id
# tx : x coord in tiles on map
# ty : y coord in tiles on map
# tx : z layer on map
# src_... : bitmap to draw on
#--------------------------------------------------------------------------
def draw_autotile(x, y, tile_id, tx, ty, tz, src_bitmap = nil)
# Kill invalid calls
return if x < 0 or y < 0
return if tile_id == nil or tile_id >= 384
return if tile_id == 0
# Get AutotileGraphic
autotile = @autotiles[tile_id/48-1]
return if autotile.nil? or autotile.disposed?
# Get Frame Data
frames = (autotile.height == 32 ? autotile.width / 32 : autotile.width / 96)
current_frame = (Graphics.frame_count/AutotileLength) % frames
# First Get Bitmap
if (src_bitmap_array = @auto_tiles[tile_id]).nil?
@auto_tiles[tile_id] = []
# If autotile is weird... :P
if autotile.height == 32
# Just iterate trough frames
for i in 0...frames
# Create a bitmap for this frame
this_frame_bitmap = Bitmap.new(32,32)
src_rect = Rect.new(i * 32, 0, 32, 32)
this_frame_bitmap.blt(0, 0, autotile, src_rect)
# Save this frame's bitmap
@auto_tiles[tile_id] << this_frame_bitmap
end
# Set the bitmap array to the created one
src_bitmap_array = @auto_tiles[tile_id]
else
# If autotile is normal, iterate
for i in 0...frames
# Create a new bitmap for this frame
this_frame_bitmap = Bitmap.new(32,32)
# Get the tiles from the Autotiles Array (tile_id corresponds
# to the autotile graphic, so left_top is different to center
tiles = Autotiles[(tile_id % 48)>>3][(tile_id % 48)&7]
# Iterate trough 0, 1, 2 and 3
for j in 0...4
# Get tile_position (to get from the graphic)
tile_position = tiles[j] - 1
src_rect = Rect.new(tile_position % 6 * 16 + i * 96, tile_position / 6 * 16, 16, 16)
this_frame_bitmap.blt(j % 2 * 16, j / 2 * 16 , autotile, src_rect)
end
@auto_tiles[tile_id][i] = this_frame_bitmap
end
src_bitmap_array = @auto_tiles[tile_id]
end
end
# Now Get Frame Bitmap
src_bitmap = src_bitmap_array[current_frame]
return if src_bitmap.nil?
# Now, if tile is not a priority tile...
if @priority_ids[tile_id].nil? and autotile.width == 32
sprite_bitmap.blt(x * 32, y * 32, src_bitmap, Rect.new(0,0,32,32))
else
priority = (@priority_ids[tile_id] or 0)
# ... Set Sprite and bitmap
sprite = Sprite.new(@viewport)
sprite.visible = visible
sprite.bitmap = src_bitmap
sprite.x, sprite.y = (tx - (@ox/32)) * 32, (ty - (@oy/32)) * 32
sprite.ox, sprite.oy = @ox % 32, @oy % 32
# Priority matches 32 (above normal) + value * 32 (priority) + tile y * 32
# Because this sprite is created later then the normal base sprite, it
# has a higher internal z value. We fix this by setting the z value to
# minus 2 + z value of this tile. This results in that a autotile is below
# minus 2 + z value of this tile. This results in that a autotile is below
# a normal sprite on the same priority
sprite.z = @viewport.z - 2 + tz # Fix for ltr drwn.
unless @priority_ids[tile_id].nil?
sprite.z = @viewport.z + y * 32 + @priority_ids[tile_id] * 32 + 32
end
# Add to sprites Array
@autotile_sprites << [sprite, tx, ty, tz]
end
end
#--------------------------------------------------------------------------
# * Get new autotile Bitmap
# tile_id : tile id
#--------------------------------------------------------------------------
def get_update_autotile(tile_id)
# Kill invalid Data
return if tile_id == nil or tile_id >= 384
return if tile_id == 0
# Get AutotileGraphic
autotile = @autotiles[tile_id/48-1]
return if autotile.nil? or autotile.disposed?
# Get Frame Data
frames = (autotile.height == 32 ? autotile.width / 32 : autotile.width / 96)
current_frame = (Graphics.frame_count/AutotileLength) % frames
# Now Get Frame Bitmap
src_bitmap = @auto_tiles[tile_id][current_frame]
return src_bitmap
end
#--------------------------------------------------------------------------
# * Set x origin value
# value : new value
#--------------------------------------------------------------------------
def ox=(value)
# Next line is needed if you want to do complex things if ox changes
return unless @ox != value
@ox = value
end
#--------------------------------------------------------------------------
# * Set y origin value
# value : new value
#--------------------------------------------------------------------------
def oy=(value)
# Next line is needed if you want to do complex things if oy changes
return unless @oy != value
@oy = value
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Redraw autotiles if changed
redraw_autotiles if autotiles_changed?
# Cancel updating if invisible
return if not visible?
# Flash Tiles
update_flashing if flashing?
# Update autotiles
update_autotiles if (Graphics.frame_count % AutotileLength) == 0
# Draw Region
draw_current_region
end
#--------------------------------------------------------------------------
# * Update (flashing)
#--------------------------------------------------------------------------
def update_flashing
# To be released
end
#--------------------------------------------------------------------------
# * Update (autotiles)
#--------------------------------------------------------------------------
def update_autotiles
# Determine x and y coords for tile top left
left_x = @ox / 32
top_y = @oy / 32
# Iterate trough sprites
for sprite in @autotile_sprites
# Get Data from Array
real_sprite, tx, ty, tz = sprite
tile_id = tile_id(tx, ty, tz)
# Replace Bitmap (can't clear the bitmap, for some reason - don't try to)
real_sprite.bitmap = get_update_autotile(tile_id)
# We do not need to update the positions already, because it will be done
# the next method call (below update_autotiles, there is draw_current_...)
# so it will be 'fixed' there. No need to call something twice, right?
end
end
end
or
Code:
#Found by Narzew
class CustomTilemapAutotiles
attr_accessor :changed
def initialize
@changed=true
@tiles=[nil,nil,nil,nil,nil,nil,nil]
end
def []=(i,value)
@tiles[i]=value
@changed=true
end
def [](i)
return @tiles[i]
end
end
class CustomTilemap
Animated_Autotiles_Frames = 15
Autotiles = [
[ [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] ]
]
FlashOpacity=[100,90,80,70,80,90]
attr_reader :tileset
attr_reader :autotiles
attr_reader :map_data
attr_accessor :flash_data
attr_accessor :priorities
attr_reader :visible
attr_accessor :ox
attr_accessor :oy
attr_reader :viewport
attr_accessor :tone
attr_accessor :color
def graphicsHeight
return 480
end
def graphicsWidth
return 640
end
def initialize(viewport)
@tileset = nil # Refers to Map Tileset Name
@autotiles = CustomTilemapAutotiles.new
@map_data = nil # Refers to 3D Array Of Tile Settings
@flash_data = nil # Refers to 3D Array of Tile Flashdata
@priorities = nil # Refers to Tileset Priorities
@visible = true # Refers to Tileset Visibleness
@ox = 0 # Bitmap Offsets
@oy = 0 # bitmap Offsets
@plane = false
@tone=Tone.new(0,0,0,0)
@color=Color.new(0,0,0,0)
@oldtone=Tone.new(0,0,0,0)
@oldcolor=Color.new(0,0,0,0)
@selfviewport=Viewport.new(0,0,graphicsWidth,graphicsHeight)
@viewport=viewport ? viewport : @selfviewport
@tiles=[]
@autotileInfo=[]
@regularTileInfo=[]
@oldOx=0
@oldOy=0
@layer0=Sprite.new(viewport)
@layer0.visible=true
@nowshown=false
@layer0.bitmap=Bitmap.new([graphicsWidth*2,1].max,[graphicsHeight*2,1].max)
@flash=nil
@layer0.ox=0
@layer0.oy=0
@oxLayer0=0
@oyLayer0=0
@oxFlash=0
@oyFlash=0
@layer0.z=0
@priotiles=[]
@prioautotiles=[]
@autosprites=[]
@framecount=[]
@tilesetChanged=true
@flashChanged=false
@firsttime=true
@disposed=false
@usedsprites=false
@layer0clip=true
@firsttimeflash=true
@fullyrefreshed=false
@fullyrefreshedautos=false
end
def disposed?
return @disposed
end
def flash_data=(value)
@flash_data=value
@flashChanged=true
end
def update
if @oldtone!=@tone
@layer0.tone=@tone
@flash.tone=@tone if @flash
for sprite in @autosprites
sprite.tone=@tone
end
for sprite in @tiles
sprite.tone=@tone if sprite.is_a?(Sprite)
end
@oldtone=@tone.clone
end
if @oldcolor!=@color
@layer0.color=@color
@flash.color=@color if @flash
for sprite in @autosprites
sprite.color=@color
end
for sprite in @tiles
sprite.color=@color if sprite.is_a?(Sprite)
end
@oldcolor=@color.clone
end
if @autotiles.changed
refresh_autotiles
repaintAutotiles
end
if @flashChanged
refresh_flash
end
if @tilesetChanged
refresh_tileset
end
if @flash
@flash.opacity=FlashOpacity[(Graphics.frame_count/2) % 6]
end
if !(@oldOx==@ox && @oldOy==@oy &&
!@tilesetChanged &&
!@autotiles.changed)
refresh
end
if (Graphics.frame_count % Animated_Autotiles_Frames == 0) || @nowshown
repaintAutotiles
refresh(true)
end
@nowshown=false
@autotiles.changed=false
@tilesetChanged=false
end
def priorities=(value)
@priorities=value
@tilesetChanged=true
end
def tileset=(value)
@tileset=value
@tilesetChanged=true
end
def shown?
return false if !@visible
ysize=@map_data.ysize
xsize=@map_data.xsize
xStart=(@ox/32)-1
xEnd=((@ox+@viewport.rect.width)/32)+1
yStart=(@oy/32)-1
yEnd=((@oy+@viewport.rect.height)/32)+1
xStart=0 if xStart<0
xStart=xsize-1 if xStart>=xsize
xEnd=0 if xEnd<0
xEnd=xsize-1 if xEnd>=xsize
yStart=0 if yStart<0
yStart=ysize-1 if yStart>=ysize
yEnd=0 if yEnd<0
yEnd=ysize-1 if yEnd>=ysize
return (xStart<xEnd && yStart<yEnd)
end
def dispose
return if disposed?
@help.dispose if @help
@help=nil
i=0;len=@autotileInfo.length;while i<len
if @autotileInfo[i]
@autotileInfo[i].dispose
@autotileInfo[i]=nil
end
i+=1
end
i=0;len=@regularTileInfo.length;while i<len
if @regularTileInfo[i]
@regularTileInfo[i].dispose
@regularTileInfo[i]=nil
end
i+=1
end
i=0;len=@tiles.length;while i<len
@tiles[i].dispose
@tiles[i]=nil
i+=2
end
i=0;len=@autosprites.length;while i<len
@autosprites[i].dispose
@autosprites[i]=nil
i+=2
end
if @layer0
@layer0.bitmap.dispose if !@layer0.disposed?
@layer0.bitmap=nil if !@layer0.disposed?
@layer0.dispose
@layer0=nil
end
if @flash
@flash.bitmap.dispose if !@flash.disposed?
@flash.bitmap=nil if !@flash.disposed?
@flash.dispose
@flash=nil
end
for i in 0...7
self.autotiles[i]=nil
end
@tiles.clear
@autosprites.clear
@autotileInfo.clear
@regularTileInfo.clear
@tilemap=nil
@tileset=nil
@priorities=nil
@selfviewport.dispose
@selfviewport=nil
@disposed=true
end
def bltAutotile(bitmap,x,y,id,frame)
return if frame<0
autotile=@autotiles[id/48-1]
return if !autotile
if autotile.height==32
anim=frame<<5
src_rect=Rect.new(anim,0,32,32)
bitmap.blt(x,y,autotile,src_rect)
else
anim=frame*96
id%=48
tiles = Autotiles[id>>3][id&7]
src=Rect.new(0,0,0,0)
for i in 0...4
tile_position = tiles[i] - 1
src.set(
(tile_position % 6)*16 + anim,
(tile_position / 6)*16, 16, 16)
bitmap.blt(i%2*16+x,i/2*16+y, autotile, src)
end
end
end
def autotileNumFrames(id)
autotile=@autotiles[id/48-1]
return 0 if !autotile || autotile.disposed?
frames=1
if autotile.height==32
frames=autotile.width>>5
else
frames=autotile.width/96
end
return frames
end
def autotileFrame(id)
autotile=@autotiles[id/48-1]
return -1 if !autotile || autotile.disposed?
frames=1
if autotile.height==32
frames=autotile.width>>5
else
frames=autotile.width/96
end
return (Graphics.frame_count/Animated_Autotiles_Frames)%frames
end
def repaintAutotiles
for i in 0...@autotileInfo.length
next if !@autotileInfo[i]
frame=autotileFrame(i)
bltAutotile(@autotileInfo[i],0,0,i,frame)
end
end
def getAutotile(sprite,id)
anim=autotileFrame(id)
return if anim<0
bitmap=@autotileInfo[id]
if !bitmap
bitmap=Bitmap.new(32,32)
bltAutotile(bitmap,0,0,id,anim)
@autotileInfo[id]=bitmap
end
sprite.bitmap=bitmap if !sprite.equal?(bitmap) || sprite.bitmap!=bitmap
end
def getRegularTile(sprite,id)
if false
sprite.bitmap=@tileset if !sprite.equal?(@tileset) || sprite.bitmap!=@tileset
sprite.src_rect.set(((id - 384)&7)<<5,((id - 384)>>3)<<5,32,32)
else
bitmap=@regularTileInfo[id]
if !bitmap
bitmap=Bitmap.new(32,32)
rect=Rect.new(((id - 384)&7)<<5,((id - 384)>>3)<<5,32,32)
bitmap.blt(0,0,@tileset,rect)
@regularTileInfo[id]=bitmap
end
sprite.bitmap=bitmap if !sprite.equal?(bitmap) || sprite.bitmap!=bitmap
end
end
def addTile(tiles,count,xpos,ypos,id)
if id>=384
if count>=tiles.length
sprite=Sprite.new(@viewport)
tiles.push(sprite,0)
else
sprite=tiles[count]
tiles[count+1]=0
end
sprite.visible=@visible
sprite.x=xpos
sprite.y=ypos
sprite.tone=@tone
sprite.color=@color
getRegularTile(sprite,id)
spriteZ=(@priorities[id]==0||!@priorities[id]) ? 0 : ypos+@priorities[id]*32+32
sprite.z=spriteZ
count+=2
else
if count>=tiles.length
sprite=Sprite.new(@viewport)
tiles.push(sprite,1)
else
sprite=tiles[count]
tiles[count+1]=1
end
sprite.visible=@visible
sprite.x=xpos
sprite.y=ypos
sprite.tone=@tone
sprite.color=@color
getAutotile(sprite,id)
spriteZ=(@priorities[id]==0||!@priorities[id]) ? 0 : ypos+@priorities[id]*32+32
sprite.z=spriteZ
count+=2
end
return count
end
def refresh_tileset
i=0;len=@regularTileInfo.length;while i<len
if @regularTileInfo[i]
@regularTileInfo[i].dispose
@regularTileInfo[i]=nil
end
i+=1
end
@regularTileInfo.clear
@priotiles.clear
ysize=@map_data.ysize
xsize=@map_data.xsize
zsize=@map_data.zsize
if xsize>100 || ysize>100
@fullyrefreshed=false
else
for z in 0...zsize
for y in 0...ysize
for x in 0...xsize
id = @map_data[x, y, z]
next if id==0 || !@priorities[id]
next if @priorities[id]==0
@priotiles.push([x,y,z,id])
end
end
end
@fullyrefreshed=true
end
end
def refresh_flash
if @flash_data && !@flash
@flash=Sprite.new(viewport)
@flash.visible=true
@flash.z=1
@flash.blend_type=1
@flash.bitmap=Bitmap.new([graphicsWidth*2,1].max,[graphicsHeight*2,1].max)
@firsttimeflash=true
elsif !@flash_data && @flash
@flash.bitmap.dispose if @flash.bitmap
@flash.dispose
@flash=nil
@firsttimeflash=false
end
end
def refresh_autotiles
i=0;len=@autotileInfo.length;while i<len
if @autotileInfo[i]
@autotileInfo[i].dispose
@autotileInfo[i]=nil
end
i+=1
end
i=0;len=@autosprites.length;while i<len
if @autosprites[i]
@autosprites[i].dispose
@autosprites[i]=nil
end
i+=2
end
@autosprites.clear
@autotileInfo.clear
@prioautotiles.clear
hasanimated=false
for i in 0...7
numframes=autotileNumFrames(48*(i+1))
hasanimated=true if numframes>=2
@framecount[i]=numframes
end
if hasanimated
ysize=@map_data.ysize
xsize=@map_data.xsize
zsize=@map_data.zsize
if xsize>100 || ysize>100
@fullyrefreshedautos=false
else
for y in 0...ysize
for x in 0...xsize
haveautotile=false
for z in 0...zsize
id = @map_data[x, y, z]
next if id==0 || id>=384 || @priorities[id]!=0 || !@priorities[id]
next if @framecount[id/48-1]<2
haveautotile=true
break
end
@prioautotiles.push([x,y]) if haveautotile
end
end
@fullyrefreshedautos=true
end
else
@fullyrefreshedautos=true
end
end
def map_data=(value)
@map_data=value
@tilesetChanged=true
end
def refreshFlashSprite
return if !@flash || @flash_data.nil?
ptX=@ox-@oxFlash
ptY=@oy-@oyFlash
if !@firsttimeflash && !@usedsprites &&
ptX>=0 && ptX+@viewport.rect.width<=@flash.bitmap.width &&
ptY>=0 && ptY+@viewport.rect.height<=@flash.bitmap.height
@flash.ox=0
@flash.oy=0
@flash.src_rect.set(ptX.round,ptY.round,
@viewport.rect.width,@viewport.rect.height)
return
end
width=@flash.bitmap.width
height=@flash.bitmap.height
bitmap=@flash.bitmap
ysize=@map_data.ysize
xsize=@map_data.xsize
zsize=@map_data.zsize
@firsttimeflash=false
@oxFlash=@ox-(width>>2)
@oyFlash=@oy-(height>>2)
@flash.ox=0
@flash.oy=0
@flash.src_rect.set(width>>2,height>>2,
@viewport.rect.width,@viewport.rect.height)
@flash.bitmap.clear
@oxFlash=@oxFlash.floor
@oyFlash=@oyFlash.floor
xStart=(@oxFlash>>5)
xStart=0 if xStart<0
yStart=(@oyFlash>>5)
yStart=0 if yStart<0
xEnd=xStart+(width>>5)+1
yEnd=yStart+(height>>5)+1
xEnd=xsize if xEnd>=xsize
yEnd=ysize if yEnd>=ysize
if xStart<xEnd && yStart<yEnd
yrange=yStart...yEnd
xrange=xStart...xEnd
tmpcolor=Color.new(0,0,0,0)
for y in yrange
ypos=(y<<5)-@oyFlash
for x in xrange
xpos=(x<<5)-@oxFlash
id = @flash_data[x, y, 0]
r=(id>>8)&15
g=(id>>4)&15
b=(id)&15
tmpcolor.set(r<<4,g<<4,b<<4)
bitmap.fill_rect(xpos,ypos,32,32,tmpcolor)
end
end
end
end
def refreshLayer0(autotiles=false)
if autotiles
return true if !shown?
end
ptX=@ox-@oxLayer0
ptY=@oy-@oyLayer0
if !autotiles && !@firsttime && !@usedsprites &&
ptX>=0 && ptX+@viewport.rect.width<=@layer0.bitmap.width &&
ptY>=0 && ptY+@viewport.rect.height<=@layer0.bitmap.height
if @layer0clip
@layer0.ox=0
@layer0.oy=0
@layer0.src_rect.set(ptX.round,ptY.round,
@viewport.rect.width,@viewport.rect.height)
else
@layer0.ox=ptX.round
@layer0.oy=ptY.round
@layer0.src_rect.set(0,0,@layer0.bitmap.width,@layer0.bitmap.height)
end
return true
end
width=@layer0.bitmap.width
height=@layer0.bitmap.height
bitmap=@layer0.bitmap
ysize=@map_data.ysize
xsize=@map_data.xsize
zsize=@map_data.zsize
if autotiles
return true if @fullyrefreshedautos && @prioautotiles.length==0
xStart=(@oxLayer0>>5)
xStart=0 if xStart<0
yStart=(@oyLayer0>>5)
yStart=0 if yStart<0
xEnd=xStart+(width>>5)+1
yEnd=yStart+(height>>5)+1
xEnd=xsize if xEnd>xsize
yEnd=ysize if yEnd>ysize
return true if xStart>=xEnd || yStart>=yEnd
trans=Color.new(0,0,0,0)
temprect=Rect.new(0,0,0,0)
tilerect=Rect.new(0,0,32,32)
range=0...zsize
overallcount=0
count=0
if !@fullyrefreshedautos
for y in yStart..yEnd
for x in xStart..xEnd
haveautotile=false
for z in range
id = @map_data[x, y, z]
next if id<48 || id>=384 || @priorities[id]!=0 || !@priorities[id]
next if @framecount[id/48-1]<2
if !haveautotile
haveautotile=true
overallcount+=1
xpos=(x<<5)-@oxLayer0
ypos=(y<<5)-@oyLayer0
bitmap.fill_rect(xpos,ypos,0,0,trans) if overallcount<=2000
break
end
end
for z in range
id = @map_data[x,y,z]
next if id<48 || @priorities[id]!=0 || !@priorities[id]
if overallcount>2000
xpos=(x<<5)-@oxLayer0
ypos=(y<<5)-@oyLayer0
count=addTile(@autosprites,count,xpos,ypos,id)
next
elsif id>=384
temprect.set(((id - 384)&7)<<5,((id - 384)>>3)<<5,32,32)
xpos=(x<<5)-@oxLayer0
ypos=(y<<5)-@oyLayer0
bitmap.blt(xpos,ypos,@tileset,temprect)
else
tilebitmap=@autotileInfo[id]
if !tilebitmap
anim=autotileFrame(id)
next if anim<0
tilebitmap=Bitmap.new(32,32)
bltAutotile(tilebitmap,0,0,id,anim)
@autotileInfo[id]=tilebitmap
end
xpos=(x<<5)-@oxLayer0
ypos=(y<<5)-@oyLayer0
bitmap.blt(xpos,ypos,tilebitmap,tilerect)
end
end
end
end
else
for tile in @prioautotiles
x=tile[0]
y=tile[1]
next if x<xStart||x>xEnd
next if y<yStart||y>yEnd
overallcount+=1
xpos=(x<<5)-@oxLayer0
ypos=(y<<5)-@oyLayer0
bitmap.fill_rect(xpos,ypos,0,0,trans) if overallcount<=2000
for z in range
id = @map_data[x,y,z]
next if id<48 || @priorities[id]!=0 || !@priorities[id]
if overallcount>2000
count=addTile(@autosprites,count,xpos,ypos,id)
next
elsif id>=384
temprect.set(((id - 384)&7)<<5,((id - 384)>>3)<<5,32,32)
bitmap.blt(xpos,ypos,@tileset,temprect)
else
tilebitmap=@autotileInfo[id]
if !tilebitmap
anim=autotileFrame(id)
next if anim<0
tilebitmap=Bitmap.new(32,32)
bltAutotile(tilebitmap,0,0,id,anim)
@autotileInfo[id]=tilebitmap
end
bitmap.blt(xpos,ypos,tilebitmap,tilerect)
end
end
end
end
Graphics.frame_reset if overallcount>2000
@usedsprites=false
return true
end
return false if @usedsprites
@firsttime=false
@oxLayer0=@ox-(width>>2)
@oyLayer0=@oy-(height>>2)
if @layer0clip
@layer0.ox=0
@layer0.oy=0
@layer0.src_rect.set(width>>2,height>>2,
@viewport.rect.width,@viewport.rect.height)
else
@layer0.ox=(width>>2)
@layer0.oy=(height>>2)
end
@layer0.bitmap.clear
@oxLayer0=@oxLayer0.floor
@oyLayer0=@oyLayer0.floor
xStart=(@oxLayer0>>5)
xStart=0 if xStart<0
yStart=(@oyLayer0>>5)
yStart=0 if yStart<0
xEnd=xStart+(width>>5)+1
yEnd=yStart+(height>>5)+1
xEnd=xsize if xEnd>=xsize
yEnd=ysize if yEnd>=ysize
if xStart<xEnd && yStart<yEnd
tmprect=Rect.new(0,0,0,0)
yrange=yStart...yEnd
xrange=xStart...xEnd
for z in 0...zsize
for y in yrange
ypos=(y<<5)-@oyLayer0
for x in xrange
xpos=(x<<5)-@oxLayer0
id = @map_data[x, y, z]
next if id==0 || @priorities[id]!=0 || !@priorities[id]
if id>=384
tmprect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
bitmap.blt(xpos,ypos,@tileset,tmprect)
else
frame=autotileFrame(id)
bltAutotile(bitmap,xpos,ypos,id,frame)
end
end
end
end
Graphics.frame_reset
end
return true
end
def getResizeFactor
return $ResizeFactor ? $ResizeFactor : 1.0
end
def ox=(val)
val=(val*getResizeFactor).to_i
val=(val/getResizeFactor).to_i
wasshown=self.shown?
@ox=val.floor
@nowshown=(!wasshown && self.shown?)
end
def oy=(val)
val=(val*getResizeFactor).to_i
val=(val/getResizeFactor).to_i
wasshown=self.shown?
@oy=val.floor
@nowshown=(!wasshown && self.shown?)
end
def visible=(val)
wasshown=@visible
@visible=val
@nowshown=(!wasshown && val)
end
def refresh(autotiles=false)
@oldOx=@ox
@oldOy=@oy
usesprites=false
if @layer0
@layer0.visible=@visible
usesprites=!refreshLayer0(autotiles)
if autotiles && !usesprites
return
end
else
usesprites=true
end
refreshFlashSprite
vpx=@viewport.rect.x
vpy=@viewport.rect.y
vpr=@viewport.rect.width+vpx
vpb=@viewport.rect.height+vpy
xsize=@map_data.xsize
ysize=@map_data.ysize
minX=(@ox/32)-1
maxX=((@ox+@viewport.rect.width)/32)+1
minY=(@oy/32)-1
maxY=((@oy+@viewport.rect.height)/32)+1
minX=0 if minX<0
minX=xsize-1 if minX>=xsize
maxX=0 if maxX<0
maxX=xsize-1 if maxX>=xsize
minY=0 if minY<0
minY=ysize-1 if minY>=ysize
maxY=0 if maxY<0
maxY=ysize-1 if maxY>=ysize
count=0
if minX<maxX && minY<maxY
@usedsprites=usesprites || @usedsprites
if @layer0
@layer0.visible=false if usesprites
end
if @fullyrefreshed
for prio in @priotiles
x=prio[0]
y=prio[1]
next if x<minX||x>maxX
next if y<minY||y>maxY
id=prio[3]
xpos=(x<<5)-@ox
ypos=(y<<5)-@oy
count=addTile(@tiles,count,xpos,ypos,id)
end
else
for z in 0...@map_data.zsize
for y in minY..maxY
for x in minX..maxX
id = @map_data[x, y, z]
next if id==0 || !@priorities[id]
next if @priorities[id]==0
xpos=(x<<5)-@ox
ypos=(y<<5)-@oy
count=addTile(@tiles,count,xpos,ypos,id)
end
end
end
end
end
if count<@tiles.length
bigchange=(count<=(@tiles.length*2/3)) && (@tiles.length*2/3)>25
j=count;len=@tiles.length;while j<len
sprite=@tiles[j]
@tiles[j+1]=-1
if bigchange
sprite.dispose
@tiles[j]=nil
@tiles[j+1]=nil
elsif !@tiles[j].disposed?
sprite.visible=false if sprite.visible
end
j+=2
end
@tiles.compact! if bigchange
end
end
#==============================================================================
# ■ Tone
#------------------------------------------------------------------------------
# by vgvgf
#==============================================================================
class Tone
def initialize(r, g, b, a = 0)
@red = r
@green = g
@blue = b
@gray = a
end
def set(r, g, b, a = 0)
@red = r
@green = g
@blue = b
@gray = a
end
def color
Tone.new(@red, @green, @blue, @gray)
end
def _dump(d = 0)
[@red, @green, @blue, @gray].pack('d4')
end
def self._load(s)
Tone.new(*s.unpack('d4'))
end
def inspect
sprintf("(%f, %f, %f, %f)", @red, @green, @blue, @gray)
end
def to_s
self.inspect
end
attr_accessor(:red, :green, :blue, :gray)
end
Viewport
Window
Code:
#==============================================================================
# ■ Window - Hidden RGSS Class
#------------------------------------------------------------------------------
# by Selwyn
#==============================================================================
class Bitmap
#--------------------------------------------------------------------------
# ● erase
#--------------------------------------------------------------------------
def erase(*args)
if args.size == 1
rect = args[0]
elsif args.size == 4
rect = Rect.new(*args)
end
fill_rect(rect, Color.new(0, 0, 0, 0))
end
end
require 'rubygems'
require 'rubysdl'
#**Part of OpenRGSS
# The module that carries out music and sound processing.
module Audio
class <
# Prepares MIDI playback by DirectMusic.
#
# A method of the processing at startup in RGSS2 for enabling execution at any time.
#
# MIDI playback is possible without calling this method, but in Windows Vista or later, a delay of 1 to 2 seconds will result at playback.
def setup_mdi
end
# Starts BGM playback. Specifies the file name, volume, pitch, and playback starting position in that order.
#
# The playback starting position (RGSS3) is only valid for ogg or wav files.
#
# Also automatically searches files included in RGSS-RTP. File extensions may be omitted.
# Starts BGM fadeout. time is the length of the fadeout in milliseconds.
def bgm_fade(time)
SDL::Mixer.fade_out_music(time)
end
# Gets the playback position of the BGM. Only valid for ogg or wav files. Returns 0 when not valid.
def bgm_pos
end
# Starts BGS playback. Specifies the file name, volume, pitch, and playback starting position in that order.
#
# The playback starting position (RGSS3) is only valid for ogg or wav files.
#
# Also automatically searches files included in RGSS-RTP. File extensions may be omitted.
def bgs_stop
SDL::Mixer.halt(@bgs_channel) if @bgs_channel
end
# Starts BGS fadeout. time is the length of the fadeout in milliseconds.
def bgs_fade(time)
SDL::Mixer.fade_out(@bgs_channel, time) if @bgs_channel
end
# Gets the playback position of the BGS. Only valid for ogg or wav files. Returns 0 when not valid.
def bgs_pos
end
# Starts ME playback. Sets the file name, volume, and pitch in turn.
#
# Also automatically searches files included in RGSS-RTP. File extensions may be omitted.
#
# When ME is playing, the BGM will temporarily stop. The timing of when the BGM restarts is slightly different from RGSS1.
def me_stop
SDL::Mixer.halt(@me_channel) if @me_channel
end
# Starts ME fadeout. time is the length of the fadeout in milliseconds.
def me_fade(time)
SDL::Mixer.fade_out(@me_channel, time) if @me_channel
end
# Starts SE playback. Sets the file name, volume, and pitch in turn.
#
# Also automatically searches files included in RGSS-RTP. File extensions may be omitted.
#
# When attempting to play the same SE more than once in a very short period, they will automatically be filtered to prevent choppy playback
def se_stop
SDL::Mixer.halt(@se_channel) if @me_channel
end
end
end
Font implementation
Code:
#**Part of OpenRGSS
# The font class. Font is a property of the Bitmap class.
#
# If there is a "Fonts" folder directly under the game folder, the font files in it can be used even if they are not installed on the system.
#
# You can change the default values set for each component when a new Font object is created.
#
# Font.default_name = ["Myriad", "Verdana"]
# Font.default_size = 22
# Font.default_bold = true
def entity
result = @@cache[[@name, @size]] ||= SDL::TTF.open('wqy-microhei.ttc', @size)
result.style = (@bold ? SDL::TTF::STYLE_BOLD : 0) | (@italic ? SDL::TTF::STYLE_ITALIC : 0)
result
end
# The font name. Include an array of strings to specify multiple fonts to be used in a desired order.
#
# font.name = ["Myriad", "Verdana"]
# In this example, if the higher priority font Myriad does not exist on the system, the second choice Verdana will be used instead.
#
# The default is ["Verdana", "Arial", "Courier New"].
attr_accessor :name
# The font size. The default is 24.
attr_accessor :size
# The bold flag. The default is FALSE.
attr_accessor :bold
# The italic flag. The default is FALSE.
attr_accessor :italic
# The flag for outline text. The default is TRUE.
attr_accessor :outline
# The flag for shadow text. The default is false (RGSS3). When enabled, a black shadow will be drawn to the bottom right of the character.
attr_accessor :shadow
# The font color (Color). Alpha values may also be used. The default is (255,255,255,255).
#
# Alpha values are also used when drawing outline (RGSS3) and shadow text.
attr_accessor :color
# The outline color (Color). The default is (0,0,0,128).
attr_accessor :out_color
class < [:name, :size, :bold, :italic, :color, :outline, :shadow, :out_color].each { |attribute|
name = 'default_' + attribute.to_s
define_method(name) { class_variable_get('@@'+name) }
define_method(name+'=') { |value| class_variable_set('@@'+name, value) }
}
end
#------------------------------------------------------------------------
# * Standard Einstellungen aus der RGSS102E.dll.
#------------------------------------------------------------------------
@@default_name = "Arial"
@@default_size = 22
@@default_bold = false
@@default_italic= false
@@default_color = Color.new(255, 255, 255, 255)
end
Plane implementation
Code:
#**Part of OpenRGSS
# The Plane class. Planes are special sprites that tile bitmap patterns across the entire screen and are used to display parallax backgrounds and so on.
class Plane
# Refers to the bitmap (Bitmap) used in the plane.
#attr_accessor :bitmap
# Refers to the viewport (Viewport) associated with the plane.
#attr_accessor :viewport
# The plane's visibility. If TRUE, the plane is visible. The default value is TRUE.
#attr_accessor :visible
# The plane's z-coordinate. The larger the value, the closer to the player the plane will be displayed.
#
# If multiple objects share the same z-coordinate, the more recently created object will be displayed closest to the player.
#attr_accessor :z
# The x-coordinate of the plane's starting point. Change this value to scroll the plane.
attr_accessor :ox
# The y-coordinate of the plane's starting point. Change this value to scroll the plane.
attr_accessor :oy
# The plane's x-axis zoom level. 1.0 denotes actual pixel size.
#attr_accessor :zoom_x
# The plane's y-axis zoom level. 1.0 denotes actual pixel size.
#attr_accessor :zoom_y
# The plane's opacity (0-255). Out-of-range values are automatically corrected.
#attr_accessor :opacity
# The color (Color) to be blended with the plane. Alpha values are used in the blending ratio.
#attr_accessor :color
# The plane's color tone (Tone).
#attr_accessor :tone
# Creates a Plane object. Specifies a viewport (Viewport) when necessary.
def initialize(arg_viewport=nil)
@sprite = Sprite.new(arg_viewport)
@src_bitmap = nil
end
# Frees the plane. If the plane has already been freed, does nothing.
def dispose
@sprite.bitmap.dispose unless @sprite.bitmap.nil? or @sprite.bitmap.disposed?
@sprite.dispose unless @sprite.nil? or @sprite.disposed?
end
# Returns TRUE if the plane has been freed.
def disposed?
@sprite.nil? or @sprite.disposed?
end
def resize_screen(width, height)
@width = width
@height = height
end
def update
RGSS.update
@frame_count += 1
if @skip >= 10 or SDL.get_ticks < @ticks + 1000 / frame_rate
@entity.fill_rect(0, 0, @width, @height, 0x000000)
if (@old_resources!=RGSS.resources) # Maybe here can make a dirty mark
RGSS.resources.sort!
@old_resources=RGSS.resources.clone
end
def snap_to_bitmap
return @graphics_render_target.clone # free
end
def frame_reset
end
def play_movie(filename)
end
def brightness=(brightness)
@brightness = brightness < 0 ? 0 : brightness > 255 ? 255 : brightness
#gamma = @brightness.to_f / 255
#SDL::Screen.set_gamma(5,1,1)
#seems SDL::Screen.set_gamma and SDL::Screen.set_gamma_rmap doesn't work
end
end
end
SDL Sprite implementation
Code:
#**Part of OpenRGSS
require 'rubygems'
require 'rubysdl'
# The sprite class. Sprites are the basic concept used to display characters and other objects on the game screen.
class Sprite
# Refers to the bitmap (Bitmap) used for the sprite's starting point.
attr_accessor :bitmap
# The box (Rect) taken from a bitmap.
attr_accessor :src_rect
# Refers to the viewport (Viewport) associated with the sprite.
attr_accessor :viewport
# The x-coordinate of the sprite's starting point.
attr_accessor :ox
# The y-coordinate of the sprite's starting point.
attr_accessor :oy
# The sprite's x-axis zoom level. 1.0 denotes actual pixel size.
attr_accessor :zoom_x
# The sprite's y-axis zoom level. 1.0 denotes actual pixel size.
attr_accessor :zoom_y
# The sprite's angle of rotation. Specifies up to 360 degrees of counterclockwise rotation. However, drawing a rotated sprite is time-consuming, so avoid overuse.
attr_accessor :angle
# Defines the amplitude, frequency, speed, and phase of the wave effect. A raster scroll effect is achieved by using a sinusoidal function to draw the sprite with each line's horizontal position slightly different from the last.
#
# wave_amp is the wave amplitude and wave_length is the wave frequency, and each is specified by a number of pixels.
#
# wave_speed specifies the speed of the wave animation. The default is 360, and the larger the value, the faster the effect.
#
# wave_phase specifies the phase of the top line of the sprite using an angle of up to 360 degrees. This is updated each time the update method is called. It is not necessary to use this property unless it is required for two sprites to have their wave effects synchronized.
attr_accessor :wave_amp
attr_accessor :wave_length
attr_accessor :wave_speed
attr_accessor :wave_phase
# A flag denoting the sprite has been flipped horizontally. If TRUE, the sprite will be drawn flipped. The default is false.
attr_accessor :mirror
# The bush depth and opacity of a sprite. This can be used to represent a situation such as the character's legs being hidden by bushes.
#
# For bush_depth, the number of pixels for the bush section is specified. The default value is 0.
#
# For bush_opacity, the opacity of the bush section from 0 to 255 is specified. Out-of-range values will be corrected automatically. The default value is 128.
#
# The bush_opacity value will be multiplied by opacity. For example, if both opacity and bush_opacity are set to 128, it will be handled as a transparency on # top of a transparency, for an actual opacity of 64.
attr_accessor :bush_depth
attr_accessor :bush_opacity
# The sprite's opacity (0-255). Out-of-range values are automatically corrected.
attr_accessor :opacity
# The color (Color) to be blended with the sprite. Alpha values are used in the blending ratio.
#
# Handled separately from the color blended into a flash effect. However, the color with the higher alpha value when displayed will have the higher priority when blended.
attr_accessor :color
# The sprite's color tone (Tone).
attr_accessor :tone
include RGSS::Drawable
# Creates a new sprite object. Specifies a viewport (Viewport) when necessary.
def bitmap=(bitmap)
@src_rect.set(0, 0, bitmap.width, bitmap.height) if bitmap
@bitmap = bitmap
end
# Begins flashing the sprite. duration specifies the number of frames flashing will last.
#
# If color is set to nil, the sprite will disappear while flashing.
def flash(color, duration)
end
# Advances the sprite flash or wave phase. As a general rule, this method is called once per frame.
#
# It is not necessary to call this if a flash or wave is not needed.
def update
end
# Gets the width of the sprite. Equivalent to src_rect.width.
def width
bitmap.width
end
# Gets the height of the sprite. Equivalent to src_rect.height.
def height
bitmap.height
end
def draw(destination=Graphics)
return unless bitmap and opacity > 0
SDL::Surface.blit(@bitmap.entity, @src_rect.x, @src_rect.y, @src_rect.width, @src_rect.height, destination.entity, base_x, base_y)
destination.entity.set_clip_rect(0, 0, destination.width, destination.height) if viewport
end
end
SDL Bitmap implementation
Code:
require 'rubygems'
require 'rubysdl'
#**Part of OpenRGSS
# The bitmap class. Bitmaps represent images.
#
# Sprites (Sprite) and other objects must be used to display bitmaps onscreen.
class Bitmap
attr_accessor :font, :entity, :text
# :call-seq:
# Bitmap.new(filename)
# Bitmap.new(width, height)
#
# Loads the graphic file specified in filename or size and creates a bitmap object.
#
# Also automatically searches files included in RGSS-RTP and encrypted archives. File extensions may be omitted.
# Frees the bitmap. If the bitmap has already been freed, does nothing.
def dispose
@entity.destroy
end
# Returns true if the bitmap has been freed.
def disposed?
@entity.destroyed?
end
# Gets the bitmap width.
def width
@entity.w
end
# Gets the bitmap height.
def height
@entity.h
end
# Gets the bitmap rectangle (Rect).
def rect
Rect.new(0, 0, width, height)
end
def clone
b =Bitmap.new(width, height)
b.entity = @entity.copyRect(0, 0, width, height)
b.font =Font.clone
return b
end
# Performs a block transfer from the src_bitmap box src_rect (Rect) to the specified bitmap coordinates (x, y).
#
# opacity can be set from 0 to 255.
def blt(x, y, src_bitmap, src_rect, opacity=255)
src_bitmap.entity.set_alpha(SDL::RLEACCEL, opacity)
SDL::Surface.blit(src_bitmap.entity, src_rect.x, src_rect.y, src_rect.width, src_rect.height, @entity, x, y)
src_bitmap.entity.set_alpha(SDL::SRCALPHA|SDL::RLEACCEL, 255)
end
# Performs a block transfer from the src_bitmap box src_rect (Rect) to the specified bitmap box dest_rect (Rect).
#
# opacity can be set from 0 to 255.
# :call-seq:
# fill_rect(x, y, width, height, color)
# fill_rect(rect, color)
#
# Fills the bitmap box (x, y, width, height) or rect (Rect) with color (Color).
def fill_rect(x, y, width=nil, height=nil, color=nil)
if x.is_a? Rect
rect = x
color = y
x = rect.x
y = rect.y
width = rect.width
height = rect.height
end
@entity.fill_rect(x, y, width, height, @entity.map_rgba(color.red, color.green, color.blue, color.alpha))
end
# :call-seq:
# gradient_fill_rect(x, y, width, height, color1, color2[, vertical])
# gradient_fill_rect(rect, color1, color2[, vertical])
#
# Fills in this bitmap box (x, y, width, height) or rect (Rect) with a gradient from color1 (Color) to color2 (Color).
#
# Set vertical to true to create a vertical gradient. Horizontal gradient is the default.
def gradient_fill_rect(x, y, width, height=false, color1=nil, color2=nil, vertical=false)
if x.is_a? Rect
rect = x
color1 = y
color2 = width
vertical = height
x = rect.x
y = rect.y
width = rect.width
height = rect.height
end
if vertical
height.times do |i|
@entity.fill_rect(x, y+i, width, 1, @entity.map_rgba(
color1.red + (color2.red - color1.red) * i / height,
color1.green + (color2.green - color1.green) * i / height,
color1.blue + (color2.blue - color1.blue) * i / height,
color1.alpha + (color2.alpha - color1.alpha) * i / height
))
end
else
width.times do |i|
@entity.fill_rect(x+i, y, 1, height, @entity.map_rgba(
color1.red + (color2.red - color1.red) * i / width,
color1.green + (color2.green - color1.green) * i / width,
color1.blue + (color2.blue - color1.blue) * i / width,
color1.alpha + (color2.alpha - color1.alpha) * i / width
))
end
end
end
# Clears the entire bitmap.
def clear
@entity.fill_rect(0, 0, width, height, 0x00000000)
end
# Clears this bitmap box or (x, y, width, height) or rect (Rect).
def clear_rect(x, y=nil, width=nil, height=nil)
if x.is_a? Rect
rect = x
x = rect.x
y = rect.y
width = rect.width
height = rect.height
end
@entity.fill_rect(x, y, width, height, 0x00000000)
end
# Gets the color (Color) at the specified pixel (x, y).
# Sets the specified pixel (x, y) to color (Color).
def set_pixel(x, y, color)
@entity.put_pixel(x, y, @entity.map_rgba(color.red, color.green, color.blue, color.alpha))
end
# Changes the bitmap's hue within 360 degrees of displacement.
#
# This process is time-consuming. Furthermore, due to conversion errors, repeated hue changes may result in color loss.
def hue_change(hue)
end
# Applies a blur effect to the bitmap. This process is time consuming.
def blur
end
# Applies a radial blur to the bitmap. angle is used to specify an angle from 0 to 360. The larger the number, the greater the roundness.
#
# division is the division number (from 2 to 100). The larger the number, the smoother it will be. This process is very time consuming.
def radial_blur(angle, division)
end
# Draws the string str in the bitmap box (x, y, width, height) or rect (Rect).
#
# If str is not a character string object, it will be converted to a character string using the to_s method before processing is performed.
#
# If the text length exceeds the box's width, the text width will automatically be reduced by up to 60 percent.
#
# Horizontal text is left-aligned by default. Set align to 1 to center the text and to 2 to right-align it. Vertical text is always centered.
#
# As this process is time-consuming, redrawing the text with every frame is not recommended.
def draw_text(x, y, width=0, height=nil, str=nil, align=0 )
if x.is_a? Rect
rect = x
str = y
align = width
x = rect.x
y = rect.y
width = rect.width
height = rect.height
end
str = str.to_s
if align == 2
x += width - @font.entity.text_size(str)[0]
elsif align == 1
x += (width - @font.entity.text_size(str)[0]) / 2
end
# @text << [str, x, y, @font.color.red, @font.color.green, @font.color.blue] See you ~
tmp = @font.entity.render_blended_utf8(str, @font.color.red, @font.color.green, @font.color.blue)
tmp.set_alpha(SDL::RLEACCEL ,0)
@entity.put tmp,x,y
#SDL::Surface.transformBlit tmp,@entity,0,1,1,0,0,x, y,SDL::Surface::TRANSFORM_AA|SDL::Surface::TRANSFORM_SAFE|SDL::Surface::TRANSFORM_SAFE
end
# Gets the box (Rect) used when drawing the string str with the draw_text method. Does not include the outline portion (RGSS3) and the angled portions of italicized text.
#
# If str is not a character string object, it will be converted to a character string using the to_s method before processing is performed.
def text_size(str)
Rect.new 0, 0, *@font.entity.text_size(str)
end
end
Rect implementation
Code:
class Rect
# The x-coordinate of the rectangle's upper left corner.
attr_accessor :x
# The y-coordinate of the rectangle's upper left corner.
attr_accessor :y
# The rectangle's width.
attr_accessor :width
# The rectangle's height.
attr_accessor :height
# :call-seq:
# Rect.new(x, y, width, height)
# Rect.new
#
# Creates a new Rect object.
#
# The default values when no arguments are specified are (0, 0, 0, 0).
def initialize(x=0, y=0, width=0, height=0)
set(x, y, width, height)
end
# :call-seq:
# set(x, y, width, height)
# set(rect)
#
# Sets all parameters at once.
#
# The second format copies all the components from a separate Rect object.
def set(x, y=0, width=0, height=0)
if x.is_a? Rect
rect = x
@x = rect.x
@y = rect.y
@width = rect.width
@height = rect.height
else
@x = x
@y = y
@width = width
@height = height
end
end
def to_s
"(#{x}, #{y}, #{width}, #{height})"
end
# Sets all components to 0.
def empty
set(0, 0, 0, 0)
end
# Vergleichsmethode
def == other
if other.kind_of?(Rect) then
x == other.x && y == other.y && width == other.width && height == other.height
else
raise TypeError.new("Can't convert #{other.class} to Rect")
end
end
# Serialisiert das Objekt
def _dump limit
[x, y, width, height].pack("iiii")
end
# Deserialisiert das Objekt
def self._load str
new(*str.unpack("iiii"))
end
end
Viewport implementation
Code:
#**Part of OpenRGSS
class Viewport
#The box (Rect) defining the viewport.
attr_accessor :rect
# The viewport's visibility. If TRUE, the viewport is visible. The default is TRUE.
attr_accessor :visible
# The viewport's z-coordinate. The larger the value, the closer to the player the plane will be displayed.
#
# If multiple objects share the same z-coordinate, the more recently created object will be displayed closest to the player.
attr_accessor :z
# The x-coordinate of the viewport's starting point. Change this value to shake the screen, etc.
attr_accessor :ox
# The y-coordinate of the viewport's starting point. Change this value to shake the screen, etc.
attr_accessor :oy
# The color (Color) to be blended with the viewport. Alpha values are used in the blending ratio.
#
# Handled separately from the color blended into a flash effect.
attr_accessor :color
# The viewport's color tone (Tone).
attr_accessor :tone
attr_accessor :created_at
# :call-seq:
# Viewport.new(x, y, width, height)
# Viewport.new(rect)
# Viewport.new (RGSS3)
#
# Creates a viewport object.
#
# Same size as the screen if no argument is specified.
# Frees the viewport. If the viewport has already been freed, does nothing.
#
# This operation will not result in a separate associated object being automatically freed.
def dispose
@disposed = true
end
# Returns TRUE if the viewport has been freed.
def disposed?
@disposed
end
# Begins flashing the viewport. duration specifies the number of frames the flash will last.
#
# If color is set to nil, the viewport will disappear while flashing.
def flash(color, duration)
end
# Refreshes the viewport flash. As a rule, this method is called once per frame.
#
# It is not necessary to call this method if no flash effect is needed.
def update
end
def z=(z)
@z = z
RGSS.resources.select { |resource| resource.viewport == self }.each { |resource| resource.visible = resource.visible }
end
end
RGSS Error implementation
Code:
class RGSSError < StandardError
end
class RGSSReset < Exception
end
RE: Hidden Class rewrites - DerVVulfman - 04-10-2013
Hey, Narzew. I had to edit your last post. You posted so much that the post -broke- and would not show. In essense, I ripped the Default RPG:: code you supplied from your post. As you ran beyond the character limit (which I dunno what it is), it is incomplete. This is what remained:
Full default RPG Class
Code:
module RPG
class Actor
def initialize
@id = 0
@name = ""
@class_id = 1
@initial_level = 1
@final_level = 99
@exp_basis = 30
@exp_inflation = 30
@character_name = ""
@character_hue = 0
@battler_name = ""
@battler_hue = 0
@parameters = Table.new(6,100)
for i in 1..99
@parameters[0,i] = 500+i*50
@parameters[1,i] = 500+i*50
@parameters[2,i] = 50+i*5
@parameters[3,i] = 50+i*5
@parameters[4,i] = 50+i*5
@parameters[5,i] = 50+i*5
end
@weapon_id = 0
@armor1_id = 0
@armor2_id = 0
@armor3_id = 0
@armor4_id = 0
@weapon_fix = false
@armor1_fix = false
@armor2_fix = false
@armor3_fix = false
@armor4_fix = false
end
attr_accessor :id
attr_accessor :name
attr_accessor :class_id
attr_accessor :initial_level
attr_accessor :final_level
attr_accessor :exp_basis
attr_accessor :exp_inflation
attr_accessor :character_name
attr_accessor :character_hue
attr_accessor :battler_name
attr_accessor :battler_hue
attr_accessor :parameters
attr_accessor :weapon_id
attr_accessor :armor1_id
attr_accessor :armor2_id
attr_accessor :armor3_id
attr_accessor :armor4_id
attr_accessor :weapon_fix
attr_accessor :armor1_fix
attr_accessor :armor2_fix
attr_accessor :armor3_fix
attr_accessor :armor4_fix
end
end
module RPG
class Animation
def initialize
@id = 0
@name = ""
@animation_name = ""
@animation_hue = 0
@position = 1
@frame_max = 1
@frames = [RPG::Animation::Frame.new]
@timings = []
end
attr_accessor :id
attr_accessor :name
attr_accessor :animation_name
attr_accessor :animation_hue
attr_accessor :position
attr_accessor :frame_max
attr_accessor :frames
attr_accessor :timings
end
end
module RPG
class Animation
class Frame
def initialize
@cell_max = 0
@cell_data = Table.new(0, 0)
end
attr_accessor :cell_max
attr_accessor :cell_data
end
end
end
module RPG
class Animation
class Timing
def initialize
@frame = 0
@se = RPG::AudioFile.new("", 80)
@flash_scope = 0
@flash_color = Color.new(255,255,255,255)
@flash_duration = 5
@condition = 0
end
attr_accessor :frame
attr_accessor :se
attr_accessor :flash_scope
attr_accessor :flash_color
attr_accessor :flash_duration
attr_accessor :condition
end
end
end
module RPG
class Armor
def initialize
@id = 0
@name = ""
@icon_name = ""
@description = ""
@kind = 0
@auto_state_id = 0
@price = 0
@pdef = 0
@mdef = 0
@eva = 0
@str_plus = 0
@dex_plus = 0
@agi_plus = 0
@int_plus = 0
@guard_element_set = []
@guard_state_set = []
end
attr_accessor :id
attr_accessor :name
attr_accessor :icon_name
attr_accessor :description
attr_accessor :kind
attr_accessor :auto_state_id
attr_accessor :price
attr_accessor :pdef
attr_accessor :mdef
attr_accessor :eva
attr_accessor :str_plus
attr_accessor :dex_plus
attr_accessor :agi_plus
attr_accessor :int_plus
attr_accessor :guard_element_set
attr_accessor :guard_state_set
end
end
module RPG
class AudioFile
def initialize(name = "", volume = 100, pitch = 100)
@name = name
@volume = volume
@pitch = pitch
end
attr_accessor :name
attr_accessor :volume
attr_accessor :pitch
end
end
module RPG
class Class
def initialize
@id = 0
@name = ""
@position = 0
@weapon_set = []
@armor_set = []
@element_ranks = Table.new(1)
@state_ranks = Table.new(1)
@learnings = []
end
attr_accessor :id
attr_accessor :name
attr_accessor :position
attr_accessor :weapon_set
attr_accessor :armor_set
attr_accessor :element_ranks
attr_accessor :state_ranks
attr_accessor :learnings
end
end
module RPG
class Class
class Learning
def initialize
@level = 1
@skill_id = 1
end
attr_accessor :level
attr_accessor :skill_id
end
end
end
module RPG
class CommonEvent
def initialize
@id = 0
@name = ""
@trigger = 0
@switch_id = 1
@list = [RPG::EventCommand.new]
end
attr_accessor :id
attr_accessor :name
attr_accessor :trigger
attr_accessor :switch_id
attr_accessor :list
end
end
module RPG
class Enemy
def initialize
@id = 0
@name = ""
@battler_name = ""
@battler_hue = 0
@maxhp = 500
@maxsp = 500
@str = 50
@dex = 50
@agi = 50
@int = 50
@atk = 100
@pdef = 100
@mdef = 100
@eva = 0
@animation1_id = 0
@animation2_id = 0
@element_ranks = Table.new(1)
@state_ranks = Table.new(1)
@actions = [RPG::Enemy::Action.new]
@exp = 0
@gold = 0
@item_id = 0
@weapon_id = 0
@armor_id = 0
@treasure_prob = 100
end
attr_accessor :id
attr_accessor :name
attr_accessor :battler_name
attr_accessor :battler_hue
attr_accessor :maxhp
attr_accessor :maxsp
attr_accessor :str
attr_accessor :dex
attr_accessor :agi
attr_accessor :int
attr_accessor :atk
attr_accessor :pdef
attr_accessor :mdef
attr_accessor :eva
attr_accessor :animation1_id
attr_accessor :animation2_id
attr_accessor :element_ranks
attr_accessor :state_ranks
attr_accessor :actions
attr_accessor :exp
attr_accessor :gold
attr_accessor :item_id
attr_accessor :weapon_id
attr_accessor :armor_id
attr_accessor :treasure_prob
end
end
module RPG
class Enemy
class Action
def initialize
@kind = 0
@basic = 0
@skill_id = 1
@condition_turn_a = 0
@condition_turn_b = 1
@condition_hp = 100
@condition_level = 1
@condition_switch_id = 0
@rating = 5
end
attr_accessor :kind
attr_accessor :basic
attr_accessor :skill_id
attr_accessor :condition_turn_a
attr_accessor :condition_turn_b
attr_accessor :condition_hp
attr_accessor :condition_level
attr_accessor :condition_switch_id
attr_accessor :rating
end
end
end
module RPG
class Event
class Page
def initialize
@condition = RPG::Event::Page::Condition.new
@graphic = RPG::Event::Page::Graphic.new
@move_type = 0
@move_speed = 3
@move_frequency = 3
@move_route = RPG::MoveRoute.new
@walk_anime = true
@step_anime = false
@direction_fix = false
@through = false
@always_on_top = false
@trigger = 0
@list = [RPG::EventCommand.new]
end
attr_accessor :condition
attr_accessor :graphic
attr_accessor :move_type
attr_accessor :move_speed
attr_accessor :move_frequency
attr_accessor :move_route
attr_accessor :walk_anime
attr_accessor :step_anime
attr_accessor :direction_fix
attr_accessor :through
attr_accessor :always_on_top
attr_accessor :trigger
attr_accessor :list
end
end
end
module RPG
class Event
def initialize(x, y)
@id = 0
@name = ""
@x = x
@y = y
@pages = [RPG::Event::Page.new]
end
attr_accessor :id
attr_accessor :name
attr_accessor :x
attr_accessor :y
attr_accessor :pages
end
end
module RPG
class Event
class Page
class Condition
def initialize
@switch1_valid = false
@switch2_valid = false
@variable_valid = false
@self_switch_valid = false
@switch1_id = 1
@switch2_id = 1
@variable_id = 1
@variable_value = 0
@self_switch_ch = "A"
end
attr_accessor :switch1_valid
attr_accessor :switch2_valid
attr_accessor :variable_valid
attr_accessor :self_switch_valid
attr_accessor :switch1_id
attr_accessor :switch2_id
attr_accessor :variable_id
attr_accessor :variable_value
attr_accessor :self_switch_ch
end
end
end
end
module RPG
class Event
class Page
class Graphic
def initialize
@tile_id = 0
@character_name = ""
@character_hue = 0
@direction = 2
@pattern = 0
@opacity = 255
@blend_type = 0
end
attr_accessor :tile_id
attr_accessor :character_name
attr_accessor :character_hue
attr_accessor :direction
attr_accessor :pattern
attr_accessor :opacity
attr_accessor :blend_type
end
end
end
end
module RPG
class EventCommand
def initialize(code = 0, indent = 0, parameters = [])
@code = code
@indent = indent
@parameters = parameters
end
attr_accessor :code
attr_accessor :indent
attr_accessor :parameters
end
end
module RPG
class Item
def initialize
@id = 0
@name = ""
@icon_name = ""
@description = ""
@scope = 0
@occasion = 0
@animation1_id = 0
@animation2_id = 0
@menu_se = RPG::AudioFile.new("", 80)
@common_event_id = 0
@price = 0
@consumable = true
@parameter_type = 0
@parameter_points = 0
@recover_hp_rate = 0
@recover_hp = 0
@recover_sp_rate = 0
@recover_sp = 0
@hit = 100
@pdef_f = 0
@mdef_f = 0
@variance = 0
@element_set = []
@plus_state_set = []
@minus_state_set = []
end
attr_accessor :id
attr_accessor :name
attr_accessor :icon_name
attr_accessor :description
attr_accessor :scope
attr_accessor :occasion
attr_accessor :animation1_id
attr_accessor :animation2_id
attr_accessor :menu_se
attr_accessor :common_event_id
attr_accessor :price
attr_accessor :consumable
attr_accessor :parameter_type
attr_accessor :parameter_points
attr_accessor :recover_hp_rate
attr_accessor :recover_hp
attr_accessor :recover_sp_rate
attr_accessor :recover_sp
attr_accessor :hit
attr_accessor :pdef_f
attr_accessor :mdef_f
attr_accessor :variance
attr_accessor :element_set
attr_accessor :plus_state_set
attr_accessor :minus_state_set
end
end
module RPG
class Map
def initialize(width, height)
@tileset_id = 1
@width = width
@height = height
@autoplay_bgm = false
@bgm = RPG::AudioFile.new
@autoplay_bgs = false
@bgs = RPG::AudioFile.new("", 80)
@encounter_list = []
@encounter_step = 30
@data = Table.new(width, height, 3)
@events = {}
end
attr_accessor :tileset_id
attr_accessor :width
attr_accessor :height
attr_accessor :autoplay_bgm
attr_accessor :bgm
attr_accessor :autoplay_bgs
attr_accessor :bgs
attr_accessor :encounter_list
attr_accessor :encounter_step
attr_accessor :data
attr_accessor :events
end
end
module RPG
class MapInfo
def initialize
@name = ""
@parent_id = 0
@order = 0
@expanded = false
@scroll_x = 0
@scroll_y = 0
end
attr_accessor :name
attr_accessor :parent_id
attr_accessor :order
attr_accessor :expanded
attr_accessor :scroll_x
attr_accessor :scroll_y
end
end
module RPG
class MoveCommand
def initialize(code = 0, parameters = [])
@code = code
@parameters = parameters
end
attr_accessor :code
attr_accessor :parameters
end
end
module RPG
class MoveRoute
def initialize
@repeat = true
@skippable = false
@list = [RPG::MoveCommand.new]
end
attr_accessor :repeat
attr_accessor :skippable
attr_accessor :list
end
end
module RPG
class Skill
def initialize
@id = 0
@name = ""
@icon_name = ""
@description = ""
@scope = 0
@occasion = 1
@animation1_id = 0
@animation2_id = 0
@menu_se = RPG::AudioFile.new("", 80)
@common_event_id = 0
@sp_cost = 0
@power = 0
@atk_f = 0
@eva_f = 0
@str_f = 0
@dex_f = 0
@agi_f = 0
@int_f = 100
@hit = 100
@pdef_f = 0
@mdef_f = 100
@variance = 15
@element_set = []
@plus_state_set = []
@minus_state_set = []
end
attr_accessor :id
attr_accessor :name
attr_accessor :icon_name
attr_accessor :description
attr_accessor :scope
attr_accessor :occasion
attr_accessor :animation1_id
attr_accessor :animation2_id
attr_accessor :menu_se
attr_accessor :common_event_id
attr_accessor :sp_cost
attr_accessor :power
attr_accessor :atk_f
attr_accessor :eva_f
attr_accessor :str_f
attr_accessor :dex_f
attr_accessor :agi_f
attr_accessor :int_f
attr_accessor :hit
attr_accessor :pdef_f
attr_accessor :mdef_f
attr_accessor :variance
attr_accessor :element_set
attr_accessor :plus_state_set
attr_accessor :minus_state_set
end
end
module RPG
class Sprite < ::Sprite
@@_animations = []
@@_reference_count = {}
def initialize(viewport = nil)
super(viewport)
@_whiten_duration = 0
@_appear_duration = 0
@_escape_duration = 0
@_collapse_duration = 0
@_damage_duration = 0
@_animation_duration = 0
@_blink = false
end
def dispose
dispose_damage
dispose_animation
dispose_loop_animation
super
end
def whiten
self.blend_type = 0
self.color.set(255, 255, 255, 128)
self.opacity = 255
@_whiten_duration = 16
@_appear_duration = 0
@_escape_duration = 0
@_collapse_duration = 0
end
def appear
self.blend_type = 0
self.color.set(0, 0, 0, 0)
self.opacity = 0
@_appear_duration = 16
@_whiten_duration = 0
@_escape_duration = 0
@_collapse_duration = 0
end
def escape
self.blend_type = 0
self.color.set(0, 0, 0, 0)
self.opacity = 255
@_escape_duration = 32
@_whiten_duration = 0
@_appear_duration = 0
@_collapse_duration = 0
end
def collapse
self.blend_type = 1
self.color.set(255, 64, 64, 255)
self.opacity = 255
@_collapse_duration = 48
@_whiten_duration = 0
@_appear_duration = 0
@_escape_duration = 0
end
def damage(value, critical)
dispose_damage
if value.is_a?(Numeric)
damage_string = value.abs.to_s
else
damage_string = value.to_s
end
bitmap = Bitmap.new(160, 48)
bitmap.font.name = "Arial Black"
bitmap.font.size = 32
bitmap.font.color.set(0, 0, 0)
bitmap.draw_text(-1, 12-1, 160, 36, damage_string, 1)
bitmap.draw_text(+1, 12-1, 160, 36, damage_string, 1)
bitmap.draw_text(-1, 12+1, 160, 36, damage_string, 1)
bitmap.draw_text(+1, 12+1, 160, 36, damage_string, 1)
if value.is_a?(Numeric) and value < 0
bitmap.font.color.set(176, 255, 144)
else
bitmap.font.color.set(255, 255, 255)
end
bitmap.draw_text(0, 12, 160, 36, damage_string, 1)
if critical
bitmap.font.size = 20
bitmap.font.color.set(0, 0, 0)
bitmap.draw_text(-1, -1, 160, 20, "CRITICAL", 1)
bitmap.draw_text(+1, -1, 160, 20, "CRITICAL", 1)
bitmap.draw_text(-1, +1, 160, 20, "CRITICAL", 1)
bitmap.draw_text(+1, +1, 160, 20, "CRITICAL", 1)
bitmap.font.color.set(255, 255, 255)
bitmap.draw_text(0, 0, 160, 20, "CRITICAL", 1)
end
@_damage_sprite = ::Sprite.new(self.viewport)
@_damage_sprite.bitmap = bitmap
@_damage_sprite.ox = 80
@_damage_sprite.oy = 20
@_damage_sprite.x = self.x
@_damage_sprite.y = self.y - self.oy / 2
@_damage_sprite.z = 3000
@_damage_duration = 40
end
def animation(animation, hit)
dispose_animation
@_animation = animation
return if @_animation == nil
@_animation_hit = hit
@_animation_duration = @_animation.frame_max
animation_name = @_animation.animation_name
animation_hue = @_animation.animation_hue
bitmap = RPG::Cache.animation(animation_name, animation_hue)
if @@_reference_count.include?(bitmap)
@@_reference_count[bitmap] += 1
else
@@_reference_count[bitmap] = 1
end
@_animation_sprites = []
if @_animation.position != 3 or not @@_animations.include?(animation)
for i in 0..15
sprite = ::Sprite.new(self.viewport)
sprite.bitmap = bitmap
sprite.visible = false
@_animation_sprites.push(sprite)
end
unless @@_animations.include?(animation)
@@_animations.push(animation)
end
end
update_animation
end
def loop_animation(animation)
return if animation == @_loop_animation
dispose_loop_animation
@_loop_animation = animation
return if @_loop_animation == nil
@_loop_animation_index = 0
animation_name = @_loop_animation.animation_name
animation_hue = @_loop_animation.animation_hue
bitmap = RPG::Cache.animation(animation_name, animation_hue)
if @@_reference_count.include?(bitmap)
@@_reference_count[bitmap] += 1
else
@@_reference_count[bitmap] = 1
end
@_loop_animation_sprites = []
for i in 0..15
sprite = ::Sprite.new(self.viewport)
sprite.bitmap = bitmap
sprite.visible = false
@_loop_animation_sprites.push(sprite)
end
update_loop_animation
end
def dispose_damage
if @_damage_sprite != nil
@_damage_sprite.bitmap.dispose
@_damage_sprite.dispose
@_damage_sprite = nil
@_damage_duration = 0
end
end
def dispose_animation
if @_animation_sprites != nil
sprite = @_animation_sprites[0]
if sprite != nil
@@_reference_count[sprite.bitmap] -= 1
if @@_reference_count[sprite.bitmap] == 0
sprite.bitmap.dispose
end
end
for sprite in @_animation_sprites
sprite.dispose
end
@_animation_sprites = nil
@_animation = nil
end
end
def dispose_loop_animation
if @_loop_animation_sprites != nil
sprite = @_loop_animation_sprites[0]
if sprite != nil
@@_reference_count[sprite.bitmap] -= 1
if @@_reference_count[sprite.bitmap] == 0
sprite.bitmap.dispose
end
end
for sprite in @_loop_animation_sprites
sprite.dispose
end
@_loop_animation_sprites = nil
@_loop_animation = nil
end
end
def blink_on
unless @_blink
@_blink = true
@_blink_count = 0
end
end
def blink_off
if @_blink
@_blink = false
self.color.set(0, 0, 0, 0)
end
end
def blink?
@_blink
end
def effect?
@_whiten_duration > 0 or
@_appear_duration > 0 or
@_escape_duration > 0 or
@_collapse_duration > 0 or
@_damage_duration > 0 or
@_animation_duration > 0
end
def update
super
if @_whiten_duration > 0
@_whiten_duration -= 1
self.color.alpha = 128 - (16 - @_whiten_duration) * 10
end
if @_appear_duration > 0
@_appear_duration -= 1
self.opacity = (16 - @_appear_duration) * 16
end
if @_escape_duration > 0
@_escape_duration -= 1
self.opacity = 256 - (32 - @_escape_duration) * 10
end
if @_collapse_duration > 0
@_collapse_duration -= 1
self.opacity = 256 - (48 - @_collapse_duration) * 6
end
if @_damage_duration > 0
@_damage_duration -= 1
case @_damage_duration
when 38..39
@_damage_sprite.y -= 4
when 36..37
@_damage_sprite.y -= 2
when 34..35
@_damage_sprite.y += 2
when 28..33
@_damage_sprite.y += 4
end
@_damage_sprite.opacity = 256 - (12 - @_damage_duration) * 32
if @_damage_duration == 0
dispose_damage
end
end
if @_animation != nil and (Graphics.frame_count % 2 == 0)
@_animation_duration -= 1
update_animation
end
if @_loop_animation != nil and (Graphics.frame_count % 2 == 0)
update_loop_animation
@_loop_animation_index += 1
@_loop_animation_index %= @_loop_animation.frame_max
end
if @_blink
@_blink_count = (@_blink_count + 1) % 32
if @_blink_count < 16
alpha = (16 - @_blink_count) * 6
else
alpha = (@_blink_count - 16) * 6
end
self.color.set(255, 255, 255, alpha)
end
@@_animations.clear
end
def update_animation
if @_animation_duration > 0
frame_index = @_animation.frame_max - @_animation_duration
cell_data = @_animation.frames[frame_index].cell_data
position = @_animation.position
animation_set_sprites(@_animation_sprites, cell_data, position)
for timing in @_animation.timings
if timing.frame == frame_index
animation_process_timing(timing, @_animation_hit)
end
end
else
dispose_animation
end
end
def update_loop_animation
frame_index = @_loop_animation_index
cell_data = @_loop_animation.frames[frame_index].cell_data
position = @_loop_animation.position
animation_set_sprites(@_loop_animation_sprites, cell_data, position)
for timing in @_loop_animation.timings
if timing.frame == frame_index
animation_process_timing(timing, true)
end
end
end
def animation_set_sprites(sprites, cell_data, position)
for i in 0..15
sprite = sprites[i]
pattern = cell_data[i, 0]
if sprite == nil or pattern == nil or pattern == -1
sprite.visible = false if sprite != nil
next
end
sprite.visible = true
sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192)
if position == 3
if self.viewport != nil
sprite.x = self.viewport.rect.width / 2
sprite.y = self.viewport.rect.height - 160
else
sprite.x = 320
sprite.y = 240
end
else
sprite.x = self.x - self.ox + self.src_rect.width / 2
sprite.y = self.y - self.oy + self.src_rect.height / 2
sprite.y -= self.src_rect.height / 4 if position == 0
sprite.y += self.src_rect.height / 4 if position == 2
end
sprite.x += cell_data[i, 1]
sprite.y += cell_data[i, 2]
sprite.z = 2000
sprite.ox = 96
sprite.oy = 96
sprite.zoom_x = cell_data[i, 3] / 100.0
sprite.zoom_y = cell_data[i, 3] / 100.0
sprite.angle = cell_data[i, 4]
sprite.mirror = (cell_data[i, 5] == 1)
sprite.opacity = cell_data[i, 6] * self.opacity / 255.0
sprite.blend_type = cell_data[i, 7]
end
end
def animation_process_timing(timing, hit)
if (timing.condition == 0) or
(timing.condition == 1 and hit == true) or
(timing.condition == 2 and hit == false)
if timing.se.name != ""
se = timing.se
Audio.se_play("Audio/SE/" + se.name, se.volume, se.pitch)
end
case timing.flash_scope
when 1
self.flash(timing.flash_color, timing.flash_duration * 2)
when 2
if self.viewport != nil
self.viewport.flash(timing.flash_color, timing.flash_duration * 2)
end
when 3
self.flash(nil, timing.flash_duration * 2)
end
end
end
def x=(x)
sx = x - self.x
if sx != 0
if @_animation_sprites != nil
for i in 0..15
@_animation_sprites[i].x += sx
end
end
if @_loop_animation_sprites != nil
for i in 0..15
@_loop_animation_sprites[i].x += sx
end
end
end
super
end
def y=(y)
sy = y - self.y
if sy != 0
if @_animation_sprites != nil
for i in 0..15
@_animation_sprites[i].y += sy
end
end
if @_loop_animation_sprites != nil
for i in 0..15
@_loop_animation_sprites[i].y += sy
end
end
end
super
end
end
end
module RPG
class State
def initialize
@id = 0
@name = ""
@animation_id = 0
@restriction = 0
@nonresistance = false
@zero_hp = false
@cant_get_exp = false
@cant_evade = false
@slip_damage = false
@rating = 5
@hit_rate = 100
@maxhp_rate = 100
@maxsp_rate = 100
@str_rate = 100
@dex_rate = 100
@agi_rate = 100
@int_rate = 100
@atk_rate = 100
@pdef_rate = 100
@mdef_rate = 100
@eva = 0
@battle_only = true
@hold_turn = 0
@auto_release_prob = 0
@shock_release_prob = 0
@guard_element_set = []
@plus_state_set = []
@minus_state_set = []
end
attr_accessor :id
attr_accessor :name
attr_accessor :animation_id
attr_accessor :restriction
attr_accessor :nonresistance
attr_accessor :zero_hp
attr_accessor :cant_get_exp
attr_accessor :cant_evade
attr_accessor :slip_damage
attr_accessor :rating
attr_accessor :hit_rate
attr_accessor :maxhp_rate
attr_accessor :maxsp_rate
attr_accessor :str_rate
attr_accessor :dex_rate
attr_accessor :agi_rate
attr_accessor :int_rate
attr_accessor :atk_rate
attr_accessor :pdef_rate
attr_accessor :mdef_rate
attr_accessor :eva
attr_accessor :battle_only
attr_accessor :hold_turn
attr_accessor :auto_release_prob
attr_accessor :shock_release_prob
attr_accessor :guard_element_set
attr_accessor :plus_state_set
attr_accessor :minus_state_set
end
end
module RPG
class System
def initialize
@magic_number = 0
@party_members = [1]
@elements = [nil, ""]
@switches = [nil, ""]
@variables = [nil, ""]
@windowskin_name = ""
@title_name = ""
@gameover_name = ""
@battle_transition = ""
@title_bgm = RPG::AudioFile.new
@battle_bgm = RPG::AudioFile.new
@battle_end_me = RPG::AudioFile.new
@gameover_me = RPG::AudioFile.new
@cursor_se = RPG::AudioFile.new("", 80)
@decision_se = RPG::AudioFile.new("", 80)
@cancel_se = RPG::AudioFile.new("", 80)
@buzzer_se = RPG::AudioFile.new("", 80)
@equip_se = RPG::AudioFile.new("", 80)
@shop_se = RPG::AudioFile.new("", 80)
@save_se = RPG::AudioFile.new("", 80)
@load_se = RPG::AudioFile.new("", 80)
@battle_start_se = RPG::AudioFile.new("", 80)
@escape_se = RPG::AudioFile.new("", 80)
@actor_collapse_se = RPG::AudioFile.new("", 80)
@enemy_collapse_se = RPG::AudioFile.new("", 80)
@words = RPG::System::Words.new
@test_battlers = []
@test_troop_id = 1
@start_map_id = 1
@start_x = 0
@start_y = 0
@battleback_name = ""
@battler_name = ""
@battler_hue = 0
@edit_map_id = 1
end
attr_accessor :magic_number
attr_accessor :party_members
attr_accessor :elements
attr_accessor :switches
attr_accessor :variables
attr_accessor :windowskin_name
attr_accessor :title_name
attr_accessor :gameover_name
attr_accessor :battle_transition
attr_accessor :title_bgm
attr_accessor :battle_bgm
attr_accessor :battle_end_me
attr_accessor :gameover_me
attr_accessor :cursor_se
attr_accessor :decision_se
attr_accessor :cancel_se
attr_accessor :buzzer_se
attr_accessor :equip_se
attr_accessor :shop_se
attr_accessor :save_se
attr_accessor :load_se
attr_accessor :battle_start_se
attr_accessor :escape_se
attr_accessor :actor_collapse_se
attr_accessor :enemy_collapse_se
attr_accessor :words
attr_accessor :test_battlers
attr_accessor :test_troop_id
attr_accessor :start_map_id
attr_accessor :start_x
attr_accessor :start_y
attr_accessor :battleback_name
attr_accessor :battler_name
attr_accessor :battler_hue
attr_accessor :edit_map_id
end
end
module RPG
class System
class TestBattler
def initialize
@actor_id = 1
@level = 1
@weapon_id = 0
@armor1_id = 0
@armor2_id = 0
@armor3_id = 0
@armor4_id = 0
end
attr_accessor :actor_id
attr_accessor :level
attr_accessor :weapon_id
attr_accessor :armor1_id
attr_accessor :armor2_id
attr_accessor :armor3_id
attr_accessor :armor4_id
end
end
end
module RPG
class System
class Words
def initialize
@gold = ""
@hp = ""
@sp = ""
@str = ""
@dex = ""
@agi = ""
@int = ""
@atk = ""
@pdef = ""
@mdef = ""
@weapon = ""
@armor1 = ""
@armor2 = ""
@armor3 = ""
@armor4 = ""
@attack = ""
@skill = ""
@guard = ""
@item = ""
@equip = ""
end
attr_accessor :gold
attr_accessor :hp
attr_accessor :sp
attr_accessor :str
attr_accessor :dex
attr_accessor :agi
attr_accessor :int
attr_accessor :atk
attr_accessor :pdef
attr_accessor :mdef
attr_accessor :weapon
attr_accessor :armor1
attr_accessor :armor2
attr_accessor :armor3
attr_accessor :armor4
attr_accessor :attack
attr_accessor :skill
attr_accessor :guard
attr_accessor :item
attr_accessor :equip
end
end
end
module RPG
class Tileset
def initialize
@id = 0
@name = ""
@tileset_name = ""
@autotile_names = [""]*7
@panorama_name = ""
@panorama_hue = 0
@fog_name = ""
@fog_hue = 0
@fog_opacity = 64
@fog_blend_type = 0
@fog_zoom = 200
@fog_sx = 0
@fog_sy = 0
@battleback_name = ""
@passages = Table.new(384)
@priorities = Table.new(384)
@priorities[0] = 5
@terrain_tags = Table.new(384)
end
attr_accessor :id
attr_accessor :name
attr_accessor :tileset_name
attr_accessor :autotile_names
attr_accessor :panorama_name
attr_accessor :panorama_hue
attr_accessor :fog_name
attr_accessor :fog_hue
attr_accessor :fog_opacity
attr_accessor :fog_blend_type
attr_accessor :fog_zoom
attr_accessor :fog_sx
attr_accessor :fog_sy
attr_accessor :battleback_name
attr_accessor :passages
attr_accessor :priorities
attr_accessor :terrain_tags
end
end
module RPG
class Troop
def initialize
@id = 0
@name = ""
@members = []
@pages = [RPG::BattleEventPage.new]
end
attr_accessor :id
attr_accessor :name
attr_accessor :members
attr_accessor :pages
end
end
module RPG
class Troop
class Member
def initialize
@enemy_id = 1
@x = 0
@y = 0
@hidden = false[/i][/i][/i][/i][/i]