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
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 # class File
#=============================================================================== #===============================================================================

View File

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

View File

@@ -1,3 +1,6 @@
module BattleAnimationEditor
module_function
#=============================================================================== #===============================================================================
# Controls # Controls
#=============================================================================== #===============================================================================
@@ -32,7 +35,7 @@ class Window_Menu < Window_CommandPokemon
rc = Rect.new(0, 32 * (i - toprow), self.contents.width, 32) rc = Rect.new(0, 32 * (i - toprow), self.contents.width, 32)
rc.x += self.x + self.leftEdge rc.x += self.x + self.leftEdge
rc.y += self.y + self.topEdge 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 end
return -1 return -1
end end
@@ -60,71 +63,9 @@ module Clipboard
end 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 mousepos = Mouse.getMousePos
return -1 if !mousepos return -1 if !mousepos
@@ -262,14 +203,14 @@ class AnimationWindow < Sprite
swatchrects.push(Rect.new(arrowwidth + (i * 96) + self.x, self.y, 96, 96)) swatchrects.push(Rect.new(arrowwidth + (i * 96) + self.x, self.y, 96, 96))
end end
NUMFRAMES.times do |i| 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 @selected = @start + i
@changed = true @changed = true
refresh refresh
return return
end end
# Left arrow # Left arrow
if left.contains(mousepos[0], mousepos[1]) if left.contains?(mousepos[0], mousepos[1])
if repeattime > 750 if repeattime > 750
@start -= 3 @start -= 3
else else
@@ -279,7 +220,7 @@ class AnimationWindow < Sprite
refresh refresh
end end
# Right arrow # Right arrow
if right.contains(mousepos[0], mousepos[1]) if right.contains?(mousepos[0], mousepos[1])
if repeattime > 750 if repeattime > 750
@start += 3 @start += 3
else else
@@ -785,6 +726,58 @@ class AnimationCanvas < Sprite
return false return false
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 updateInput def updateInput
cel = currentCel cel = currentCel
mousepos = Mouse.getMousePos mousepos = Mouse.getMousePos
@@ -840,7 +833,7 @@ class AnimationCanvas < Sprite
return return
end end
if Input.triggerex?(:P) || Input.repeatex?(:P) # Properties if Input.triggerex?(:P) || Input.repeatex?(:P) # Properties
pbCellProperties(self) BattleAnimationEditor.pbCellProperties(self)
@dirty[@currentcel] = true @dirty[@currentcel] = true
return return
end end
@@ -1016,3 +1009,4 @@ class AnimationNameWindow
def dispose; @window.dispose; end def dispose; @window.dispose; end
def disposed; @window.disposed?; end def disposed; @window.disposed?; end
end end
end

View File

@@ -1,3 +1,6 @@
module BattleAnimationEditor
module_function
#=============================================================================== #===============================================================================
# #
#=============================================================================== #===============================================================================
@@ -128,12 +131,12 @@ class Button < UIControl
rect = Rect.new(self.x + 1, self.y + 1, self.width - 2, self.height - 2) rect = Rect.new(self.x + 1, self.y + 1, self.width - 2, self.height - 2)
rect = toAbsoluteRect(rect) rect = toAbsoluteRect(rect)
if Input.trigger?(Input::MOUSELEFT) && if Input.trigger?(Input::MOUSELEFT) &&
rect.contains(mousepos[0], mousepos[1]) && !@captured rect.contains?(mousepos[0], mousepos[1]) && !@captured
@captured = true @captured = true
self.invalidate self.invalidate
end end
if Input.release?(Input::MOUSELEFT) && @captured 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 @captured = false
self.invalidate self.invalidate
end end
@@ -217,7 +220,6 @@ class Checkbox < Button
shadowtext(bitmap, x + 36, y, size, height, self.label, @disabled) shadowtext(bitmap, x + 36, y, size, height, self.label, @disabled)
# Draw outline # Draw outline
color = Color.new(120, 120, 120) 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, width - 2, 1, color)
bitmap.fill_rect(x + 1, y + 1, 1, height - 2, color) bitmap.fill_rect(x + 1, y + 1, 1, height - 2, color)
bitmap.fill_rect(x + 1, y + height - 2, width - 2, 1, color) bitmap.fill_rect(x + 1, y + height - 2, width - 2, 1, color)
@@ -421,7 +423,7 @@ class Slider < UIControl
oldvalue = self.curvalue oldvalue = self.curvalue
repeattime = Input.time?(Input::MOUSELEFT) / 1000 repeattime = Input.time?(Input::MOUSELEFT) / 1000
# Left arrow # Left arrow
if left.contains(mousepos[0], mousepos[1]) if left.contains?(mousepos[0], mousepos[1])
if repeattime > 3000 if repeattime > 3000
self.curvalue -= 10 self.curvalue -= 10
elsif repeattime > 1500 elsif repeattime > 1500
@@ -434,7 +436,7 @@ class Slider < UIControl
self.invalidate self.invalidate
end end
# Right arrow # Right arrow
if right.contains(mousepos[0], mousepos[1]) if right.contains?(mousepos[0], mousepos[1])
if repeattime > 3000 if repeattime > 3000
self.curvalue += 10 self.curvalue += 10
elsif repeattime > 1500 elsif repeattime > 1500
@@ -673,7 +675,7 @@ class TextSlider < UIControl
oldvalue = self.curvalue oldvalue = self.curvalue
repeattime = Input.time?(Input::MOUSELEFT) / 1000 repeattime = Input.time?(Input::MOUSELEFT) / 1000
# Left arrow # Left arrow
if left.contains(mousepos[0], mousepos[1]) if left.contains?(mousepos[0], mousepos[1])
if repeattime > 3000 if repeattime > 3000
self.curvalue -= 10 self.curvalue -= 10
elsif repeattime > 1500 elsif repeattime > 1500
@@ -685,7 +687,7 @@ class TextSlider < UIControl
self.invalidate self.invalidate
end end
# Right arrow # Right arrow
if right.contains(mousepos[0], mousepos[1]) if right.contains?(mousepos[0], mousepos[1])
if repeattime > 3000 if repeattime > 3000
self.curvalue += 10 self.curvalue += 10
elsif repeattime > 1500 elsif repeattime > 1500
@@ -862,7 +864,7 @@ class ControlWindow < SpriteWindow_Base
return false if i < 0 || i >= @controls.length return false if i < 0 || i >= @controls.length
rc = Rect.new(@controls[i].parentX, @controls[i].parentY, rc = Rect.new(@controls[i].parentX, @controls[i].parentY,
@controls[i].width, @controls[i].height) @controls[i].width, @controls[i].height)
return rc.contains(mousepos[0], mousepos[1]) return rc.contains?(mousepos[0], mousepos[1])
end end
def addControl(control) def addControl(control)
@@ -927,3 +929,4 @@ class ControlWindow < SpriteWindow_Base
return @controls[i].curvalue return @controls[i].curvalue
end end
end end
end

