Finished FPS agnosticism, removed particle engine

This commit is contained in:
Maruno17
2023-06-03 21:55:02 +01:00
parent 68de25562a
commit 1901675e33
39 changed files with 652 additions and 1504 deletions

View File

@@ -446,5 +446,5 @@ end
module Essentials module Essentials
VERSION = "20.1.dev" VERSION = "20.1.dev"
ERROR_TEXT = "" ERROR_TEXT = ""
MKXPZ_VERSION = "2.4.2/b0d8e0b" MKXPZ_VERSION = "2.4.2/ee8dc7e"
end end

View File

@@ -1,4 +1,5 @@
# Using mkxp-z v2.4.2/b0d8e0b - https://github.com/mkxp-z/mkxp-z/actions/runs/5033679007 # Using mkxp-z v2.4.2/ee8dc7e - built 2023-05-28
# https://github.com/mkxp-z/mkxp-z/actions/runs/5107184579
$VERBOSE = nil $VERBOSE = nil
Font.default_shadow = false if Font.respond_to?(:default_shadow) Font.default_shadow = false if Font.respond_to?(:default_shadow)
Graphics.frame_rate = 40 Graphics.frame_rate = 40

View File

@@ -389,3 +389,17 @@ end
def nil_or_empty?(string) def nil_or_empty?(string)
return string.nil? || !string.is_a?(String) || string.size == 0 return string.nil? || !string.is_a?(String) || string.size == 0
end end
#===============================================================================
# Linear interpolation between two values, given the duration of the change and
# either:
# - the time passed since the start of the change (delta), or
# - the start time of the change (delta) and the current time (now)
#===============================================================================
def lerp(start_val, end_val, duration, delta, now = nil)
return end_val if duration <= 0
delta = now - delta if now
return start_val if delta <= 0
return end_val if delta >= duration
return start_val + (end_val - start_val) * delta / duration.to_f
end

View File

@@ -260,100 +260,38 @@ module RPG
class Sprite < ::Sprite class Sprite < ::Sprite
def initialize(viewport = nil) def initialize(viewport = nil)
super(viewport) super(viewport)
@_whiten_duration = 0
@_appear_duration = 0
@_escape_duration = 0
@_collapse_duration = 0
@_damage_duration = 0
@_animation_duration = 0 @_animation_duration = 0
@_animation_frame = 0 @_animation_frame = 0
@_blink = false @animations = []
@animations = []
@loopAnimations = [] @loopAnimations = []
end end
def dispose def dispose
dispose_damage
dispose_animation dispose_animation
dispose_loop_animation dispose_loop_animation
super super
end end
def whiten def dispose_animation
self.blend_type = 0 @animations.each { |a| a&.dispose_animation }
self.color.set(255, 255, 255, 128) @animations.clear
self.opacity = 255
@_whiten_duration = 16
@_appear_duration = 0
@_escape_duration = 0
@_collapse_duration = 0
end end
def appear def dispose_loop_animation
self.blend_type = 0 @loopAnimations.each { |a| a&.dispose_loop_animation }
self.color.set(0, 0, 0, 0) @loopAnimations.clear
self.opacity = 0
@_appear_duration = 16
@_whiten_duration = 0
@_escape_duration = 0
@_collapse_duration = 0
end end
def escape def x=(x)
self.blend_type = 0 @animations.each { |a| a.x = x if a }
self.color.set(0, 0, 0, 0) @loopAnimations.each { |a| a.x = x if a }
self.opacity = 255 super
@_escape_duration = 32
@_whiten_duration = 0
@_appear_duration = 0
@_collapse_duration = 0
end end
def collapse def y=(y)
self.blend_type = 1 @animations.each { |a| a.y = y if a }
self.color.set(255, 64, 64, 255) @loopAnimations.each { |a| a.y = y if a }
self.opacity = 255 super
@_collapse_duration = 48
@_whiten_duration = 0
@_appear_duration = 0
@_escape_duration = 0
end
def damage(value, critical)
dispose_damage
damage_string = (value.is_a?(Numeric)) ? value.abs.to_s : value.to_s
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) && 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 end
def pushAnimation(array, anim) def pushAnimation(array, anim)
@@ -377,97 +315,11 @@ module RPG
pushAnimation(@loopAnimations, anim) pushAnimation(@loopAnimations, anim)
end end
def dispose_damage
return if @_damage_sprite.nil?
@_damage_sprite.bitmap.dispose
@_damage_sprite.dispose
@_damage_sprite = nil
@_damage_duration = 0
end
def dispose_animation
@animations.each { |a| a&.dispose_animation }
@animations.clear
end
def dispose_loop_animation
@loopAnimations.each { |a| a&.dispose_loop_animation }
@loopAnimations.clear
end
def blink_on
return if @_blink
@_blink = true
@_blink_count = 0
end
def blink_off
return unless @_blink
@_blink = false
self.color.set(0, 0, 0, 0)
end
def blink?
return @_blink
end
def effect? def effect?
return true if @_whiten_duration > 0
return true if @_appear_duration > 0
return true if @_escape_duration > 0
return true if @_collapse_duration > 0
return true if @_damage_duration > 0
@animations.each { |a| return true if a.effect? } @animations.each { |a| return true if a.effect? }
return false return false
end 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)
dispose_damage if @_damage_duration == 0
end
@animations.each { |a| a.update }
@loopAnimations.each { |a| a.update }
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
SpriteAnimation.clear
end
def update_animation def update_animation
@animations.each { |a| a.update_animation if a&.active? } @animations.each { |a| a.update_animation if a&.active? }
end end
@@ -476,16 +328,11 @@ module RPG
@loopAnimations.each { |a| a.update_loop_animation if a&.active? } @loopAnimations.each { |a| a.update_loop_animation if a&.active? }
end end
def x=(x) def update
@animations.each { |a| a.x = x if a }
@loopAnimations.each { |a| a.x = x if a }
super
end
def y=(y)
@animations.each { |a| a.y = y if a }
@loopAnimations.each { |a| a.y = y if a }
super super
@animations.each { |a| a.update }
@loopAnimations.each { |a| a.update }
SpriteAnimation.clear
end end
end end
end end

View File

@@ -1,186 +0,0 @@
#===============================================================================
# Linear interpolation between two values, given the duration of the change and
# either:
# - the time passed since the start of the change (delta), or
# - the start time of the change (delta) and the current time (now)
#===============================================================================
def lerp(start_val, end_val, duration, delta, now = nil)
delta = now - delta if now
return start_val if delta <= 0
return end_val if delta >= duration
return start_val + (end_val - start_val) * delta / duration.to_f
end
#===============================================================================
#
#===============================================================================
class PointInterpolator
attr_reader :x
attr_reader :y
def initialize(oldx, oldy, newx, newy, frames)
restart(oldx, oldy, newx, newy, frames)
end
def restart(oldx, oldy, newx, newy, frames)
@oldx = oldx
@oldy = oldy
@newx = newx
@newy = newy
@frames = frames
@curframe = 0
@x = oldx
@y = oldy
end
def done?
@curframe > @frames
end
def update
return if done?
t = @curframe.to_f / @frames
rx1 = @oldx
rx2 = @newx
@x = rx1 + (t * (rx2 - rx1))
ry1 = @oldy
ry2 = @newy
@y = ry1 + (t * (ry2 - ry1))
@curframe += 1
end
end
#===============================================================================
#
#===============================================================================
class RectInterpolator
def initialize(oldrect, newrect, frames)
restart(oldrect, newrect, frames)
end
def restart(oldrect, newrect, frames)
@oldrect = oldrect
@newrect = newrect
@frames = [frames, 1].max
@curframe = 0
@rect = oldrect.clone
end
def set(rect)
rect.set(@rect.x, @rect.y, @rect.width, @rect.height)
end
def done?
@curframe > @frames
end
def update
return if done?
t = @curframe.to_f / @frames
x1 = @oldrect.x
x2 = @newrect.x
x = x1 + (t * (x2 - x1))
y1 = @oldrect.y
y2 = @newrect.y
y = y1 + (t * (y2 - y1))
rx1 = @oldrect.x + @oldrect.width
rx2 = @newrect.x + @newrect.width
rx = rx1 + (t * (rx2 - rx1))
ry1 = @oldrect.y + @oldrect.height
ry2 = @newrect.y + @newrect.height
ry = ry1 + (t * (ry2 - ry1))
minx = x < rx ? x : rx
maxx = x > rx ? x : rx
miny = y < ry ? y : ry
maxy = y > ry ? y : ry
@rect.set(minx, miny, maxx - minx, maxy - miny)
@curframe += 1
end
end
#===============================================================================
#
#===============================================================================
class SpriteInterpolator
X = 1
Y = 2
ZOOM_X = 3
ZOOM_Y = 4
COLOR = 5
OPACITY = 6
def initialize
@tweening = false
@tweensteps = []
@sprite = nil
@frames = 0
@step = 0
end
def tweening?
return @tweening
end
def tween(sprite, items, frames)
@tweensteps = []
if sprite && !sprite.disposed? && frames > 0
@frames = frames
@step = 0
@sprite = sprite
items.each do |item|
case item[0]
when X
@tweensteps[item[0]] = [sprite.x, item[1] - sprite.x]
when Y
@tweensteps[item[0]] = [sprite.y, item[1] - sprite.y]
when ZOOM_X
@tweensteps[item[0]] = [sprite.zoom_x, item[1] - sprite.zoom_x]
when ZOOM_Y
@tweensteps[item[0]] = [sprite.zoom_y, item[1] - sprite.zoom_y]
when COLOR
@tweensteps[item[0]] = [sprite.color.clone,
Color.new(item[1].red - sprite.color.red,
item[1].green - sprite.color.green,
item[1].blue - sprite.color.blue,
item[1].alpha - sprite.color.alpha)]
when OPACITY
@tweensteps[item[0]] = [sprite.opacity, item[1] - sprite.opacity]
end
end
@tweening = true
end
end
def update
if @tweening
t = @step.to_f / @frames
@tweensteps.length.times do |i|
item = @tweensteps[i]
next if !item
case i
when X
@sprite.x = item[0] + (item[1] * t)
when Y
@sprite.y = item[0] + (item[1] * t)
when ZOOM_X
@sprite.zoom_x = item[0] + (item[1] * t)
when ZOOM_Y
@sprite.zoom_y = item[0] + (item[1] * t)
when COLOR
@sprite.color = Color.new(item[0].red + (item[1].red * t),
item[0].green + (item[1].green * t),
item[0].blue + (item[1].blue * t),
item[0].alpha + (item[1].alpha * t))
when OPACITY
@sprite.opacity = item[0] + (item[1] * t)
end
end
@step += 1
if @step == @frames
@step = 0
@frames = 0
@tweening = false
end
end
end
end

View File

@@ -84,6 +84,7 @@ class Interpreter
def update def update
@loop_count = 0 @loop_count = 0
loop do loop do
# TODO: Possibly not needed?
@loop_count += 1 @loop_count += 1
if @loop_count > 100 # Call Graphics.update for freeze prevention if @loop_count > 100 # Call Graphics.update for freeze prevention
Graphics.update Graphics.update

View File

@@ -16,8 +16,6 @@ class Game_Screen
def initialize def initialize
@brightness = 255 @brightness = 255
@fadeout_duration = 0
@fadein_duration = 0
@tone = Tone.new(0, 0, 0, 0) @tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0) @tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0 @tone_duration = 0
@@ -72,16 +70,6 @@ class Game_Screen
end end
def update def update
if @fadeout_duration && @fadeout_duration >= 1
d = @fadeout_duration
@brightness = (@brightness * (d - 1)) / d
@fadeout_duration -= 1
end
if @fadein_duration && @fadein_duration >= 1
d = @fadein_duration
@brightness = ((@brightness * (d - 1)) + 255) / d
@fadein_duration -= 1
end
now = $stats.play_time now = $stats.play_time
if @tone_timer_start if @tone_timer_start
@tone.red = lerp(@tone_initial.red, @tone_target.red, @tone_duration, @tone_timer_start, now) @tone.red = lerp(@tone_initial.red, @tone_target.red, @tone_duration, @tone_timer_start, now)

View File

@@ -437,6 +437,8 @@ class Game_Map
end end
def update def update
uptime_now = System.uptime
play_now = $stats.play_time
# Refresh maps if necessary # Refresh maps if necessary
if $map_factory if $map_factory
$map_factory.maps.each { |i| i.refresh if i.need_refresh } $map_factory.maps.each { |i| i.refresh if i.need_refresh }
@@ -445,13 +447,13 @@ class Game_Map
# If scrolling # If scrolling
if (@scroll_distance_x || 0) != 0 if (@scroll_distance_x || 0) != 0
duration = @scroll_distance_x.abs * TILE_WIDTH.to_f / (10 * (2**@scroll_speed)) duration = @scroll_distance_x.abs * TILE_WIDTH.to_f / (10 * (2**@scroll_speed))
scroll_offset = lerp(0, @scroll_distance_x, duration, @scroll_timer_start, System.uptime) scroll_offset = lerp(0, @scroll_distance_x, duration, @scroll_timer_start, uptime_now)
self.display_x = @scroll_start_x + scroll_offset * REAL_RES_X self.display_x = @scroll_start_x + scroll_offset * REAL_RES_X
@scroll_distance_x = 0 if scroll_offset == @scroll_distance_x @scroll_distance_x = 0 if scroll_offset == @scroll_distance_x
end end
if (@scroll_distance_y || 0) != 0 if (@scroll_distance_y || 0) != 0
duration = @scroll_distance_y.abs * TILE_HEIGHT.to_f / (10 * (2**@scroll_speed)) duration = @scroll_distance_y.abs * TILE_HEIGHT.to_f / (10 * (2**@scroll_speed))
scroll_offset = lerp(0, @scroll_distance_y, duration, @scroll_timer_start, System.uptime) scroll_offset = lerp(0, @scroll_distance_y, duration, @scroll_timer_start, uptime_now)
self.display_y = @scroll_start_y + scroll_offset * REAL_RES_Y self.display_y = @scroll_start_y + scroll_offset * REAL_RES_Y
@scroll_distance_y = 0 if scroll_offset == @scroll_distance_y @scroll_distance_y = 0 if scroll_offset == @scroll_distance_y
end end
@@ -462,22 +464,24 @@ class Game_Map
# Update common events # Update common events
@common_events.each_value { |common_event| common_event.update } @common_events.each_value { |common_event| common_event.update }
# Update fog # Update fog
now = $stats.play_time @fog_scroll_last_update_timer = uptime_now if !@fog_scroll_last_update_timer
@fog_ox -= @fog_sx / 8.0 scroll_mult = (uptime_now - @fog_scroll_last_update_timer) * 5
@fog_oy -= @fog_sy / 8.0 @fog_ox -= @fog_sx * scroll_mult
@fog_oy -= @fog_sy * scroll_mult
@fog_scroll_last_update_timer = uptime_now
if @fog_tone_timer_start if @fog_tone_timer_start
@fog_tone.red = lerp(@fog_tone_initial.red, @fog_tone_target.red, @fog_tone_duration, @fog_tone_timer_start, now) @fog_tone.red = lerp(@fog_tone_initial.red, @fog_tone_target.red, @fog_tone_duration, @fog_tone_timer_start, play_now)
@fog_tone.green = lerp(@fog_tone_initial.green, @fog_tone_target.green, @fog_tone_duration, @fog_tone_timer_start, now) @fog_tone.green = lerp(@fog_tone_initial.green, @fog_tone_target.green, @fog_tone_duration, @fog_tone_timer_start, play_now)
@fog_tone.blue = lerp(@fog_tone_initial.blue, @fog_tone_target.blue, @fog_tone_duration, @fog_tone_timer_start, now) @fog_tone.blue = lerp(@fog_tone_initial.blue, @fog_tone_target.blue, @fog_tone_duration, @fog_tone_timer_start, play_now)
@fog_tone.gray = lerp(@fog_tone_initial.gray, @fog_tone_target.gray, @fog_tone_duration, @fog_tone_timer_start, now) @fog_tone.gray = lerp(@fog_tone_initial.gray, @fog_tone_target.gray, @fog_tone_duration, @fog_tone_timer_start, play_now)
if now - @fog_tone_timer_start >= @fog_tone_duration if play_now - @fog_tone_timer_start >= @fog_tone_duration
@fog_tone_initial = nil @fog_tone_initial = nil
@fog_tone_timer_start = nil @fog_tone_timer_start = nil
end end
end end
if @fog_opacity_timer_start if @fog_opacity_timer_start
@fog_opacity = lerp(@fog_opacity_initial, @fog_opacity_target, @fog_opacity_duration, @fog_opacity_timer_start, now) @fog_opacity = lerp(@fog_opacity_initial, @fog_opacity_target, @fog_opacity_duration, @fog_opacity_timer_start, play_now)
if now - @fog_opacity_timer_start >= @fog_opacity_duration if play_now - @fog_opacity_timer_start >= @fog_opacity_duration
@fog_opacity_initial = nil @fog_opacity_initial = nil
@fog_opacity_timer_start = nil @fog_opacity_timer_start = nil
end end

View File

