Refactored animation editor code into a single module

This commit is contained in:
Maruno17
2023-03-06 22:25:45 +00:00
parent ee72ad371f
commit 3a9199da1b
8 changed files with 3454 additions and 3435 deletions

View File

@@ -127,6 +127,16 @@ module Enumerable
end
end
#===============================================================================
# Collision testing
#===============================================================================
class Rect < Object
def contains?(cx, cy)
return cx >= self.x && cx < self.x + self.width &&
cy >= self.y && cy < self.y + self.height
end
end
#===============================================================================
# class File
#===============================================================================

View File

@@ -53,7 +53,7 @@ module GameData
extend ClassMethodsSymbols
include InstanceMethods
# @param other [Symbol, String, self]
# @param area [Symbol, String, self]
# @param version [Integer]
# @return [self]
def self.try_get(area, version = 0)

View File

@@ -1,7 +1,10 @@
#===============================================================================
# Controls
#===============================================================================
class Window_Menu < Window_CommandPokemon
module BattleAnimationEditor
module_function
#===============================================================================
# Controls
#===============================================================================
class Window_Menu < Window_CommandPokemon
def initialize(commands, x, y)
tempbitmap = Bitmap.new(32, 32)
w = 0
@@ -32,16 +35,16 @@ class Window_Menu < Window_CommandPokemon
rc = Rect.new(0, 32 * (i - toprow), self.contents.width, 32)
rc.x += self.x + self.leftEdge
rc.y += self.y + self.topEdge
return i if rc.contains(mousepos[0], mousepos[1])
return i if rc.contains?(mousepos[0], mousepos[1])
end
return -1
end
end
end
#===============================================================================
# Clipboard
#===============================================================================
module Clipboard
#===============================================================================
# Clipboard
#===============================================================================
module Clipboard
@data = nil
@typekey = ""
@@ -58,74 +61,12 @@ module Clipboard
@data = Marshal.dump(data)
@typekey = key
end
end
end
#===============================================================================
# Collision testing
#===============================================================================
class Rect < Object
def contains(x, y)
return x >= self.x && x < self.x + self.width &&
y >= self.y && y < self.y + self.height
end
end
#===============================================================================
#
#===============================================================================
def pbSpriteHitTest(sprite, x, y, usealpha = true, wholecanvas = false)
return false if !sprite || sprite.disposed?
return false if !sprite.bitmap
return false if !sprite.visible
return false if sprite.bitmap.disposed?
width = sprite.src_rect.width
height = sprite.src_rect.height
if wholecanvas
xwidth = 0
xheight = 0
else
xwidth = width - 64
xheight = height - 64
width = 64 if width > 64 && !usealpha
height = 64 if height > 64 && !usealpha
end
width = sprite.bitmap.width if width > sprite.bitmap.width
height = sprite.bitmap.height if height > sprite.bitmap.height
if usealpha
spritex = sprite.x - (sprite.ox * sprite.zoom_x)
spritey = sprite.y - (sprite.oy * sprite.zoom_y)
width *= sprite.zoom_x
height *= sprite.zoom_y
else
spritex = sprite.x - sprite.ox
spritey = sprite.y - sprite.oy
spritex += xwidth / 2
spritey += xheight / 2
end
if !(x >= spritex && x <= spritex + width && y >= spritey && y <= spritey + height)
return false
end
if usealpha
# TODO: This should account for sprite.angle as well
bitmapX = sprite.src_rect.x
bitmapY = sprite.src_rect.y
bitmapX += sprite.ox
bitmapY += sprite.oy
bitmapX += (x - sprite.x) / sprite.zoom_x if sprite.zoom_x > 0
bitmapY += (y - sprite.y) / sprite.zoom_y if sprite.zoom_y > 0
bitmapX = bitmapX.round
bitmapY = bitmapY.round
if sprite.mirror
xmirror = bitmapX - sprite.src_rect.x
bitmapX = sprite.src_rect.x + 192 - xmirror
end
color = sprite.bitmap.get_pixel(bitmapX, bitmapY)
return false if color.alpha == 0
end
return true
end
def pbTrackPopupMenu(commands)
#===============================================================================
#
#===============================================================================
def pbTrackPopupMenu(commands)
mousepos = Mouse.getMousePos
return -1 if !mousepos
menuwindow = Window_Menu.new(commands, mousepos[0], mousepos[1])
@@ -151,12 +92,12 @@ def pbTrackPopupMenu(commands)
end
menuwindow.dispose
return -1
end
end
#===============================================================================
# Sprite sheet scrolling bar
#===============================================================================
class AnimationWindow < Sprite
#===============================================================================
# Sprite sheet scrolling bar
#===============================================================================
class AnimationWindow < Sprite
attr_reader :animbitmap
attr_reader :start
attr_reader :selected
@@ -262,14 +203,14 @@ class AnimationWindow < Sprite
swatchrects.push(Rect.new(arrowwidth + (i * 96) + self.x, self.y, 96, 96))
end
NUMFRAMES.times do |i|
next if !swatchrects[i].contains(mousepos[0], mousepos[1])
next if !swatchrects[i].contains?(mousepos[0], mousepos[1])
@selected = @start + i
@changed = true
refresh
return
end
# Left arrow
if left.contains(mousepos[0], mousepos[1])
if left.contains?(mousepos[0], mousepos[1])
if repeattime > 750
@start -= 3
else
@@ -279,7 +220,7 @@ class AnimationWindow < Sprite
refresh
end
# Right arrow
if right.contains(mousepos[0], mousepos[1])
if right.contains?(mousepos[0], mousepos[1])
if repeattime > 750
@start += 3
else
@@ -289,12 +230,12 @@ class AnimationWindow < Sprite
refresh
end
end
end
end
#===============================================================================
#
#===============================================================================
class CanvasAnimationWindow < AnimationWindow
#===============================================================================
#
#===============================================================================
class CanvasAnimationWindow < AnimationWindow
def animbitmap
return @canvas.animbitmap
end
@@ -303,12 +244,12 @@ class CanvasAnimationWindow < AnimationWindow
@canvas = canvas
super(x, y, width, height, viewport)
end
end
end
#===============================================================================
# Cel sprite
#===============================================================================
class InvalidatableSprite < Sprite
#===============================================================================
# Cel sprite
#===============================================================================
class InvalidatableSprite < Sprite
def initialize(viewport = nil)
super(viewport)
@invalid = false
@@ -340,12 +281,12 @@ class InvalidatableSprite < Sprite
# Redraws the sprite. This method should not check whether
# the sprite is invalid, to allow it to be explicitly called.
def refresh; end
end
end
#===============================================================================
#
#===============================================================================
class SpriteFrame < InvalidatableSprite
#===============================================================================
#
#===============================================================================
class SpriteFrame < InvalidatableSprite
attr_reader :id
attr_reader :locked
attr_reader :selected
@@ -409,12 +350,12 @@ class SpriteFrame < InvalidatableSprite
@contents.blt(16, 0, @iconbitmap.bitmap, bmrect)
end
end
end
end
#===============================================================================
# Canvas
#===============================================================================
class AnimationCanvas < Sprite
#===============================================================================
# Canvas
#===============================================================================
class AnimationCanvas < Sprite
attr_reader :viewport
attr_reader :sprites
attr_reader :currentframe # Currently active frame
@@ -785,6 +726,58 @@ class AnimationCanvas < Sprite
return false
end
def pbSpriteHitTest(sprite, x, y, usealpha = true, wholecanvas = false)
return false if !sprite || sprite.disposed?
return false if !sprite.bitmap
return false if !sprite.visible
return false if sprite.bitmap.disposed?
width = sprite.src_rect.width
height = sprite.src_rect.height
if wholecanvas
xwidth = 0
xheight = 0
else
xwidth = width - 64
xheight = height - 64
width = 64 if width > 64 && !usealpha
height = 64 if height > 64 && !usealpha
end
width = sprite.bitmap.width if width > sprite.bitmap.width
height = sprite.bitmap.height if height > sprite.bitmap.height
if usealpha
spritex = sprite.x - (sprite.ox * sprite.zoom_x)
spritey = sprite.y - (sprite.oy * sprite.zoom_y)
width *= sprite.zoom_x
height *= sprite.zoom_y
else
spritex = sprite.x - sprite.ox
spritey = sprite.y - sprite.oy
spritex += xwidth / 2
spritey += xheight / 2
end
if !(x >= spritex && x <= spritex + width && y >= spritey && y <= spritey + height)
return false
end
if usealpha
# TODO: This should account for sprite.angle as well
bitmapX = sprite.src_rect.x
bitmapY = sprite.src_rect.y
bitmapX += sprite.ox
bitmapY += sprite.oy
bitmapX += (x - sprite.x) / sprite.zoom_x if sprite.zoom_x > 0
bitmapY += (y - sprite.y) / sprite.zoom_y if sprite.zoom_y > 0
bitmapX = bitmapX.round
bitmapY = bitmapY.round
if sprite.mirror
xmirror = bitmapX - sprite.src_rect.x
bitmapX = sprite.src_rect.x + 192 - xmirror
end
color = sprite.bitmap.get_pixel(bitmapX, bitmapY)
return false if color.alpha == 0
end
return true
end
def updateInput
cel = currentCel
mousepos = Mouse.getMousePos
@@ -840,7 +833,7 @@ class AnimationCanvas < Sprite
return
end
if Input.triggerex?(:P) || Input.repeatex?(:P) # Properties
pbCellProperties(self)
BattleAnimationEditor.pbCellProperties(self)
@dirty[@currentcel] = true
return
end
@@ -909,8 +902,8 @@ class AnimationCanvas < Sprite
return
end
updateInput
# @testscreen.update
# self.bitmap=@testscreen.bitmap
# @testscreen.update
# self.bitmap=@testscreen.bitmap
if @currentframe < @animation.length
PBAnimation::MAX_SPRITES.times do |i|
next if !@dirty[i]
@@ -935,12 +928,12 @@ class AnimationCanvas < Sprite
end
end
end
end
end
#===============================================================================
# Window classes
#===============================================================================
class BitmapDisplayWindow < SpriteWindow_Base
#===============================================================================
# Window classes
#===============================================================================
class BitmapDisplayWindow < SpriteWindow_Base
attr_reader :bitmapname
attr_reader :hue
@@ -987,12 +980,12 @@ class BitmapDisplayWindow < SpriteWindow_Base
self.contents.stretch_blt(dest, bmap, src)
bmap.dispose
end
end
end
#===============================================================================
#
#===============================================================================
class AnimationNameWindow
#===============================================================================
#
#===============================================================================
class AnimationNameWindow
def initialize(canvas, x, y, width, height, viewport = nil)
@canvas = canvas
@oldname = nil
@@ -1015,4 +1008,5 @@ class AnimationNameWindow
def refresh; @window.refresh; end
def dispose; @window.dispose; end
def disposed; @window.disposed?; end
end
end