View File

@@ -1,3 +1,6 @@
module BattleAnimationEditor
module_function
#=============================================================================== #===============================================================================
# Paths and interpolation # Paths and interpolation
#=============================================================================== #===============================================================================
@@ -430,3 +433,4 @@ def pbDefinePath(canvas)
sliderwin2.dispose sliderwin2.dispose
return return
end end
end

View File

@@ -1,3 +1,6 @@
module BattleAnimationEditor
module_function
################################################################################ ################################################################################
# Importing and exporting # Importing and exporting
################################################################################ ################################################################################
@@ -141,3 +144,4 @@ def pbConvertAnimsToNewFormat
end end
pbMessage(_INTL("{1} animations converted to new format.", count)) pbMessage(_INTL("{1} animations converted to new format.", count))
end end
end

View File

@@ -1,3 +1,6 @@
module BattleAnimationEditor
module_function
#=============================================================================== #===============================================================================
# Mini battle scene # Mini battle scene
#=============================================================================== #===============================================================================
@@ -533,9 +536,8 @@ def pbSelectSE(canvas, audio)
Input.update Input.update
cmdwin.update cmdwin.update
maxsizewindow.update maxsizewindow.update
if maxsizewindow.changed?(3) && animfiles.length > 0 # Play Sound if maxsizewindow.changed?(3) && animfiles.length > 0 && filename != "" # Play Sound
fname = (cmdwin.index == 0) ? "Cries/000" : "Anim/" + filename pbSEPlay(RPG::AudioFile.new("Anim/" + filename, maxsizewindow.value(1), maxsizewindow.value(2)))
pbSEPlay(RPG::AudioFile.new(fname, maxsizewindow.value(1), maxsizewindow.value(2)))
end end
pbSEStop if maxsizewindow.changed?(4) && animfiles.length > 0 # Stop Sound pbSEStop if maxsizewindow.changed?(4) && animfiles.length > 0 # Stop Sound
if maxsizewindow.changed?(5) # OK if maxsizewindow.changed?(5) # OK
@@ -945,10 +947,11 @@ def pbAnimEditorHelpWindow
cmdwin.dispose cmdwin.dispose
end end
#=============================================================================== #=============================================================================
# Main # Main
#=============================================================================== #=============================================================================
def animationEditorMain(animation) def animationEditorMain(animation)
echoln animation.selected
viewport = Viewport.new(0, 0, Settings::SCREEN_WIDTH + 288, Settings::SCREEN_HEIGHT + 288) viewport = Viewport.new(0, 0, Settings::SCREEN_WIDTH + 288, Settings::SCREEN_HEIGHT + 288)
viewport.z = 99999 viewport.z = 99999
# Canvas # Canvas
@@ -1109,7 +1112,7 @@ def animationEditorMain(animation)
indexes = [2, 1, 3, 4] # Keeping backwards compatibility indexes = [2, 1, 3, 4] # Keeping backwards compatibility
positions.length.times do |i| positions.length.times do |i|
selected = "[ ]" 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]) positions[i] = sprintf("%s %s", selected, positions[i])
end end
pos = pbShowCommands(nil, positions, -1) pos = pbShowCommands(nil, positions, -1)
@@ -1149,6 +1152,7 @@ def animationEditorMain(animation)
viewport.dispose viewport.dispose
RPG::Cache.clear RPG::Cache.clear
end end
end
#=============================================================================== #===============================================================================
# Start # Start
@@ -1162,7 +1166,7 @@ def pbAnimationEditor
end end
Graphics.resize_screen(Settings::SCREEN_WIDTH + 288, Settings::SCREEN_HEIGHT + 288) Graphics.resize_screen(Settings::SCREEN_WIDTH + 288, Settings::SCREEN_HEIGHT + 288)
pbSetResizeFactor(1) pbSetResizeFactor(1)
animationEditorMain(animation) BattleAnimationEditor.animationEditorMain(animation)
Graphics.resize_screen(Settings::SCREEN_WIDTH, Settings::SCREEN_HEIGHT) Graphics.resize_screen(Settings::SCREEN_WIDTH, Settings::SCREEN_HEIGHT)
pbSetResizeFactor($PokemonSystem.screensize) pbSetResizeFactor($PokemonSystem.screensize)
$game_map&.autoplay $game_map&.autoplay

View File

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