@@ -1,605 +0,0 @@
#===============================================================================
# Particle Engine, Peter O., 2007-11-03
# Based on version 2 by Near Fantastica, 04.01.06
# In turn based on the Particle Engine designed by PinkMan
#===============================================================================
class Particle_Engine
def initialize(viewport = nil, map = nil)
@map = (map) ? map : $game_map
@viewport = viewport
@effect = []
@disposed = false
@firsttime = true
@effects = {
# PinkMan's Effects
"fire" => Particle_Engine::Fire,
"smoke" => Particle_Engine::Smoke,
"teleport" => Particle_Engine::Teleport,
"spirit" => Particle_Engine::Spirit,
"explosion" => Particle_Engine::Explosion,
"aura" => Particle_Engine::Aura,
# BlueScope's Effects
"soot" => Particle_Engine::Soot,
"sootsmoke" => Particle_Engine::SootSmoke,
"rocket" => Particle_Engine::Rocket,
"fixteleport" => Particle_Engine::FixedTeleport,
"smokescreen" => Particle_Engine::Smokescreen,
"flare" => Particle_Engine::Flare,
"splash" => Particle_Engine::Splash,
# By Peter O.
"starteleport" => Particle_Engine::StarTeleport
}
end
def dispose
return if disposed?
@effect.each do |particle|
next if particle.nil?
particle.dispose
end
@effect.clear
@map = nil
@disposed = true
end
def disposed?
return @disposed
end
def add_effect(event)
@effect[event.id] = pbParticleEffect(event)
end
def remove_effect(event)
return if @effect[event.id].nil?
@effect[event.id].dispose
@effect.delete_at(event.id)
end
def realloc_effect(event, particle)
type = pbEventCommentInput(event, 1, "Particle Engine Type")
if type.nil?
particle&.dispose
return nil
end
type = type[0].downcase
cls = @effects[type]
if cls.nil?
particle&.dispose
return nil
end
if !particle || !particle.is_a?(cls)
particle&.dispose
particle = cls.new(event, @viewport)
end
return particle
end
def pbParticleEffect(event)
return realloc_effect(event, nil)
end
def update
if @firsttime
@firsttime = false
@map.events.each_value do |event|
remove_effect(event)
add_effect(event)
end
end
@effect.each_with_index do |particle, i|
next if particle.nil?
if particle.event.pe_refresh
event = particle.event
event.pe_refresh = false
particle = realloc_effect(event, particle)
@effect[i] = particle
end
particle&.update
end
end
end
#===============================================================================
#
#===============================================================================
class ParticleEffect
attr_accessor :x, :y, :z
def initialize
@x = 0
@y = 0
@z = 0
end
def update; end
def dispose; end
end
#===============================================================================
#
#===============================================================================
class ParticleSprite
attr_accessor :x, :y, :z, :ox, :oy, :opacity, :blend_type
attr_reader :bitmap
def initialize(viewport)
@viewport = viewport
@sprite = nil
@x = 0
@y = 0
@z = 0
@ox = 0
@oy = 0
@opacity = 255
@bitmap = nil
@blend_type = 0
@minleft = 0
@mintop = 0
end
def dispose
@sprite&.dispose
end
def bitmap=(value)
@bitmap = value
if value
@minleft = -value.width
@mintop = -value.height
else
@minleft = 0
@mintop = 0
end
end
def update
w = Graphics.width
h = Graphics.height
if !@sprite && @x >= @minleft && @y >= @mintop && @x < w && @y < h
@sprite = Sprite.new(@viewport)
elsif @sprite && (@x < @minleft || @y < @mintop || @x >= w || @y >= h)
@sprite.dispose
@sprite = nil
end
if @sprite
@sprite.x = @x if @sprite.x != @x
@sprite.x -= @ox
@sprite.y = @y if @sprite.y != @y
@sprite.y -= @oy
@sprite.z = @z if @sprite.z != @z
@sprite.opacity = @opacity if @sprite.opacity != @opacity
@sprite.blend_type = @blend_type if @sprite.blend_type != @blend_type
@sprite.bitmap = @bitmap if @sprite.bitmap != @bitmap
end
end
end
#===============================================================================
#
#===============================================================================
class ParticleEffect_Event < ParticleEffect
attr_accessor :event
def initialize(event, viewport = nil)
@event = event
@viewport = viewport
@particles = []
@bitmaps = {}
end
def setParameters(params)
@randomhue, @leftright, @fade,
@maxparticless, @hue, @slowdown,
@ytop, @ybottom, @xleft, @xright,
@xgravity, @ygravity, @xoffset, @yoffset,
@opacityvar, @originalopacity = params
end
def loadBitmap(filename, hue)
key = [filename, hue]
bitmap = @bitmaps[key]
if !bitmap || bitmap.disposed?
bitmap = AnimatedBitmap.new("Graphics/Fogs/" + filename, hue).deanimate
@bitmaps[key] = bitmap
end
return bitmap
end
def initParticles(filename, opacity, zOffset = 0, blendtype = 1)
@particles = []
@particlex = []
@particley = []
@opacity = []
@startingx = self.x + @xoffset
@startingy = self.y + @yoffset
@screen_x = self.x
@screen_y = self.y
@real_x = @event.real_x
@real_y = @event.real_y
@filename = filename
@zoffset = zOffset
@bmwidth = 32
@bmheight = 32
@maxparticless.times do |i|
@particlex[i] = -@xoffset
@particley[i] = -@yoffset
@particles[i] = ParticleSprite.new(@viewport)
@particles[i].bitmap = loadBitmap(filename, @hue) if filename
if i == 0 && @particles[i].bitmap
@bmwidth = @particles[i].bitmap.width
@bmheight = @particles[i].bitmap.height
end
@particles[i].blend_type = blendtype
@particles[i].y = @startingy
@particles[i].x = @startingx
@particles[i].z = self.z + zOffset
@opacity[i] = rand(opacity / 4)
@particles[i].opacity = @opacity[i]
@particles[i].update
end
end
def x; return ScreenPosHelper.pbScreenX(@event); end
def y; return ScreenPosHelper.pbScreenY(@event); end
def z; return ScreenPosHelper.pbScreenZ(@event); end
def update
if @viewport &&
(@viewport.rect.x >= Graphics.width ||
@viewport.rect.y >= Graphics.height)
return
end
selfX = self.x
selfY = self.y
selfZ = self.z
newRealX = @event.real_x
newRealY = @event.real_y
@startingx = selfX + @xoffset
@startingy = selfY + @yoffset
@__offsetx = (@real_x == newRealX) ? 0 : selfX - @screen_x
@__offsety = (@real_y == newRealY) ? 0 : selfY - @screen_y
@screen_x = selfX
@screen_y = selfY
@real_x = newRealX
@real_y = newRealY
if @opacityvar > 0 && @viewport
opac = 255.0 / @opacityvar
minX = (opac * (-@xgravity.to_f / @slowdown).floor) + @startingx
maxX = (opac * (@xgravity.to_f / @slowdown).floor) + @startingx
minY = (opac * (-@ygravity.to_f / @slowdown).floor) + @startingy
maxY = @startingy
minX -= @bmwidth
minY -= @bmheight
maxX += @bmwidth
maxY += @bmheight
if maxX < 0 || maxY < 0 || minX >= Graphics.width || minY >= Graphics.height
# echo "skipped"
return
end
end
particleZ = selfZ + @zoffset
@maxparticless.times do |i|
@particles[i].z = particleZ
if @particles[i].y <= @ytop
@particles[i].y = @startingy + @yoffset
@particles[i].x = @startingx + @xoffset
@particlex[i] = 0.0
@particley[i] = 0.0
end
if @particles[i].x <= @xleft
@particles[i].y = @startingy + @yoffset
@particles[i].x = @startingx + @xoffset
@particlex[i] = 0.0
@particley[i] = 0.0
end
if @particles[i].y >= @ybottom
@particles[i].y = @startingy + @yoffset
@particles[i].x = @startingx + @xoffset
@particlex[i] = 0.0
@particley[i] = 0.0
end
if @particles[i].x >= @xright
@particles[i].y = @startingy + @yoffset
@particles[i].x = @startingx + @xoffset
@particlex[i] = 0.0
@particley[i] = 0.0
end
if @fade == 0
if @opacity[i] <= 0
@opacity[i] = @originalopacity
@particles[i].y = @startingy + @yoffset
@particles[i].x = @startingx + @xoffset
@particlex[i] = 0.0
@particley[i] = 0.0
end
elsif @opacity[i] <= 0
@opacity[i] = 250
@particles[i].y = @startingy + @yoffset
@particles[i].x = @startingx + @xoffset
@particlex[i] = 0.0
@particley[i] = 0.0
end
calcParticlePos(i)
if @randomhue == 1
@hue += 0.5
@hue = 0 if @hue >= 360
@particles[i].bitmap = loadBitmap(@filename, @hue) if @filename
end
@opacity[i] = @opacity[i] - rand(@opacityvar)
@particles[i].opacity = @opacity[i]
@particles[i].update
end
end
def calcParticlePos(i)
@leftright = rand(2)
if @leftright == 1
xo = -@xgravity.to_f / @slowdown
else
xo = @xgravity.to_f / @slowdown
end
yo = -@ygravity.to_f / @slowdown
@particlex[i] += xo
@particley[i] += yo
@particlex[i] -= @__offsetx
@particley[i] -= @__offsety
@particlex[i] = @particlex[i].floor
@particley[i] = @particley[i].floor
@particles[i].x = @particlex[i] + @startingx + @xoffset
@particles[i].y = @particley[i] + @startingy + @yoffset
end
def dispose
@particles.each do |particle|
particle.dispose
end
@bitmaps.each_value do |bitmap|
bitmap.dispose
end
@particles.clear
@bitmaps.clear
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Fire < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 1, 20, 40, 0.5, -64,
Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -13, 30, 0])
initParticles("particle", 250)
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Smoke < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 0, 80, 20, 0.5, -64,
Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -15, 5, 80])
initParticles("smoke", 250)
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Teleport < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([1, 1, 1, 10, rand(360), 1, -64,
Graphics.height, -64, Graphics.width, 0, 3, -8, -15, 20, 0])
initParticles("wideportal", 250)
@maxparticless.times do |i|
@particles[i].ox = 16
@particles[i].oy = 16
end
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Spirit < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([1, 0, 1, 20, rand(360), 0.5, -64,
Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -13, 30, 0])
initParticles("particle", 250)
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Explosion < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 1, 20, 0, 0.5, -64,
Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -13, 30, 0])
initParticles("explosion", 250)
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Aura < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 1, 20, 0, 1, -64,
Graphics.height, -64, Graphics.width, 2, 2, -5, -13, 30, 0])
initParticles("particle", 250)
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Soot < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 0, 20, 0, 0.5, -64,
Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -15, 5, 80])
initParticles("smoke", 100, 0, 2)
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::SootSmoke < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 0, 30, 0, 0.5, -64,
Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -15, 5, 80])
initParticles("smoke", 100, 0)
@maxparticless.times do |i|
@particles[i].blend_type = rand(6) < 3 ? 1 : 2
end
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Rocket < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 0, 60, 0, 0.5, -64,
Graphics.height, -64, Graphics.width, 0.5, 0, -5, -15, 5, 80])
initParticles("smoke", 100, -1)
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::FixedTeleport < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([1, 0, 1, 10, rand(360), 1,
-Graphics.height, Graphics.height, 0, Graphics.width, 0, 3, -8, -15, 20, 0])
initParticles("wideportal", 250)
@maxparticless.times do |i|
@particles[i].ox = 16
@particles[i].oy = 16
end
end
end
#===============================================================================
# By Peter O.
#===============================================================================
class Particle_Engine::StarTeleport < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 1, 10, 0, 1,
-Graphics.height, Graphics.height, 0, Graphics.width, 0, 3, -8, -15, 10, 0])
initParticles("star", 250)
@maxparticless.times do |i|
@particles[i].ox = 48
@particles[i].oy = 48
end
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Smokescreen < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 0, 250, 0, 0.2, -64,
Graphics.height, -64, Graphics.width, 0.8, 0.8, -5, -15, 5, 80])
initParticles(nil, 100)
@maxparticless.times do |i|
rnd = rand(3)
@opacity[i] = (rnd == 0) ? 1 : 100
filename = (rnd == 0) ? "explosionsmoke" : "smoke"
@particles[i].bitmap = loadBitmap(filename, @hue)
end
end
def calcParticlePos(i)
if @randomhue == 1
filename = (rand(3) == 0) ? "explosionsmoke" : "smoke"
@particles[i].bitmap = loadBitmap(filename, @hue)
end
multiple = 1.7
xgrav = @xgravity * multiple / @slowdown
xgrav = -xgrav if rand(2) == 1
ygrav = @ygravity * multiple / @slowdown
ygrav = -ygrav if rand(2) == 1
@particlex[i] += xgrav
@particley[i] += ygrav
@particlex[i] -= @__offsetx
@particley[i] -= @__offsety
@particlex[i] = @particlex[i].floor
@particley[i] = @particley[i].floor
@particles[i].x = @particlex[i] + @startingx + @xoffset
@particles[i].y = @particley[i] + @startingy + @yoffset
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Flare < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 1, 30, 10, 1, -64,
Graphics.height, -64, Graphics.width, 2, 2, -5, -12, 30, 0])
initParticles("particle", 255)
end
end
#===============================================================================
#
#===============================================================================
class Particle_Engine::Splash < ParticleEffect_Event
def initialize(event, viewport)
super
setParameters([0, 0, 1, 30, 255, 1, -64,
Graphics.height, -64, Graphics.width, 4, 2, -5, -12, 30, 0])
initParticles("smoke", 50)
end
def update
super
@maxparticless.times do |i|
@particles[i].opacity = 50
@particles[i].update
end
end
end
#===============================================================================
#
#===============================================================================
class Game_Event < Game_Character
attr_accessor :pe_refresh
alias nf_particles_game_map_initialize initialize unless private_method_defined?(:nf_particles_game_map_initialize)
def initialize(map_id, event, map = nil)
@pe_refresh = false
begin
nf_particles_game_map_initialize(map_id, event, map)
rescue ArgumentError
nf_particles_game_map_initialize(map_id, event)
end
end
alias nf_particles_game_map_refresh refresh unless method_defined?(:nf_particles_game_map_refresh)
def refresh
nf_particles_game_map_refresh
@pe_refresh = true
end
end

View File