View File

@@ -1,7 +1,10 @@
#===============================================================================
#
#===============================================================================
module ShadowText
module BattleAnimationEditor
module_function
#===============================================================================
#
#===============================================================================
module ShadowText
def shadowtext(bitmap, x, y, w, h, t, disabled = false, align = 0)
width = bitmap.text_size(t).width
case align
@@ -14,12 +17,12 @@ module ShadowText
disabled ? Color.new(208, 208, 200) : Color.new(96, 96, 96),
Color.new(208, 208, 200))
end
end
end
#===============================================================================
#
#===============================================================================
class UIControl
#===============================================================================
#
#===============================================================================
class UIControl
include ShadowText
attr_accessor :bitmap
attr_accessor :label
@@ -90,12 +93,12 @@ class UIControl
self.validate
end
end
end
end
#===============================================================================
#
#===============================================================================
class Label < UIControl
#===============================================================================
#
#===============================================================================
class Label < UIControl
def text=(value)
self.label = value
refresh
@@ -107,12 +110,12 @@ class Label < UIControl
size = bitmap.text_size(self.label).width
shadowtext(bitmap, self.x + 4, self.y, size, self.height, self.label, @disabled)
end
end
end
#===============================================================================
#
#===============================================================================
class Button < UIControl
#===============================================================================
#
#===============================================================================
class Button < UIControl
attr_accessor :label
def initialize(label)
@@ -128,12 +131,12 @@ class Button < UIControl
rect = Rect.new(self.x + 1, self.y + 1, self.width - 2, self.height - 2)
rect = toAbsoluteRect(rect)
if Input.trigger?(Input::MOUSELEFT) &&
rect.contains(mousepos[0], mousepos[1]) && !@captured
rect.contains?(mousepos[0], mousepos[1]) && !@captured
@captured = true
self.invalidate
end
if Input.release?(Input::MOUSELEFT) && @captured
self.changed = true if rect.contains(mousepos[0], mousepos[1])
self.changed = true if rect.contains?(mousepos[0], mousepos[1])
@captured = false
self.invalidate
end
@@ -164,12 +167,12 @@ class Button < UIControl
ret = Rect.new(x + 1, y + 1, width - 2, height - 2)
return ret
end
end
end
#===============================================================================
#
#===============================================================================
class Checkbox < Button
#===============================================================================
#
#===============================================================================
class Checkbox < Button
attr_reader :checked
def curvalue
@@ -217,7 +220,6 @@ class Checkbox < Button
shadowtext(bitmap, x + 36, y, size, height, self.label, @disabled)
# Draw outline
color = Color.new(120, 120, 120)
bitmap.fill_rect(x + 1, y + 1, width - 2, height - 2, color)
bitmap.fill_rect(x + 1, y + 1, width - 2, 1, color)
bitmap.fill_rect(x + 1, y + 1, 1, height - 2, color)
bitmap.fill_rect(x + 1, y + height - 2, width - 2, 1, color)
@@ -226,12 +228,12 @@ class Checkbox < Button
ret = Rect.new(x + 1, y + 1, width - 2, height - 2)
return ret
end
end
end
#===============================================================================
#
#===============================================================================
class TextField < UIControl
#===============================================================================
#
#===============================================================================
class TextField < UIControl
attr_accessor :label
attr_reader :text
@@ -362,12 +364,12 @@ class TextField < UIControl
ret = Rect.new(x + 1, y + 1, width - 2, height - 2)
return ret
end
end
end
#===============================================================================
#
#===============================================================================
class Slider < UIControl
#===============================================================================
#
#===============================================================================
class Slider < UIControl
attr_reader :minvalue
attr_reader :maxvalue
attr_reader :curvalue
@@ -421,7 +423,7 @@ class Slider < UIControl
oldvalue = self.curvalue
repeattime = Input.time?(Input::MOUSELEFT) / 1000
# Left arrow
if left.contains(mousepos[0], mousepos[1])
if left.contains?(mousepos[0], mousepos[1])
if repeattime > 3000
self.curvalue -= 10
elsif repeattime > 1500
@@ -434,7 +436,7 @@ class Slider < UIControl
self.invalidate
end
# Right arrow
if right.contains(mousepos[0], mousepos[1])
if right.contains?(mousepos[0], mousepos[1])
if repeattime > 3000
self.curvalue += 10
elsif repeattime > 1500
@@ -476,12 +478,12 @@ class Slider < UIControl
self.disabled || self.curvalue == self.maxvalue)
@rightarrow = Rect.new(x, y, rightarrows.width, height)
end
end
end
#===============================================================================
#
#===============================================================================
class OptionalSlider < Slider
#===============================================================================
#
#===============================================================================
class OptionalSlider < Slider
def initialize(label, minvalue, maxvalue, curvalue)
@slider = Slider.new(label, minvalue, maxvalue, curvalue)
@checkbox = Checkbox.new("")
@@ -569,12 +571,12 @@ class OptionalSlider < Slider
@slider.height = self.height
@slider.disabled = !@checkbox.checked
end
end
end
#===============================================================================
#
#===============================================================================
class ArrayCountSlider < Slider
#===============================================================================
#
#===============================================================================
class ArrayCountSlider < Slider
def maxvalue
return @array.length - 1
end
@@ -583,12 +585,12 @@ class ArrayCountSlider < Slider
@array = array
super(label, 0, canvas.animation.length - 1, 0)
end
end
end
#===============================================================================
#
#===============================================================================
class FrameCountSlider < Slider
#===============================================================================
#
#===============================================================================
class FrameCountSlider < Slider
def maxvalue
return @canvas.animation.length
end
@@ -597,12 +599,12 @@ class FrameCountSlider < Slider
@canvas = canvas
super(_INTL("Frame:"), 1, canvas.animation.length, 0)
end
end
end
#===============================================================================
#
#===============================================================================
class FrameCountButton < Button
#===============================================================================
#
#===============================================================================
class FrameCountButton < Button
def label
return _INTL("Total Frames: {1}", @canvas.animation.length)
end
@@ -611,12 +613,12 @@ class FrameCountButton < Button
@canvas = canvas
super(self.label)
end
end
end
#===============================================================================
#
#===============================================================================
class TextSlider < UIControl
#===============================================================================
#
#===============================================================================
class TextSlider < UIControl
attr_reader :minvalue
attr_reader :maxvalue
attr_reader :curvalue
@@ -673,7 +675,7 @@ class TextSlider < UIControl
oldvalue = self.curvalue
repeattime = Input.time?(Input::MOUSELEFT) / 1000
# Left arrow
if left.contains(mousepos[0], mousepos[1])
if left.contains?(mousepos[0], mousepos[1])
if repeattime > 3000
self.curvalue -= 10
elsif repeattime > 1500
@@ -685,7 +687,7 @@ class TextSlider < UIControl
self.invalidate
end
# Right arrow
if right.contains(mousepos[0], mousepos[1])
if right.contains?(mousepos[0], mousepos[1])
if repeattime > 3000
self.curvalue += 10
elsif repeattime > 1500
@@ -731,12 +733,12 @@ class TextSlider < UIControl
self.disabled || self.curvalue == self.maxvalue)
@rightarrow = Rect.new(x, y, rightarrows.width, height)
end
end
end
#===============================================================================
#
#===============================================================================
class OptionalTextSlider < TextSlider
#===============================================================================
#
#===============================================================================
class OptionalTextSlider < TextSlider
def initialize(label, options, curval)
@slider = TextSlider.new(label, options, curval)
@checkbox = Checkbox.new("")
@@ -824,12 +826,12 @@ class OptionalTextSlider < TextSlider
@slider.height = self.height
@slider.disabled = !@checkbox.checked
end
end
end
#===============================================================================
#
#===============================================================================
class ControlWindow < SpriteWindow_Base
#===============================================================================
#
#===============================================================================
class ControlWindow < SpriteWindow_Base
attr_reader :controls
def initialize(x, y, width, height)
@@ -862,7 +864,7 @@ class ControlWindow < SpriteWindow_Base
return false if i < 0 || i >= @controls.length
rc = Rect.new(@controls[i].parentX, @controls[i].parentY,
@controls[i].width, @controls[i].height)
return rc.contains(mousepos[0], mousepos[1])
return rc.contains?(mousepos[0], mousepos[1])
end
def addControl(control)
@@ -926,4 +928,5 @@ class ControlWindow < SpriteWindow_Base
return false if i < 0
return @controls[i].curvalue
end
end
end

