[BABS] DoT system; state that deals damage based on a spell

Started by sasofrass, March 20, 2012, 05:33:25 pm

Previous topic - Next topic

sasofrass

I would like to say I am sorry about the recent flood of requests, I am just trying to prepare all of my spells and abilities lol.

I was wondering if it would be possible to make a state deal damage based off of a skill that would work with BABS.

Example:
A state is applied with the condition [After 10 turns, 100% chance] set and Slip Damage is checked off.
The state is also considered as a DoT type of state through the script.
The script defines the state to deal damage at least 3 times throughout the 10 seconds (3.3 seconds, 6.6 seconds, 10 seconds, split evenly - damage should not be instant)
The script defines the damage should be dealt according to the skill ID set with it (to take the power/ATK/STR/DEX/AGI/INT coefficients).

Basically, I do not want a percentage dealing DoT like one that is built in. On a boss battle, it would be game breaking to have a DoT dealing like 10% every 2 seconds, while your other abilities may only do like 0.25% of the health.

I would like DoTs to deal damage based off of the skill, last as long as the duration of the state, and tick for the amount specified within the script at an equal rate.

Example 2:
State 050: Fire Damage
-Slip Damage checked
-After 12 turns, 100% chance
-when 50 return (4, 20) [when STATE_ID return (TICK_AMOUNT, SPELL_ID)]

Every 3 seconds, the damage that would be dealt from Spell_ID will be dealt instead of a percentage.


I hope that isn't too confusing or difficult.

Thanks a bunch!  :D


G_G


sasofrass

Quote from: game_guy on March 20, 2012, 07:42:59 pm
This? http://forum.chaos-project.com/index.php/topic,2481.0.html



It is not quite the effect I was going for, that does allow for a set amount of a percentage, but as you level up it will not scale with you if you do not use a percentage and that is what I was mainly looking for without it doing a percentage of damage to an enemy.

I was suggesting having it go with a skill because those can be designed to scale upwards as you level and can be based off of many different coefficients, making better gameplay in my opinion.

KK20

Took me a while to understand the request, but I get it now. Essentially you want a DoT system that works like Maplestory's (yes, I had to go there...)

There are a number of things to keep in mind for this:
1) Can different DoT states stack?
2) How about in such an instance where Actor A and Actor B both use a "burn" skill on an enemy? Do both of their burns take effect? Or will the stronger one of the two only do DoT? Or is it based off of "whoever put DoT on the monster last takes priority"?
3) Is there such thing as SP DoT in your game? How about regen HP and/or SP?

Since Actor A's "burn" and Actor B's "burn" should do different DoT, the enemy will have to know which actor burned it. Not to mention, the method 'slip_damage_effect' will have to follow the same damage formula as the method 'skill_effect'.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

sasofrass

Quote from: KK20 on March 21, 2012, 12:43:27 am
Took me a while to understand the request, but I get it now. Essentially you want a DoT system that works like Maplestory's (yes, I had to go there...)

There are a number of things to keep in mind for this:
1) Can different DoT states stack?
2) How about in such an instance where Actor A and Actor B both use a "burn" skill on an enemy? Do both of their burns take effect? Or will the stronger one of the two only do DoT? Or is it based off of "whoever put DoT on the monster last takes priority"?
3) Is there such thing as SP DoT in your game? How about regen HP and/or SP?