@@ -99,6 +99,27 @@ class PictureEx
attr_reader :cropBottom # crops sprite to above this y-coordinate attr_reader :cropBottom # crops sprite to above this y-coordinate
attr_reader :frameUpdates # Array of processes updated in a frame attr_reader :frameUpdates # Array of processes updated in a frame
def move_processes
ret = []
@processes.each do |p|
next if ![Processes::XY, Processes::DELTA_XY].include?(p[0])
pro = []
pro.push(p[0] == Processes::XY ? "XY" : "DELTA")
if p[1] == 0 && p[2] == 0
pro.push("start " + p[7].to_i.to_s + ", " + p[8].to_i.to_s)
else
pro.push("for " + p[2].to_s) if p[2] > 0
if p[0] == Processes::XY
pro.push("go to " + p[7].to_i.to_s + ", " + p[8].to_i.to_s)
else
pro.push("move by " + p[7].to_i.to_s + ", " + p[8].to_i.to_s)
end
end
ret.push(pro)
end
return ret
end
def initialize(z) def initialize(z)
# process: [type, delay, total_duration, frame_counter, cb, etc.] # process: [type, delay, total_duration, frame_counter, cb, etc.]
@processes = [] @processes = []
@@ -338,8 +359,9 @@ class PictureEx
end end
def update def update
@timer_start = System.uptime if !@timer_start time_now = System.uptime
this_frame = ((System.uptime - @timer_start) * 20).to_i # 20 frames per second @timer_start = time_now if !@timer_start
this_frame = ((time_now - @timer_start) * 20).to_i # 20 frames per second
procEnded = false procEnded = false
@frameUpdates.clear @frameUpdates.clear
@processes.each_with_index do |process, i| @processes.each_with_index do |process, i|
@@ -379,35 +401,35 @@ class PictureEx
end end
# Update process # Update process
@frameUpdates.push(process[0]) if !@frameUpdates.include?(process[0]) @frameUpdates.push(process[0]) if !@frameUpdates.include?(process[0])
start_time = @timer_start + process[1] / 20.0 start_time = @timer_start + (process[1] / 20.0)
duration = process[2] / 20.0 duration = process[2] / 20.0
case process[0] case process[0]
when Processes::XY, Processes::DELTA_XY when Processes::XY, Processes::DELTA_XY
@x = lerp(process[5], process[7], duration, start_time, System.uptime) @x = lerp(process[5], process[7], duration, start_time, time_now)
@y = lerp(process[6], process[8], duration, start_time, System.uptime) @y = lerp(process[6], process[8], duration, start_time, time_now)
when Processes::CURVE when Processes::CURVE
@x, @y = getCubicPoint2(process[5], (System.uptime - start_time) / duration) @x, @y = getCubicPoint2(process[5], (time_now - start_time) / duration)
when Processes::Z when Processes::Z
@z = lerp(process[5], process[6], duration, start_time, System.uptime) @z = lerp(process[5], process[6], duration, start_time, time_now)
when Processes::ZOOM when Processes::ZOOM
@zoom_x = lerp(process[5], process[7], duration, start_time, System.uptime) @zoom_x = lerp(process[5], process[7], duration, start_time, time_now)
@zoom_y = lerp(process[6], process[8], duration, start_time, System.uptime) @zoom_y = lerp(process[6], process[8], duration, start_time, time_now)
when Processes::ANGLE when Processes::ANGLE
@angle = lerp(process[5], process[6], duration, start_time, System.uptime) @angle = lerp(process[5], process[6], duration, start_time, time_now)
when Processes::TONE when Processes::TONE
@tone.red = lerp(process[5].red, process[6].red, duration, start_time, System.uptime) @tone.red = lerp(process[5].red, process[6].red, duration, start_time, time_now)
@tone.green = lerp(process[5].green, process[6].green, duration, start_time, System.uptime) @tone.green = lerp(process[5].green, process[6].green, duration, start_time, time_now)
@tone.blue = lerp(process[5].blue, process[6].blue, duration, start_time, System.uptime) @tone.blue = lerp(process[5].blue, process[6].blue, duration, start_time, time_now)
@tone.gray = lerp(process[5].gray, process[6].gray, duration, start_time, System.uptime) @tone.gray = lerp(process[5].gray, process[6].gray, duration, start_time, time_now)
when Processes::COLOR when Processes::COLOR
@color.red = lerp(process[5].red, process[6].red, duration, start_time, System.uptime) @color.red = lerp(process[5].red, process[6].red, duration, start_time, time_now)
@color.green = lerp(process[5].green, process[6].green, duration, start_time, System.uptime) @color.green = lerp(process[5].green, process[6].green, duration, start_time, time_now)
@color.blue = lerp(process[5].blue, process[6].blue, duration, start_time, System.uptime) @color.blue = lerp(process[5].blue, process[6].blue, duration, start_time, time_now)
@color.alpha = lerp(process[5].alpha, process[6].alpha, duration, start_time, System.uptime) @color.alpha = lerp(process[5].alpha, process[6].alpha, duration, start_time, time_now)
when Processes::HUE when Processes::HUE
@hue = lerp(process[5], process[6], duration, start_time, System.uptime) @hue = lerp(process[5], process[6], duration, start_time, time_now)
when Processes::OPACITY when Processes::OPACITY
@opacity = lerp(process[5], process[6], duration, start_time, System.uptime) @opacity = lerp(process[5], process[6], duration, start_time, time_now)
when Processes::VISIBLE when Processes::VISIBLE
@visible = process[5] @visible = process[5]
when Processes::BLEND_TYPE when Processes::BLEND_TYPE
@@ -439,7 +461,7 @@ class PictureEx
# Add the constant rotation speed # Add the constant rotation speed
if @rotate_speed != 0 if @rotate_speed != 0
@frameUpdates.push(Processes::ANGLE) if !@frameUpdates.include?(Processes::ANGLE) @frameUpdates.push(Processes::ANGLE) if !@frameUpdates.include?(Processes::ANGLE)
@auto_angle = @rotate_speed * (System.uptime - @timer_start) @auto_angle = @rotate_speed * (time_now - @timer_start)
while @auto_angle < 0 while @auto_angle < 0
@auto_angle += 360 @auto_angle += 360
end end

View File

@@ -538,7 +538,7 @@ class TilemapRenderer
if @old_color != @color if @old_color != @color
@tiles.each do |col| @tiles.each do |col|
col.each do |coord| col.each do |coord|
coord.each { |tile| tile.color = @tone } coord.each { |tile| tile.color = @color }
end end
end end
@old_color = @color.clone @old_color = @color.clone

View File

@@ -24,8 +24,7 @@ module MessageConfig
# 2 = Pause cursor is displayed at lower middle side # 2 = Pause cursor is displayed at lower middle side
CURSOR_POSITION = 1 CURSOR_POSITION = 1
WINDOW_OPACITY = 255 WINDOW_OPACITY = 255
TEXT_SPEED = nil # can be positive to wait frames, or negative TEXT_SPEED = nil # Time in seconds between two characters
# to show multiple characters in a single frame
@@systemFrame = nil @@systemFrame = nil
@@defaultTextSkin = nil @@defaultTextSkin = nil
@@textSpeed = nil @@textSpeed = nil
@@ -100,13 +99,16 @@ module MessageConfig
@@textSpeed = value @@textSpeed = value
end end
# Text speed is the delay in seconds between two adjacent characters being
# shown.
def self.pbSettingToTextSpeed(speed) def self.pbSettingToTextSpeed(speed)
case speed case speed
when 0 then return 2 when 0 then return 4 / 80.0 # Slow
when 1 then return 1 when 1 then return 2 / 80.0 # Medium
when 2 then return -2 when 2 then return 1 / 80.0 # Fast
when 3 then return 0 # Instant
end end
return TEXT_SPEED || 1 return TEXT_SPEED || 2 / 80.0 # Normal
end end
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------

View File

@@ -123,7 +123,6 @@ class Window
@back_opacity = 255 @back_opacity = 255
@contents_opacity = 255 @contents_opacity = 255
@cursor_rect = WindowCursorRect.new(self) @cursor_rect = WindowCursorRect.new(self)
@cursorblink = 0
@cursoropacity = 255 @cursoropacity = 255
@pause = false @pause = false
@pauseopacity = 255 @pauseopacity = 255
@@ -302,12 +301,11 @@ class Window
return if disposed? return if disposed?
mustchange = false mustchange = false
if @active if @active
if @cursorblink == 0 cursor_time = System.uptime / 0.4
@cursoropacity -= 8 if cursor_time.to_i % 2 == 0
@cursorblink = 1 if @cursoropacity <= 128 @cursoropacity = lerp(255, 128, 0.4, cursor_time % 2)
else else
@cursoropacity += 8 @cursoropacity = lerp(128, 255, 0.4, (cursor_time - 1) % 2)
@cursorblink = 0 if @cursoropacity >= 255
end end
mustchange = true if !@cursor_rect.empty? mustchange = true if !@cursor_rect.empty?
else else

View File

@@ -99,11 +99,10 @@ class SpriteWindow < Window
@contents_blend_type = 0 @contents_blend_type = 0
@contents_opacity = 255 @contents_opacity = 255
@cursor_rect = WindowCursorRect.new(self) @cursor_rect = WindowCursorRect.new(self)
@cursorblink = 0
@cursoropacity = 255 @cursoropacity = 255
@pause = false @pause = false
@pauseframe = 0 @pauseframe = 0
@flash = 0 @flash_duration = 0
@pauseopacity = 0 @pauseopacity = 0
@skinformat = 0 @skinformat = 0
@skinrect = Rect.new(0, 0, 0, 0) @skinrect = Rect.new(0, 0, 0, 0)
@@ -286,11 +285,13 @@ class SpriteWindow < Window
privRefresh if @visible privRefresh if @visible
end end
# duration is in 1/20ths of a second
def flash(color, duration) def flash(color, duration)
return if disposed? return if disposed?
@flash = duration + 1 @flash_duration = duration / 20.0
@flash_timer_start = System.uptime
@sprites.each do |i| @sprites.each do |i|
i[1].flash(color, duration) i[1].flash(color, (@flash_duration * Graphics.frame_rate).to_i) # Must be in frames
end end
end end
@@ -298,12 +299,11 @@ class SpriteWindow < Window
return if disposed? return if disposed?
mustchange = false mustchange = false
if @active if @active
if @cursorblink == 0 cursor_time = System.uptime / 0.4
@cursoropacity -= 8 if cursor_time.to_i % 2 == 0
@cursorblink = 1 if @cursoropacity <= 128 @cursoropacity = lerp(255, 128, 0.4, cursor_time % 2)
else else
@cursoropacity += 8 @cursoropacity = lerp(128, 255, 0.4, (cursor_time - 1) % 2)
@cursorblink = 0 if @cursoropacity >= 255
end end
else else
@cursoropacity = 128 @cursoropacity = 128
@@ -312,16 +312,14 @@ class SpriteWindow < Window
if @pause if @pause
oldpauseframe = @pauseframe oldpauseframe = @pauseframe
oldpauseopacity = @pauseopacity oldpauseopacity = @pauseopacity
@pauseframe = (System.uptime * 5) % 4 # 4 frames, 5 frames per second @pauseframe = (System.uptime * 5).to_i % 4 # 4 frames, 5 frames per second
@pauseopacity = [@pauseopacity + 64, 255].min @pauseopacity = [@pauseopacity + 64, 255].min
mustchange = @pauseframe != oldpauseframe || @pauseopacity != oldpauseopacity mustchange = @pauseframe != oldpauseframe || @pauseopacity != oldpauseopacity
end end
privRefresh if mustchange privRefresh if mustchange
if @flash > 0 if @flash_timer_start
@sprites.each_value do |i| @sprites.each_value { |i| i.update }
i.update @flash_timer_start = nil if System.uptime - @flash_timer_start >= @flash_duration
end
@flash -= 1
end end
end end

View File

@@ -116,33 +116,34 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
attr_reader :waitcount attr_reader :waitcount
def initialize(text = "") def initialize(text = "")
@cursorMode = MessageConfig::CURSOR_POSITION @cursorMode = MessageConfig::CURSOR_POSITION
@endOfText = nil @endOfText = nil
@scrollstate = 0 @scrollstate = 0
@realframes = 0 @scrollY = 0
@scrollY = 0 @scroll_timer_start = nil
@nodraw = false @realframes = 0
@lineHeight = 32 @nodraw = false
@linesdrawn = 0 @lineHeight = 32
@bufferbitmap = nil @linesdrawn = 0
@letterbyletter = false @bufferbitmap = nil
@starting = true @letterbyletter = false
@displaying = false @starting = true
@lastDrawnChar = -1 @displaying = false
@fmtchars = [] @lastDrawnChar = -1
@frameskipChanged = false @fmtchars = []
@frameskip = MessageConfig.pbGetTextSpeed @text_delay_changed = false
@text_delay = MessageConfig.pbGetTextSpeed
super(0, 0, 33, 33) super(0, 0, 33, 33)
@pausesprite = nil @pausesprite = nil
@text = "" @text = ""
self.contents = Bitmap.new(1, 1) self.contents = Bitmap.new(1, 1)
pbSetSystemFont(self.contents) pbSetSystemFont(self.contents)
self.resizeToFit(text, Graphics.width) self.resizeToFit(text, Graphics.width)
colors = getDefaultTextColors(self.windowskin) colors = getDefaultTextColors(self.windowskin)
@baseColor = colors[0] @baseColor = colors[0]
@shadowColor = colors[1] @shadowColor = colors[1]
self.text = text self.text = text
@starting = false @starting = false
end end
def self.newWithSize(text, x, y, width, height, viewport = nil) def self.newWithSize(text, x, y, width, height, viewport = nil)
@@ -189,13 +190,14 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
refresh refresh
end end
# Delay in seconds between two adjacent characters appearing.
def textspeed def textspeed
@frameskip return @text_delay
end end
def textspeed=(value) def textspeed=(value)
@frameskipChanged = true if @frameskip != value @text_delay_changed = true if @text_delay != value
@frameskip = value @text_delay = value
end end
def width=(value) def width=(value)
@@ -285,6 +287,8 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
def setText(value) def setText(value)
@waitcount = 0 @waitcount = 0
@wait_timer_start = nil @wait_timer_start = nil
@display_timer = 0.0
@display_last_updated = System.uptime
@curchar = 0 @curchar = 0
@drawncurchar = -1 @drawncurchar = -1
@lastDrawnChar = -1 @lastDrawnChar = -1
@@ -292,6 +296,7 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
@textlength = unformattedTextLength(value) @textlength = unformattedTextLength(value)
@scrollstate = 0 @scrollstate = 0
@scrollY = 0 @scrollY = 0
@scroll_timer_start = nil
@linesdrawn = 0 @linesdrawn = 0
@realframes = 0 @realframes = 0
@textchars = [] @textchars = []
@@ -400,7 +405,7 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
resume resume
visiblelines = (self.height - self.borderY) / @lineHeight visiblelines = (self.height - self.borderY) / @lineHeight
loop do loop do
curcharSkip(999) curcharSkip(true)
break if @curchar >= @fmtchars.length # End of message break if @curchar >= @fmtchars.length # End of message
if @textchars[@curchar] == "\1" # Pause message if @textchars[@curchar] == "\1" # Pause message
@pausing = true if @curchar < @numtextchars - 1 @pausing = true if @curchar < @numtextchars - 1
@@ -462,7 +467,7 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
self.oy = @scrollY self.oy = @scrollY
numchars = @numtextchars numchars = @numtextchars
numchars = [@curchar, @numtextchars].min if self.letterbyletter numchars = [@curchar, @numtextchars].min if self.letterbyletter
return if busy? && @drawncurchar == @curchar && @scrollstate == 0 return if busy? && @drawncurchar == @curchar && !@scroll_timer_start
if !self.letterbyletter || !oldcontents.equal?(self.contents) if !self.letterbyletter || !oldcontents.equal?(self.contents)
@drawncurchar = -1 @drawncurchar = -1
@needclear = true @needclear = true
@@ -508,7 +513,7 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
def redrawText def redrawText
if @letterbyletter if @letterbyletter
oldPosition = self.position oldPosition = self.position
self.text = self.text self.text = self.text # Clears the text already drawn
oldPosition = @numtextchars if oldPosition > @numtextchars oldPosition = @numtextchars if oldPosition > @numtextchars
while self.position != oldPosition while self.position != oldPosition
refresh refresh
@@ -520,55 +525,56 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
end end
def updateInternal def updateInternal
curcharskip = @frameskip < 0 ? @frameskip.abs : 1 time_now = System.uptime
@display_last_updated = time_now if !@display_last_updated
delta_t = time_now - @display_last_updated
@display_last_updated = time_now
visiblelines = (self.height - self.borderY) / @lineHeight visiblelines = (self.height - self.borderY) / @lineHeight
if @textchars[@curchar] == "\1" show_more_characters = false
if !@pausing # Pauses and new lines
@realframes += 1 if @textchars[@curchar] == "\1" # Waiting
if @realframes >= @frameskip || @frameskip < 0 show_more_characters = true if !@pausing
curcharSkip(curcharskip) elsif @textchars[@curchar] == "\n" # Move to new line
@realframes = 0 if @linesdrawn >= visiblelines - 1 # Need to scroll text to show new line
end if @scroll_timer_start
end old_y = @scrollstate
elsif @textchars[@curchar] == "\n" new_y = lerp(0, @lineHeight, 0.1, @scroll_timer_start, time_now)
if @linesdrawn >= visiblelines - 1 @scrollstate = new_y
if @scrollstate < @lineHeight @scrollY += new_y - old_y
@scrollstate += [(@lineHeight / 4), 1].max if @scrollstate >= @lineHeight
@scrollY += [(@lineHeight / 4), 1].max
end
if @scrollstate >= @lineHeight
@realframes += 1
if @realframes >= @frameskip || @frameskip < 0
curcharSkip(curcharskip)
@linesdrawn += 1
@realframes = 0
@scrollstate = 0 @scrollstate = 0
@scroll_timer_start = nil
@linesdrawn += 1
show_more_characters = true
end end
else
show_more_characters = true
end end
else else # New line but the next line can be shown without scrolling to it
@realframes += 1 @linesdrawn += 1
if @realframes >= @frameskip || @frameskip < 0 show_more_characters = true
curcharSkip(curcharskip)
@linesdrawn += 1
@realframes = 0
end
end
elsif @curchar <= @numtextchars
@realframes += 1
if @realframes >= @frameskip || @frameskip < 0
curcharSkip(curcharskip)
@realframes = 0
end
if @textchars[@curchar] == "\1"
@pausing = true if @curchar < @numtextchars - 1
self.startPause
refresh
end end
elsif @curchar <= @numtextchars # Displaying more text
show_more_characters = true
else else
@displaying = false @displaying = false
@scrollstate = 0 @scrollstate = 0
@scrollY = 0 @scrollY = 0
@linesdrawn = 0 @scroll_timer_start = nil
@linesdrawn = 0
end
# Keep displaying more text
if show_more_characters
@display_timer += delta_t
if curcharSkip
if @textchars[@curchar] == "\n" && @linesdrawn >= visiblelines - 1
@scroll_timer_start = time_now
elsif @textchars[@curchar] == "\1"
@pausing = true if @curchar < @numtextchars - 1
self.startPause
refresh
end
end
end end
end end
@@ -583,26 +589,33 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
return if @wait_timer_start return if @wait_timer_start
end end
if busy? if busy?
refresh if !@frameskipChanged refresh if !@text_delay_changed
updateInternal updateInternal
# following line needed to allow "textspeed=-999" to work seamlessly # following line needed to allow "textspeed=0" to work seamlessly
refresh if @frameskipChanged # TODO: I don't think this is needed any more, but I don't know where to
# look to confirm it'd work properly without this line.
refresh if @text_delay_changed
end end
@frameskipChanged = false @text_delay_changed = false
end end
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
private private
def curcharSkip(skip) def curcharSkip(instant = false)
skip.times do ret = false
loop do
break if @display_timer < @text_delay && !instant
@display_timer -= @text_delay if !instant
ret = true
@curchar += 1 @curchar += 1
break if @textchars[@curchar] == "\n" || # newline break if @textchars[@curchar] == "\n" || # newline
@textchars[@curchar] == "\1" || # pause @textchars[@curchar] == "\1" || # pause
@textchars[@curchar] == "\2" || # letter-by-letter break @textchars[@curchar] == "\2" || # letter-by-letter break
@textchars[@curchar].nil? @textchars[@curchar].nil?
end end
return ret
end end
end end
@@ -615,7 +628,8 @@ class Window_InputNumberPokemon < SpriteWindow_Base
def initialize(digits_max) def initialize(digits_max)
@digits_max = digits_max @digits_max = digits_max
@number = 0 @number = 0
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
@sign = false @sign = false
@negative = false @negative = false
super(0, 0, 32, 32) super(0, 0, 32, 32)
@@ -674,7 +688,11 @@ class Window_InputNumberPokemon < SpriteWindow_Base
def update def update
super super
digits = @digits_max + (@sign ? 1 : 0) digits = @digits_max + (@sign ? 1 : 0)
refresh if @frame % 15 == 0 cursor_to_show = ((System.uptime - @cursor_timer_start) / 0.35).to_i % 2 == 0
if cursor_to_show != @cursor_shown
@cursor_shown = cursor_to_show
refresh
end
if self.active if self.active
if Input.repeat?(Input::UP) || Input.repeat?(Input::DOWN) if Input.repeat?(Input::UP) || Input.repeat?(Input::DOWN)
pbPlayCursorSE pbPlayCursorSE
@@ -696,19 +714,20 @@ class Window_InputNumberPokemon < SpriteWindow_Base
if digits >= 2 if digits >= 2
pbPlayCursorSE pbPlayCursorSE
@index = (@index + 1) % digits @index = (@index + 1) % digits
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
refresh refresh
end end
elsif Input.repeat?(Input::LEFT) elsif Input.repeat?(Input::LEFT)
if digits >= 2 if digits >= 2
pbPlayCursorSE pbPlayCursorSE
@index = (@index + digits - 1) % digits @index = (@index + digits - 1) % digits
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
refresh refresh
end end
end end
end end
@frame = (@frame + 1) % 30
end end
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
@@ -721,8 +740,10 @@ class Window_InputNumberPokemon < SpriteWindow_Base
x + (12 - (textwidth / 2)), x + (12 - (textwidth / 2)),
y - 2 + (self.contents.text_offset_y || 0), # TEXT OFFSET (the - 2) y - 2 + (self.contents.text_offset_y || 0), # TEXT OFFSET (the - 2)
textwidth + 4, 32, text, @baseColor, @shadowColor) textwidth + 4, 32, text, @baseColor, @shadowColor)
if @index == i && @active && @frame / 15 == 0 # Draw cursor
self.contents.fill_rect(x + (12 - (textwidth / 2)), y + 30, textwidth, 2, @baseColor) if @index == i && @active && @cursor_shown
self.contents.fill_rect(x + (12 - (textwidth / 2)), y + 28, textwidth, 4, @shadowColor)
self.contents.fill_rect(x + (12 - (textwidth / 2)), y + 28, textwidth - 2, 2, @baseColor)
end end
end end
end end

