Archeia

Anaryu's Particle Engine VXAce Port (Ver 1.0)

Dec 22nd, 2014
377
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #==============================================================================
  2. # P A R T I C L E    E N G I N E    VXAce Port
  3. #------------------------------------------------------------------------------
  4. #  Author: Andrew McKellar (Anaryu) (anmckell@gmail.com)
  5. #
  6. #  Version: 1.2
  7. #
  8. #  1.2: Added animation support to Partile Engine.
  9. #
  10. #  This script is built to work with the default systems but can be adapated
  11. #  to work with most, epsecially event-driven systems.
  12. #
  13. #  All particles should be loaded into the Pictures folder.
  14. #
  15. #  Please credit if used, not licensed for commercial use without consent.
  16. #==============================================================================
  17.  
  18. #==============================================================================
  19. # ** Particle Setting
  20. #------------------------------------------------------------------------------
  21. #  Instance of the settings for a particle
  22. #==============================================================================
  23.  
  24. class Particle_Setting
  25.   #--------------------------------------------------------------------------
  26.   # * Public Instance Variables
  27.   #--------------------------------------------------------------------------
  28.   # [Speed] is how many frames to wait before
  29.   # making [Power] amount of the parctile
  30.   # So [Power] of 2 and [Speed] of 3 means 2 particles every 3 frames
  31.   attr_accessor       :power          # Power of the particle
  32.   attr_accessor       :speed          # Speed of the particle generation
  33.   # [Intensity] is the starting opacity 1-255 and
  34.   # [burnout] is how how much the opacity changes a particle
  35.   # is considered "done" when opacity is more than 255 or less than 1
  36.   attr_accessor       :intensity
  37.   attr_accessor       :burnout
  38.   # H and V scatter are how much of a random value the starting location
  39.   # can have, so a [h_scatter] of 10 and a [v_scatter] of 0 means it will
  40.   # generate all particles at the same y location, but with a random
  41.   # difference of 10 pixels (in either direction) of it's x starting location
  42.   attr_accessor       :h_scatter
  43.   attr_accessor       :v_scatter
  44.   # [Velocity] is how fast it changes in each direction [down, left, right, up]
  45.   # [acceleration] is how much the [velocity] changes each frame
  46.   # in each of the same directions [down, left, right, up]
  47.   attr_accessor       :velocity
  48.   attr_accessor       :acceleration
  49.   # [Angle_change] is how much the angle should change each frame and
  50.   # [achange_delta] is how much that angle change will chance each frame
  51.   attr_accessor       :angle_change
  52.   attr_accessor       :achange_delta
  53.   # [zoom_start] is the start value of the zoom for the sprite [x,y]
  54.   # [zoom_starts] is when the zoom transition starts (frame) [x,y]
  55.   # [zoom_change] is the amount to change it [x,y]
  56.   attr_accessor       :zoom_start
  57.   attr_accessor       :zoom_starts
  58.   attr_accessor       :zoom_change
  59.   # [Move_type] decides the move type of the particle
  60.   # 0: Standard Linear Movement
  61.   # 1: Circular movement offset [x,y] used to define x and y radius
  62.   # 2: Explode/collapse based on velocity being + or -
  63.   # 3: Circular in X, linear in Y
  64.   # 4: Circular in Y, linear in X
  65.   attr_accessor       :move_type
  66.   # [Lock] decides if the particle is locked on it's target or will
  67.   # remain where it started
  68.   attr_accessor       :lock
  69.   # [wAmp] and [wLength] and [wSpeed] and [wPhase] are the default values
  70.   # for the wave attributes (read VX documentation under "Sprite" for details)
  71.   attr_accessor       :wamp
  72.   attr_accessor       :wlength
  73.   attr_accessor       :wspeed
  74.   attr_accessor       :wphase
  75.   # [Animation_Frames] if set will create an animated particle instead,
  76.   # which will loop through an image assuming it's width / [animation_frames]
  77.   # will produce the correct number of frames and will loops through
  78.   # these with [Animation_Speed] pause between each frame.
  79.   attr_accessor       :animation_frames
  80.   attr_accessor       :animation_speed
  81.   # The starting frame for the particle, if set to -1 it will be random
  82.   # if set past the pattern limitation it will be the first
  83.   attr_accessor       :animation_start_frame
  84. end
  85.  
  86. #==============================================================================
  87. # ** Particle
  88. #------------------------------------------------------------------------------
  89. #  A Particle is the actual particle itself.
  90. #==============================================================================
  91.  
  92. class Combat_Effect_Setting
  93.   #--------------------------------------------------------------------------
  94.   # * Public Instance Variables
  95.   #--------------------------------------------------------------------------
  96.   attr_accessor   :particle
  97.   attr_accessor   :blend
  98.   attr_accessor   :setting
  99.   attr_accessor   :duration
  100.   attr_accessor   :offset
  101. end
  102.  
  103. #==============================================================================
  104. # ** Game_Character
  105. #------------------------------------------------------------------------------
  106. #  This class deals with characters. It's used as a superclass of the
  107. # Game_Player and Game_Event classes.
  108. #==============================================================================
  109.  
  110. class Game_Character < Game_CharacterBase
  111.   #--------------------------------------------------------------------------
  112.   # * Get X for Particle Engine System
  113.   #--------------------------------------------------------------------------
  114.   def get_pe_x
  115.     return @real_x * 256
  116.   end
  117.   #--------------------------------------------------------------------------
  118.   # * Get Y for Particle Engine System
  119.   #--------------------------------------------------------------------------
  120.   def get_pe_y
  121.     return @real_y * 256
  122.   end
  123. end
  124.  
  125. #==============================================================================
  126. # ** Game_Event
  127. #------------------------------------------------------------------------------
  128. #  This class deals with events. It handles functions including event page
  129. # switching via condition determinants, and running parallel process events.
  130. # It's used within the Game_Map class.
  131. #==============================================================================
  132.  
  133. class Game_Event < Game_Character
  134.   #--------------------------------------------------------------------------
  135.   # * Public Instance Variables
  136.   #--------------------------------------------------------------------------
  137.   attr_reader     :particles
  138.   #--------------------------------------------------------------------------
  139.   # * Object Initialization
  140.   #     map_id : map ID
  141.   #     event  : event (RPG::Event)
  142.   #--------------------------------------------------------------------------
  143.   alias :pre_pe_initialize  :initialize
  144.   def initialize(map_id, event)
  145.     # Generate particle variables
  146.     @particles = []
  147.     @particles_created = false
  148.     # Normal init
  149.     pre_pe_initialize(map_id, event)
  150.   end
  151.   #--------------------------------------------------------------------------
  152.   # * Create Particles
  153.   #--------------------------------------------------------------------------
  154.   def create_particles
  155.     # Check to see if we have particles
  156.     if @event.name.include?("PART") and not @particles_created
  157.       # Add effects found in the event codes
  158.       if self.list != nil
  159.         for item in self.list
  160.           if item.code == 108 and item.parameters[0].include?("PARTICLE=")
  161.             id = item.parameters[0].split('=')
  162.             particle_settings = id[1].to_s
  163.             ps = particle_settings.split(',')
  164.             if ps.size == 3
  165.               particle = SceneManager.scene.ap(ps[0].to_s, self, ps[1].to_i, -1, ps[2].to_s)
  166.               @particles.push(particle)
  167.             elsif ps.size == 5
  168.               particle = SceneManager.scene.ap(ps[0].to_s, self, ps[1].to_i, -1, ps[2].to_s, [ps[3].to_i, ps[4].to_i])
  169.               @particles.push(particle)
  170.             end
  171.           end
  172.         end
  173.       end
  174.     end
  175.     @particles_created = true
  176.   end
  177.   #--------------------------------------------------------------------------
  178.   # * Clear Starting Flag
  179.   #--------------------------------------------------------------------------
  180.   alias :pre_pe_clear_starting  :clear_starting_flag
  181.   def clear_starting_flag
  182.     pre_pe_clear_starting
  183.     # Also clear particle flags and clear all particles
  184.     for i in 0...@particles.size
  185.       @particles[i].dispose
  186.       @particles[i] = nil
  187.     end
  188.     @particles.delete(nil)
  189.     @particles_created = false
  190.   end
  191.   #--------------------------------------------------------------------------
  192.   # * Clear Starting Flag
  193.   #--------------------------------------------------------------------------
  194.   def clear_particles
  195.     @particles = [] if @particles == nil
  196.     # Also clear particle flags and clear all particles
  197.     for i in 0...@particles.size
  198.       @particles[i].dispose
  199.       @particles[i] = nil
  200.     end
  201.     @particles.delete(nil)
  202.     @particles_created = false
  203.   end
  204. end
  205.  
  206. #==============================================================================
  207. # ** Game_Player
  208. #------------------------------------------------------------------------------
  209. #  This class handles maps. It includes event starting determinants and map
  210. # scrolling functions. The instance of this class is referenced by $game_map.
  211. #==============================================================================
  212.  
  213. class Game_Player < Game_Character
  214.   #--------------------------------------------------------------------------
  215.   # * Execute Player Transfer
  216.   #--------------------------------------------------------------------------
  217.   alias :pre_pe_perform_transfer  :perform_transfer
  218.   def perform_transfer
  219.     # Perform normal transfer
  220.     pre_pe_perform_transfer
  221.     # If we're staying on the same map, remake the particles
  222.     if $game_map.map_id == @new_map_id
  223.       for event in $game_map.events.values
  224.         event.clear_particles
  225.       end
  226.     end
  227.   end
  228. end
  229.  
  230. #==============================================================================
  231. # ** Game_System
  232. #------------------------------------------------------------------------------
  233. #  This class handles data surrounding the system. Backround music, etc.
  234. #  is managed here as well. Refer to "$game_system" for the instance of
  235. #  this class.
  236. #==============================================================================
  237.  
  238. class Game_System
  239.   attr_accessor   :particle_level
  240.   attr_accessor   :particle_settings
  241.   attr_accessor   :combat_settings
  242.   alias :pre_pe_initialize  :initialize
  243.   def initialize
  244.     # Run original initialize
  245.     pre_pe_initialize
  246.     # Set new values
  247.     @particle_level = 100
  248.     @particle_settings = {}
  249.     @combat_settings = {}
  250.     battle_effect_settings
  251.   end
  252. end
  253.  
  254. #==============================================================================
  255. # ** Interpreter
  256. #------------------------------------------------------------------------------
  257. #  This interpreter runs event commands. This class is used within the
  258. #  Game_System class and the Game_Event class.
  259. #==============================================================================
  260.  
  261. class Game_Interpreter
  262.   attr_accessor   :effects
  263.   #--------------------------------------------------------------------------
  264.   # * Object Initialization
  265.   #--------------------------------------------------------------------------
  266.   alias :pre_pe_initialize  :initialize
  267.   def initialize(depth = 0)
  268.     @effects = []
  269.     pre_pe_initialize(depth)
  270.   end
  271.   #--------------------------------------------------------------------------
  272.   # * Add Effect
  273.   #--------------------------------------------------------------------------
  274.   def add_effect(id, particle)
  275.     # Initialize @effects if it's not initialized yet to cope
  276.     # with late particle system integration
  277.     @effects = [] if @effects == nil
  278.     # Dispose of effect at given id if possible
  279.     if @effects[id] == nil
  280.       @effects[id] = particle
  281.     else
  282.       @effects[id].disposed = true
  283.       @effects[id] = particle
  284.     end
  285.   end
  286.   #--------------------------------------------------------------------------
  287.   # * Dispose Effect
  288.   #--------------------------------------------------------------------------
  289.   def dispose_effect(id = 0)
  290.     # Initialize @effects if it's not initialized yet to cope
  291.     # with late particle system integration
  292.     @effects = [] if @effects == nil
  293.     # Dispose of effect at given id if possible
  294.     if @effects[id] != nil
  295.       @effects[id].disposed = true
  296.     end
  297.   end
  298. end
  299.  
  300. #==============================================================================
  301. # ** Particle_Effect
  302. #------------------------------------------------------------------------------
  303. #  A Particle_Effect will generate particles based on it's settings.
  304. #==============================================================================
  305.  
  306. class Scene_Map
  307.   #--------------------------------------------------------------------------
  308.   # * Execute Screen Switch
  309.   #--------------------------------------------------------------------------
  310.   alias  :pre_pe_update_scene_change    :update_scene
  311.   def update_scene
  312.     # Run normal function
  313.     pre_pe_update_scene_change
  314.     # Clear particles as the scene has changed
  315.     if scene_changing?
  316.       for event in $game_map.events.values
  317.         event.clear_particles
  318.       end
  319.     end
  320.   end
  321.   #--------------------------------------------------------------------------
  322.   # * Add Particle Effect
  323.   #--------------------------------------------------------------------------
  324.   def ap(name, target, blend, duration, setting, offset = [0,0])
  325.     s = $game_system.particle_settings[setting]
  326.     if target?(target)
  327.       return @spriteset.ap(name, target, blend, duration, s, offset.clone)
  328.     else
  329.       return @spriteset.ap(name, target.clone, blend, duration, s, offset.clone)
  330.     end
  331.   end
  332.   #--------------------------------------------------------------------------
  333.   # * Frame Update
  334.   #--------------------------------------------------------------------------
  335.   alias :pre_pe_update  :update
  336.   def update
  337.     # Run normal update
  338.     pre_pe_update
  339.     # Update particles
  340.     if SceneManager.scene_is?(Scene_Map)
  341.       for event in $game_map.events.values
  342.         event.create_particles
  343.       end
  344.     end
  345.   end
  346.   #--------------------------------------------------------------------------
  347.   # * Add Particle
  348.   #--------------------------------------------------------------------------
  349.   def add_particle(target, name, blend, setting, offset, v = nil, a = nil)
  350.     @spriteset.add_particle(target, name, blend, setting, offset, v, a)
  351.   end
  352.   #--------------------------------------------------------------------------
  353.   # * Add Particle
  354.   #--------------------------------------------------------------------------
  355.   def target?(t)
  356.     return true if t.is_a?(Game_Character)
  357.     return true if t.is_a?(Sprite_Battler)
  358.     return false
  359.   end
  360. end
  361.  
  362. #==============================================================================
  363. # ** Scene_Battle
  364. #------------------------------------------------------------------------------
  365. #  This class performs battle screen processing.
  366. #==============================================================================
  367.  
  368. class Scene_Battle < Scene_Base
  369.   #--------------------------------------------------------------------------
  370.   # * Start processing
  371.   #--------------------------------------------------------------------------
  372.   alias :pre_pe_start   :start
  373.   def start
  374.     # Generate battle effect settings
  375.     $game_system.battle_effect_settings
  376.     # Run normal start
  377.     pre_pe_start
  378.   end
  379.   #--------------------------------------------------------------------------
  380.   # * Add Particle Effect
  381.   #--------------------------------------------------------------------------
  382.   def ap(name, target, blend, duration, setting, offset = [0,0])
  383.     s = $game_system.particle_settings[setting]
  384.     if target?(target)
  385.       return @spriteset.ap(name, target, blend, duration, s, offset.clone)
  386.     else
  387.       return @spriteset.ap(name, target.clone, blend, duration, s, offset.clone)
  388.     end
  389.   end
  390.   #--------------------------------------------------------------------------
  391.   # * Add Particle
  392.   #--------------------------------------------------------------------------
  393.   def add_particle(target, name, blend, setting, offset, v = nil, a = nil)
  394.     @spriteset.add_particle(target, name, blend, setting, offset, v, a)
  395.   end
  396.   #--------------------------------------------------------------------------
  397.   # * Add Particle
  398.   #--------------------------------------------------------------------------
  399.   def target?(t)
  400.     return true if t.is_a?(Game_Character)
  401.     return true if t.is_a?(Sprite_Battler)
  402.     return false
  403.   end
  404. end
  405.  
  406. #==============================================================================
  407. # ** Sprite_Base
  408. #------------------------------------------------------------------------------
  409. #  A sprite class with animation display processing added.
  410. #==============================================================================
  411.  
  412. class Sprite_Base < Sprite
  413.   #--------------------------------------------------------------------------
  414.   # * SE and Flash Timing Processing
  415.   #     timing : timing data (RPG::Animation::Timing)
  416.   #--------------------------------------------------------------------------
  417.   alias   :pre_pe_animation_process_timing  :animation_process_timing
  418.   def animation_process_timing(timing)
  419.     c = timing.flash_color
  420.     if c.alpha == 0 and c.red == 1
  421.       e = $game_system.combat_settings[timing.flash_duration]
  422.       if SceneManager.scene_is?(Scene_Battle)
  423.         offset = [e.offset[0], e.offset[1]]
  424.         offset[0] += c.green
  425.         offset[1] += c.blue
  426.         SceneManager.scene.ap(e.particle, self, e.blend, e.duration, e.setting, offset)
  427.       end
  428.     else
  429.       pre_pe_animation_process_timing(timing)
  430.     end
  431.   end
  432.   #--------------------------------------------------------------------------
  433.   # * Get X for Particle Engine System
  434.   #--------------------------------------------------------------------------
  435.   def get_pe_x
  436.     return (@battler.screen_x * 8)
  437.   end
  438.   #--------------------------------------------------------------------------
  439.   # * Get Y for Particle Engine System
  440.   #--------------------------------------------------------------------------
  441.   def get_pe_y
  442.     return ((@battler.screen_y * 8) - (@height * 4))
  443.   end
  444. end
  445.  
  446. #==============================================================================
  447. # ** Spriteset
  448. #------------------------------------------------------------------------------
  449. #  A Particle_Effect will generate particles based on it's settings.
  450. #==============================================================================
  451.  
  452. class Spriteset_Map
  453.   #--------------------------------------------------------------------------
  454.   # * Public Instance Variables
  455.   #--------------------------------------------------------------------------
  456.   attr_reader     :particles
  457.   attr_reader     :effects
  458.   #--------------------------------------------------------------------------
  459.   # * Initialization
  460.   #--------------------------------------------------------------------------
  461.   alias :pre_pe_initialize  :initialize
  462.   def initialize
  463.     @frame = 0
  464.     @particles = []
  465.     @effects = []
  466.     $game_system.particle_settings = {} if $game_system.particle_settings == nil
  467.     $game_system.create_particle_settings
  468.     pre_pe_initialize
  469.   end
  470.   #--------------------------------------------------------------------------
  471.   # * Dispose
  472.   #--------------------------------------------------------------------------
  473.   alias :pre_pe_dispose :dispose
  474.   def dispose
  475.     for particle in @particles
  476.       particle.dispose
  477.     end
  478.     pre_pe_dispose
  479.   end
  480.   #--------------------------------------------------------------------------
  481.   # * Frame Update
  482.   #--------------------------------------------------------------------------
  483.   alias :pre_pe_update :update
  484.   def update    
  485.     # Set the particle level if it's nil to 100 (full amount)
  486.     $game_system.particle_level = 100 if $game_system.particle_level == nil
  487.     # Go through and update effects
  488.     for i in 0...@effects.size
  489.       # Update only if on_screen (or close)
  490.       @effects[i].update if on_screen(@effects[i])
  491.       # Nil it if it's time to dispose it
  492.       @effects[i] = nil if @effects[i].dispose?
  493.     end
  494.     # Delete those disposed effects
  495.     @effects.delete(nil)
  496.     # Updated particles
  497.     for i in 0...@particles.size
  498.       # Update
  499.       @particles[i].update
  500.       # Check if disposed
  501.       dispose = @particles[i].dispose?
  502.       # If disposed dispose and nil it
  503.       @particles[i].dispose if dispose
  504.       @particles[i] = nil if dispose
  505.     end
  506.     # Delete disposed particles
  507.     @particles.delete(nil)
  508.     # Run standard update
  509.     pre_pe_update
  510.   end
  511.   #--------------------------------------------------------------------------
  512.   # * Add Particle
  513.   #--------------------------------------------------------------------------
  514.   def ap(name, target, blend, duration, setting, offset = [0,0])
  515.     s = $game_system.particle_settings[setting]
  516.     t = target
  517.     t = target.clone if not target?(target)
  518.     effect = Particle_Effect.new(name, target, blend, duration, setting, offset.clone)
  519.     @effects.push(effect)
  520.     return effect
  521.   end
  522.   #--------------------------------------------------------------------------
  523.   # * Add Particle
  524.   #--------------------------------------------------------------------------
  525.   def add_particle(target, name, blend, setting, offset, v = nil, a = nil)
  526.     particle = Particle.new(@viewport1, target, name, blend, setting, offset, v, a)
  527.     @particles.push(particle)
  528.   end
  529.   #--------------------------------------------------------------------------
  530.   # * On Screen
  531.   #--------------------------------------------------------------------------
  532.   def on_screen(effect)
  533.     x = effect.origin[0]
  534.     y = effect.origin[1]
  535.     x_range = ((x <= ($game_map.display_x + 4352)) and (x >= ($game_map.display_x - 512)))
  536.     y_range = ((y <= ($game_map.display_y + 3072)) and (y >= ($game_map.display_y - 512)))
  537.     if x_range and y_range
  538.       return true
  539.     end
  540.     return true if effect.target.is_a?(Game_Player)
  541.     return false
  542.   end
  543.   #--------------------------------------------------------------------------
  544.   # * Add Particle
  545.   #--------------------------------------------------------------------------
  546.   def target?(t)
  547.     return true if t.is_a?(Game_Character)
  548.     return true if t.is_a?(Sprite_Battler)
  549.     return false
  550.   end
  551. end
  552.  
  553. #==============================================================================
  554. # ** Spriteset
  555. #------------------------------------------------------------------------------
  556. #  A Particle_Effect will generate particles based on it's settings.
  557. #==============================================================================
  558.  
  559. class Spriteset_Battle
  560.   #--------------------------------------------------------------------------
  561.   # * Public Instance Variables
  562.   #--------------------------------------------------------------------------
  563.   attr_reader     :particles
  564.   attr_reader     :effects
  565.   #--------------------------------------------------------------------------
  566.   # * Initialization
  567.   #--------------------------------------------------------------------------
  568.   alias :pre_pe_initialize  :initialize
  569.   def initialize
  570.     @particles = []
  571.     @effects = []
  572.     $game_system.particle_settings = {} if $game_system.particle_settings == nil
  573.     $game_system.create_particle_settings
  574.     pre_pe_initialize
  575.   end
  576.   #--------------------------------------------------------------------------
  577.   # * Dispose
  578.   #--------------------------------------------------------------------------
  579.   alias :pre_pe_dispose :dispose
  580.   def dispose
  581.     for particle in @particles
  582.       particle.dispose
  583.     end
  584.     pre_pe_dispose
  585.   end
  586.   #--------------------------------------------------------------------------
  587.   # * Frame Update
  588.   #--------------------------------------------------------------------------
  589.   alias :pre_pe_update :update
  590.   def update
  591.     # Set the particle level if it's nil to 100 (full amount)
  592.     $game_system.particle_level = 100 if $game_system.particle_level == nil
  593.     # Go through and update effects
  594.     for i in 0...@effects.size
  595.       # Update only if on_screen (or close)
  596.       @effects[i].update
  597.       # Nil it if it's time to dispose it
  598.       @effects[i] = nil if @effects[i].dispose?
  599.     end
  600.     # Delete those disposed effects
  601.     @effects.delete(nil)
  602.     # Updated particles
  603.     for i in 0...@particles.size
  604.       # Update
  605.       @particles[i].update
  606.       # Check if disposed
  607.       dispose = @particles[i].dispose?
  608.       # If disposed dispose and nil it
  609.       @particles[i].dispose if dispose
  610.       @particles[i] = nil if dispose
  611.     end
  612.     # Delete disposed particles
  613.     @particles.delete(nil)
  614.     # Run standard update
  615.     pre_pe_update
  616.   end
  617.   #--------------------------------------------------------------------------
  618.   # * Add Particle
  619.   #--------------------------------------------------------------------------
  620.   def ap(name, target, blend, duration, setting, offset = [0,0])
  621.     s = $game_system.particle_settings[setting]
  622.     t = target
  623.     t = target.clone if not target?(target)
  624.     effect = Particle_Effect.new(name, target, blend, duration, setting, offset.clone)
  625.     @effects.push(effect)
  626.     return effect
  627.   end
  628.   #--------------------------------------------------------------------------
  629.   # * Add Particle
  630.   #--------------------------------------------------------------------------
  631.   def add_particle(target, name, blend, setting, offset, v = nil, a = nil)
  632.     particle = Particle.new(@viewport1, target, name, blend, setting, offset, v, a)
  633.     @particles.push(particle)
  634.   end
  635.   #--------------------------------------------------------------------------
  636.   # * Add Particle
  637.   #--------------------------------------------------------------------------
  638.   def target?(t)
  639.     return true if t.is_a?(Game_Character)
  640.     return true if t.is_a?(Sprite_Battler)
  641.     return false
  642.   end
  643. end
  644.  
  645. #==============================================================================
  646. # ** Particle_Effect
  647. #------------------------------------------------------------------------------
  648. #  A Particle_Effect will generate particles based on it's settings.
  649. #==============================================================================
  650.  
  651. class Particle_Effect
  652.   #--------------------------------------------------------------------------
  653.   # * Public Instance Variables
  654.   #--------------------------------------------------------------------------
  655.   attr_accessor   :origin       # starting location in realx/realy location
  656.   attr_accessor   :target       # game character or starting [x,y] origin
  657.   attr_reader     :power        # higher power means more particles per tick
  658.   attr_reader     :speed        # higher speed means faster particle generation
  659.   attr_reader     :blend        # blend type 0 = normal, 1 = add, 2 = subtract
  660.   attr_reader     :velocity     # initial speed [x,y]
  661.   attr_reader     :acceleration # amount to change speed [x,y]
  662.   attr_reader     :duration     # length of frames to produce particles
  663.   attr_reader     :h_scatter    # magnitude of random horizontal offsets
  664.   attr_reader     :v_scatter    # magnitude of random vertical offsets
  665.   attr_reader     :particle     # name of the picture file to use
  666.   attr_reader     :lock         # locked on target or not?
  667.   attr_reader     :offset       # [x,y] offset
  668.   attr_accessor   :disposed     # should this be disposed of now?
  669.   attr_reader     :frame        # frames, starts at zero and increases over time
  670.   #--------------------------------------------------------------------------
  671.   # * Object Initialization
  672.   #--------------------------------------------------------------------------
  673.   def initialize(name, target, blend, duration, setting, offset)
  674.     # Assign starting values
  675.     if target?(target)
  676.       @origin = [target.get_pe_x, target.get_pe_y]
  677.       @target = target
  678.     else
  679.       @origin = [target[0], target[1]]
  680.       @target = target.clone
  681.     end
  682.     @name = name
  683.     @setting = setting
  684.     @blend = blend
  685.     @duration = duration
  686.     @particle = name
  687.     @offset = offset
  688.     @frames = 0
  689.     @powered = 0
  690.     @disposed = false
  691.   end
  692.   #--------------------------------------------------------------------------
  693.   # * Frame Update
  694.   #--------------------------------------------------------------------------
  695.   def update
  696.     # Add new particles if necessary
  697.     gen_frame = (@frames % @setting.speed == 0)
  698.     powed = (@powered[1] == 0 or (@powered[0] > 0 and @frames % @powered[1] == 0))
  699.     # Check if the level of particles set will allow us to generate or not
  700.     rand = $game_system.particle_level > rand(100)
  701.     # Use the checks to determine if we should generate a particle right now
  702.     if (gen_frame or powed) and rand
  703.       # If we're going to generate more than one per tick, do it!
  704.       @setting.power[1] == 0 ? @repeat = @setting.power[0] : @repeat = 1
  705.       for i in 0...@repeat
  706.         # Set the powered value
  707.         @powered = @setting.power.clone if @powered[0] <= 0
  708.         # Generate scattered start points
  709.         x_rand = rand(@setting.h_scatter+1)
  710.         y_rand = rand(@setting.v_scatter+1)
  711.         # Scatter in all directions, not just one
  712.         neg1 = rand(2)
  713.         x_rand *= -1 if neg1 == 1
  714.         neg2 = rand(2)
  715.         y_rand *= -1 if neg2 == 1
  716.         # Apply the scatter values
  717.         offset = [@offset[0] + x_rand, @offset[1] + y_rand]
  718.         # Set the particles starting conditions based on move_type
  719.         case @setting.move_type
  720.         when 0, 1, 3, 4
  721.           # Create the particles with the offset
  722.           offset = [@offset[0] + x_rand, @offset[1] + y_rand]
  723.           SceneManager.scene.add_particle(@target, @name, @blend, @setting, offset)
  724.         when 2
  725.           # Get a scatter value
  726.           x_mod = x_rand.abs * 1.0 / (@setting.h_scatter + 1)
  727.           y_mod = y_rand.abs * 1.0 / (@setting.v_scatter + 1)
  728.           # Clone our velocity and accelerate to accomodate random start place
  729.           # but identical ending location
  730.           v = [@setting.velocity[0] * x_mod, @setting.velocity[1] * y_mod]
  731.           a = [@setting.acceleration[0] * x_mod, @setting.acceleration[1] * y_mod]
  732.           # Invert values if necessary
  733.           if neg1 == 1
  734.             v = [v[0] * -1.0, v[1]]
  735.             a = [a[0] * -1.0, a[1]]
  736.           end
  737.           if neg2 == 1
  738.             v = [v[0], v[1] * -1.0]
  739.             a = [a[0], a[1] * -1.0]
  740.           end
  741.           # Fix origin to accomodate moving characters
  742.           if target?(target)
  743.             @origin = [target.get_pe_x, target.get_pe_y]
  744.           end
  745.           # Add the particle
  746.           SceneManager.scene.add_particle(@target, @name, @blend, @setting, offset, v, a)
  747.         end
  748.         # Reduced our powered value
  749.         @powered[0] -= 1
  750.       end
  751.     end
  752.     # Increase frame
  753.     @frames += 1
  754.   end
  755.   #--------------------------------------------------------------------------
  756.   # * Frame Update
  757.   #--------------------------------------------------------------------------
  758.   def dispose?
  759.     # Return true if we're set to be disposed
  760.     return true if @disposed
  761.     # Return false immediately if our duration is 01
  762.     return false if @duration == -1
  763.     # Return true if our frames are at or past duration
  764.     if @frames > @duration
  765.       return true
  766.     end
  767.     # Default false
  768.     return false
  769.   end
  770.   #--------------------------------------------------------------------------
  771.   # * Frame Update
  772.   #--------------------------------------------------------------------------
  773.   def dispose
  774.     @disposed = true
  775.   end
  776.   #--------------------------------------------------------------------------
  777.   # * Add Particle
  778.   #--------------------------------------------------------------------------
  779.   def target?(t)
  780.     return true if t.is_a?(Game_Character)
  781.     return true if t.is_a?(Sprite_Battler)
  782.     return false
  783.   end
  784. end
  785.  
  786.  
  787. #==============================================================================
  788. # ** Particle
  789. #------------------------------------------------------------------------------
  790. #  A Particle is the actual particle itself.
  791. #==============================================================================
  792.  
  793. class Particle < Sprite
  794.   #--------------------------------------------------------------------------
  795.   # * Public Instance Variables
  796.   #--------------------------------------------------------------------------
  797.   attr_reader     :target       # game character or starting [x,y] origin
  798.   attr_reader     :velocity     # initial speed [x,y]
  799.   attr_reader     :acceleration # amount to change speed [x,y]
  800.   attr_reader     :duration     # length of frames to produce particles
  801.   attr_reader     :particle     # name of the picture file to use
  802.   attr_reader     :offset       # [x,y] offset
  803.   attr_reader     :opacity      # current opacity
  804.   attr_reader     :achange      # angle change
  805.   attr_reader     :opacity      # current opacity
  806.   attr_reader     :setting      # the particle settings to use
  807.   #--------------------------------------------------------------------------
  808.   # * Object Initialization
  809.   #--------------------------------------------------------------------------
  810.   def initialize(viewport, target, name, blend, setting, offset = [0,0], v = nil, a = nil)
  811.     super(viewport)
  812.     self.bitmap = Cache.picture(name)
  813.     # Set the setting variable
  814.     @s = setting
  815.     # Set x/y based on target
  816.     @target = target
  817.     @offset = offset.clone
  818.     # Set wave and angle defaults
  819.     self.wave_amp = @s.wamp if @s.wamp != nil
  820.     self.wave_length = @s.wlength if @s.wlength != nil
  821.     self.wave_speed = @s.wspeed if @s.wspeed != nil
  822.     self.wave_phase = @s.wphase if @s.wphase != nil
  823.     @angle = self.angle
  824.     # Set the angle values
  825.     @achange = @s.angle_change
  826.     # Set starting point based on target type (character vs. array)
  827.     if target?(@target)
  828.       self.x = (@target.get_pe_x / 8) + @offset[0]
  829.       self.y = (@target.get_pe_y / 8) + @offset[1]
  830.       @origin = [(@target.get_pe_x / 8) + @offset[0], (@target.get_pe_y / 8) + @offset[1]]
  831.     else
  832.       self.x = @target[0] + @offset[0]
  833.       self.y = @target[1] + @offset[1]
  834.       @origin = [@target[0] + @offset[0], @target[1] + @offset[1]]
  835.     end
  836.     # Set zoome values if they're there
  837.     if @s.zoom_start != nil
  838.       @zoom = [(@s.zoom_start[0] / 100.0), (@s.zoom_start[1] / 100.0)]
  839.       self.zoom_x = @zoom[0]
  840.       self.zoom_y = @zoom[1]
  841.     end
  842.     # Set width and height for animation
  843.     @width = self.bitmap.width
  844.     @width = self.bitmap.width / @s.animation_frames if animated?
  845.     @height = self.bitmap.height
  846.     # Offset x/y based on our sprite size
  847.     self.ox = (@width / 2)
  848.     self.oy = (@height / 2)
  849.     # Set default extra x/y for tile offset
  850.     @x_extra = 0
  851.     @y_extra = 0
  852.     # Set the extra offset if we're a special case type
  853.     set_extra_offset
  854.     # Set blend type and other values
  855.     self.blend_type = blend
  856.     @opacity = @s.intensity
  857.     @velocity = @s.velocity.clone
  858.     @acceleration = @s.acceleration.clone
  859.     @velocity = v if v != nil
  860.     @acceleration = a if a != nil
  861.     # Set internal variables
  862.     @delta = [0,0]
  863.     @frame = 0
  864.     # Set pattern and animation variables
  865.     if @s.animation_start_frame != nil
  866.       if @s.animation_start_frame == -1
  867.         @pattern = rand((@s.animation_frames+1))
  868.       else
  869.         if @s.animation_start_frame > @s.animation_frames
  870.           @pattern = 0
  871.         else
  872.           @pattern = @s.animation_start_frame
  873.         end
  874.       end
  875.     end
  876.     # Run first frame
  877.     update
  878.     update_pattern
  879.   end
  880.   #--------------------------------------------------------------------------
  881.   # * Should I be disposed?
  882.   #--------------------------------------------------------------------------
  883.   def dispose?
  884.     # We're dead if our opacity is zero
  885.     return ((@opacity <= 0) or (@opacity > 255))
  886.   end
  887.   #--------------------------------------------------------------------------
  888.   # * Should I be disposed?
  889.   #--------------------------------------------------------------------------
  890.   def animated?
  891.     # We're dead if our opacity is zero
  892.     return (@s.animation_frames != nil and @s.animation_frames > 0)
  893.   end
  894.   #--------------------------------------------------------------------------
  895.   # * Update Transfer Origin Rectangle
  896.   #--------------------------------------------------------------------------
  897.   def update_pattern
  898.     if animated?
  899.       sx = @pattern * @width
  900.       sy = 0
  901.       self.src_rect.set(sx, sy, @width, @height)
  902.     end
  903.   end
  904.   #--------------------------------------------------------------------------
  905.   # * Frame Update
  906.   #--------------------------------------------------------------------------
  907.   def update
  908.     # Change angle
  909.     @achange = @achange + @s.achange_delta
  910.     @angle = @angle + @achange
  911.     self.angle = @angle
  912.     # Decay opacity
  913.     @opacity -= @s.burnout
  914.     self.opacity = @opacity
  915.     # Update animation
  916.     # working
  917.     if animated?
  918.       if @s.animation_speed > 0 and @frame % @s.animation_speed == 0
  919.         @pattern = ((@pattern + 1) % @s.animation_frames)
  920.         update_pattern
  921.       end
  922.     end
  923.     # Change velocity
  924.     @velocity[0] += @acceleration[0]
  925.     @velocity[1] += @acceleration[1]
  926.     @delta[0] += @velocity[0]
  927.     @delta[1] += @velocity[1]
  928.     # Check zoom changes
  929.     if @s.zoom_starts != nil
  930.       # Check each zoom starts frame to see if we start on that axis yet
  931.       if @s.zoom_starts[0] <= @frame
  932.         @zoom[0] += (@s.zoom_change[0] / 100.0)
  933.       end
  934.       if @s.zoom_starts[1] <= @frame
  935.         @zoom[1] += (@s.zoom_change[1] / 100.0)
  936.       end
  937.       # Reset zoom values
  938.       self.zoom_x = @zoom[0]
  939.       self.zoom_y = @zoom[1]
  940.     end
  941.     # Set Z value
  942.     if @target.is_a?(Game_Character)
  943.       if @target.priority_type != nil and @target.priority_type == 2
  944.         self.z = @target.screen_z + 1000
  945.       else
  946.         if self.y > (@target.screen_y - 64)
  947.           self.z = @target.screen_z + 32 + @delta[1]
  948.         else
  949.           self.z = @target.screen_z - 16 + @delta[1]
  950.         end
  951.       end
  952.     elsif @target.is_a?(Sprite_Base)
  953.       self.z = @target.z + 100
  954.     elsif $game_player != nil
  955.       if self.y > ($game_player.screen_y - 16)
  956.         self.z = $game_player.screen_z + 32 + @delta[1]
  957.       else
  958.         self.z = $game_player.screen_z - 16 + @delta[1]
  959.       end
  960.     end
  961.     # Set Screen offsets
  962.     x_screen = 0
  963.     y_screen = 0
  964.     if $game_map != nil
  965.       x_screen = $game_map.display_x * 32
  966.       y_screen = $game_map.display_y * 32
  967.     end
  968.     # Set x/y location
  969.     case @s.move_type
  970.     # Standard acceleration based vector movement
  971.     when 0, 2
  972.       if target?(@target)
  973.         if @s.lock
  974.           self.x = (@target.get_pe_x / 8) + @offset[0] + @delta[0] + @x_extra - x_screen
  975.           self.y = (@target.get_pe_y / 8) + @offset[1] + @delta[1] + @y_extra - y_screen
  976.         else
  977.           self.x = @origin[0] + @offset[0] + @delta[0] + @x_extra - x_screen
  978.           self.y = @origin[1] + @offset[1] + @delta[1] + @y_extra - y_screen
  979.         end
  980.       else
  981.         if @s.lock
  982.           self.x = @target[0] + @offset[0] + @delta[0] + @x_extra - x_screen
  983.           self.y = @target[1] + @offset[1] + @delta[1] + @y_extra - y_screen
  984.         else
  985.           self.x = @origin[0] + @offset[0] + @delta[0] + @x_extra - x_screen
  986.           self.y = @origin[1] + @offset[1] + @delta[1] + @y_extra - y_screen
  987.         end
  988.       end
  989.     # Circles around the target
  990.     when 1
  991.       if target?(@target)
  992.         if @s.lock
  993.           self.x = ((@target.get_pe_x / 8) + @x_extra) + @offset[0] * Math.cos(@velocity[0]*@frame) - x_screen
  994.           self.y = ((@target.get_pe_y / 8) + @y_extra) + @offset[1] * Math.sin(@velocity[1]*@frame) - y_screen
  995.         else
  996.           self.x = @origin[0] + @offset[0] * Math.cos(@velocity[0]*@frame) - x_screen
  997.           self.y = @origin[1] + @offset[1] * Math.sin(@velocity[1]*@frame) - y_screen
  998.         end
  999.       else
  1000.         if @s.lock
  1001.           self.x = (@target[0] + @x_extra) + @offset[0] * Math.cos(@velocity[0]*@frame) - x_screen
  1002.           self.y = (@target[1] + @y_extra) + @offset[1] * Math.sin(@velocity[1]*@frame) - y_screen
  1003.         else
  1004.           self.x = @origin[0] + @offset[0] * Math.cos(@velocity[0]*@frame) - x_screen
  1005.           self.y = @origin[1] + @offset[1] * Math.sin(@velocity[1]*@frame) - y_screen
  1006.         end
  1007.       end
  1008.     # Circles around the X moves in Y
  1009.     when 3
  1010.       if target?(@target)
  1011.         if @s.lock
  1012.           self.x = ((@target.get_pe_x / 8) + @x_extra) + @offset[0] * Math.cos(@velocity[0]*@frame) - x_screen
  1013.           self.y = (@target.get_pe_y / 8) + @offset[1] + @delta[1] + @y_extra - y_screen
  1014.         else
  1015.           self.x = @origin[0] + @offset[0] * Math.cos(@velocity[0]*@frame) - x_screen
  1016.           self.y = @origin[1] + @offset[1] + @delta[1] + @y_extra - y_screen
  1017.         end
  1018.       else
  1019.         if @s.lock
  1020.           self.x = (@target[0] + @x_extra) + @offset[0] * Math.cos(@velocity[0]*@frame) - x_screen
  1021.           self.y = @target[1] + @offset[1] + @delta[1] + @y_extra - y_screen
  1022.         else
  1023.           self.x = @origin[0] + @offset[0] * Math.cos(@velocity[0]*@frame) - x_screen
  1024.           self.y = @origin[1] + @offset[1] + @delta[1] + @y_extra - y_screen
  1025.         end
  1026.       end
  1027.     # Circles around the Y and moves in X
  1028.     when 4
  1029.       if target?(@target)
  1030.         if @s.lock
  1031.           self.x = (@target.get_pe_x / 8) + @offset[0] + @delta[0] + @x_extra - x_screen
  1032.           self.y = ((@target.get_pe_y / 8) + @y_extra) + @offset[1] * Math.sin(@velocity[1]*@frame) - y_screen
  1033.         else
  1034.           self.x = @origin[0] + @offset[0] + @delta[0] + @x_extra - x_screen
  1035.           self.y = @origin[1] + @offset[1] * Math.sin(@velocity[1]*@frame) - y_screen
  1036.         end
  1037.       else
  1038.         if @s.lock
  1039.           self.x = @target[0] + @offset[0] + @delta[0] + @x_extra - x_screen
  1040.           self.y = (@target[1] + @y_extra) + @offset[1] * Math.sin(@velocity[1]*@frame) - y_screen
  1041.         else
  1042.           self.x = @origin[0] + @offset[0] + @delta[0] + @x_extra - x_screen
  1043.           self.y = @origin[1] + @offset[1] * Math.sin(@velocity[1]*@frame) - y_screen
  1044.         end
  1045.       end
  1046.     end
  1047.     # Increase frame count
  1048.     @frame += 1
  1049.   end
  1050.   #--------------------------------------------------------------------------
  1051.   # * Add Particle
  1052.   #--------------------------------------------------------------------------
  1053.   def target?(t)
  1054.     return true if t.is_a?(Game_Character)
  1055.     return true if t.is_a?(Sprite_Battler)
  1056.     return false
  1057.   end
  1058.   #--------------------------------------------------------------------------
  1059.   # * Add Particle
  1060.   #--------------------------------------------------------------------------
  1061.   def set_extra_offset
  1062.     if @target.is_a?(Game_Character)
  1063.       @x_extra = 16
  1064.       @y_extra = 16
  1065.     end
  1066.   end
  1067. end
RAW Paste Data