1. If the states are different, they should stack
2. If they both use an ability that apply the same state, it will take whoever the first person applied it (which wouldn't be a problem, my game uses no partners in battle)
3. SP DoT's would not be necessary, neither would regen DoT's.


To make it simple, each time the DoT does tick damage, it will use the skill that goes with the state.


KK20

Alright, I'll take a look at it more. I can't promise anything yet, but I'll update whether or not I will do it.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

sasofrass

Quote from: KK20 on March 21, 2012, 10:13:01 pm
Alright, I'll take a look at it more. I can't promise anything yet, but I'll update whether or not I will do it.


I would greatly appreciate it! Any abilities right now that I would like to be DoT's I can't yet make because I don't have a system for it :(


I am also trying to contact some of the creators of the few scripts I am using for commercial use. I am willing to pay a reasonable fee for a commercial use script when ready.

KK20

Spoiler: ShowHide
=begin
===============================================================================
Skill Damage Over Time (Blizz ABS add-on)
Version 1.00
Created by KK20

Requested by sasofrass
===============================================================================
===============================================================================
[Description]
  States that applied damage over time (DoT) always dealt damage that was equal
  to some percentage amount of the player's HP. In Blizz ABS, any state that had
  'slip damage' checked as true would always do damage equal to 2% of the
  battler's max HP every second (40 frames).
 
  This script modifies that and allows some customizable DoT amounts. States
  with 'slip damage' will now be associated with a skill. In other words, every
  time DoT takes place, the affected battler will now take damage as if it was
  attacked by a skill. Essentially, you can make a DoT state called "Burn" and
  assign it to the skill "Fire". Instead of the battler taking 2% of max HP
  damage, it will now take damage as if it were being hit by "Fire".
 
  Also, you can assign how many times DoT will take place during the duration of
  the state. No longer will DoT have to take place every second of gameplay. You
  can make DoT take place once every 3 seconds, only once in 20 seconds, or even
  3 times every second.
 
[Features]
  - Assign skills to states that deal DoT
  - Customize how many times DoT takes place
  - Maintains Blizz ABS's original slip_damage_effect, just in case you want to
    use the original "2% of max HP damage every second" somewhere
   
[Instructions]
  > In order for skills to deal damage over time, check the box "Slip Damage"
  > If you want the state to wear off after so many seconds, check the box
    "Release at the end of battle".
    If you want the state to remain forever until it is cured, don't check it.
  > How frequent DoT takes place is based on the following formula:
        FREQUENCY = TURNS / TICKS
    where TURNS is the value you put in "After [ x ] turns" in the database
    and   TICKS is the number of times you want DoT to take place (config below)
   
[Credits]
  KK20 ==> Writing the script
  Blizzard ==> For Blizz-ABS (and making this script possible)

===============================================================================
=end

#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
# B E G I N     C O N F I G U R A T I O N
#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
module Skills_DoT
 
  def self.dot_states(state_id)
    return nil unless $data_states[state_id].slip_damage
    case state_id
    #--------------------------------------------------------------------------
    # self.dot_states(state_id)
    #   Configure what skill you would like to associate to the DoT state here.
    #   Also, configure how frequent the DoT takes place during the duration of
    #   the state.
    # Format:
    #     When STATE_ID then return (SKILL_ID, TICKS)
    #     
    #   STATE_ID: The state's ID value located within the database
    #   SKILL_ID: The skill's ID value located within the database
    #   TICKS   : The number of times DoT will take place
    #--------------------------------------------------------------------------
    when 3 then return [7, 10] # when Venom, then use skill 'Fire' 10 times
    when 8 then return [13, 1] # when Paralyzed, then use skill 'Thunder' 1 time
    else
      return nil
    end
  end

end
#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
# E N D     C O N F I G U R A T I O N
#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*

#=============================================================================
# Map_Battler < Game_Character                                (Blizz ABS class)
#   Aliased:
#     slip_damage_effect
#   Rewrite:
#     count_states
#     additional_states
#=============================================================================
class Map_Battler < Game_Character
  #----------------------------------------------------------------------------
  # count_states
  #  Changes the state time counters.
  #----------------------------------------------------------------------------
  def count_states
    # check each state
    battler.state_time.each_key {|id|
        # decrease counter if fading state
        battler.state_time[id] -= 1
        # if 1 second has passed and probability that the state gets removed
        ### ADDED '$data_states[id].battle_only' CONDITION ###
        if $data_states[id].battle_only && battler.state_time[id] <= 0 &&
          battler.state_time[id] % 40 == 0 && rand(100) < $data_states[id].auto_release_prob
          # remove state and counter
          battler.remove_state(id)
          battler.state_time.delete(id)
        # If this state cannot be removed after a while and reached end of timer
        elsif !$data_states[id].battle_only && battler.state_time[id] <= 0
          # Reset the state's timer
          battler.state_time[id] = $data_states[id].hold_turn * 40 + 1
        end
    }
  end
  #----------------------------------------------------------------------------
  # additional_states
  #  Handles poison and paralyze effects as well as additional status effects.
  #
  #  This method has been REWRITTEN by KK20.
  #----------------------------------------------------------------------------
  def additional_states
    # temporary variable
    slip_damage = battler.slip_damage?
    # if Tons of Add-ons is there and using Regen Status
    if $tons_version != nil && $tons_version >= 5.98 &&
        $game_system.REGEN_STATUS
      # modify slip damage flag
      slip_damage |= (HP_REGEN_IDS + SP_REGEN_IDS + SP_POISON_IDS).any? {|i|
          battler.states.include?(i)}
    end
    # if not dead and getting slip damage
    ### MOVED THE 'PER SECOND' CONDITION TO 'slip_damage_effect' ###
    if valid? && slip_damage
      # apply the slip damage
      slip_damage_effect
    end
    # if old direction fix was stored
    if @old_direction_fix != nil
      # if able to move again
      if self.restriction < 4
        # reset everything
        @direction_fix, @old_direction_fix = @old_direction_fix, nil
      end
    # if paralyzed
    elsif self.restriction == 4
      # store old direction fix and set new direction fix
      @direction_fix, @old_direction_fix = true, @direction_fix
      # reset movement
      @force_move = []
      # reset action if valid and not charging
      self.reset_action if self.valid? && !self.charging?(BlizzABS::CHARGEFreeze)
    end
  end
  #----------------------------------------------------------------------------
  # slip_damage_effect
  #  Applies slip damage effect.
  # 
  #  This method has been ALIASED and EDITTED by KK20.
  #---------------------------------------------------------------------------- 
  alias babs_slip_damage_effect_original slip_damage_effect
  def slip_damage_effect
    ids = []
    @battler.states.each{|state_id|
      # skip this state if it isn't a slip_damage or configured
      next unless Skills_DoT.dot_states(state_id) != nil
      # Calculate on what frame to apply the DoT
      frame = ($data_states[state_id].hold_turn * 40) / Skills_DoT.dot_states(state_id)[1]
      # Only do DoT damage if correct frame
      next if battler.state_time[state_id] % frame != 0
      # Prepare to calculate damage
      user = @battler.states_caused_by_characters_list[state_id]
      skill = $data_skills[Skills_DoT.dot_states(state_id)[0]]
      # Calculate power
      power = skill.power + user.atk * skill.atk_f / 100
      if power > 0
        power -= @battler.pdef * skill.pdef_f / 200
        power -= @battler.mdef * skill.mdef_f / 200
        power = [power, 1].max
      end
      # Calculate rate
      rate = 20
      rate += (user.str * skill.str_f / 100)
      rate += (user.dex * skill.dex_f / 100)
      rate += (user.agi * skill.agi_f / 100)
      rate += (user.int * skill.int_f / 100)
      # Calculate basic damage
      damage = power * rate / 20
      # Element correction
      damage *= @battler.elements_correct(skill.element_set)
      damage /= 100
      # Dispersion
      if skill.variance > 0 and damage.abs > 0
        amp = [damage.abs * skill.variance / 100, 1].max
        damage += rand(amp+1) + rand(amp+1) - amp
      end
      # Damage will always do at least 1 HP
      damage = (damage <= 0 ? 1 : damage)
      # Apply the damage
      @battler.hp -= damage
    }
    # Call BABS original slip damage method afterwards
    if Graphics.frame_count % 40 == 0
      @battler.states.each{|state_id|
        if $data_states[state_id].slip_damage and Skills_DoT.dot_states(state_id) == nil
          babs_slip_damage_effect_original
          break
        end
      }
    end
  end
end
#=============================================================================
# Game_Battler
#   Aliased:
#     initialize
#     attack_effect
#     skill_effect
#   Rewrite:
#     add_state
#     remove_state
#=============================================================================
class Game_Battler
  #-----------------------
  # Create 'set' and 'get'
  #-----------------------
  attr_accessor :state_giver_attacker
  attr_accessor :states_caused_by_characters_list
  #---------------------------------------------------------------------------
  # The following three methods have been ALIASED and EDITTED by KK20.
  #---------------------------------------------------------------------------
  alias call_orig_init_again initialize
  def initialize
    @state_giver_attacker = nil
    @states_caused_by_characters_list = {}
    call_orig_init_again
  end
 
  alias call_original_attack_effect attack_effect
  def attack_effect(attacker)
    @state_giver_attacker = attacker
    call_original_attack_effect(attacker)
  end
 
  alias call_original_skill_effect skill_effect
  def skill_effect(user, skill)
    @state_giver_attacker = user
    call_original_skill_effect(user, skill)
  end
 
  #--------------------------------------------------------------------------
  # Add State
  #
  # This method has been EDITTED by KK20.
  #--------------------------------------------------------------------------
  def add_state(state_id, force = false)
    # For an ineffective state
    if $data_states[state_id] == nil
      # End Method
      return
    end
    # If not forcefully added
    unless force
      # A state loop already in existance
      for i in @states
        # If a new state is included in the state change (-) of an existing
        # state, and that state is not included in the state change (-) of
        # a new state (example: an attempt to add poison during dead)
        if $data_states[i].minus_state_set.include?(state_id) and
           not $data_states[state_id].minus_state_set.include?(i)
          # End Method
          return
        end
      end
    end
    # If this state is not added
    unless state?(state_id)
      # Add state ID to @states array
      @states.push(state_id)
      # If this state does Skill DoT, find the actor that caused this state
      if Skills_DoT.dot_states(state_id) != nil
        @states_caused_by_characters_list[state_id] = @state_giver_attacker.clone
      end
      # If option [regarded as HP 0]is effective
      if $data_states[state_id].zero_hp
        # Change HP to 0
        @hp = 0
      end
      # All state loops
      for i in 1...$data_states.size
        # Dealing with a state change (+)
        if $data_states[state_id].plus_state_set.include?(i)
          add_state(i)
        end
        # Dealing with a state change (-)
        if $data_states[state_id].minus_state_set.include?(i)
          remove_state(i)
        end
      end
      # line change to a large rating order (if value is the same, then a
      # strong restriction order)
      @states.sort! do |a, b|
        state_a = $data_states[a]
        state_b = $data_states[b]
        if state_a.rating > state_b.rating
          -1
        elsif state_a.rating < state_b.rating
          +1
        elsif state_a.restriction > state_b.restriction
          -1
        elsif state_a.restriction < state_b.restriction
          +1
        else
          a <=> b
        end
      end
    end
    # If added forcefully
    if force
      # Set the natural removal's lowest number of turns to -1
      @states_turn[state_id] = -1
    end
    # If not added forcefully
    unless  @states_turn[state_id] == -1
      # Set the natural removal's lowest number of turns
      @states_turn[state_id] = $data_states[state_id].hold_turn
    end
    # If unable to move
    unless movable?
      # Clear action
      @current_action.clear
    end
    # Check the maximum value of HP and SP
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
  #--------------------------------------------------------------------------
  # Remove State
  #
  # This method has been EDITTED by KK20.
  #--------------------------------------------------------------------------
  def remove_state(state_id, force = false)
    # If this state is added
    if state?(state_id)
      # If a forcefully added state is not forcefully removed
      if @states_turn[state_id] == -1 and not force
        # End Method
        return
      end
      # If current HP is at 0 and options are effective [regarded as HP 0]
      if @hp == 0 and $data_states[state_id].zero_hp
        # Determine if there's another state [regarded as HP 0] or not
        zero_hp = false
        for i in @states
          if i != state_id and $data_states[i].zero_hp
            zero_hp = true
          end
        end
        # Change HP to 1 if OK to remove incapacitation.
        if zero_hp == false
          @hp = 1
        end
      end
      # Delete state ID from @states and @states_turn hash array
      @states.delete(state_id)
      @states_turn.delete(state_id)
      # Clear the state-causing-actor value from hash
      @states_caused_by_characters_list.delete(state_id)
    end
    # Check maximum value for HP and SP
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
end

Place below BABS and Tons. Before Main of course.

Give that a test and tell me what you think. It looked good on my end, but I didn't try to break the system.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

sasofrass

Quote from: KK20 on March 22, 2012, 08:22:13 pm
Spoiler: ShowHide
=begin
===============================================================================
Skill Damage Over Time (Blizz ABS add-on)
Version 1.00
Created by KK20

Requested by sasofrass
===============================================================================
===============================================================================
[Description]
  States that applied damage over time (DoT) always dealt damage that was equal
  to some percentage amount of the player's HP. In Blizz ABS, any state that had
  'slip damage' checked as true would always do damage equal to 2% of the
  battler's max HP every second (40 frames).
 
  This script modifies that and allows some customizable DoT amounts. States
  with 'slip damage' will now be associated with a skill. In other words, every
  time DoT takes place, the affected battler will now take damage as if it was
  attacked by a skill. Essentially, you can make a DoT state called "Burn" and
  assign it to the skill "Fire". Instead of the battler taking 2% of max HP
  damage, it will now take damage as if it were being hit by "Fire".
 
  Also, you can assign how many times DoT will take place during the duration of
  the state. No longer will DoT have to take place every second of gameplay. You
  can make DoT take place once every 3 seconds, only once in 20 seconds, or even
  3 times every second.
 
[Features]
  - Assign skills to states that deal DoT
  - Customize how many times DoT takes place
  - Maintains Blizz ABS's original slip_damage_effect, just in case you want to
    use the original "2% of max HP damage every second" somewhere
   
[Instructions]
  > In order for skills to deal damage over time, check the box "Slip Damage"
  > If you want the state to wear off after so many seconds, check the box
    "Release at the end of battle".
    If you want the state to remain forever until it is cured, don't check it.
  > How frequent DoT takes place is based on the following formula:
        FREQUENCY = TURNS / TICKS
    where TURNS is the value you put in "After [ x ] turns" in the database
    and   TICKS is the number of times you want DoT to take place (config below)
   
[Credits]
  KK20 ==> Writing the script
  Blizzard ==> For Blizz-ABS (and making this script possible)

===============================================================================
=end

#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
# B E G I N     C O N F I G U R A T I O N
#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
module Skills_DoT
 
  def self.dot_states(state_id)
    return nil unless $data_states[state_id].slip_damage
    case state_id
    #--------------------------------------------------------------------------
    # self.dot_states(state_id)
    #   Configure what skill you would like to associate to the DoT state here.
    #   Also, configure how frequent the DoT takes place during the duration of
    #   the state.
    # Format:
    #     When STATE_ID then return (SKILL_ID, TICKS)
    #     
    #   STATE_ID: The state's ID value located within the database
    #   SKILL_ID: The skill's ID value located within the database
    #   TICKS   : The number of times DoT will take place
    #--------------------------------------------------------------------------
    when 3 then return [7, 10] # when Venom, then use skill 'Fire' 10 times
    when 8 then return [13, 1] # when Paralyzed, then use skill 'Thunder' 1 time
    else
      return nil
    end
  end

end
#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
# E N D     C O N F I G U R A T I O N
#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*

#=============================================================================
# Map_Battler < Game_Character                                (Blizz ABS class)
#   Aliased:
#     slip_damage_effect
#   Rewrite:
#     count_states
#     additional_states
#=============================================================================
class Map_Battler < Game_Character
  #----------------------------------------------------------------------------
  # count_states
  #  Changes the state time counters.
  #----------------------------------------------------------------------------
  def count_states
    # check each state
    battler.state_time.each_key {|id|
        # decrease counter if fading state
        battler.state_time[id] -= 1
        # if 1 second has passed and probability that the state gets removed
        ### ADDED '$data_states[id].battle_only' CONDITION ###
        if $data_states[id].battle_only && battler.state_time[id] <= 0 &&
          battler.state_time[id] % 40 == 0 && rand(100) < $data_states[id].auto_release_prob
          # remove state and counter
          battler.remove_state(id)
          battler.state_time.delete(id)
        # If this state cannot be removed after a while and reached end of timer
        elsif !$data_states[id].battle_only && battler.state_time[id] <= 0
          # Reset the state's timer
          battler.state_time[id] = $data_states[id].hold_turn * 40 + 1
        end
    }
  end
  #----------------------------------------------------------------------------
  # additional_states
  #  Handles poison and paralyze effects as well as additional status effects.
  #
  #  This method has been REWRITTEN by KK20.
  #----------------------------------------------------------------------------
  def additional_states
    # temporary variable
    slip_damage = battler.slip_damage?
    # if Tons of Add-ons is there and using Regen Status
    if $tons_version != nil && $tons_version >= 5.98 &&
        $game_system.REGEN_STATUS
      # modify slip damage flag
      slip_damage |= (HP_REGEN_IDS + SP_REGEN_IDS + SP_POISON_IDS).any? {|i|
          battler.states.include?(i)}
    end
    # if not dead and getting slip damage
    ### MOVED THE 'PER SECOND' CONDITION TO 'slip_damage_effect' ###
    if valid? && slip_damage
      # apply the slip damage
      slip_damage_effect
    end
    # if old direction fix was stored
    if @old_direction_fix != nil
      # if able to move again
      if self.restriction < 4
        # reset everything
        @direction_fix, @old_direction_fix = @old_direction_fix, nil
      end
    # if paralyzed
    elsif self.restriction == 4
      # store old direction fix and set new direction fix
      @direction_fix, @old_direction_fix = true, @direction_fix
      # reset movement
      @force_move = []
      # reset action if valid and not charging
      self.reset_action if self.valid? && !self.charging?(BlizzABS::CHARGEFreeze)
    end
  end
  #----------------------------------------------------------------------------
  # slip_damage_effect
  #  Applies slip damage effect.
  # 
  #  This method has been ALIASED and EDITTED by KK20.
  #---------------------------------------------------------------------------- 
  alias babs_slip_damage_effect_original slip_damage_effect
  def slip_damage_effect
    ids = []
    @battler.states.each{|state_id|
      # skip this state if it isn't a slip_damage or configured
      next unless Skills_DoT.dot_states(state_id) != nil
      # Calculate on what frame to apply the DoT
      frame = ($data_states[state_id].hold_turn * 40) / Skills_DoT.dot_states(state_id)[1]
      # Only do DoT damage if correct frame
      next if battler.state_time[state_id] % frame != 0
      # Prepare to calculate damage
      user = @battler.states_caused_by_characters_list[state_id]
      skill = $data_skills[Skills_DoT.dot_states(state_id)[0]]
      # Calculate power
      power = skill.power + user.atk * skill.atk_f / 100
      if power > 0
        power -= @battler.pdef * skill.pdef_f / 200
        power -= @battler.mdef * skill.mdef_f / 200
        power = [power, 1].max
      end
      # Calculate rate
      rate = 20
      rate += (user.str * skill.str_f / 100)
      rate += (user.dex * skill.dex_f / 100)
      rate += (user.agi * skill.agi_f / 100)
      rate += (user.int * skill.int_f / 100)
      # Calculate basic damage
      damage = power * rate / 20
      # Element correction
      damage *= @battler.elements_correct(skill.element_set)
      damage /= 100
      # Dispersion
      if skill.variance > 0 and damage.abs > 0
        amp = [damage.abs * skill.variance / 100, 1].max
        damage += rand(amp+1) + rand(amp+1) - amp
      end
      # Damage will always do at least 1 HP
      damage = (damage <= 0 ? 1 : damage)
      # Apply the damage
      @battler.hp -= damage
    }
    # Call BABS original slip damage method afterwards
    if Graphics.frame_count % 40 == 0
      @battler.states.each{|state_id|
        if $data_states[state_id].slip_damage and Skills_DoT.dot_states(state_id) == nil
          babs_slip_damage_effect_original
          break
        end
      }
    end
  end
end
#=============================================================================
# Game_Battler
#   Aliased:
#     initialize
#     attack_effect
#     skill_effect
#   Rewrite:
#     add_state
#     remove_state
#=============================================================================
class Game_Battler
  #-----------------------
  # Create 'set' and 'get'
  #-----------------------
  attr_accessor :state_giver_attacker
  attr_accessor :states_caused_by_characters_list
  #---------------------------------------------------------------------------
  # The following three methods have been ALIASED and EDITTED by KK20.
  #---------------------------------------------------------------------------
  alias call_orig_init_again initialize
  def initialize
    @state_giver_attacker = nil
    @states_caused_by_characters_list = {}
    call_orig_init_again
  end
 
  alias call_original_attack_effect attack_effect
  def attack_effect(attacker)
    @state_giver_attacker = attacker
    call_original_attack_effect(attacker)
  end
 
  alias call_original_skill_effect skill_effect
  def skill_effect(user, skill)
    @state_giver_attacker = user
    call_original_skill_effect(user, skill)
  end
 
  #--------------------------------------------------------------------------
  # Add State
  #
  # This method has been EDITTED by KK20.
  #--------------------------------------------------------------------------
  def add_state(state_id, force = false)
    # For an ineffective state
    if $data_states[state_id] == nil
      # End Method
      return
    end
    # If not forcefully added
    unless force
      # A state loop already in existance
      for i in @states
        # If a new state is included in the state change (-) of an existing
        # state, and that state is not included in the state change (-) of
        # a new state (example: an attempt to add poison during dead)
        if $data_states[i].minus_state_set.include?(state_id) and
           not $data_states[state_id].minus_state_set.include?(i)
          # End Method
          return
        end
      end
    end
    # If this state is not added
    unless state?(state_id)
      # Add state ID to @states array
      @states.push(state_id)
      # If this state does Skill DoT, find the actor that caused this state
      if Skills_DoT.dot_states(state_id) != nil
        @states_caused_by_characters_list[state_id] = @state_giver_attacker.clone
      end
      # If option [regarded as HP 0]is effective
      if $data_states[state_id].zero_hp
        # Change HP to 0
        @hp = 0
      end
      # All state loops
      for i in 1...$data_states.size
        # Dealing with a state change (+)
        if $data_states[state_id].plus_state_set.include?(i)
          add_state(i)
        end
        # Dealing with a state change (-)
        if $data_states[state_id].minus_state_set.include?(i)
          remove_state(i)
        end
      end
      # line change to a large rating order (if value is the same, then a
      # strong restriction order)
      @states.sort! do |a, b|
        state_a = $data_states[a]
        state_b = $data_states[b]
        if state_a.rating > state_b.rating
          -1
        elsif state_a.rating < state_b.rating
          +1
        elsif state_a.restriction > state_b.restriction
          -1
        elsif state_a.restriction < state_b.restriction
          +1
        else
          a <=> b
        end
      end
    end
    # If added forcefully
    if force
      # Set the natural removal's lowest number of turns to -1
      @states_turn[state_id] = -1
    end
    # If not added forcefully
    unless  @states_turn[state_id] == -1
      # Set the natural removal's lowest number of turns
      @states_turn[state_id] = $data_states[state_id].hold_turn
    end
    # If unable to move
    unless movable?
      # Clear action
      @current_action.clear
    end
    # Check the maximum value of HP and SP
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
  #--------------------------------------------------------------------------
  # Remove State
  #
  # This method has been EDITTED by KK20.
  #--------------------------------------------------------------------------
  def remove_state(state_id, force = false)
    # If this state is added
    if state?(state_id)
      # If a forcefully added state is not forcefully removed
      if @states_turn[state_id] == -1 and not force
        # End Method
        return
      end
      # If current HP is at 0 and options are effective [regarded as HP 0]
      if @hp == 0 and $data_states[state_id].zero_hp
        # Determine if there's another state [regarded as HP 0] or not
        zero_hp = false
        for i in @states
          if i != state_id and $data_states[i].zero_hp
            zero_hp = true
          end
        end
        # Change HP to 1 if OK to remove incapacitation.
        if zero_hp == false
          @hp = 1
        end
      end
      # Delete state ID from @states and @states_turn hash array
      @states.delete(state_id)
      @states_turn.delete(state_id)
      # Clear the state-causing-actor value from hash
      @states_caused_by_characters_list.delete(state_id)
    end
    # Check maximum value for HP and SP
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
end

Place below BABS and Tons. Before Main of course.

Give that a test and tell me what you think. It looked good on my end, but I didn't try to break the system.


This works perfectly!! :D Thanks you!

Is there any way to make it so it can show the damage ticks like bouncing damage?

KK20

Updated the script to Version 1.01
Spoiler: ShowHide
=begin
===============================================================================
Skill Damage Over Time (Blizz ABS add-on)
Version 1.01
Created by KK20

Requested by sasofrass
===============================================================================
                                  [Change Log]
Version
  1.01 :
    <> If DoT state was applied through an event, Nil Error was thrown
    <> Added the option to make DoT damage pop up
===============================================================================
[Description]
  States that applied damage over time (DoT) always dealt damage that was equal
  to some percentage amount of the player's HP. In Blizz ABS, any state that had
  'slip damage' checked as true would always do damage equal to 2% of the
  battler's max HP every second (40 frames).
 
  This script modifies that and allows some customizable DoT amounts. States
  with 'slip damage' will now be associated with a skill. In other words, every
  time DoT takes place, the affected battler will now take damage as if it was
  attacked by a skill. Essentially, you can make a DoT state called "Burn" and
  assign it to the skill "Fire". Instead of the battler taking 2% of max HP
  damage, it will now take damage as if it were being hit by "Fire".
 
  Also, you can assign how many times DoT will take place during the duration of
  the state. No longer will DoT have to take place every second of gameplay. You
  can make DoT take place once every 3 seconds, only once in 20 seconds, or even
  3 times every second.
 
[Features]
  - Assign skills to states that deal DoT
  - Customize how many times DoT takes place
  - Maintains Blizz ABS's original slip_damage_effect, just in case you want to
    use the original "2% of max HP damage every second" somewhere
  - (NEW) Can display DoT damage as pop up damage
   
[Instructions]
  > In order for skills to deal damage over time, check the box "Slip Damage"
  > If you want the state to wear off after so many seconds, check the box
    "Release at the end of battle".
    If you want the state to remain forever until it is cured, don't check it.
  > How frequent DoT takes place is based on the following formula:
        FREQUENCY = TURNS / TICKS
    where TURNS is the value you put in "After [ x ] turns" in the database
    and   TICKS is the number of times you want DoT to take place (config below)
   
[Credits]
  KK20 ==> Writing the script
  Blizzard ==> For Blizz-ABS (and making this script possible)

===============================================================================
=end

#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
# B E G I N     C O N F I G U R A T I O N
#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
module Skills_DoT
 
  #-----------------------------------------------------------------------------
  # DISPLAY_DOT_DAMAGE - Set to true if you want the damage values to pop up
  #                      during battle when affected by a DoT state.
  #-----------------------------------------------------------------------------
  DISPLAY_DOT_DAMAGE = true
 
  def self.dot_states(state_id)
    return nil unless $data_states[state_id].slip_damage
    case state_id
    #--------------------------------------------------------------------------
    # self.dot_states(state_id)
    #   Configure what skill you would like to associate to the DoT state here.
    #   Also, configure how frequent the DoT takes place during the duration of
    #   the state.
    # Format:
    #     When STATE_ID then return [SKILL_ID, TICKS]
    #     
    #   STATE_ID: The state's ID value located within the database
    #   SKILL_ID: The skill's ID value located within the database
    #   TICKS   : The number of times DoT will take place
    #--------------------------------------------------------------------------
    when 3 then return [81, 10] # when Venom, then use skill 'Fire' 10 times
    when 8 then return [13, 1] # when Paralyzed, then use skill 'Thunder' 1 time
    else
      return nil
    end
  end

end
#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
# E N D     C O N F I G U R A T I O N
#~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*

#=============================================================================
# Map_Battler < Game_Character                                (Blizz ABS class)
#   Aliased:
#     slip_damage_effect
#   Rewrite:
#     count_states
#     additional_states
#=============================================================================
class Map_Battler < Game_Character
  #----------------------------------------------------------------------------
  # count_states
  #  Changes the state time counters.
  #----------------------------------------------------------------------------
  def count_states
    # check each state
    battler.state_time.each_key {|id|
        # decrease counter if fading state
        battler.state_time[id] -= 1
        # if 1 second has passed and probability that the state gets removed
        ### ADDED '$data_states[id].battle_only' CONDITION ###
        if $data_states[id].battle_only && battler.state_time[id] <= 0 &&
          battler.state_time[id] % 40 == 0 && rand(100) < $data_states[id].auto_release_prob
          # remove state and counter
          battler.remove_state(id)
          battler.state_time.delete(id)
        # If this state cannot be removed after a while and reached end of timer
        elsif !$data_states[id].battle_only && battler.state_time[id] <= 0
          # Reset the state's timer
          battler.state_time[id] = $data_states[id].hold_turn * 40
        end
    }
  end
  #----------------------------------------------------------------------------
  # additional_states
  #  Handles poison and paralyze effects as well as additional status effects.
  #
  #  This method has been REWRITTEN by KK20.
  #----------------------------------------------------------------------------
  def additional_states
    # temporary variable
    slip_damage = battler.slip_damage?
    # if Tons of Add-ons is there and using Regen Status
    if $tons_version != nil && $tons_version >= 5.98 &&
        $game_system.REGEN_STATUS
      # modify slip damage flag
      slip_damage |= (HP_REGEN_IDS + SP_REGEN_IDS + SP_POISON_IDS).any? {|i|
          battler.states.include?(i)}
    end
    # if not dead and getting slip damage
    ### MOVED THE 'PER SECOND' CONDITION TO 'slip_damage_effect' ###
    if valid? && slip_damage
      # apply the slip damage
      slip_damage_effect
    end
    # if old direction fix was stored
    if @old_direction_fix != nil
      # if able to move again
      if self.restriction < 4
        # reset everything
        @direction_fix, @old_direction_fix = @old_direction_fix, nil
      end
    # if paralyzed
    elsif self.restriction == 4
      # store old direction fix and set new direction fix
      @direction_fix, @old_direction_fix = true, @direction_fix
      # reset movement
      @force_move = []
      # reset action if valid and not charging
      self.reset_action if self.valid? && !self.charging?(BlizzABS::CHARGEFreeze)
    end
  end
  #----------------------------------------------------------------------------
  # slip_damage_effect
  #
  #  This method has been EDITTED by KK20. (but only slightly)
  #----------------------------------------------------------------------------
  def slip_damage_effect
    # store hpdamage and spdamage
    hpdamage, spdamage = battler.hpdamage, battler.spdamage
    # store current hp and sp
    old_hp, old_sp = battler.hp, battler.sp
    # if Tons of Add-ons is there and using Regen Status
    if $tons_version != nil && $tons_version >= 5.98 &&
        $game_system.REGEN_STATUS
      # calculate HP damage
      damage_hp = battler.maxhp / 50
      damage_hp = 1 if damage_hp < 1
      # if HP damaging state
      if !(HP_REGEN_IDS.any? {|i| battler.states.include?(i)}) &&
          battler.slip_damage?
        # decrease HP by 2%
        battler.hp -= damage_hp
      # if HP regenarating state
      elsif HP_REGEN_IDS.any? {|i| battler.states.include?(i)} &&
          !battler.slip_damage?
        # increase HP by 2%
        battler.hp += damage_hp
      end
      # calculate SP damage
      damage_sp = battler.maxsp / 50
      damage_sp = 1 if damage_sp < 1
      # if SP damaging state
      if SP_POISON_IDS.any? {|i| battler.states.include?(i)}
        # decrease SP by 2%
        battler.sp -= damage_sp
      end
      # if SP regenarating state
      if SP_REGEN_IDS.any? {|i| battler.states.include?(i)}
        # increase SP by 2%
        battler.sp += damage_sp
      end
    else
      # decrease HP by 2%
      dam = battler.maxhp / 50
      dam = 1 if dam < 1
      battler.hp -= dam
      # set attacker and target data
    end
    # request damage sprite
    $BlizzABS.util.request_damage_sprite(@body == nil ? self : @body) if Skills_DoT::DISPLAY_DOT_DAMAGE
    # set last hit by
    if (@battler.hp < old_hp || @battler.sp < old_sp)
      slip_atk_size = @battler.last_slip_attackers.size
       slip_atk_size > 0
      @battler.last_hit_by = @battler.last_slip_attackers[slip_atk_size - 1]
    end
    # restore hpdamage and spdamage
    battler.hpdamage, battler.spdamage = hpdamage, spdamage
  end
  #----------------------------------------------------------------------------
  # slip_damage_effect
  #  Applies slip damage effect.
  # 
  #  This method has been ALIASED and EDITTED by KK20.
  #---------------------------------------------------------------------------- 
  alias babs_slip_damage_effect_original slip_damage_effect
  def slip_damage_effect
    ids = []
    @battler.states.each{|state_id|
      # skip this state if it isn't a slip_damage or configured
      next unless Skills_DoT.dot_states(state_id) != nil
      # Calculate on what frame to apply the DoT
      frame = ($data_states[state_id].hold_turn * 40) / Skills_DoT.dot_states(state_id)[1]
      # Only do DoT damage if correct frame
      next if battler.state_time[state_id] % frame != 0
      # Prepare to calculate damage
      user = @battler.states_caused_by_characters_list[state_id]
      skill = $data_skills[Skills_DoT.dot_states(state_id)[0]]
      # Begin DoT damage calculation...
      unless user.nil?
        # Calculate power
        power = skill.power + user.atk * skill.atk_f / 100
        if power > 0
          power -= @battler.pdef * skill.pdef_f / 200
          power -= @battler.mdef * skill.mdef_f / 200
          power = [power, 1].max
        end
        # Calculate rate
        rate = 20
        rate += (user.str * skill.str_f / 100)
        rate += (user.dex * skill.dex_f / 100)
        rate += (user.agi * skill.agi_f / 100)
        rate += (user.int * skill.int_f / 100)
        # Calculate basic damage
        damage = power * rate / 20
      else
        # Calculate damage if no battler caused this status ailment
        power = skill.power
        if power > 0
          power -= @battler.pdef * skill.pdef_f / 200
          power -= @battler.mdef * skill.mdef_f / 200
          power = [power, 1].max
        end
        damage = power
      end
      # Element correction
      damage *= @battler.elements_correct(skill.element_set)
      damage /= 100
      # Dispersion
      if skill.variance > 0 and damage.abs > 0
        amp = [damage.abs * skill.variance / 100, 1].max
        damage += rand(amp+1) + rand(amp+1) - amp
      end
      # Damage will always do at least 1 HP
      damage = (damage <= 0 ? 1 : damage)
      # Apply the damage
      @battler.hp -= damage
      # request damage sprite
      $BlizzABS.util.request_damage_sprite(@body == nil ? self : @body) if Skills_DoT::DISPLAY_DOT_DAMAGE
    }
    # Call BABS original slip damage method afterwards
    if Graphics.frame_count % 40 == 0
      @battler.states.each{|state_id|
        if $data_states[state_id].slip_damage and Skills_DoT.dot_states(state_id) == nil
          babs_slip_damage_effect_original
          break
        end
      }
    end
  end
end
#=============================================================================
# Game_Battler
#   Aliased:
#     initialize
#     attack_effect
#     skill_effect
#   Rewrite:
#     add_state
#     remove_state
#=============================================================================
class Game_Battler
  #-----------------------
  # Create 'set' and 'get'
  #-----------------------
  attr_accessor :state_giver_attacker
  attr_accessor :states_caused_by_characters_list
  #---------------------------------------------------------------------------
  # The following three methods have been ALIASED and EDITTED by KK20.
  #---------------------------------------------------------------------------
  alias call_orig_init_again initialize
  def initialize
    @state_giver_attacker = nil
    @states_caused_by_characters_list = {}
    call_orig_init_again
  end
 
  alias call_original_attack_effect attack_effect
  def attack_effect(attacker)
    @state_giver_attacker = attacker
    call_original_attack_effect(attacker)
  end
 
  alias call_original_skill_effect skill_effect
  def skill_effect(user, skill)
    @state_giver_attacker = user
    call_original_skill_effect(user, skill)
  end
 
  #--------------------------------------------------------------------------
  # Add State
  #
  # This method has been EDITTED by KK20.
  #--------------------------------------------------------------------------
  def add_state(state_id, force = false)
    # For an ineffective state
    if $data_states[state_id] == nil
      # End Method
      return
    end
    # If not forcefully added
    unless force
      # A state loop already in existance
      for i in @states
        # If a new state is included in the state change (-) of an existing
        # state, and that state is not included in the state change (-) of
        # a new state (example: an attempt to add poison during dead)
        if $data_states[i].minus_state_set.include?(state_id) and
           not $data_states[state_id].minus_state_set.include?(i)
          # End Method
          return
        end
      end
    end
    # If this state is not added
    unless state?(state_id)
      # Add state ID to @states array
      @states.push(state_id)
      # If this state does Skill DoT, find the actor that caused this state
      if Skills_DoT.dot_states(state_id) != nil
        if @state_giver_attacker.nil?
          @states_caused_by_characters_list[state_id] = nil
        else
          @states_caused_by_characters_list[state_id] = @state_giver_attacker.clone
        end
      end
      # If option [regarded as HP 0]is effective
      if $data_states[state_id].zero_hp
        # Change HP to 0
        @hp = 0
      end
      # All state loops
      for i in 1...$data_states.size
        # Dealing with a state change (+)
        if $data_states[state_id].plus_state_set.include?(i)
          add_state(i)
        end
        # Dealing with a state change (-)
        if $data_states[state_id].minus_state_set.include?(i)
          remove_state(i)
        end
      end
      # line change to a large rating order (if value is the same, then a
      # strong restriction order)
      @states.sort! do |a, b|
        state_a = $data_states[a]
        state_b = $data_states[b]
        if state_a.rating > state_b.rating
          -1
        elsif state_a.rating < state_b.rating
          +1
        elsif state_a.restriction > state_b.restriction
          -1
        elsif state_a.restriction < state_b.restriction
          +1
        else
          a <=> b
        end
      end
    end
    # If added forcefully
    if force
      # Set the natural removal's lowest number of turns to -1
      @states_turn[state_id] = -1
    end
    # If not added forcefully
    unless  @states_turn[state_id] == -1
      # Set the natural removal's lowest number of turns
      @states_turn[state_id] = $data_states[state_id].hold_turn
    end
    # If unable to move
    unless movable?
      # Clear action
      @current_action.clear
    end
    # Check the maximum value of HP and SP
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
  #--------------------------------------------------------------------------
  # Remove State
  #
  # This method has been EDITTED by KK20.
  #--------------------------------------------------------------------------
  def remove_state(state_id, force = false)
    # If this state is added
    if state?(state_id)
      # If a forcefully added state is not forcefully removed
      if @states_turn[state_id] == -1 and not force
        # End Method
        return
      end
      # If current HP is at 0 and options are effective [regarded as HP 0]
      if @hp == 0 and $data_states[state_id].zero_hp
        # Determine if there's another state [regarded as HP 0] or not
        zero_hp = false
        for i in @states
          if i != state_id and $data_states[i].zero_hp
            zero_hp = true
          end
        end
        # Change HP to 1 if OK to remove incapacitation.
        if zero_hp == false
          @hp = 1
        end
      end
      # Delete state ID from @states and @states_turn hash array
      @states.delete(state_id)
      @states_turn.delete(state_id)
      # Clear the state-causing-actor value from hash
      @states_caused_by_characters_list.delete(state_id)
    end
    # Check maximum value for HP and SP
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
  #--------------------------------------------------------------------------
  # State Change (+) Application
  #
  # This method has yet been EDITTED by KK20.
  #--------------------------------------------------------------------------
  def states_plus(plus_state_set)
    # Clear effective flag
    effective = false
    # Loop (added state)
    for i in plus_state_set
      # If this state is not guarded
      unless self.state_guard?(i)
        # Set effective flag if this state is not full
        effective |= self.state_full?(i) == false
        # If states offer [no resistance]
        if $data_states[i].nonresistance
          # Set state change flag
          @state_changed = true
          # Add a state
          add_state(i)
        # If this state is not full
        elsif self.state_full?(i) == false
          # Convert state effectiveness to probability,
          # compare to random numbers
          if rand(100) < [0,100,80,60,40,20,0][self.state_ranks[i]]
            # Set state change flag
            @state_changed = true
            # Add a state
            add_state(i)
          end
        end
      end
    end
    # Reset variable
    @state_giver_attacker = nil
    # End Method
    return effective
  end
end


Glad to hear it works for you. :D

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

sasofrass

Thank you so, so very much! This works exactly as intended! :D

<3