View File

@@ -43,19 +43,19 @@ class PngAnimatedBitmap
def initialize(dir, filename, hue = 0) def initialize(dir, filename, hue = 0)
@frames = [] @frames = []
@currentFrame = 0 @currentFrame = 0
@framecount = 0 @timer_start = System.uptime
panorama = RPG::Cache.load_bitmap(dir, filename, hue) panorama = RPG::Cache.load_bitmap(dir, filename, hue)
if filename[/^\[(\d+)(?:,(\d+))?\]/] # Starts with 1 or 2 numbers in brackets if filename[/^\[(\d+)(?:,(\d+))?\]/] # Starts with 1 or 2 numbers in brackets
# File has a frame count # File has a frame count
numFrames = $1.to_i numFrames = $1.to_i
delay = $2.to_i duration = $2.to_i
delay = 10 if delay == 0 duration = 5 if duration == 0
raise "Invalid frame count in #{filename}" if numFrames <= 0 raise "Invalid frame count in #{filename}" if numFrames <= 0
raise "Invalid frame delay in #{filename}" if delay <= 0 raise "Invalid frame duration in #{filename}" if duration <= 0
if panorama.width % numFrames != 0 if panorama.width % numFrames != 0
raise "Bitmap's width (#{panorama.width}) is not divisible by frame count: #{filename}" raise "Bitmap's width (#{panorama.width}) is not divisible by frame count: #{filename}"
end end
@frameDelay = delay @frame_duration = duration
subWidth = panorama.width / numFrames subWidth = panorama.width / numFrames
numFrames.times do |i| numFrames.times do |i|
subBitmap = Bitmap.new(subWidth, panorama.height) subBitmap = Bitmap.new(subWidth, panorama.height)
@@ -68,6 +68,16 @@ class PngAnimatedBitmap
end end
end end
def dispose
return if @disposed
@frames.each { |f| f.dispose }
@disposed = true
end
def disposed?
return @disposed
end
def [](index) def [](index)
return @frames[index] return @frames[index]
end end
@@ -75,15 +85,6 @@ class PngAnimatedBitmap
def width; self.bitmap.width; end def width; self.bitmap.width; end
def height; self.bitmap.height; end def height; self.bitmap.height; end
def deanimate
(1...@frames.length).each do |i|
@frames[i].dispose
end
@frames = [@frames[0]]
@currentFrame = 0
return @frames[0]
end
def bitmap def bitmap
return @frames[@currentFrame] return @frames[@currentFrame]
end end
@@ -92,43 +93,27 @@ class PngAnimatedBitmap
return @currentFrame return @currentFrame
end end
def frameDelay(_index)
return @frameDelay
end
def length def length
return @frames.length return @frames.length
end end
# Actually returns the total number of 1/20ths of a second this animation lasts.
def totalFrames
return @frame_duration * @frames.length
end
def each def each
@frames.each { |item| yield item } @frames.each { |item| yield item }
end end
def totalFrames def deanimate
return @frameDelay * @frames.length (1...@frames.length).each do |i|
end @frames[i].dispose
def disposed?
return @disposed
end
def update
return if disposed?
if @frames.length > 1
@framecount += 1
if @framecount >= @frameDelay
@framecount = 0
@currentFrame += 1
@currentFrame %= @frames.length
end
end end
end @frames = [@frames[0]]
@currentFrame = 0
def dispose @frame_duration = 0
if !@disposed return @frames[0]
@frames.each { |f| f.dispose }
end
@disposed = true
end end
def copy def copy
@@ -137,6 +122,13 @@ class PngAnimatedBitmap
x.frames.each_with_index { |frame, i| x.frames[i] = frame.copy } x.frames.each_with_index { |frame, i| x.frames[i] = frame.copy }
return x return x
end end
def update
return if disposed?
if @frames.length > 1
@currentFrame = ((System.uptime - @timer_start) / @frame_duration).to_i % @frames.length
end
end
end end
#=============================================================================== #===============================================================================

View File

@@ -613,7 +613,7 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni
msgwindow.y = lerp(y_start, y_end, appear_duration, appear_timer_start, System.uptime) msgwindow.y = lerp(y_start, y_end, appear_duration, appear_timer_start, System.uptime)
end end
when "ts" # Change text speed when "ts" # Change text speed
msgwindow.textspeed = (param == "") ? -999 : param.to_i msgwindow.textspeed = (param == "") ? 0 : param.to_i / 80.0
when "." # Wait 0.25 seconds when "." # Wait 0.25 seconds
msgwindow.waitcount += 0.25 msgwindow.waitcount += 0.25
when "|" # Wait 1 second when "|" # Wait 1 second

View File

@@ -94,8 +94,9 @@ class Window_TextEntry < SpriteWindow_Base
end end
@helper = CharacterEntryHelper.new(text) @helper = CharacterEntryHelper.new(text)
@heading = heading @heading = heading
@cursor_timer_start = System.uptime
@cursor_shown = true
self.active = true self.active = true
@frame = 0
refresh refresh
end end
@@ -128,7 +129,8 @@ class Window_TextEntry < SpriteWindow_Base
def insert(ch) def insert(ch)
if @helper.insert(ch) if @helper.insert(ch)
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh self.refresh
return true return true
end end
@@ -137,7 +139,8 @@ class Window_TextEntry < SpriteWindow_Base
def delete def delete
if @helper.delete if @helper.delete
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh self.refresh
return true return true
end end
@@ -145,21 +148,25 @@ class Window_TextEntry < SpriteWindow_Base
end end
def update def update
@frame += 1 cursor_to_show = ((System.uptime - @cursor_timer_start) / 0.35).to_i % 2 == 0
@frame %= 20 if cursor_to_show != @cursor_shown
self.refresh if (@frame % 10) == 0 @cursor_shown = cursor_to_show
refresh
end
return if !self.active return if !self.active
# Moving cursor # Moving cursor
if Input.repeat?(Input::LEFT) && Input.press?(Input::ACTION) if Input.repeat?(Input::LEFT) && Input.press?(Input::ACTION)
if @helper.cursor > 0 if @helper.cursor > 0
@helper.cursor -= 1 @helper.cursor -= 1
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh self.refresh
end end
elsif Input.repeat?(Input::RIGHT) && Input.press?(Input::ACTION) elsif Input.repeat?(Input::RIGHT) && Input.press?(Input::ACTION)
if @helper.cursor < self.text.scan(/./m).length if @helper.cursor < self.text.scan(/./m).length
@helper.cursor += 1 @helper.cursor += 1
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh self.refresh
end end
elsif Input.repeat?(Input::BACK) # Backspace elsif Input.repeat?(Input::BACK) # Backspace
@@ -201,13 +208,13 @@ class Window_TextEntry < SpriteWindow_Base
# Draw text # Draw text
pbDrawShadowText(bitmap, x, y, textwidth + 4, 32, c, @baseColor, @shadowColor) pbDrawShadowText(bitmap, x, y, textwidth + 4, 32, c, @baseColor, @shadowColor)
# Draw cursor if necessary # Draw cursor if necessary
if ((@frame / 10) & 1) == 0 && i == @helper.cursor if i == @helper.cursor && @cursor_shown
bitmap.fill_rect(x, y + 4, 2, 24, cursorcolor) bitmap.fill_rect(x, y + 4, 2, 24, cursorcolor)
end end
# Add x to drawn text width # Add x to drawn text width
x += textwidth x += textwidth
end end
if ((@frame / 10) & 1) == 0 && textscan.length == @helper.cursor if textscan.length == @helper.cursor && @cursor_shown
bitmap.fill_rect(x, y + 4, 2, 24, cursorcolor) bitmap.fill_rect(x, y + 4, 2, 24, cursorcolor)
end end
end end
@@ -218,22 +225,26 @@ end
#=============================================================================== #===============================================================================
class Window_TextEntry_Keyboard < Window_TextEntry class Window_TextEntry_Keyboard < Window_TextEntry
def update def update
@frame += 1 cursor_to_show = ((System.uptime - @cursor_timer_start) / 0.35).to_i % 2 == 0
@frame %= 20 if cursor_to_show != @cursor_shown
self.refresh if (@frame % 10) == 0 @cursor_shown = cursor_to_show
refresh
end
return if !self.active return if !self.active
# Moving cursor # Moving cursor
if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT) if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
if @helper.cursor > 0 if @helper.cursor > 0
@helper.cursor -= 1 @helper.cursor -= 1
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh self.refresh
end end
return return
elsif Input.triggerex?(:RIGHT) || Input.repeatex?(:RIGHT) elsif Input.triggerex?(:RIGHT) || Input.repeatex?(:RIGHT)
if @helper.cursor < self.text.scan(/./m).length if @helper.cursor < self.text.scan(/./m).length
@helper.cursor += 1 @helper.cursor += 1
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh self.refresh
end end
return return
@@ -260,7 +271,8 @@ class Window_MultilineTextEntry < SpriteWindow_Base
@firstline = 0 @firstline = 0
@cursorLine = 0 @cursorLine = 0
@cursorColumn = 0 @cursorColumn = 0
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.active = true self.active = true
refresh refresh
end end
@@ -301,7 +313,8 @@ class Window_MultilineTextEntry < SpriteWindow_Base
def insert(ch) def insert(ch)
@helper.cursor = getPosFromLineAndColumn(@cursorLine, @cursorColumn) @helper.cursor = getPosFromLineAndColumn(@cursorLine, @cursorColumn)
if @helper.insert(ch) if @helper.insert(ch)
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
@textchars = nil @textchars = nil
moveCursor(0, 1) moveCursor(0, 1)
self.refresh self.refresh
@@ -313,7 +326,8 @@ class Window_MultilineTextEntry < SpriteWindow_Base
def delete def delete
@helper.cursor = getPosFromLineAndColumn(@cursorLine, @cursorColumn) @helper.cursor = getPosFromLineAndColumn(@cursorLine, @cursorColumn)
if @helper.delete if @helper.delete
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
moveCursor(0, -1) # use old textchars moveCursor(0, -1) # use old textchars
@textchars = nil @textchars = nil
self.refresh self.refresh
@@ -407,7 +421,8 @@ class Window_MultilineTextEntry < SpriteWindow_Base
# Calculate new cursor position # Calculate new cursor position
@helper.cursor = getPosFromLineAndColumn(@cursorLine, @cursorColumn) @helper.cursor = getPosFromLineAndColumn(@cursorLine, @cursorColumn)
if doRefresh if doRefresh
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.refresh self.refresh
end end
@firstline = @cursorLine if @cursorLine < @firstline @firstline = @cursorLine if @cursorLine < @firstline
@@ -450,9 +465,11 @@ class Window_MultilineTextEntry < SpriteWindow_Base
end end
def update def update
@frame += 1 cursor_to_show = ((System.uptime - @cursor_timer_start) / 0.35).to_i % 2 == 0
@frame %= 20 if cursor_to_show != @cursor_shown
self.refresh if (@frame % 10) == 0 @cursor_shown = cursor_to_show
refresh
end
return if !self.active return if !self.active
# Moving cursor # Moving cursor
if Input.triggerex?(:UP) || Input.repeatex?(:UP) if Input.triggerex?(:UP) || Input.repeatex?(:UP)
@@ -519,7 +536,7 @@ class Window_MultilineTextEntry < SpriteWindow_Base
pbDrawShadowText(bitmap, text[1], textY, textwidth, textheight, c, @baseColor, @shadowColor) pbDrawShadowText(bitmap, text[1], textY, textwidth, textheight, c, @baseColor, @shadowColor)
end end
# Draw cursor # Draw cursor
if ((@frame / 10) & 1) == 0 if @cursor_shown
textheight = bitmap.text_size("X").height textheight = bitmap.text_size("X").height
cursorY = (textheight * @cursorLine) - startY cursorY = (textheight * @cursorLine) - startY
cursorX = 0 cursorX = 0

View File

@@ -131,18 +131,25 @@ class EventScene
return @pictures[num] return @pictures[num]
end end
def wait(frames) # ticks is in 1/20ths of a second.
frames.times { update } def wait(ticks)
return if ticks <= 0
timer_start = System.uptime
loop do
update
break if System.uptime - timer_start >= ticks / 20.0
end
end end
def pictureWait(extraframes = 0) # extra_ticks is in 1/20ths of a second.
def pictureWait(extra_ticks = 0)
loop do loop do
hasRunning = false hasRunning = false
@pictures.each { |pic| hasRunning = true if pic.running? } @pictures.each { |pic| hasRunning = true if pic.running? }
break if !hasRunning break if !hasRunning
update update
end end
extraframes.times { update } wait(extra_ticks)
end end
def update def update
@@ -164,8 +171,9 @@ class EventScene
end end
def main def main
until disposed? loop do
update update
break if disposed?
end end
end end
end end

View File