View File

@@ -1,7 +1,10 @@
#===============================================================================
# Paths and interpolation
#===============================================================================
class ControlPointSprite < Sprite
module BattleAnimationEditor
module_function
#===============================================================================
# Paths and interpolation
#===============================================================================
class ControlPointSprite < Sprite
attr_accessor :dragging
def initialize(red, viewport = nil)
@@ -46,12 +49,12 @@ class ControlPointSprite < Sprite
self.bitmap.dispose
super
end
end
end
#===============================================================================
#
#===============================================================================
class PointSprite < Sprite
#===============================================================================
#
#===============================================================================
class PointSprite < Sprite
def initialize(x, y, viewport = nil)
super(viewport)
self.bitmap = Bitmap.new(2, 2)
@@ -64,12 +67,12 @@ class PointSprite < Sprite
self.bitmap.dispose
super
end
end
end
#===============================================================================
#
#===============================================================================
class PointPath
#===============================================================================
#
#===============================================================================
class PointPath
include Enumerable
def initialize
@@ -174,21 +177,21 @@ class PointPath
end
return ret
end
end
end
#===============================================================================
#
#===============================================================================
def catmullRom(p1, p2, p3, p4, t)
#===============================================================================
#
#===============================================================================
def catmullRom(p1, p2, p3, p4, t)
# p1=prevPoint, p2=startPoint, p3=endPoint, p4=nextPoint, t is from 0 through 1
t2 = t * t
t3 = t2 * t
return 0.5 * ((2 * p2) + (t * (p3 - p1)) +
(t2 * ((2 * p1) - (5 * p2) + (4 * p3) - p4)) +
(t3 * (p4 - (3 * p3) + (3 * p2) - p1)))
end
end
def getCatmullRomPoint(src, t)
def getCatmullRomPoint(src, t)
x = 0, y = 0
t *= 3.0
if t < 1.0
@@ -204,13 +207,13 @@ def getCatmullRomPoint(src, t)
y = catmullRom(src[1].y, src[2].y, src[3].y, src[3].y, t)
end
return [x, y]
end
end
def getCurvePoint(src, t)
def getCurvePoint(src, t)
return getCatmullRomPoint(src, t)
end
end
def curveToPointPath(curve, numpoints)
def curveToPointPath(curve, numpoints)
return nil if numpoints < 2
path = PointPath.new
step = 1.0 / (numpoints - 1)
@@ -221,9 +224,9 @@ def curveToPointPath(curve, numpoints)
t += step
end
return path
end
end
def pbDefinePath(canvas)
def pbDefinePath(canvas)
sliderwin2 = ControlWindow.new(0, 0, 320, 320)
sliderwin2.viewport = canvas.viewport
sliderwin2.addSlider(_INTL("Number of frames:"), 2, 500, 20)
@@ -338,7 +341,7 @@ def pbDefinePath(canvas)
points.clear
if showline
path = curveToPointPath(curve, sliderwin2.value(0))
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
path.each do |point|
points.push(PointSprite.new(point[0], point[1], canvas.viewport))
end
@@ -397,11 +400,11 @@ def pbDefinePath(canvas)
path.each do |point|
points.push(PointSprite.new(point[0], point[1], canvas.viewport))
end
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
sliderwin2.visible = true
next
elsif sliderwin2.changed?(okbutton) && path
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
neededsize = canvas.currentframe + sliderwin2.value(0)
if neededsize > canvas.animation.length
canvas.animation.resize(neededsize)
@@ -429,4 +432,5 @@ def pbDefinePath(canvas)
points.clear
sliderwin2.dispose
return
end
end

