[XP] Action Recharge Times (for BABS)

Started by winkio, December 11, 2008, 07:25:43 pm

Previous topic - Next topic

winkio

December 11, 2008, 07:25:43 pm Last Edit: August 15, 2013, 10:31:41 pm by KK20
Action Recharge Times
Authors: winkio
Version: 1.11
Type: Misc. Add-on
Key Term: Blizz-ABS Plugin



Introduction

This script adds the function of recharge times for weapons, items, skills, and enemy attacks to Blizz-ABS.


Features


  • Recharge times for weapons, items, skills, and enemy attacks
  • Works with custom HUDs
  • Recharge bar and number counter



Screenshots
Note: this screenshot also features my custom HUD, but this script works without it.
Spoiler: ShowHide



Script

Spoiler: ShowHide

#|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
# Blizz-ABS Action Recharge Time by Winkio
# Version: 1.11
#|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
#
#
#|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
# This script modifies the Blizz-ABS system to allow for recharge times.  These
# times are graphically represented on the hotkey bar
#
# If you find any bugs, please report them here:
# http://forum.chaos-project.com
#|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
module BlizzABS
  #-----------------------------------------------------------------------------
  # configure recharge times like everything else.
  # put in the number of frames (40 = 1 second)
  #-----------------------------------------------------------------------------
  module Weapons
    def self.recharge(id)
      case id
      when 1 then return 0
      end
      return 0
    end
  end
  module Skills
    def self.recharge(id)
      case id
      when 1 then return 800
      end
      return 800
    end
  end
  module Items
    def self.recharge(id)
      case id
      when 1 then return 40
      end
      return 40
    end
  end
  module Enemies
    def self.recharge(id)
      case id
      when 1 then return 0
      end
      return 0
    end
  end
end

class Map_Battler
  attr_reader :recharge
  attr_reader :rechcounter
  attr_reader :rechcheck
 
  #----------------------------------------------------------------------------
  # Initialize
  #----------------------------------------------------------------------------
  alias initialize_recharge_later initialize
  def initialize
    @rechcounter = [0, 0] #attack, defend
    (0...999).each {|i| @rechcounter.push(0)} #500 skills and 500 items
    @recharge = @rechcounter.clone
    @recheck = []
    initialize_recharge_later
  end
  #----------------------------------------------------------------------------
  # Recharging
  #----------------------------------------------------------------------------
  def recharging?(index)
    return (@rechcounter[index] > 0)
  end
  #----------------------------------------------------------------------------
  # Recharge Rate
  #----------------------------------------------------------------------------
  def rech_rate(index)
    return 0.0 if @recharge[index] == 0
    return (@rechcounter[index].to_f/@recharge[index].to_f)
  end
  #----------------------------------------------------------------------------
  # attack_can_use?
  #----------------------------------------------------------------------------
  alias attack_can_use_recharge_later? attack_can_use?
  def attack_can_use?
    return (!recharging?(0) && attack_can_use_recharge_later?)
  end
  #----------------------------------------------------------------------------
  # skill_can_use?
  #----------------------------------------------------------------------------
  alias skill_can_use_recharge_later? skill_can_use?
  def skill_can_use?(id, forced = false)
    return (!recharging?(1+id) && skill_can_use_recharge_later?(id, forced))
  end
  #----------------------------------------------------------------------------
  # item_can_use?
  #----------------------------------------------------------------------------
  alias item_can_use_recharge_later? item_can_use?
  def item_can_use?(id, forced = false)
    return (!recharging?(501+id) && item_can_use_recharge_later?(id, forced))
  end
end

class Map_Actor
  #----------------------------------------------------------------------------
  # Update
  #----------------------------------------------------------------------------
  alias upd_recharger_later update
  def update
    @recheck.each {|i|
      if recharging?(i)
        @rechcounter[i] -= 1
      else
        @recheck.delete(i)
      end}
    upd_recharger_later
  end
  #----------------------------------------------------------------------------
  # Attack Penalty
  #----------------------------------------------------------------------------
  alias attack_penalty_recharger_later attack_penalty
  def attack_penalty
    re = BlizzABS::Weapons.recharge(@battler.weapon_id)
    @recharge[0], @rechcounter[0] = re, re
    @recheck.push(0)
    return attack_penalty_recharger_later
  end
  #----------------------------------------------------------------------------
  # Skill Penalty
  #----------------------------------------------------------------------------
  alias skill_penalty_recharger_later skill_penalty
  def skill_penalty(id)
    re = BlizzABS::Skills.recharge(id)
    @recharge[1+id], @rechcounter[1+id] = re, re
    @recheck.push(1+id)
    return skill_penalty_recharger_later(id)
  end
  #----------------------------------------------------------------------------
  # Item Penalty
  #----------------------------------------------------------------------------
  alias item_penalty_recharger_later item_penalty
  def item_penalty(id)
    re = BlizzABS::Items.recharge(id)
    @recharge[501+id], @rechcounter[501+id] = re, re
    @recheck.push(501+id)
    return item_penalty_recharger_later(id)
  end