@@ -271,6 +271,7 @@ module RPG
def update_sprite_position(sprite, index, is_new_sprite = false) def update_sprite_position(sprite, index, is_new_sprite = false)
return if !sprite || !sprite.bitmap || !sprite.visible return if !sprite || !sprite.bitmap || !sprite.visible
# TODO: FPS.
delta_t = Graphics.delta delta_t = Graphics.delta
lifetimes = (is_new_sprite) ? @new_sprite_lifetimes : @sprite_lifetimes lifetimes = (is_new_sprite) ? @new_sprite_lifetimes : @sprite_lifetimes
if lifetimes[index] >= 0 if lifetimes[index] >= 0
@@ -286,6 +287,7 @@ module RPG
if @weatherTypes[weather_type][0].category == :Rain && index.odd? # Splash if @weatherTypes[weather_type][0].category == :Rain && index.odd? # Splash
sprite.opacity = (lifetimes[index] < 0.2) ? 255 : 0 # 0.2 seconds sprite.opacity = (lifetimes[index] < 0.2) ? 255 : 0 # 0.2 seconds
else else
# TODO: FPS.
dist_x = @weatherTypes[weather_type][0].particle_delta_x * delta_t dist_x = @weatherTypes[weather_type][0].particle_delta_x * delta_t
dist_y = @weatherTypes[weather_type][0].particle_delta_y * delta_t dist_y = @weatherTypes[weather_type][0].particle_delta_y * delta_t
sprite.x += dist_x sprite.x += dist_x
@@ -299,6 +301,7 @@ module RPG
sprite.x += Graphics.width if sprite.x - @ox < -sprite.width sprite.x += Graphics.width if sprite.x - @ox < -sprite.width
sprite.y -= Graphics.height if sprite.y - @oy > Graphics.height sprite.y -= Graphics.height if sprite.y - @oy > Graphics.height
sprite.y += Graphics.height if sprite.y - @oy < -sprite.height sprite.y += Graphics.height if sprite.y - @oy < -sprite.height
# TODO: FPS.
sprite.opacity += @weatherTypes[weather_type][0].particle_delta_opacity * delta_t sprite.opacity += @weatherTypes[weather_type][0].particle_delta_opacity * delta_t
x = sprite.x - @ox x = sprite.x - @ox
y = sprite.y - @oy y = sprite.y - @oy
@@ -310,11 +313,13 @@ module RPG
end end
def recalculate_tile_positions def recalculate_tile_positions
# TODO: FPS.
delta_t = Graphics.delta delta_t = Graphics.delta
weather_type = @type weather_type = @type
if @fading && @fade_time >= [FADE_OLD_TONE_END - @time_shift, 0].max if @fading && @fade_time >= [FADE_OLD_TONE_END - @time_shift, 0].max
weather_type = @target_type weather_type = @target_type
end end
# TODO: FPS.
@tile_x += @weatherTypes[weather_type][0].tile_delta_x * delta_t @tile_x += @weatherTypes[weather_type][0].tile_delta_x * delta_t
@tile_y += @weatherTypes[weather_type][0].tile_delta_y * delta_t @tile_y += @weatherTypes[weather_type][0].tile_delta_y * delta_t
while @tile_x < @ox - @weatherTypes[weather_type][2][0].width while @tile_x < @ox - @weatherTypes[weather_type][2][0].width
@@ -411,6 +416,7 @@ module RPG
@sun_magnitude = weather_max if @sun_magnitude != weather_max && @sun_magnitude != -weather_max @sun_magnitude = weather_max if @sun_magnitude != weather_max && @sun_magnitude != -weather_max
@sun_magnitude *= -1 if (@sun_magnitude > 0 && @sun_strength > @sun_magnitude) || @sun_magnitude *= -1 if (@sun_magnitude > 0 && @sun_strength > @sun_magnitude) ||
(@sun_magnitude < 0 && @sun_strength < 0) (@sun_magnitude < 0 && @sun_strength < 0)
# TODO: FPS.
@sun_strength += @sun_magnitude.to_f * Graphics.delta / 0.4 # 0.4 seconds per half flash @sun_strength += @sun_magnitude.to_f * Graphics.delta / 0.4 # 0.4 seconds per half flash
tone_red += @sun_strength tone_red += @sun_strength
tone_green += @sun_strength tone_green += @sun_strength
@@ -424,6 +430,7 @@ module RPG
def update_fading def update_fading
return if !@fading return if !@fading
old_fade_time = @fade_time old_fade_time = @fade_time
# TODO: FPS.
@fade_time += Graphics.delta @fade_time += Graphics.delta
# Change tile bitmaps # Change tile bitmaps
if @type != @target_type if @type != @target_type
@@ -482,6 +489,7 @@ module RPG
update_screen_tone update_screen_tone
# Storm flashes # Storm flashes
if @type == :Storm && !@fading if @type == :Storm && !@fading
# TODO: FPS.
if @time_until_flash > 0 if @time_until_flash > 0
@time_until_flash -= Graphics.delta @time_until_flash -= Graphics.delta
if @time_until_flash <= 0 if @time_until_flash <= 0

View File

@@ -223,6 +223,5 @@ EventHandlers.add(:on_new_spriteset_map, :add_light_effects,
spriteset.addUserSprite(LightEffect_Basic.new(map.events[i], viewport, map)) spriteset.addUserSprite(LightEffect_Basic.new(map.events[i], viewport, map))
end end
end end
spriteset.addUserSprite(Particle_Engine.new(viewport, map))
} }
) )

View File