View File

@@ -1,27 +1,30 @@
################################################################################
# Importing and exporting
################################################################################
def pbRgssChdir(dir)
RTP.eachPathFor(dir) { |path| Dir.chdir(path) { yield } }
end
module BattleAnimationEditor
module_function
def tryLoadData(file)
################################################################################
# Importing and exporting
################################################################################
def pbRgssChdir(dir)
RTP.eachPathFor(dir) { |path| Dir.chdir(path) { yield } }
end
def tryLoadData(file)
begin
return load_data(file)
rescue
return nil
end
end
end
def dumpBase64Anim(s)
def dumpBase64Anim(s)
return [Zlib::Deflate.deflate(Marshal.dump(s))].pack("m").gsub(/\n/, "\r\n")
end
end
def loadBase64Anim(s)
def loadBase64Anim(s)
return Marshal.restore(Zlib::Inflate.inflate(s.unpack("m")[0]))
end
end
def pbExportAnim(animations)
def pbExportAnim(animations)
filename = pbMessageFreeText(_INTL("Enter a filename."), "", false, 32)
if filename != ""
begin
@@ -39,9 +42,9 @@ def pbExportAnim(animations)
pbMessage(_INTL("It's a text file, so it can be transferred to others easily."))
end
end
end
end
def pbImportAnim(animations, canvas, animwin)
def pbImportAnim(animations, canvas, animwin)
animfiles = []
pbRgssChdir(".") { animfiles.concat(Dir.glob("*.anm")) }
cmdwin = pbListWindow(animfiles, 320)
@@ -78,12 +81,12 @@ def pbImportAnim(animations, canvas, animwin)
end
cmdwin.dispose
return
end
end
################################################################################
# Format conversion
################################################################################
def pbConvertAnimToNewFormat(textdata)
################################################################################
# Format conversion
################################################################################
def pbConvertAnimToNewFormat(textdata)
needconverting = false
textdata.length.times do |i|
next if !textdata[i]
@@ -120,9 +123,9 @@ def pbConvertAnimToNewFormat(textdata)
end
end
return needconverting
end
end
def pbConvertAnimsToNewFormat
def pbConvertAnimsToNewFormat
pbMessage(_INTL("Will convert animations now."))
count = 0
animations = pbLoadBattleAnimations
@@ -140,4 +143,5 @@ def pbConvertAnimsToNewFormat
$game_temp.battle_animations_data = nil
end
pbMessage(_INTL("{1} animations converted to new format.", count))
end
end