end


class Map_Enemy
  #----------------------------------------------------------------------------
  # Update
  #----------------------------------------------------------------------------
  alias upd_recharger_later update
  def update
    @recheck.each {|i|
      if recharging?(i)
        @rechcounter[i] -= 1
      else
        @recheck.delete(i)
      end}
    upd_recharger_later
  end
  #----------------------------------------------------------------------------
  # Attack Penalty
  #----------------------------------------------------------------------------
  alias attack_penalty_recharger_later attack_penalty
  def attack_penalty
    re = BlizzABS::Enemies.recharge(@battler.weapon_id)
    @recharge[0], @rechcounter[0] = re, re
    @recheck.push(0)
    return attack_penalty_recharger_later
  end
  #----------------------------------------------------------------------------
  # Skill Penalty
  #----------------------------------------------------------------------------
  alias skill_penalty_recharger_later skill_penalty
  def skill_penalty(id)
    re = BlizzABS::Skills.recharge(id)
    @recharge[1+id], @rechcounter[1+id] = re, re
    @recheck.push(1+id)
    return skill_penalty_recharger_later(id)
  end
  #----------------------------------------------------------------------------
  # Item Penalty
  #----------------------------------------------------------------------------
  alias item_penalty_recharger_later item_penalty
  def item_penalty(id)
    re = BlizzABS::Items.recharge(id)
    @recharge[501+id], @rechcounter[501+id] = re, re
    @recheck.push(501+id)
    return item_penalty_recharger_later(id)
  end
end



class Hotkey_Assignment < Sprite
 
  attr_accessor :recharge
  alias initialize_recharge_later initialize
  def initialize(viewport = nil)
    initialize_recharge_later(viewport)
    @recharge = Hotkey_Assignment_Recharge.new(self.x, self.y, self.z)
   
  end
  #----------------------------------------------------------------------------
  # update
  #  Updates the hotkey display.
  #----------------------------------------------------------------------------
  alias update_recharge_later update
  def update
    update_recharge_later
    if @recharge != nil
      @recharge.update
    end
  end
  #----------------------------------------------------------------------------
  # dispose
  #  Removes recharge time graphics from screen and memory.
  #----------------------------------------------------------------------------
  alias dispose_recharge_later dispose
  def dispose
    @recharge.dispose
    dispose_recharge_later
  end
end