@@ -574,6 +574,7 @@ EventHandlers.add(:on_frame_update, :phone_call_counter,
if $PokemonGlobal.phone.time_to_next_call <= 0 if $PokemonGlobal.phone.time_to_next_call <= 0
$PokemonGlobal.phone.time_to_next_call = rand(20...40) * 60.0 # 20-40 minutes $PokemonGlobal.phone.time_to_next_call = rand(20...40) * 60.0 # 20-40 minutes
end end
# TODO: FPS. Can probably leave this alone.
$PokemonGlobal.phone.time_to_next_call -= Graphics.delta $PokemonGlobal.phone.time_to_next_call -= Graphics.delta
next if $PokemonGlobal.phone.time_to_next_call > 0 next if $PokemonGlobal.phone.time_to_next_call > 0
# Time for a random phone call; generate one # Time for a random phone call; generate one

View File

@@ -15,30 +15,31 @@
# #
#=============================================================================== #===============================================================================
class HallOfFame_Scene class HallOfFame_Scene
# When true, all pokémon will be in one line # When true, all pokémon will be in one line.
# When false, all pokémon will be in two lines # When false, all pokémon will be in two lines.
SINGLE_ROW_OF_POKEMON = false SINGLE_ROW_OF_POKEMON = false
# Make the pokémon movement ON in hall entry # Make the pokémon movement ON in hall entry.
ANIMATION = true ANIMATION = true
# Speed in pokémon movement in hall entry. Don't use less than 2! # Time in seconds for a Pokémon to slide to its position from off-screen.
ANIMATIONSPEED = 32 APPEAR_SPEED = 0.4
# Entry wait time (in seconds) between showing each Pokémon (and trainer). # Entry wait time (in seconds) between showing each Pokémon (and trainer).
# Waits for twice this tme when showing "Welcome to the Hall of Fame!".
ENTRY_WAIT_TIME = 3.0 ENTRY_WAIT_TIME = 3.0
# Wait time (in seconds) when showing "Welcome to the Hall of Fame!".
WELCOME_WAIT_TIME = 4.0
# Maximum number limit of simultaneous hall entries saved. # Maximum number limit of simultaneous hall entries saved.
# 0 = Doesn't save any hall. -1 = no limit # 0 = Doesn't save any hall. -1 = no limit
# Prefer to use larger numbers (like 500 and 1000) than don't put a limit # Prefer to use larger numbers (like 500 and 1000) than don't put a limit.
# If a player exceed this limit, the first one will be removed # If a player exceed this limit, the first one will be removed.
HALL_ENTRIES_LIMIT = 50 HALL_ENTRIES_LIMIT = 50
# The entry music name. Put "" to doesn't play anything # The entry music name. Put "" to doesn't play anything.
HALL_OF_FAME_BGM = "Hall of Fame" HALL_OF_FAME_BGM = "Hall of Fame"
# Allow eggs to be show and saved in hall # Allow eggs to be show and saved in hall.
ALLOW_EGGS = true ALLOW_EGGS = true
# Remove the hallbars when the trainer sprite appears # Remove the hallbars when the trainer sprite appears.
REMOVE_BARS_WHEN_SHOWING_TRAINER = true REMOVE_BARS_WHEN_SHOWING_TRAINER = true
# The final fade speed on entry # The final fade speed on entry.
FINAL_FADE_DURATION = 1.0 FINAL_FADE_DURATION = 1.0
# Sprite's opacity value when it isn't selected # Sprite's opacity value when it isn't selected.
OPACITY = 64 OPACITY = 64
TEXT_BASE_COLOR = Color.new(248, 248, 248) TEXT_BASE_COLOR = Color.new(248, 248, 248)
TEXT_SHADOW_COLOR = Color.new(0, 0, 0) TEXT_SHADOW_COLOR = Color.new(0, 0, 0)
@@ -68,8 +69,7 @@ class HallOfFame_Scene
@useMusic = (HALL_OF_FAME_BGM && HALL_OF_FAME_BGM != "") @useMusic = (HALL_OF_FAME_BGM && HALL_OF_FAME_BGM != "")
pbBGMPlay(HALL_OF_FAME_BGM) if @useMusic pbBGMPlay(HALL_OF_FAME_BGM) if @useMusic
saveHallEntry saveHallEntry
@xmovement = [] @movements = []
@ymovement = []
createBattlers createBattlers
pbFadeInAndShow(@sprites) { pbUpdate } pbFadeInAndShow(@sprites) { pbUpdate }
end end
@@ -92,14 +92,15 @@ class HallOfFame_Scene
end end
def slowFadeOut(duration) def slowFadeOut(duration)
col = Color.new(0, 0, 0, 0)
timer_start = System.uptime timer_start = System.uptime
loop do loop do
alpha = lerp(255, 0, duration, timer_start, System.uptime) col.alpha = lerp(0, 255, duration, timer_start, System.uptime)
pbSetSpritesToColor(@sprites, Color.new(0, 0, 0, alpha)) @viewport.color = col
Graphics.update Graphics.update
Input.update Input.update
pbUpdate pbUpdate
break if alpha == 0 break if col.alpha == 255
end end
end end
@@ -132,120 +133,94 @@ class HallOfFame_Scene
# Return the x/y point position in screen for battler index number # Return the x/y point position in screen for battler index number
# Don't use odd numbers! # Don't use odd numbers!
def xpointformula(battlernumber) def xpointformula(battlernumber)
ret = 0
if SINGLE_ROW_OF_POKEMON if SINGLE_ROW_OF_POKEMON
ret = ((60 * (battlernumber / 2)) + 48) * (xpositionformula(battlernumber) - 1) ret = ((60 * (battlernumber / 2)) + 48) * (xpositionformula(battlernumber) - 1) # -48, 48, -108, 108, -168, 168
ret += (Graphics.width / 2) - 56 return ret + (Graphics.width / 2) # 208, 304, 148, 364, 88, 424
else
ret = 32 + (160 * xpositionformula(battlernumber))
end end
return ret return 96 + (160 * xpositionformula(battlernumber)) # 256, 96, 456, 256, 456, 96
end end
def ypointformula(battlernumber) def ypointformula(battlernumber)
ret = 0 return 180 - (32 * (battlernumber / 2)) if SINGLE_ROW_OF_POKEMON # 180, 180, 148, 148, 116, 116
if SINGLE_ROW_OF_POKEMON return 96 + (64 * ypositionformula(battlernumber)) # 90, 90, 90, 160, 160, 160
ret = 96 - (8 * (battlernumber / 2))
else
ret = 32 + (128 * ypositionformula(battlernumber) / 2)
end
return ret
end end
# Returns 0, 1 or 2 as the x/y column value # Returns 0, 1 or 2 as the x position value (left, middle, right column)
def xpositionformula(battlernumber) def xpositionformula(battlernumber)
ret = 0 return (battlernumber % 2) * 2 if SINGLE_ROW_OF_POKEMON # 0, 2, 0, 2, 0, 2
if SINGLE_ROW_OF_POKEMON return (1 - battlernumber) % 3 if (battlernumber / 3).even? # First 3 mons: 1, 0, 2
ret = (battlernumber % 2) * 2 return (1 + battlernumber) % 3 # Second 3 mons: 1, 2, 0
else
ret = (battlernumber / 3).even? ? (19 - battlernumber) % 3 : (19 + battlernumber) % 3
end
return ret
end end
# Returns 0, 1 or 2 as the y position value (top, middle, bottom row)
def ypositionformula(battlernumber) def ypositionformula(battlernumber)
ret = 0 return 1 if SINGLE_ROW_OF_POKEMON # 1, 1, 1, 1, 1, 1
if SINGLE_ROW_OF_POKEMON return ((battlernumber / 3) % 2) * 2 # 0, 0, 0, 2, 2, 2
ret = 1
else
ret = ((battlernumber / 3) % 2) * 2
end
return ret
end end
def moveSprite(i) def moveSprite(i)
spritename = (i > -1) ? "pokemon#{i}" : "trainer" spritename = (i > -1) ? "pokemon#{i}" : "trainer"
speed = (i > -1) ? ANIMATIONSPEED : 2 if !ANIMATION # Skips animation, place directly in end position
if !ANIMATION # Skips animation @sprites[spritename].x = @movements[i][1]
@sprites[spritename].x -= speed * @xmovement[i] @sprites[spritename].y = @movements[i][3]
@xmovement[i] = 0 @movements[i][0] = @movements[i][1]
@sprites[spritename].y -= speed * @ymovement[i] @movements[i][2] = @movements[i][3]
@ymovement[i] = 0 return
end
if @xmovement[i] != 0
direction = (@xmovement[i] > 0) ? -1 : 1
@sprites[spritename].x += speed * direction
@xmovement[i] += direction
end
if @ymovement[i] != 0
direction = (@ymovement[i] > 0) ? -1 : 1
@sprites[spritename].y += speed * direction
@ymovement[i] += direction
end end
@movements[i][4] = System.uptime if !@movements[i][4]
speed = (i > -1) ? APPEAR_SPEED : APPEAR_SPEED * 3
@sprites[spritename].x = lerp(@movements[i][0], @movements[i][1], speed, @movements[i][4], System.uptime)
@sprites[spritename].y = lerp(@movements[i][2], @movements[i][3], speed, @movements[i][4], System.uptime)
@movements[i][0] = @movements[i][1] if @sprites[spritename].x == @movements[i][1]
@movements[i][2] = @movements[i][3] if @sprites[spritename].y == @movements[i][3]
end end
def createBattlers(hide = true) def createBattlers(hide = true)
# Movement in animation # Movement in animation
6.times do |i| Settings::MAX_PARTY_SIZE.times do |i|
# Clear all 6 pokémon sprites and dispose the ones that exists every time # Clear all pokémon sprites and dispose the ones that exists every time
# that this method is call # that this method is call
restartSpritePosition(@sprites, "pokemon#{i}") restartSpritePosition(@sprites, "pokemon#{i}")
next if i >= @hallEntry.size next if i >= @hallEntry.size
xpoint = xpointformula(i) end_x = xpointformula(i)
ypoint = ypointformula(i) end_y = ypointformula(i)
pok = @hallEntry[i]
@sprites["pokemon#{i}"] = PokemonSprite.new(@viewport) @sprites["pokemon#{i}"] = PokemonSprite.new(@viewport)
@sprites["pokemon#{i}"].setOffset(PictureOrigin::TOP_LEFT) @sprites["pokemon#{i}"].setPokemonBitmap(@hallEntry[i])
@sprites["pokemon#{i}"].setPokemonBitmap(pok)
# This method doesn't put the exact coordinates # This method doesn't put the exact coordinates
@sprites["pokemon#{i}"].x = xpoint @sprites["pokemon#{i}"].x = end_x
@sprites["pokemon#{i}"].y = ypoint @sprites["pokemon#{i}"].y = end_y
if @sprites["pokemon#{i}"].bitmap && !@sprites["pokemon#{i}"].disposed? @sprites["pokemon#{i}"].z = Settings::MAX_PARTY_SIZE - i if SINGLE_ROW_OF_POKEMON
@sprites["pokemon#{i}"].x += (128 - @sprites["pokemon#{i}"].bitmap.width) / 2
@sprites["pokemon#{i}"].y += (128 - @sprites["pokemon#{i}"].bitmap.height) / 2
end
@sprites["pokemon#{i}"].z = 7 - i if SINGLE_ROW_OF_POKEMON
next if !hide next if !hide
# Animation distance calculation # Animation distance calculation
horizontal = 1 - xpositionformula(i) x_direction = xpositionformula(i) - 1
vertical = 1 - ypositionformula(i) y_direction = ypositionformula(i) - 1
xdistance = (horizontal == -1) ? -@sprites["pokemon#{i}"].bitmap.width : Graphics.width distance = 0
ydistance = (vertical == -1) ? -@sprites["pokemon#{i}"].bitmap.height : Graphics.height if y_direction == 0
xdistance = ((xdistance - @sprites["pokemon#{i}"].x) / ANIMATIONSPEED).abs + 1 distance = (x_direction > 0) ? end_x : Graphics.width - end_x
ydistance = ((ydistance - @sprites["pokemon#{i}"].y) / ANIMATIONSPEED).abs + 1 distance += @sprites["pokemon#{i}"].bitmap.width / 2
biggerdistance = (xdistance > ydistance) ? xdistance : ydistance else
@xmovement[i] = biggerdistance distance = (y_direction > 0) ? end_y : Graphics.height - end_y
@xmovement[i] *= -1 if horizontal == -1 distance += @sprites["pokemon#{i}"].bitmap.height / 2
@xmovement[i] = 0 if horizontal == 0 end
@ymovement[i] = biggerdistance start_x = end_x - x_direction * distance
@ymovement[i] *= -1 if vertical == -1 start_y = end_y - y_direction * distance
@ymovement[i] = 0 if vertical == 0 @sprites["pokemon#{i}"].x = start_x
# Hide the battlers @sprites["pokemon#{i}"].y = start_y
@sprites["pokemon#{i}"].x += @xmovement[i] * ANIMATIONSPEED @movements[i] = [start_x, end_x, start_y, end_y]
@sprites["pokemon#{i}"].y += @ymovement[i] * ANIMATIONSPEED
end end
end end
def createTrainerBattler def createTrainerBattler
@sprites["trainer"] = IconSprite.new(@viewport) @sprites["trainer"] = IconSprite.new(@viewport)
@sprites["trainer"].setBitmap(GameData::TrainerType.front_sprite_filename($player.trainer_type)) @sprites["trainer"].setBitmap(GameData::TrainerType.player_front_sprite_filename($player.trainer_type))
if SINGLE_ROW_OF_POKEMON if SINGLE_ROW_OF_POKEMON
@sprites["trainer"].x = Graphics.width / 2 @sprites["trainer"].x = Graphics.width / 2
@sprites["trainer"].y = 178 @sprites["trainer"].y = 208
else else
@sprites["trainer"].x = Graphics.width - 96 @sprites["trainer"].x = Graphics.width - 96
@sprites["trainer"].y = 160 @sprites["trainer"].y = 160
end end
@movements.push([Graphics.width / 2, @sprites["trainer"].x, @sprites["trainer"].y, @sprites["trainer"].y])
@sprites["trainer"].z = 9 @sprites["trainer"].z = 9
@sprites["trainer"].ox = @sprites["trainer"].bitmap.width / 2 @sprites["trainer"].ox = @sprites["trainer"].bitmap.width / 2
@sprites["trainer"].oy = @sprites["trainer"].bitmap.height / 2 @sprites["trainer"].oy = @sprites["trainer"].bitmap.height / 2
@@ -253,13 +228,8 @@ class HallOfFame_Scene
@sprites["overlay"].bitmap.clear @sprites["overlay"].bitmap.clear
@sprites["hallbars"].visible = false @sprites["hallbars"].visible = false
end end
@xmovement[@battlerIndex] = 0
@ymovement[@battlerIndex] = 0
if ANIMATION && !SINGLE_ROW_OF_POKEMON # Trainer Animation if ANIMATION && !SINGLE_ROW_OF_POKEMON # Trainer Animation
startpoint = Graphics.width / 2 @sprites["trainer"].x = @movements.last[0]
# 2 is the trainer speed
@xmovement[@battlerIndex] = (startpoint - @sprites["trainer"].x) / 2
@sprites["trainer"].x = startpoint
else else
timer_start = System.uptime timer_start = System.uptime
loop do loop do
@@ -376,7 +346,9 @@ class HallOfFame_Scene
def pbUpdateAnimation def pbUpdateAnimation
if @battlerIndex <= @hallEntry.size if @battlerIndex <= @hallEntry.size
if @xmovement[@battlerIndex] != 0 || @ymovement[@battlerIndex] != 0 if @movements[@battlerIndex] &&
(@movements[@battlerIndex][0] != @movements[@battlerIndex][1] ||
@movements[@battlerIndex][2] != @movements[@battlerIndex][3])
spriteIndex = (@battlerIndex < @hallEntry.size) ? @battlerIndex : -1 spriteIndex = (@battlerIndex < @hallEntry.size) ? @battlerIndex : -1
moveSprite(spriteIndex) moveSprite(spriteIndex)
else else
@@ -404,7 +376,7 @@ class HallOfFame_Scene
Graphics.update Graphics.update
Input.update Input.update
pbUpdate pbUpdate
break if System.uptime - timer_start >= ENTRY_WAIT_TIME * 2 break if System.uptime - timer_start >= WELCOME_WAIT_TIME
end end
setPokemonSpritesOpacity(-1, OPACITY) if !SINGLE_ROW_OF_POKEMON setPokemonSpritesOpacity(-1, OPACITY) if !SINGLE_ROW_OF_POKEMON
createTrainerBattler createTrainerBattler

View File

@@ -17,7 +17,7 @@ class PokemonSystem
attr_accessor :textinput attr_accessor :textinput
def initialize def initialize
@textspeed = 1 # Text speed (0=slow, 1=normal, 2=fast) @textspeed = 1 # Text speed (0=slow, 1=medium, 2=fast, 3=instant)
@battlescene = 0 # Battle effects (animations) (0=on, 1=off) @battlescene = 0 # Battle effects (animations) (0=on, 1=off)
@battlestyle = 0 # Battle style (0=switch, 1=set) @battlestyle = 0 # Battle style (0=switch, 1=set)
@sendtoboxes = 0 # Send to Boxes (0=manual, 1=automatic) @sendtoboxes = 0 # Send to Boxes (0=manual, 1=automatic)
@@ -422,7 +422,7 @@ MenuHandlers.add(:options_menu, :text_speed, {
"name" => _INTL("Text Speed"), "name" => _INTL("Text Speed"),
"order" => 30, "order" => 30,
"type" => EnumOption, "type" => EnumOption,
"parameters" => [_INTL("Slow"), _INTL("Normal"), _INTL("Fast")], "parameters" => [_INTL("Slow"), _INTL("Mid"), _INTL("Fast"), _INTL("Inst")],
"description" => _INTL("Choose the speed at which text appears."), "description" => _INTL("Choose the speed at which text appears."),
"on_select" => proc { |scene| scene.sprites["textbox"].letterbyletter = true }, "on_select" => proc { |scene| scene.sprites["textbox"].letterbyletter = true },
"get_proc" => proc { next $PokemonSystem.textspeed }, "get_proc" => proc { next $PokemonSystem.textspeed },

View File

@@ -5,26 +5,20 @@ class PokemonBoxIcon < IconSprite
def initialize(pokemon, viewport = nil) def initialize(pokemon, viewport = nil)
super(0, 0, viewport) super(0, 0, viewport)
@pokemon = pokemon @pokemon = pokemon
@release = SpriteInterpolator.new @release_timer_start = nil
@startRelease = false
refresh refresh
end end
def releasing? def releasing?
return @release.tweening? return !@release_timer_start.nil?
end end
def release def release
self.ox = self.src_rect.width / 2 # 32 self.ox = self.src_rect.width / 2 # 32
self.oy = self.src_rect.height / 2 # 32 self.oy = self.src_rect.height / 2 # 32
self.x += self.src_rect.width / 2 # 32 self.x += self.src_rect.width / 2 # 32
self.y += self.src_rect.height / 2 # 32 self.y += self.src_rect.height / 2 # 32
@release.tween(self, @release_timer_start = System.uptime
[[SpriteInterpolator::ZOOM_X, 0],
[SpriteInterpolator::ZOOM_Y, 0],
[SpriteInterpolator::OPACITY, 0]],
100)
@startRelease = true
end end
def refresh def refresh
@@ -35,9 +29,17 @@ class PokemonBoxIcon < IconSprite
def update def update
super super
@release.update if releasing?
self.color = Color.new(0, 0, 0, 0) time_now = System.uptime
dispose if @startRelease && !releasing? self.zoom_x = lerp(1.0, 0.0, 1.5, @release_timer_start, System.uptime)
self.zoom_y = self.zoom_x
self.opacity = lerp(255, 0, 1.5, @release_timer_start, System.uptime)
self.color = Color.new(0, 0, 0, 0)
if self.opacity == 0
@release_timer_start = nil
dispose
end
end
end end
end end

View File

@@ -35,11 +35,11 @@ def pbDrawGauge(bitmap, rect, color, value, maxValue)
end end
end end
def calcPoint(x, y, distance, angle) # angle in degrees def calcPoint(x, y, distance, angle) # angle in degrees
angle -= (angle / 360.0).floor * 360 # normalize angle -= (angle / 360.0).floor * 360 # normalize
angle = (angle / 360.0) * (2 * Math::PI) # convert to radians angle = (angle / 360.0) * (2 * Math::PI) # convert to radians
angle = -angle % (2 * Math::PI) # normalize radians angle = -angle % (2 * Math::PI) # normalize radians
point = [(Math.cos(angle) * distance), (Math.sin(angle) * distance)] point = [distance * Math.cos(angle), distance * Math.sin(angle)]
point[0] += x point[0] += x
point[1] += y point[1] += y
return point return point
@@ -670,6 +670,9 @@ end
# #
#=============================================================================== #===============================================================================
class DirectFlowDiagram class DirectFlowDiagram
# Distance travelled by a dot in 1 second.
DOT_SPEED = 80
def initialize(viewport = nil) def initialize(viewport = nil)
@points = [] @points = []
@angles = [] @angles = []
@@ -681,21 +684,25 @@ class DirectFlowDiagram
@distance = 96 @distance = 96
end end
def dispose
@points.each { |point| point.dispose }
end
# 0=none, 1=weak, 2=strong # 0=none, 1=weak, 2=strong
def setFlowStrength(strength) def setFlowStrength(strength)
@strength = strength @strength = strength
end end
def visible=(value) def visible=(value)
@points.each do |point| @points.each { |point| point.visible = value }
point.visible = value
end
end end
def dispose def color=(value)
@points.each do |point| @points.each { |point| point.color = value }
point.dispose end
end
def setAngle(angle1)
@angle = angle1 - ((angle1 / 360).floor * 360)
end end
def ensurePoint(j) def ensurePoint(j)
@@ -725,18 +732,9 @@ class DirectFlowDiagram
end end
i += (@strength == 2) ? 16 : 32 i += (@strength == 2) ? 16 : 32
end end
@offset += (@strength == 2) ? 3 : 2 offset_delta = System.uptime * DOT_SPEED
@offset %= @distance offset_delta *= 1.5 if @strength == 2
end @offset = offset_delta % @distance
def color=(value)
@points.each do |point|
point.color = value
end
end
def setAngle(angle1)
@angle = angle1 - ((angle1 / 360).floor * 360)
end end
end end
@@ -744,6 +742,9 @@ end
# #
#=============================================================================== #===============================================================================
class FlowDiagram class FlowDiagram
# Distance travelled by a dot in 1 second.
DOT_SPEED = 80
def initialize(viewport = nil) def initialize(viewport = nil)
@points = [] @points = []
@angles = [] @angles = []
@@ -755,21 +756,21 @@ class FlowDiagram
@distance = 96 @distance = 96
end end
# 0=none, 1=weak, 2=strong def dispose
def setFlowStrength(strength) @points.each { |point| point.dispose }
@strength = strength
end end
def visible=(value) def visible=(value)
@points.each do |point| @points.each { |point| point.visible = value }
point.visible = value
end
end end
def dispose def color=(value)
@points.each do |point| @points.each { |point| point.color = value }
point.dispose end
end
# 0=none, 1=weak, 2=strong
def setFlowStrength(strength)
@strength = strength
end end
def ensurePoint(j) def ensurePoint(j)
@@ -781,6 +782,15 @@ class FlowDiagram
@points[j].visible = (@strength != 0) @points[j].visible = (@strength != 0)
end end
def setRange(angle1, angle2)
@startAngle = angle1 - ((angle1 / 360).floor * 360)
@endAngle = angle2 - ((angle2 / 360).floor * 360)
if @startAngle == @endAngle && angle1 != angle2
@startAngle = 0
@endAngle = 359.99
end
end
def withinRange(angle, startAngle, endAngle) def withinRange(angle, startAngle, endAngle)
if startAngle > endAngle if startAngle > endAngle
return (angle >= startAngle || angle <= endAngle) && return (angle >= startAngle || angle <= endAngle) &&
@@ -808,23 +818,9 @@ class FlowDiagram
end end
i += (@strength == 2) ? 10 : 20 i += (@strength == 2) ? 10 : 20
end end
@offset -= (@strength == 2) ? 3 : 2 offset_delta = -System.uptime * DOT_SPEED
@offset %= (360 * 6) offset_delta *= 1.5 if @strength == 2
end @offset = offset_delta % (360 * 6)
def color=(value)
@points.each do |point|
point.color = value
end
end
def setRange(angle1, angle2)
@startAngle = angle1 - ((angle1 / 360).floor * 360)
@endAngle = angle2 - ((angle2 / 360).floor * 360)
if @startAngle == @endAngle && angle1 != angle2
@startAngle = 0
@endAngle = 359.99
end
end end
end end
@@ -870,7 +866,7 @@ class PurifyChamberSetView < Sprite
setcount.times do |i| setcount.times do |i|
@flows[i] = FlowDiagram.new(self.viewport) if !@flows[i] @flows[i] = FlowDiagram.new(self.viewport) if !@flows[i]
angle = 360 - (i * 360 / setcount) angle = 360 - (i * 360 / setcount)
angle += 90 # start at 12 not 3 o'clock angle += 90 # start at 12 not 3 o'clock
endAngle = angle - (360 / setcount) endAngle = angle - (360 / setcount)
@flows[i].setRange(endAngle, angle) @flows[i].setRange(endAngle, angle)
@flows[i].setFlowStrength(@chamber[@set].affinity(i)) @flows[i].setFlowStrength(@chamber[@set].affinity(i))
@@ -913,7 +909,7 @@ class PurifyChamberSetView < Sprite
if pos.nil? if pos.nil?
@cursor = 0 @cursor = 0
else else
pos -= (pos / points).floor * points # modulus pos -= (pos / points).floor * points # modulus
pos *= 2 if @chamber.setCount(@set) == PurifyChamber::SETSIZE pos *= 2 if @chamber.setCount(@set) == PurifyChamber::SETSIZE
@cursor = pos + 1 @cursor = pos + 1
end end

View File

@@ -216,19 +216,19 @@ class PokemonEntryScene
pbPlayDecisionSE pbPlayDecisionSE
break break
end end
elsif index == -1 # Insert a space elsif index == -1 # Insert a space
if @sprites["entry"].insert(" ") if @sprites["entry"].insert(" ")
pbPlayDecisionSE pbPlayDecisionSE
else else
pbPlayBuzzerSE pbPlayBuzzerSE
end end
elsif index == -2 # Change character set elsif index == -2 # Change character set
pbPlayDecisionSE pbPlayDecisionSE
@symtype += 1 @symtype += 1
@symtype = 0 if @symtype >= @@Characters.length @symtype = 0 if @symtype >= @@Characters.length
@sprites["entry2"].setCharset(@@Characters[@symtype][0]) @sprites["entry2"].setCharset(@@Characters[@symtype][0])
@sprites["entry2"].setOtherCharset(@@Characters[@symtype][1]) @sprites["entry2"].setOtherCharset(@@Characters[@symtype][1])
else # Insert given character else # Insert given character
if @sprites["entry"].insert(@sprites["entry2"].character) if @sprites["entry"].insert(@sprites["entry2"].character)
pbPlayDecisionSE pbPlayDecisionSE
else else

View File

@@ -6,28 +6,23 @@
# - The number is either 0 (easy), 1 (default) or 2 (hard). # - The number is either 0 (easy), 1 (default) or 2 (hard).
#=============================================================================== #===============================================================================
class SlotMachineReel < BitmapSprite class SlotMachineReel < BitmapSprite
attr_accessor :reel SCROLL_SPEED = 640 # Pixels moved per second
attr_accessor :toppos ICONS_SETS = [[3, 2, 7, 6, 3, 1, 5, 2, 3, 0, 6, 4, 7, 5, 1, 3, 2, 3, 6, 0, 4, 5], # Reel 1
attr_accessor :spinning [0, 4, 1, 2, 7, 4, 6, 0, 1, 5, 4, 0, 1, 3, 4, 0, 1, 6, 7, 0, 1, 5], # Reel 2
attr_accessor :stopping [6, 2, 1, 4, 3, 2, 1, 4, 7, 3, 2, 1, 4, 3, 7, 2, 4, 3, 1, 2, 4, 5]] # Reel 3
attr_accessor :slipping
SCROLLSPEED = 16 # Must be a divisor of 48
ICONSPOOL = [[0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7], # 0 - Easy
[0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7], # 1 - Medium (default)
[0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7]] # 2 - Hard
SLIPPING = [0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3] SLIPPING = [0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3]
def initialize(x, y, difficulty = 1) def initialize(x, y, reel_num, difficulty = 1)
@viewport = Viewport.new(x, y, 64, 144) @viewport = Viewport.new(x, y, 64, 144)
@viewport.z = 99999 @viewport.z = 99999
super(64, 144, @viewport) super(64, 144, @viewport)
@reel = [] @reel_num = reel_num
ICONSPOOL[difficulty].length.times do |i| @difficulty = difficulty
@reel.push(ICONSPOOL[difficulty][i]) @reel = ICONS_SETS[reel_num - 1].clone
end
@reel.shuffle!
@toppos = 0 @toppos = 0
@current_y_pos = -1
@spin_speed = SCROLL_SPEED
@spin_speed /= 1.5 if difficulty == 0
@spinning = false @spinning = false
@stopping = false @stopping = false
@slipping = 0 @slipping = 0
@@ -39,11 +34,25 @@ class SlotMachineReel < BitmapSprite
def startSpinning def startSpinning
@spinning = true @spinning = true
@spin_timer_start = System.uptime
@initial_index = @index + 1
@current_y_pos = -1
end
def spinning?
return @spinning
end end
def stopSpinning(noslipping = false) def stopSpinning(noslipping = false)
@stopping = true @stopping = true
@slipping = SLIPPING[rand(SLIPPING.length)] @slipping = SLIPPING.sample
if @difficulty == 0 # Easy
second_slipping = SLIPPING.sample
@slipping = [@slipping, second_slipping].min
elsif @difficulty == 2 # Hard
second_slipping = SLIPPING.sample
@slipping = [@slipping, second_slipping].max
end
@slipping = 0 if noslipping @slipping = 0 if noslipping
end end
@@ -59,15 +68,28 @@ class SlotMachineReel < BitmapSprite
def update def update
self.bitmap.clear self.bitmap.clear
if @toppos == 0 && @stopping && @slipping == 0
@spinning = @stopping = false
end
if @spinning if @spinning
@toppos += SCROLLSPEED new_y_pos = (System.uptime - @spin_timer_start) * @spin_speed
if @toppos > 0 new_index = (new_y_pos / @images.height).to_i
@toppos -= 48 old_index = (@current_y_pos / @images.height).to_i
@index = (@index + 1) % @reel.length @current_y_pos = new_y_pos
@slipping -= 1 if @slipping > 0 @toppos = new_y_pos
while @toppos > 0
@toppos -= @images.height
end
if new_index != old_index
if @stopping
if @slipping == 0
@spinning = false
@stopping = false
@toppos = 0
else
@slipping = [@slipping - new_index + old_index, 0].max
end
end
if @spinning
@index = (new_index + @initial_index) % @reel.length
end
end end
end end
4.times do |i| 4.times do |i|
@@ -130,11 +152,11 @@ class SlotMachineScene
reel1 = @sprites["reel1"].showing reel1 = @sprites["reel1"].showing
reel2 = @sprites["reel2"].showing reel2 = @sprites["reel2"].showing
reel3 = @sprites["reel3"].showing reel3 = @sprites["reel3"].showing
combinations = [[reel1[1], reel2[1], reel3[1]], # Centre row combinations = [[reel1[1], reel2[1], reel3[1]], # Centre row
[reel1[0], reel2[0], reel3[0]], # Top row [reel1[0], reel2[0], reel3[0]], # Top row
[reel1[2], reel2[2], reel3[2]], # Bottom row [reel1[2], reel2[2], reel3[2]], # Bottom row
[reel1[0], reel2[1], reel3[2]], # Diagonal top left -> bottom right [reel1[0], reel2[1], reel3[2]], # Diagonal top left -> bottom right
[reel1[2], reel2[1], reel3[0]]] # Diagonal bottom left -> top right [reel1[2], reel2[1], reel3[0]]] # Diagonal bottom left -> top right
combinations.length.times do |i| combinations.length.times do |i|
break if i >= 1 && @wager <= 1 # One coin = centre row only break if i >= 1 && @wager <= 1 # One coin = centre row only
break if i >= 3 && @wager <= 2 # Two coins = three rows only break if i >= 3 && @wager <= 2 # Two coins = three rows only
@@ -206,18 +228,25 @@ class SlotMachineScene
@sprites["light2"].visible = false @sprites["light2"].visible = false
@sprites["window1"].src_rect.set(0, 0, 152, 208) @sprites["window1"].src_rect.set(0, 0, 152, 208)
# Pay out # Pay out
timer_start = System.uptime
last_paid_tick = -1
loop do loop do
break if @sprites["payout"].score <= 0 break if @sprites["payout"].score <= 0
Graphics.update Graphics.update
Input.update Input.update
update update
@sprites["payout"].score -= 1 this_tick = ((System.uptime - timer_start) * 20).to_i # Pay out 1 coin every 1/20 seconds
@sprites["credit"].score += 1 if this_tick != last_paid_tick
@sprites["payout"].score -= 1
@sprites["credit"].score += 1
this_tick = last_paid_tick
end
if Input.trigger?(Input::USE) || @sprites["credit"].score == Settings::MAX_COINS if Input.trigger?(Input::USE) || @sprites["credit"].score == Settings::MAX_COINS
@sprites["credit"].score += @sprites["payout"].score @sprites["credit"].score += @sprites["payout"].score
@sprites["payout"].score = 0 @sprites["payout"].score = 0
end end
end end
# Wait
timer_start = System.uptime timer_start = System.uptime
loop do loop do
Graphics.update Graphics.update
@@ -247,9 +276,9 @@ class SlotMachineScene
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height) @viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = 99999 @viewport.z = 99999
addBackgroundPlane(@sprites, "bg", "Slot Machine/bg", @viewport) addBackgroundPlane(@sprites, "bg", "Slot Machine/bg", @viewport)
@sprites["reel1"] = SlotMachineReel.new(64, 112, difficulty) @sprites["reel1"] = SlotMachineReel.new(64, 112, 1, difficulty)
@sprites["reel2"] = SlotMachineReel.new(144, 112, difficulty) @sprites["reel2"] = SlotMachineReel.new(144, 112, 2, difficulty)
@sprites["reel3"] = SlotMachineReel.new(224, 112, difficulty) @sprites["reel3"] = SlotMachineReel.new(224, 112, 3, difficulty)
(1..3).each do |i| (1..3).each do |i|
@sprites["button#{i}"] = IconSprite.new(68 + (80 * (i - 1)), 260, @viewport) @sprites["button#{i}"] = IconSprite.new(68 + (80 * (i - 1)), 260, @viewport)
@sprites["button#{i}"].setBitmap("Graphics/UI/Slot Machine/button") @sprites["button#{i}"].setBitmap("Graphics/UI/Slot Machine/button")
@@ -304,18 +333,18 @@ class SlotMachineScene
update update
if Input.trigger?(Input::USE) if Input.trigger?(Input::USE)
pbSEPlay("Slots stop") pbSEPlay("Slots stop")
if @sprites["reel1"].spinning if @sprites["reel1"].spinning?
@sprites["reel1"].stopSpinning(@replay) @sprites["reel1"].stopSpinning(@replay)
@sprites["button1"].visible = true @sprites["button1"].visible = true
elsif @sprites["reel2"].spinning elsif @sprites["reel2"].spinning?
@sprites["reel2"].stopSpinning(@replay) @sprites["reel2"].stopSpinning(@replay)
@sprites["button2"].visible = true @sprites["button2"].visible = true
elsif @sprites["reel3"].spinning elsif @sprites["reel3"].spinning?
@sprites["reel3"].stopSpinning(@replay) @sprites["reel3"].stopSpinning(@replay)
@sprites["button3"].visible = true @sprites["button3"].visible = true
end end
end end
if !@sprites["reel3"].spinning if !@sprites["reel3"].spinning?
@gameEnd = true @gameEnd = true
@gameRunning = false @gameRunning = false
end end

View File

@@ -75,11 +75,10 @@ end
# #
#=============================================================================== #===============================================================================
class MiningGameCursor < BitmapSprite class MiningGameCursor < BitmapSprite
attr_accessor :mode
attr_accessor :position attr_accessor :position
attr_accessor :hit attr_accessor :mode
attr_accessor :counter
HIT_FRAME_DURATION = 0.05 # In seconds
TOOL_POSITIONS = [[1, 0], [1, 1], [1, 1], [0, 0], [0, 0], TOOL_POSITIONS = [[1, 0], [1, 1], [1, 1], [0, 0], [0, 0],
[0, 2], [0, 2], [0, 0], [0, 0], [0, 2], [0, 2]] # Graphic, position [0, 2], [0, 2], [0, 0], [0, 0], [0, 2], [0, 2]] # Graphic, position
@@ -90,51 +89,53 @@ class MiningGameCursor < BitmapSprite
@position = position @position = position
@mode = mode @mode = mode
@hit = 0 # 0=regular, 1=hit item, 2=hit iron @hit = 0 # 0=regular, 1=hit item, 2=hit iron
@counter = 0
@cursorbitmap = AnimatedBitmap.new("Graphics/UI/Mining/cursor") @cursorbitmap = AnimatedBitmap.new("Graphics/UI/Mining/cursor")
@toolbitmap = AnimatedBitmap.new("Graphics/UI/Mining/tools") @toolbitmap = AnimatedBitmap.new("Graphics/UI/Mining/tools")
@hitsbitmap = AnimatedBitmap.new("Graphics/UI/Mining/hits") @hitsbitmap = AnimatedBitmap.new("Graphics/UI/Mining/hits")
update update
end end
def isAnimating? def animate(hit)
return @counter > 0 @hit = hit
@hit_timer_start = System.uptime
end end
def animate(hit) def isAnimating?
@counter = 22 return !@hit_timer_start.nil?
@hit = hit
end end
def update def update
self.bitmap.clear self.bitmap.clear
x = 32 * (@position % MiningGameScene::BOARD_WIDTH) x = 32 * (@position % MiningGameScene::BOARD_WIDTH)
y = 32 * (@position / MiningGameScene::BOARD_WIDTH) y = 32 * (@position / MiningGameScene::BOARD_WIDTH)
if @counter > 0 if @hit_timer_start
@counter -= 1 hit_frame = ((System.uptime - @hit_timer_start) / HIT_FRAME_DURATION).to_i
toolx = x @hit_timer_start = nil if hit_frame >= TOOL_POSITIONS.length
tooly = y if @hit_timer_start
i = 10 - (@counter / 2).floor toolx = x
case TOOL_POSITIONS[i][1] tooly = y
when 1 case TOOL_POSITIONS[hit_frame][1]
toolx -= 8 when 1
tooly += 8 toolx -= 8
when 2 tooly += 8
toolx += 6 when 2
end toolx += 6
self.bitmap.blt(toolx, tooly, @toolbitmap.bitmap, end
Rect.new(96 * TOOL_POSITIONS[i][0], 96 * @mode, 96, 96)) self.bitmap.blt(toolx, tooly, @toolbitmap.bitmap,
if i < 5 && i.even? Rect.new(96 * TOOL_POSITIONS[hit_frame][0], 96 * @mode, 96, 96))
if @hit == 2 if hit_frame < 5 && hit_frame.even?
self.bitmap.blt(x - 64, y, @hitsbitmap.bitmap, Rect.new(160 * 2, 0, 160, 160)) if @hit == 2
else self.bitmap.blt(x - 64, y, @hitsbitmap.bitmap, Rect.new(160 * 2, 0, 160, 160))
self.bitmap.blt(x - 64, y, @hitsbitmap.bitmap, Rect.new(160 * @mode, 0, 160, 160)) else
self.bitmap.blt(x - 64, y, @hitsbitmap.bitmap, Rect.new(160 * @mode, 0, 160, 160))
end
end
if @hit == 1 && hit_frame < 3
self.bitmap.blt(x - 64, y, @hitsbitmap.bitmap, Rect.new(160 * hit_frame, 160, 160, 160))
end end
end end
if @hit == 1 && i < 3 end
self.bitmap.blt(x - 64, y, @hitsbitmap.bitmap, Rect.new(160 * i, 160, 160, 160)) if !@hit_timer_start
end
else
self.bitmap.blt(x, y + 64, @cursorbitmap.bitmap, Rect.new(32 * @mode, 0, 32, 32)) self.bitmap.blt(x, y + 64, @cursorbitmap.bitmap, Rect.new(32 * @mode, 0, 32, 32))
end end
end end

View File

@@ -491,6 +491,7 @@ class MapScreenScene
end end
end end
end end
# TODO: FPS. Scroll speed with arrow keys. Can probably leave this alone.
if Input.press?(Input::UP) if Input.press?(Input::UP)
@mapsprites.each do |i| @mapsprites.each do |i|
i[1].y += 4 if i i[1].y += 4 if i

View File

@@ -77,7 +77,7 @@ module BattleAnimationEditor
menuwindow.update menuwindow.update
hit = menuwindow.hittest hit = menuwindow.hittest
menuwindow.index = hit if hit >= 0 menuwindow.index = hit if hit >= 0
if Input.trigger?(Input::MOUSELEFT) || Input.trigger?(Input::MOUSERIGHT) # Left or right button if Input.trigger?(Input::MOUSELEFT) || Input.trigger?(Input::MOUSERIGHT) # Left or right button
menuwindow.dispose menuwindow.dispose
return hit return hit
end end
@@ -86,7 +86,7 @@ module BattleAnimationEditor
menuwindow.dispose menuwindow.dispose
return hit return hit
end end
if Input.trigger?(Input::BACK) # Escape if Input.trigger?(Input::BACK) # Escape
break break
end end
end end
@@ -198,7 +198,7 @@ module BattleAnimationEditor
right.x += self.x right.x += self.x
right.y += self.y right.y += self.y
swatchrects = [] swatchrects = []
repeattime = Input.time?(Input::MOUSELEFT) / 1000 repeattime = Input.time?(Input::MOUSELEFT)
NUMFRAMES.times do |i| NUMFRAMES.times do |i|
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
@@ -211,7 +211,7 @@ module BattleAnimationEditor
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 > 0.75
@start -= 3 @start -= 3
else else
@start -= 1 @start -= 1
@@ -221,7 +221,7 @@ module BattleAnimationEditor
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 > 0.75
@start += 3 @start += 3
else else
@start += 1 @start += 1
@@ -903,7 +903,7 @@ module BattleAnimationEditor
end end
updateInput updateInput
# @testscreen.update # @testscreen.update
# self.bitmap=@testscreen.bitmap # self.bitmap = @testscreen.bitmap
if @currentframe < @animation.length if @currentframe < @animation.length
PBAnimation::MAX_SPRITES.times do |i| PBAnimation::MAX_SPRITES.times do |i|
next if !@dirty[i] next if !@dirty[i]

View File

@@ -237,12 +237,14 @@ module BattleAnimationEditor
def text=(value) def text=(value)
@text = value @text = value
@cursor_shown = true
self.invalidate self.invalidate
end end
def initialize(label, text) def initialize(label, text)
super(label) super(label)
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
@label = label @label = label
@text = text @text = text
@cursor = text.scan(/./m).length @cursor = text.scan(/./m).length
@@ -254,7 +256,8 @@ module BattleAnimationEditor
@text = "" @text = ""
chars.each { |char| @text += char } chars.each { |char| @text += char }
@cursor += 1 @cursor += 1
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.changed = true self.changed = true
self.invalidate self.invalidate
end end
@@ -265,21 +268,25 @@ module BattleAnimationEditor
@text = "" @text = ""
chars.each { |char| @text += char } chars.each { |char| @text += char }
@cursor -= 1 @cursor -= 1
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.changed = true self.changed = true
self.invalidate self.invalidate
end end
def update def update
@frame += 1 cursor_to_show = ((System.uptime - @cursor_timer_start) / 0.35).to_i % 2 == 0
@frame %= 20
self.changed = false self.changed = false
self.invalidate if (@frame % 10) == 0 if cursor_to_show != @cursor_shown
@cursor_shown = cursor_to_show
self.invalidate
end
# Moving cursor # Moving cursor
if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT) if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
if @cursor > 0 if @cursor > 0
@cursor -= 1 @cursor -= 1
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.invalidate self.invalidate
end end
return return
@@ -287,7 +294,8 @@ module BattleAnimationEditor
if Input.triggerex?(:RIGHT) || Input.repeatex?(:RIGHT) if Input.triggerex?(:RIGHT) || Input.repeatex?(:RIGHT)
if @cursor < self.text.scan(/./m).length if @cursor < self.text.scan(/./m).length
@cursor += 1 @cursor += 1
@frame = 0 @cursor_timer_start = System.uptime
@cursor_shown = true
self.invalidate self.invalidate
end end
return return
@@ -344,13 +352,13 @@ module BattleAnimationEditor
# Draw text # Draw text
shadowtext(bitmap, x, y, textwidth + 4, 32, c) shadowtext(bitmap, x, y, textwidth + 4, 32, c)
# Draw cursor if necessary # Draw cursor if necessary
if ((@frame / 10) & 1) == 0 && i == @cursor if i == @cursor && @cursor_shown
bitmap.fill_rect(x, y + 4, 2, 24, Color.new(120, 120, 120)) bitmap.fill_rect(x, y + 4, 2, 24, Color.new(120, 120, 120))
end end
# Add x to drawn text width # Add x to drawn text width
x += textwidth x += textwidth
end end
if ((@frame / 10) & 1) == 0 && textscan.length == @cursor if textscan.length == @cursor && @cursor_shown
bitmap.fill_rect(x, y + 4, 2, 24, Color.new(120, 120, 120)) bitmap.fill_rect(x, y + 4, 2, 24, Color.new(120, 120, 120))
end end
# Draw outline # Draw outline
@@ -419,12 +427,12 @@ module BattleAnimationEditor
left = toAbsoluteRect(@leftarrow) left = toAbsoluteRect(@leftarrow)
right = toAbsoluteRect(@rightarrow) right = toAbsoluteRect(@rightarrow)
oldvalue = self.curvalue oldvalue = self.curvalue
repeattime = Input.time?(Input::MOUSELEFT) / 1000 repeattime = Input.time?(Input::MOUSELEFT)
# Left arrow # Left arrow
if left.contains?(mousepos[0], mousepos[1]) if left.contains?(mousepos[0], mousepos[1])
if repeattime > 3000 if repeattime > 3.0
self.curvalue -= 10 self.curvalue -= 10
elsif repeattime > 1500 elsif repeattime > 1.5
self.curvalue -= 5 self.curvalue -= 5
else else
self.curvalue -= 1 self.curvalue -= 1
@@ -435,9 +443,9 @@ module BattleAnimationEditor
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 > 3.0
self.curvalue += 10 self.curvalue += 10
elsif repeattime > 1500 elsif repeattime > 1.5
self.curvalue += 5 self.curvalue += 5
else else
self.curvalue += 1 self.curvalue += 1
@@ -671,12 +679,12 @@ module BattleAnimationEditor
left = toAbsoluteRect(@leftarrow) left = toAbsoluteRect(@leftarrow)
right = toAbsoluteRect(@rightarrow) right = toAbsoluteRect(@rightarrow)
oldvalue = self.curvalue oldvalue = self.curvalue
repeattime = Input.time?(Input::MOUSELEFT) / 1000 repeattime = Input.time?(Input::MOUSELEFT)
# Left arrow # Left arrow
if left.contains?(mousepos[0], mousepos[1]) if left.contains?(mousepos[0], mousepos[1])
if repeattime > 3000 if repeattime > 3.0
self.curvalue -= 10 self.curvalue -= 10
elsif repeattime > 1500 elsif repeattime > 1.5
self.curvalue -= 5 self.curvalue -= 5
else else
self.curvalue -= 1 self.curvalue -= 1
@@ -686,9 +694,9 @@ module BattleAnimationEditor
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 > 3.0
self.curvalue += 10 self.curvalue += 10
elsif repeattime > 1500 elsif repeattime > 1.5
self.curvalue += 5 self.curvalue += 5
else else
self.curvalue += 1 self.curvalue += 1

View File

@@ -241,7 +241,7 @@ module BattleAnimationEditor
Graphics.update Graphics.update
Input.update Input.update
sliderwin2.update sliderwin2.update
if sliderwin2.changed?(0) # Number of frames if sliderwin2.changed?(0) # Number of frames
if path if path
path = path.smoothPointPath(sliderwin2.value(0), false) path = path.smoothPointPath(sliderwin2.value(0), false)
i = 0 i = 0
@@ -341,7 +341,7 @@ module BattleAnimationEditor
points.clear points.clear
if showline if showline
path = curveToPointPath(curve, sliderwin2.value(0)) 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| path.each do |point|
points.push(PointSprite.new(point[0], point[1], canvas.viewport)) points.push(PointSprite.new(point[0], point[1], canvas.viewport))
end end
@@ -400,11 +400,11 @@ module BattleAnimationEditor
path.each do |point| path.each do |point|
points.push(PointSprite.new(point[0], point[1], canvas.viewport)) points.push(PointSprite.new(point[0], point[1], canvas.viewport))
end end
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) } # File.open("pointpath.txt", "wb") { |f| f.write(path.inspect) }
sliderwin2.visible = true sliderwin2.visible = true
next next
elsif sliderwin2.changed?(okbutton) && path 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) neededsize = canvas.currentframe + sliderwin2.value(0)
if neededsize > canvas.animation.length if neededsize > canvas.animation.length
canvas.animation.resize(neededsize) canvas.animation.resize(neededsize)