View File

@@ -1,29 +1,32 @@
#===============================================================================
# Mini battle scene
#===============================================================================
class MiniBattler
module BattleAnimationEditor
module_function
#===============================================================================
# Mini battle scene
#===============================================================================
class MiniBattler
attr_accessor :index
attr_accessor :pokemon
def initialize(index); self.index = index; end
end
end
#===============================================================================
#
#===============================================================================
class MiniBattle
#===============================================================================
#
#===============================================================================
class MiniBattle
attr_accessor :battlers
def initialize
@battlers = []
4.times { |i| @battlers[i] = MiniBattler.new(i) }
end
end
end
#===============================================================================
# Pop-up menus for buttons in bottom menu
#===============================================================================
def pbSelectAnim(canvas, animwin)
#===============================================================================
# Pop-up menus for buttons in bottom menu
#===============================================================================
def pbSelectAnim(canvas, animwin)
animfiles = []
pbRgssChdir(File.join("Graphics", "Animations")) { animfiles.concat(Dir.glob("*.png")) }
cmdwin = pbListWindow(animfiles, 320)
@@ -60,9 +63,9 @@ def pbSelectAnim(canvas, animwin)
cmdwin.dispose
ctlwin.dispose
return
end
end
def pbChangeMaximum(canvas)
def pbChangeMaximum(canvas)
sliderwin2 = ControlWindow.new(0, 0, 320, 32 * 4)
sliderwin2.viewport = canvas.viewport
sliderwin2.addSlider(_INTL("Frames:"), 1, 1000, canvas.animation.length)
@@ -83,9 +86,9 @@ def pbChangeMaximum(canvas)
end
sliderwin2.dispose
return
end
end
def pbAnimName(animation, cmdwin)
def pbAnimName(animation, cmdwin)
window = ControlWindow.new(320, 128, 320, 32 * 4)
window.z = 99999
window.addControl(TextField.new(_INTL("New Name:"), animation.name))
@@ -109,9 +112,9 @@ def pbAnimName(animation, cmdwin)
window.dispose
Input.text_input = false
return
end
end
def pbAnimList(animations, canvas, animwin)
def pbAnimList(animations, canvas, animwin)
commands = []
animations.length.times do |i|
animations[i] = PBAnimation.new if !animations[i]
@@ -177,12 +180,12 @@ def pbAnimList(animations, canvas, animwin)
helpwindow.dispose
maxsizewindow.dispose
cmdwin.dispose
end
end
#===============================================================================
# Pop-up menus for individual cels
#===============================================================================
def pbChooseNum(cel)
#===============================================================================
# Pop-up menus for individual cels
#===============================================================================
def pbChooseNum(cel)
ret = cel
sliderwin2 = ControlWindow.new(0, 0, 320, 32 * 5)
sliderwin2.z = 99999
@@ -205,9 +208,9 @@ def pbChooseNum(cel)
end
sliderwin2.dispose
return ret
end
end
def pbSetTone(cel, previewsprite)
def pbSetTone(cel, previewsprite)
sliderwin2 = ControlWindow.new(0, 0, 320, 320)
sliderwin2.z = 99999
sliderwin2.addSlider(_INTL("Red Offset:"), -255, 255, cel[AnimFrame::TONERED])
@@ -235,9 +238,9 @@ def pbSetTone(cel, previewsprite)
end
sliderwin2.dispose
return
end
end
def pbSetFlash(cel, previewsprite)
def pbSetFlash(cel, previewsprite)
sliderwin2 = ControlWindow.new(0, 0, 320, 320)
sliderwin2.z = 99999
sliderwin2.addSlider(_INTL("Red:"), 0, 255, cel[AnimFrame::COLORRED])
@@ -265,9 +268,9 @@ def pbSetFlash(cel, previewsprite)
end
sliderwin2.dispose
return
end
end
def pbCellProperties(canvas)
def pbCellProperties(canvas)
cel = canvas.currentCel.clone # Clone cell, in case operation is canceled
return if !cel
sliderwin2 = ControlWindow.new(0, 0, 320, 32 * 16)
@@ -365,12 +368,12 @@ def pbCellProperties(canvas)
previewsprite.dispose
sliderwin2.dispose
return
end
end
#===============================================================================
# Pop-up menus for buttons in right hand menu
#===============================================================================
def pbTimingList(canvas)
#===============================================================================
# Pop-up menus for buttons in right hand menu
#===============================================================================
def pbTimingList(canvas)
commands = []
cmdNewSound = -1
cmdNewBG = -1
@@ -498,16 +501,16 @@ def pbTimingList(canvas)
cmdwin.dispose
framewindow.dispose
return
end
end
def pbSelectSE(canvas, audio)
def pbSelectSE(canvas, audio)
filename = (audio.name != "") ? audio.name : ""
displayname = (filename != "") ? filename : _INTL("<user's cry>")
animfiles = []
ret = false
pbRgssChdir(File.join("Audio", "SE", "Anim")) do
animfiles.concat(Dir.glob("*.wav"))
# animfiles.concat(Dir.glob("*.mp3"))
# animfiles.concat(Dir.glob("*.mp3"))
animfiles.concat(Dir.glob("*.ogg"))
animfiles.concat(Dir.glob("*.wma"))
end
@@ -533,9 +536,8 @@ def pbSelectSE(canvas, audio)
Input.update
cmdwin.update
maxsizewindow.update
if maxsizewindow.changed?(3) && animfiles.length > 0 # Play Sound
fname = (cmdwin.index == 0) ? "Cries/000" : "Anim/" + filename
pbSEPlay(RPG::AudioFile.new(fname, maxsizewindow.value(1), maxsizewindow.value(2)))
if maxsizewindow.changed?(3) && animfiles.length > 0 && filename != "" # Play Sound
pbSEPlay(RPG::AudioFile.new("Anim/" + filename, maxsizewindow.value(1), maxsizewindow.value(2)))
end
pbSEStop if maxsizewindow.changed?(4) && animfiles.length > 0 # Stop Sound
if maxsizewindow.changed?(5) # OK
@@ -557,9 +559,9 @@ def pbSelectSE(canvas, audio)
cmdwin.dispose
maxsizewindow.dispose
return ret
end
end
def pbSelectBG(canvas, timing)
def pbSelectBG(canvas, timing)
filename = timing.name
cmdErase = -1
animfiles = []
@@ -568,9 +570,9 @@ def pbSelectBG(canvas, timing)
pbRgssChdir(File.join("Graphics", "Animations")) do
animfiles.concat(Dir.glob("*.png"))
animfiles.concat(Dir.glob("*.gif"))
# animfiles.concat(Dir.glob("*.jpg"))
# animfiles.concat(Dir.glob("*.jpeg"))
# animfiles.concat(Dir.glob("*.bmp"))
# animfiles.concat(Dir.glob("*.jpg"))
# animfiles.concat(Dir.glob("*.jpeg"))
# animfiles.concat(Dir.glob("*.bmp"))
end
animfiles.uniq!
animfiles.sort! { |a, b| a.downcase <=> b.downcase }
@@ -619,9 +621,9 @@ def pbSelectBG(canvas, timing)
cmdwin.dispose
maxsizewindow.dispose
return ret
end
end
def pbEditBG(canvas, timing)
def pbEditBG(canvas, timing)
ret = false
maxsizewindow = ControlWindow.new(0, 0, 320, 32 * 11)
maxsizewindow.addSlider(_INTL("Duration:"), 0, 50, timing.duration)
@@ -674,9 +676,9 @@ def pbEditBG(canvas, timing)
end
maxsizewindow.dispose
return ret
end
end
def pbCopyFrames(canvas)
def pbCopyFrames(canvas)
sliderwin2 = ControlWindow.new(0, 0, 320, 32 * 6)
sliderwin2.viewport = canvas.viewport
sliderwin2.addSlider(_INTL("First Frame:"), 1, canvas.animation.length, 1)
@@ -721,9 +723,9 @@ def pbCopyFrames(canvas)
end
sliderwin2.dispose
return
end
end
def pbClearFrames(canvas)
def pbClearFrames(canvas)
sliderwin2 = ControlWindow.new(0, 0, 320, 32 * 5)
sliderwin2.viewport = canvas.viewport
sliderwin2.addSlider(_INTL("First Frame:"), 1, canvas.animation.length, 1)
@@ -749,9 +751,9 @@ def pbClearFrames(canvas)
end
sliderwin2.dispose
return
end
end
def pbTweening(canvas)
def pbTweening(canvas)
sliderwin2 = ControlWindow.new(0, 0, 320, 32 * 10)
sliderwin2.viewport = canvas.viewport
sliderwin2.opacity = 200
@@ -826,9 +828,9 @@ def pbTweening(canvas)
end
end
sliderwin2.dispose
end
end
def pbCellBatch(canvas)
def pbCellBatch(canvas)
sliderwin1 = ControlWindow.new(0, 0, 300, 32 * 5)
sliderwin1.viewport = canvas.viewport
sliderwin1.opacity = 200
@@ -891,9 +893,9 @@ def pbCellBatch(canvas)
end
sliderwin1.dispose
sliderwin2.dispose
end
end
def pbEntireSlide(canvas)
def pbEntireSlide(canvas)
sliderwin2 = ControlWindow.new(0, 0, 320, 32 * 7)
sliderwin2.viewport = canvas.viewport
sliderwin2.addSlider(_INTL("First Frame:"), 1, canvas.animation.length, 1)
@@ -923,9 +925,9 @@ def pbEntireSlide(canvas)
end
sliderwin2.dispose
return
end
end
def pbAnimEditorHelpWindow
def pbAnimEditorHelpWindow
helptext = "" +
"To add a cel to the scene, click on the canvas. The selected cel will have a black " +
"frame. After a cel is selected, you can modify its properties using the keyboard:\n" +
@@ -943,12 +945,13 @@ def pbAnimEditorHelpWindow
break if Input.trigger?(Input::BACK) || Input.trigger?(Input::USE)
end
cmdwin.dispose
end
end
#===============================================================================
# Main
#===============================================================================
def animationEditorMain(animation)
#=============================================================================
# Main
#=============================================================================
def animationEditorMain(animation)
echoln animation.selected
viewport = Viewport.new(0, 0, Settings::SCREEN_WIDTH + 288, Settings::SCREEN_HEIGHT + 288)
viewport.z = 99999
# Canvas
@@ -1109,7 +1112,7 @@ def animationEditorMain(animation)
indexes = [2, 1, 3, 4] # Keeping backwards compatibility
positions.length.times do |i|
selected = "[ ]"
selected = "[x]" if animation[animation.selected].position == indexes[i]
selected = "[X]" if animation[animation.selected].position == indexes[i]
positions[i] = sprintf("%s %s", selected, positions[i])
end
pos = pbShowCommands(nil, positions, -1)
@@ -1148,6 +1151,7 @@ def animationEditorMain(animation)
bottomwindow.dispose
viewport.dispose
RPG::Cache.clear
end
end
#===============================================================================
@@ -1162,7 +1166,7 @@ def pbAnimationEditor
end
Graphics.resize_screen(Settings::SCREEN_WIDTH + 288, Settings::SCREEN_HEIGHT + 288)
pbSetResizeFactor(1)
animationEditorMain(animation)
BattleAnimationEditor.animationEditorMain(animation)
Graphics.resize_screen(Settings::SCREEN_WIDTH, Settings::SCREEN_HEIGHT)
pbSetResizeFactor($PokemonSystem.screensize)
$game_map&.autoplay