class Hotkey_Assignment_Recharge < Sprite
 
  attr_reader :skillrecharge
  attr_reader :itemrecharge
  attr_reader :chargebitmaps
  #----------------------------------------------------------------------------
  # Initialization
  #  viewport - the viewport for the sprite
  #----------------------------------------------------------------------------
  def initialize(x0, y0, z0, viewport = nil)
    # call superclass
    super(viewport)
    # create bitmap
    self.bitmap = Bitmap.new(320, 32)
    # set font name
    self.bitmap.font.name = 'Arial'
    # set font size
    self.bitmap.font.size = 16
    # set font to bold
    self.bitmap.font.bold = true
    # set x and y position
    self.x, self.y, self.z = x0, y0, z0+100
    # update display
    @actor = $game_player.battler
    @skillrecharge = []
    @itemrecharge = []
    (1...10).each {|i|
        @skillrecharge.push(i)
        @itemrecharge.push(i)}
    update
  end
  #----------------------------------------------------------------------------
  # draw
  #  Draws the recharge sectors over the hotkey display.
  #----------------------------------------------------------------------------
  def draw(index = nil)
    # iterate through all skills that need to be recharged
    (@skillrecharge).each {|i|
      # temporary var
      object = $data_skills[$game_player.skill_hotkeys[i%10]]
      ind = $game_player.skill_hotkeys[i%10]+1
      if $game_player.recharging?(ind)
        # remove old image
        self.bitmap.fill_rect(32*(i-1), 0, 32, 32, Color.new(0, 0, 0, 0))
        # draw recharge indicator
        len = (24*$game_player.rech_rate(ind)).to_i
        self.bitmap.fill_rect(32*(i-1)+4, 0, len, 4, Color.new(255, 255, 0))
        self.bitmap.draw_text_full(32*(i-1)+4, 4, 24, 24, (($game_player.rechcounter[ind]/40).to_i+1).to_s, 1)
      else
        if object != nil
          # remove old image
          self.bitmap.fill_rect(32*(i-1), 0, 32, 32, Color.new(0, 0, 0, 0))
        end
        @skillrecharge.delete(i)
      end}
    # iterate through all items that need to be recharged
    (@itemrecharge).each {|i|
      # temporary var
      object = $data_items[$game_player.item_hotkeys[i%10]]
      ind = $game_player.item_hotkeys[i%10]+501
      if $game_player.recharging?(ind)
        # remove old image
        self.bitmap.fill_rect(32*(i-1), 0, 32, 32, Color.new(0, 0, 0, 0))
        # draw recharge indicator
        len = (24*$game_player.rech_rate(ind)).to_i
        self.bitmap.fill_rect(32*(i-1)+4, 0, len, 4, Color.new(255, 255, 0))
        self.bitmap.draw_text_full(32*(i-1)+4, 4, 24, 24, (($game_player.rechcounter[ind]/40).to_i+1).to_s, 1)
      else
        if object != nil
          # remove old image
          self.bitmap.fill_rect(32*(i-1), 0, 32, 32, Color.new(0, 0, 0, 0))
        end
        @itemrecharge.delete(i)
      end}
  end
  #----------------------------------------------------------------------------
  # update
  #  Updates the hotkey display.
  #----------------------------------------------------------------------------
  def update
    if @actor != $game_player.battler
      # set new actor
      @actor = $game_player.battler
      @skillrecharge = []
      @itemrecharge = []
      self.bitmap.fill_rect(0, 0, 320, 32, Color.new(0, 0, 0, 0))
      (1...10).each {|i|
        @skillrecharge.push(i)
        @itemrecharge.push(i)}
      draw
    end
    draw if test_recharge
  end
  #----------------------------------------------------------------------------
  # test_recharge
  #  Updates the hotkey display.
  #----------------------------------------------------------------------------
  def test_recharge
    BlizzABS::Cache::HotkeyRange.each {|i|
      if $game_player.skill_hotkeys[i%10] != 0 and !@skillrecharge.include?(i)
        ind = $game_player.skill_hotkeys[i%10]+1
        if $game_player.recharging?(ind)
          @skillrecharge.push(i)
          return true
        end
      elsif $game_player.item_hotkeys[i%10] != 0 and !@itemrecharge.include?(i)
        ind = $game_player.item_hotkeys[i%10]+501
        if $game_player.recharging?(ind)
          @itemrecharge.push(i)
          return true
        end
      end}
    return false if @skillrecharge.size < 1 and @itemrecharge.size < 1
    return true
  end
  #----------------------------------------------------------------------------
  # bitmap_square_sect
  #  w          - width
  #  rate       - fill rate
  #  color    - color
  #  Draws the HUD gradient bar.
  #  This was going to be used a recharge graphic, but it lagged.  I included
  #  the code in case someone ever wanted to use it or fixes the lag.
  #----------------------------------------------------------------------------
  def bitmap_square_sect(w, rate)
    b = Bitmap.new(w, w)
    return b if rate <= 0.0 or rate > 1.0
    color = Color.new(0, 0, 0, 127)
    (0...23).each {|x|
      (0...23).each {|y|
        angle = (Math.atan2(x-w/2, y-w/2) + 6*Math::PI/2)%(2*Math::PI)
        b.set_pixel(x, y, color) if angle <= 2*Math::PI*rate}}
    return b
  end
end




Instructions
PUT BELOW BLIZZ-ABS
Configure the recharge times like they are in Blizz-ABS.  What that means in for each skill/item/weapo/enemy, under the appropriate area, put in
when (ID OF SKILL/ITEM/WEAPON/ENEMY) then return (RECHARGE TIME)

The recharge time is in frames.  40 frames is about 1 second.


Compatibility

Made for Blizz-ABS 2.82 and above.


Credits and Thanks


  • Blizzard for setting down some main code
  • Aqua for testing it and telling me all my stupid mistakes
  • winkio



Author's Notes

Just a note: it seems to lag very slightly if a lot of stuff is recharging at once, like 5 or more things.

If you have any ideas for other ways to show something recharging that you want implemented, let me know.  I originally had a spiral recharge thing like most MMOs do (WoW and Guild Wars, for example), but it lagged too much.  I will look into ways to reduce that lag, but it may not be possible.

Blizzard