View File

@@ -157,15 +157,15 @@ module BattleAnimationEditor
_INTL("Rename"), _INTL("Rename"),
_INTL("Delete")], -1) _INTL("Delete")], -1)
case cmd2 case cmd2
when 0 # Load Animation when 0 # Load Animation
canvas.loadAnimation(animations[cmdwin.index]) canvas.loadAnimation(animations[cmdwin.index])
animwin.animbitmap = canvas.animbitmap animwin.animbitmap = canvas.animbitmap
animations.selected = cmdwin.index animations.selected = cmdwin.index
break break
when 1 # Rename when 1 # Rename
pbAnimName(animations[cmdwin.index], cmdwin) pbAnimName(animations[cmdwin.index], cmdwin)
cmdwin.refresh cmdwin.refresh
when 2 # Delete when 2 # Delete
if pbConfirmMessage(_INTL("Are you sure you want to delete this animation?")) if pbConfirmMessage(_INTL("Are you sure you want to delete this animation?"))
animations[cmdwin.index] = PBAnimation.new animations[cmdwin.index] = PBAnimation.new
cmdwin.commands[cmdwin.index] = _INTL("{1} {2}", cmdwin.index, animations[cmdwin.index].name) cmdwin.commands[cmdwin.index] = _INTL("{1} {2}", cmdwin.index, animations[cmdwin.index].name)
@@ -409,13 +409,13 @@ module BattleAnimationEditor
cmdwin.index != cmdEditBG && cmdwin.index != cmdEditBG &&
cmdwin.index != cmdNewFO && cmdwin.index != cmdNewFO &&
cmdwin.index != cmdEditFO cmdwin.index != cmdEditFO
if framewindow.changed?(1) # Set Frame if framewindow.changed?(1) # Set Frame
canvas.animation.timing[cmdwin.index].frame = framewindow.value(0) - 1 canvas.animation.timing[cmdwin.index].frame = framewindow.value(0) - 1
cmdwin.commands[cmdwin.index] = canvas.animation.timing[cmdwin.index].to_s cmdwin.commands[cmdwin.index] = canvas.animation.timing[cmdwin.index].to_s
cmdwin.refresh cmdwin.refresh
next next
end end
if framewindow.changed?(2) # Delete Timing if framewindow.changed?(2) # Delete Timing
canvas.animation.timing.delete_at(cmdwin.index) canvas.animation.timing.delete_at(cmdwin.index)
cmdwin.commands.delete_at(cmdwin.index) cmdwin.commands.delete_at(cmdwin.index)
cmdNewSound -= 1 if cmdNewSound >= 0 cmdNewSound -= 1 if cmdNewSound >= 0
@@ -429,35 +429,35 @@ module BattleAnimationEditor
end end
if Input.trigger?(Input::USE) if Input.trigger?(Input::USE)
redrawcmds = false redrawcmds = false
if cmdwin.index == cmdNewSound # Add new sound if cmdwin.index == cmdNewSound # Add new sound
newaudio = PBAnimTiming.new(0) newaudio = PBAnimTiming.new(0)
if pbSelectSE(canvas, newaudio) if pbSelectSE(canvas, newaudio)
newaudio.frame = framewindow.value(0) - 1 newaudio.frame = framewindow.value(0) - 1
canvas.animation.timing.push(newaudio) canvas.animation.timing.push(newaudio)
redrawcmds = true redrawcmds = true
end end
elsif cmdwin.index == cmdNewBG # Add new background graphic set elsif cmdwin.index == cmdNewBG # Add new background graphic set
newtiming = PBAnimTiming.new(1) newtiming = PBAnimTiming.new(1)
if pbSelectBG(canvas, newtiming) if pbSelectBG(canvas, newtiming)
newtiming.frame = framewindow.value(0) - 1 newtiming.frame = framewindow.value(0) - 1
canvas.animation.timing.push(newtiming) canvas.animation.timing.push(newtiming)
redrawcmds = true redrawcmds = true
end end
elsif cmdwin.index == cmdEditBG # Add new background edit elsif cmdwin.index == cmdEditBG # Add new background edit
newtiming = PBAnimTiming.new(2) newtiming = PBAnimTiming.new(2)
if pbEditBG(canvas, newtiming) if pbEditBG(canvas, newtiming)
newtiming.frame = framewindow.value(0) - 1 newtiming.frame = framewindow.value(0) - 1
canvas.animation.timing.push(newtiming) canvas.animation.timing.push(newtiming)
redrawcmds = true redrawcmds = true
end end
elsif cmdwin.index == cmdNewFO # Add new foreground graphic set elsif cmdwin.index == cmdNewFO # Add new foreground graphic set
newtiming = PBAnimTiming.new(3) newtiming = PBAnimTiming.new(3)
if pbSelectBG(canvas, newtiming) if pbSelectBG(canvas, newtiming)
newtiming.frame = framewindow.value(0) - 1 newtiming.frame = framewindow.value(0) - 1
canvas.animation.timing.push(newtiming) canvas.animation.timing.push(newtiming)
redrawcmds = true redrawcmds = true
end end
elsif cmdwin.index == cmdEditFO # Add new foreground edit elsif cmdwin.index == cmdEditFO # Add new foreground edit
newtiming = PBAnimTiming.new(4) newtiming = PBAnimTiming.new(4)
if pbEditBG(canvas, newtiming) if pbEditBG(canvas, newtiming)
newtiming.frame = framewindow.value(0) - 1 newtiming.frame = framewindow.value(0) - 1
@@ -596,7 +596,7 @@ module BattleAnimationEditor
Input.update Input.update
cmdwin.update cmdwin.update
maxsizewindow.update maxsizewindow.update
if maxsizewindow.changed?(8) # OK if maxsizewindow.changed?(8) # OK
timing.name = File.basename(filename, ".*") timing.name = File.basename(filename, ".*")
timing.bgX = maxsizewindow.value(1) timing.bgX = maxsizewindow.value(1)
timing.bgY = maxsizewindow.value(2) timing.bgY = maxsizewindow.value(2)
@@ -647,7 +647,7 @@ module BattleAnimationEditor
Graphics.update Graphics.update
Input.update Input.update
maxsizewindow.update maxsizewindow.update
if maxsizewindow.changed?(8) # OK if maxsizewindow.changed?(8) # OK
if maxsizewindow.controls[1].checked || if maxsizewindow.controls[1].checked ||
maxsizewindow.controls[2].checked || maxsizewindow.controls[2].checked ||
maxsizewindow.controls[3].checked || maxsizewindow.controls[3].checked ||
@@ -694,7 +694,7 @@ module BattleAnimationEditor
endvalue = sliderwin2.value(1) - 1 endvalue = sliderwin2.value(1) - 1
dstvalue = sliderwin2.value(2) - 1 dstvalue = sliderwin2.value(2) - 1
length = (endvalue - startvalue) + 1 length = (endvalue - startvalue) + 1
if length > 0 # Ensure correct overlap handling if length > 0 # Ensure correct overlap handling
if startvalue < dstvalue if startvalue < dstvalue
startvalue += length startvalue += length
dstvalue += length dstvalue += length
@@ -1037,7 +1037,7 @@ module BattleAnimationEditor
sliderwin.invalidate sliderwin.invalidate
end end
next next
elsif Input.trigger?(Input::MOUSERIGHT) # Right mouse button elsif Input.trigger?(Input::MOUSERIGHT) # Right mouse button
mousepos = Mouse.getMousePos mousepos = Mouse.getMousePos
mousepos = [0, 0] if !mousepos mousepos = [0, 0] if !mousepos
commands = [ commands = [
@@ -1051,29 +1051,29 @@ module BattleAnimationEditor
] ]
hit = pbTrackPopupMenu(commands) hit = pbTrackPopupMenu(commands)
case hit case hit
when 0 # Properties when 0 # Properties
if canvas.currentCel if canvas.currentCel
pbCellProperties(canvas) pbCellProperties(canvas)
canvas.invalidateCel(canvas.currentcel) canvas.invalidateCel(canvas.currentcel)
end end
when 1 # Cut when 1 # Cut
if canvas.currentCel if canvas.currentCel
Clipboard.setData(canvas.currentCel, "PBAnimCel") Clipboard.setData(canvas.currentCel, "PBAnimCel")
canvas.deleteCel(canvas.currentcel) canvas.deleteCel(canvas.currentcel)
end end
when 2 # Copy when 2 # Copy
Clipboard.setData(canvas.currentCel, "PBAnimCel") if canvas.currentCel Clipboard.setData(canvas.currentCel, "PBAnimCel") if canvas.currentCel
when 3 # Paste when 3 # Paste
canvas.pasteCel(mousepos[0], mousepos[1]) canvas.pasteCel(mousepos[0], mousepos[1])
when 4 # Delete when 4 # Delete
canvas.deleteCel(canvas.currentcel) canvas.deleteCel(canvas.currentcel)
when 5 # Renumber when 5 # Renumber
if canvas.currentcel && canvas.currentcel >= 2 if canvas.currentcel && canvas.currentcel >= 2
cel1 = canvas.currentcel cel1 = canvas.currentcel
cel2 = pbChooseNum(cel1) cel2 = pbChooseNum(cel1)
canvas.swapCels(cel1, cel2) if cel2 >= 2 && cel1 != cel2 canvas.swapCels(cel1, cel2) if cel2 >= 2 && cel1 != cel2
end end
when 6 # Extrapolate Path when 6 # Extrapolate Path
if canvas.currentCel if canvas.currentCel
pbDefinePath(canvas) pbDefinePath(canvas)
sliderwin.invalidate sliderwin.invalidate
@@ -1081,10 +1081,10 @@ module BattleAnimationEditor
end end
next next
end end
if sliderwin.changed?(0) # Current frame changed if sliderwin.changed?(0) # Current frame changed
canvas.currentframe = sliderwin.value(0) - 1 canvas.currentframe = sliderwin.value(0) - 1
end end
if sliderwin.changed?(1) # Change frame count if sliderwin.changed?(1) # Change frame count
pbChangeMaximum(canvas) pbChangeMaximum(canvas)
if canvas.currentframe >= canvas.animation.length if canvas.currentframe >= canvas.animation.length
canvas.currentframe = canvas.animation.length - 1 canvas.currentframe = canvas.animation.length - 1
@@ -1092,12 +1092,12 @@ module BattleAnimationEditor
end end
sliderwin.refresh sliderwin.refresh
end end
if sliderwin.changed?(2) # Set Animation Sheet if sliderwin.changed?(2) # Set Animation Sheet
pbSelectAnim(canvas, animwin) pbSelectAnim(canvas, animwin)
animwin.refresh animwin.refresh
sliderwin.refresh sliderwin.refresh
end end
if sliderwin.changed?(3) # List of Animations if sliderwin.changed?(3) # List of Animations
pbAnimList(animation, canvas, animwin) pbAnimList(animation, canvas, animwin)
sliderwin.controls[0].curvalue = canvas.currentframe + 1 sliderwin.controls[0].curvalue = canvas.currentframe + 1
bottomwindow.refresh bottomwindow.refresh
@@ -1107,7 +1107,7 @@ module BattleAnimationEditor
pbTimingList(canvas) if sidewin.changed?(0) pbTimingList(canvas) if sidewin.changed?(0)
if sidewin.changed?(1) if sidewin.changed?(1)
positions = [_INTL("User"), _INTL("Target"), _INTL("User and target"), _INTL("Screen")] positions = [_INTL("User"), _INTL("Target"), _INTL("User and target"), _INTL("Screen")]
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]