View File

@@ -558,7 +558,7 @@ def pbExportAllAnimations
safename = anim.name.gsub(/\W/, "_")
Dir.mkdir("Animations/#{safename}") rescue nil
File.open("Animations/#{safename}/#{safename}.anm", "wb") do |f|
f.write(dumpBase64Anim(anim))
f.write(BattleAnimationEditor.dumpBase64Anim(anim))
end
if anim.graphic && anim.graphic != ""
graphicname = RTP.getImagePath("Graphics/Animations/" + anim.graphic)
@@ -626,13 +626,13 @@ def pbImportAllAnimations
pbSafeCopyFile(image, RTP.getImagePath("Graphics/Animations/" + File.basename(image)), "Graphics/Animations/" + File.basename(image))
end
Dir.glob(folder + "/*.anm") do |f|
textdata = loadBase64Anim(IO.read(f)) rescue nil
textdata = BattleAnimationEditor.loadBase64Anim(IO.read(f)) rescue nil
if textdata.is_a?(PBAnimation)
index = pbAllocateAnimation(animations, textdata.name)
missingFiles = []
textdata.name = File.basename(folder) if textdata.name == ""
textdata.id = -1 # This is not an RPG Maker XP animation
pbConvertAnimToNewFormat(textdata)
BattleAnimationEditor.pbConvertAnimToNewFormat(textdata)
if textdata.graphic && textdata.graphic != "" &&
!safeExists?(folder + "/" + textdata.graphic) &&
!FileTest.image_exist?("Graphics/Animations/" + textdata.graphic)