I actually made a plugin for that. I just can't remember for whom it was. >.< I think it was NAMKCOR. Anyway, I promised not to release it. ._. You should ask him if it's ok with him. Or wait until I implement it into Blizz-ABS. >.<
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio

I think it's all right.  I don't want to get you in trouble (although I don't know why the person would think that recharge times are so original) but I figured it out from the AI triggers :P
(don't know why I didn't look there earlier)

So... once I end up getting this to work, will it be allowed for me to post it up?  Because this is kind of independent...

And if I do end up posting this up, will you just put yours up too thereby nullifying mine?  In which case, it wouldn't even be worth it to develop it on my own...

I'll pm Namkcor and see what he thinks as well.

tSwitch

Quote from: Blizzard on December 12, 2008, 05:23:55 am
I actually made a plugin for that. I just can't remember for whom it was. >.< I think it was NAMKCOR. Anyway, I promised not to release it. ._. You should ask him if it's ok with him. Or wait until I implement it into Blizz-ABS. >.<


Blizz, go ahead and release it


FCF3a A+ C- D H- M P+ R T W- Z- Sf RLCT a cmn+++ d++ e++ f h+++ iw+++ j+ p sf+
Follow my project: MBlok | Find me on: tSwitch.us | Twitter | Tumblr

Blizzard

Alright, here you go:

class BlizzABS::Cache
 
  alias init_recharger_later initialize
  def initialize
    init_recharger_later
    @data['empty_hud_yellow_bar'] = @data['empty_hud_green_bar'].clone
    @data['empty_hud_yellow_bar'].hue_change(-60)
    @data['hud_yellow_bar'] = @data['hud_green_bar'].clone
    @data['hud_yellow_bar'].hue_change(-60)
    #p 1
    #p self.image('hud_yellow_bar')
  end
   
end
 
$BlizzABS = BlizzABS::Processor.new

class Recharger < Sprite
  def initialize
    super
    self.bitmap = Bitmap.new(156, 14)
    color = case BlizzABS::Config::HUD_TYPE
    when 0 then Color.new(255, 255, 255, 192)
    when 1 then Color.new(0, 0, 0, 0)
    end
    self.bitmap.fill_rect(0, 0, 156, 14, color) if color.is_a?(Color)
    self.x = 4
    update
  end
  def update
    super
    now, full = $game_player.recharge
    self.bitmap.gradient_bar_hud(0, 0, 154, now.to_f/full, 'hud_yellow_bar')
    self.dispose if !$game_player.recharging?
  end
end

class Scene_Map
  alias main_recharger_later main
  def main
    @recharge_bar = Recharger.new if $game_player.recharging?
    main_recharger_later
    @recharge_bar.dispose if @recharge_bar != nil
  end
  alias upd_recharger_later update
  def update
    if $game_player.recharging? && @recharge_bar == nil
      @recharge_bar = Recharger.new
    end
    upd_recharger_later
    if @recharge_bar != nil
      if @hud != nil
        @recharge_bar.y = @hud.y + @hud.bitmap.height + 4
      else
        @recharge_bar.y = 4
      end
      @recharge_bar.update
      @recharge_bar = nil if @recharge_bar.disposed?
    end
  end
end

class Map_Battler
  attr_reader :recharge
  alias upd_recharger_later update
  def update
    @recharge[0] -= 1 if recharging?
    upd_recharger_later
  end
  alias freeze_action_recharger_later freeze_action
  def freeze_action
    return (freeze_action_recharger_later || recharging?)
  end
  alias skill_penalty_recharger_later skill_penalty
  def skill_penalty(id)
    re = BlizzABS::Skills.recharge(id)
    @recharge = [re, re]
    return skill_penalty_recharger_later(id)
  end
  alias item_penalty_recharger_later item_penalty
  def item_penalty(id)
    re = BlizzABS::Skills.recharge(id)
    @recharge = [re, re]
    return item_penalty_recharger_later(id)
  end
  def recharging?
    return (@recharge != nil && @recharge[0] > 0)
  end
end

class Map_Actor
  alias attack_penalty_recharger_later attack_penalty
  def attack_penalty
    re = BlizzABS::Weapons.recharge(@battler.weapon_id)
    @recharge = [re, re]
    return attack_penalty_recharger_later
  end
end

class Map_Enemy
  alias attack_penalty_recharger_later attack_penalty
  def attack_penalty
    re = BlizzABS::Enemies.recharge(@battler.weapon_id)
    @recharge = [re, re]
    return attack_penalty_recharger_later
  end
end

module BlizzABS
  module Weapons
    def self.recharge(id)
      case id
      when 1 then return 40
      end
      return 40
    end
  end
  module Skills
    def self.recharge(id)
      case id
      when 1 then return 40
      end
      return 40
    end
  end
  module Items
    def self.recharge(id)
      case id
      when 1 then return 40
      end
      return 40
    end
  end
  module Enemies
    def self.recharge(id)
      case id
      when 1 then return 40
      end
      return 40
    end
  end
end


I'll put it up later as plugin.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Aqua

Eep!  This is not what I wanted...

Lol winkio was actually making this system because I requested it.

I wanted that each skill have its OWN counter to prevent itself from being used spammily instead of just one that prevents the character from doing anything else.
*cough* like in MMOs *cough*

I'm pretty sure winkio knows what I'm talking about.

winkio

Yeah sorry Aqua for not doing this over the weekend.  I underestimated the amount of studying I needed (and still need) to do for finals, which I have through friday this week.  I should have it done by Christmas, as long as my family doesn't have too much planned...

Blizz's system is pretty much how I am doing mine, except of course the array of recharge counters that I have, and the update is on the hotkey bar, not the hud.

Another thing that you might be able to help me with blizz is if there is any method to fill a polygon.  I'm sure there is, I just can't seem to find it.

And yes, Aqua requested this, but I had this idea for a while on my back burner, along with most of my other stuff.  So it's for me too.  (And other people may want this as well)

Aqua

winkio, take your time with this; I'm in no rush.
Eductation is always important!

Diokatsu

"Eductation"...Irony! XD

I'm actually look to use this :X This is quite neat and really simplifies my project that I'm working on.

winkio

December 15, 2008, 08:38:56 pm #9 Last Edit: December 15, 2008, 09:33:35 pm by winkio
I'm working on it a bit tonight because it kind-of counts as studying for my low-level computer science class. ;)

EDIT:  Ok, finished the system, only through borrowing a small part of Blizz's code.  Now to add the visual indicators on the hotkey bar.

@anyone who knows: how do I fill a polygon?

Blizzard

LMAO! I made that for NAMK almost a year ago. xD Feel free to take the entire code and make a new version featuring individual recharges without the bar. Just be sure to add the appropriate stuff like Blizz-ABS-is-there check, etc. Best you integrate the check for usage in Map_Battler#skill_can_use? instead of direct implementation in the deriving classes like I did.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio

Yes, I modified skill_can_use, attack_can_use, and item_can use, and I'm using two paralell arrays: one for max recharge times, and one for the counters.  And there is no lag:)

The only thing left is some way to show it's charging.  If there is a way to fill a polygon or triangle, I can use that, otherwise, I'll make a little bar for each thing on the hotkeys

Blizzard

You have to code the filling of polygons or triangles yourself by using pixel and rectangle filling. In other words: no.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio

December 16, 2008, 11:49:05 am #13 Last Edit: December 17, 2008, 04:21:56 pm by winkio
darn, thought so.  Well, as might as well just code the whole drawing of the sector at once.

EDIT:  Sweet, I finished it, using a 3-part piecewise function.  The only problem is that it seems to go one pixel over each edge of the icon.  Any ideas why?

Also, it won't fill the rectangle the opacity of the color I give it.  Why?

Final question: It seems that the hotkey bar only updates upon activation/deactivation for me.  Why?

Aqua

Woah that lagged a lot :O
And I'm not sure about this, but the rectangles over the icons might not be disposed when the time is over.

Other than that, good job :)

winkio

December 17, 2008, 05:20:55 pm #15 Last Edit: December 19, 2008, 12:13:07 pm by winkio
MAJOR EDIT: All the old testing code is gone, because the script is finished!!!

winkio

bump bump bump bump BUMP BUMP BUMP BUMP BUMP BUUMMMMMMMMMMMMP

Ah, that felt good. :^_^':

Yep, this thing is done, so look at it!

Blizzard

Quote from: winkio on December 11, 2008, 07:25:43 pm
The recharge time is in frames.  40 frames is about 1 second.


Lol, 40 frames is exactly one second.
That reminds me of that episode of Big Bang Theory where those two guys have to push a closet up the stairs and the angle is 30°. One of them is like "That should decrease the power needed by around half." and the other is like "... by EXACTLY half."
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Kagutsuchi


Makasu

Does it matter where this script is posted? IE above BABS or below it? Just curious is all. G'job as well. :3
Dead on Arrival is the name of my project. Topic thread coming sooner or later.

Me on deviantart.com
My talents: ShowHide

  • Spriting
  • drawing
  • html coding
  • website design
  • skating
             PM now for a personal quote!
[[Will draw character art for you for $$$ or scripts!]]