View File

@@ -1030,12 +1030,14 @@ MenuHandlers.add(:debug_menu, :toggle_snag_machine, {
} }
}) })
MenuHandlers.add(:debug_menu, :relic_stone, { MenuHandlers.add(:debug_menu, :toggle_purify_chamber_access, {
"name" => _INTL("Use Relic Stone"), "name" => _INTL("Toggle Purify Chamber Access"),
"parent" => :shadow_pokemon_menu, "parent" => :shadow_pokemon_menu,
"description" => _INTL("Choose a Shadow Pokémon to show to the Relic Stone for purification."), "description" => _INTL("Toggle access to the Purify Chamber via the PC."),
"effect" => proc { "effect" => proc {
pbRelicStone $player.seen_purify_chamber = !$player.seen_purify_chamber
pbMessage(_INTL("The Purify Chamber is accessible.")) if $player.seen_purify_chamber
pbMessage(_INTL("The Purify Chamber is not accessible.")) if !$player.seen_purify_chamber
} }
}) })
@@ -1048,6 +1050,15 @@ MenuHandlers.add(:debug_menu, :purify_chamber, {
} }
}) })
MenuHandlers.add(:debug_menu, :relic_stone, {
"name" => _INTL("Use Relic Stone"),
"parent" => :shadow_pokemon_menu,
"description" => _INTL("Choose a Shadow Pokémon to show to the Relic Stone for purification."),
"effect" => proc {
pbRelicStone
}
})
#=============================================================================== #===============================================================================
# PBS file editors # PBS file editors
#=============================================================================== #===============================================================================

View File

@@ -185,14 +185,14 @@ def pbDebugVariables(mode)
end end
current_id = right_window.index + 1 current_id = right_window.index + 1
case mode case mode
when 0 # Switches when 0 # Switches
if Input.trigger?(Input::USE) if Input.trigger?(Input::USE)
pbPlayDecisionSE pbPlayDecisionSE
$game_switches[current_id] = !$game_switches[current_id] $game_switches[current_id] = !$game_switches[current_id]
right_window.refresh right_window.refresh
$game_map.need_refresh = true $game_map.need_refresh = true
end end
when 1 # Variables when 1 # Variables
if Input.repeat?(Input::LEFT) if Input.repeat?(Input::LEFT)
pbDebugSetVariable(current_id, -1) pbDebugSetVariable(current_id, -1)
right_window.refresh right_window.refresh

View File

@@ -1098,9 +1098,7 @@ module Compiler
end end
end end
raise Reset.new if e.is_a?(Hangup) raise Reset.new if e.is_a?(Hangup)
loop do raise "Unknown exception when compiling."
Graphics.update
end
end end
end end
end end

BIN
Game.exe

Binary file not shown.