Roninator2

Gamer
Veteran
Joined
May 22, 2016
Messages
3,999
Reaction score
1,042
First Language
English
Primarily Uses
RMVXA
Display Damage Value v1.07
by Roninator2​

Introduction
A script I made for my game, but I like to share my work.

Features
- Display potential damage to the enemy for the skill selected
- Accounts for element weakness or defense
- Set text colour

How to Use
Put below ▼ Materials

Images
1620920334147.png1620920360331.png1620929073460.pngskill window hidden

Script
Ruby:
# ╔═════════════════════════════════════╦════════════════════╗
# ║ Title: Display Damage Values        ║  Version: 1.07     ║
# ║ Author: Roninator2                  ║                    ║
# ╠═════════════════════════════════════╬════════════════════╣
# ║ Function:                           ║   Date Created     ║
# ║                                     ╠════════════════════╣
# ║ Show potential damage values        ║    13 May 2021     ║
# ╚═════════════════════════════════════╩════════════════════╝
# ╔══════════════════════════════════════════════════════════╗
# ║ Displays text on battler to show damage range            ║
# ║ for the skill selected.                                  ║
# ╚══════════════════════════════════════════════════════════╝
# ╔═════════════════════════════════════╗
# ║ Terms of use:                       ║
# ║ Free for all uses in RPG Maker      ║
# ╚═════════════════════════════════════╝
# ╔══════════════════════════════════════════════════════════╗
# ║ Updates:                                                 ║
# ║ - When selecting a skill, the window will now hide       ║
# ║ - Corrected damage value checking every frame            ║
# ║ - fixed error when first battler is defeated             ║
# ║ - Added Color Settings                                   ║
# ║ - Fixed formula processing for variable use              ║
# ╚══════════════════════════════════════════════════════════╝
# ╔═════════════════════════════════════╗
# ║ Credits to:                         ║
# ║ Vlue & Tsukihime                    ║
# ╚═════════════════════════════════════╝
$imported = {} if $imported.nil?

module R2_DAM
  #Whether to place the hp bar above or below the enemy
  ABOVE_MONSTER = true
  #The width of the hp bar
  TEXT_WIDTH = 150
  #The height of the hp bar
  TEXT_HEIGHT = 20
  #Offset the hit rate along the x-axis(left,right)
  TEXT_OFFSET_X = -50
  #Offset the hit rate along the y-axis(up,down)
  TEXT_OFFSET_Y = 2

  #The width of the hp bar
  LOC_WIDTH = 100
  #The height of the hp bar
  LOC_HEIGHT = 15

  #Size of the displayed text
  TEXT_SIZE = Font.default_size
  #Font of the displayed text
  TEXT_FONT = Font.default_name

  TEXT_RED = 255
  TEXT_GREEN = 255
  TEXT_BLUE = 255

  TEXT = "damage"
 
  DAMAGE_SWITCH = 2
end

class Sprite_Battler
  alias dam_value_update update
  def update
    dam_value_update
    return unless @battler.is_a?(Game_Enemy)
    if @battler
      update_dam_value
    end
  end
  def update_dam_value
    setup_dam_value if @dam_value.nil?
    if @dam_display.nil?
      @dam_display = Sprite_Base.new(self.viewport)
      @dam_display.bitmap = Bitmap.new(R2_DAM::TEXT_WIDTH,R2_DAM::TEXT_SIZE)
      @dam_display.bitmap.font.color.set(R2_DAM::TEXT_RED, R2_DAM::TEXT_GREEN, R2_DAM::TEXT_BLUE)
      @dam_display.bitmap.font.size = R2_DAM::TEXT_SIZE
      @dam_display.bitmap.font.name = R2_DAM::TEXT_FONT
      @dam_display.x = @dam_value.x + R2_DAM::TEXT_OFFSET_X
      @dam_display.y = @dam_value.y + R2_DAM::TEXT_OFFSET_Y
      @dam_display.z = 110
    end
    determine_dam_visible
    return unless @dam_value.visible
    if @dam_value.opacity != self.opacity
      @dam_value.opacity = self.opacity
    end
    @dam_value.bitmap.clear
    @dam_display.opacity = @dam_value.opacity if @dam_display.opacity != @dam_value.opacity
    @dam_display.bitmap.clear
    text = draw_dam_value(@dam_display.x,@dam_display.y)
    return if text.nil?
    @dam_display.bitmap.draw_text(0,0,R2_DAM::TEXT_WIDTH,@dam_display.height,text)
  end

  def setup_dam_value
    @dam_value = Sprite_Base.new(self.viewport)
    width = R2_DAM::LOC_WIDTH
    height = R2_DAM::LOC_HEIGHT
    @dam_value.bitmap = Bitmap.new(width,height)
    @dam_value.x = self.x + @dam_value.width / 2 + R2_DAM::TEXT_OFFSET_X
    @dam_value.y = self.y + R2_DAM::TEXT_OFFSET_Y - self.bitmap.height - @dam_value.height
    @dam_value.y = self.y + R2_DAM::TEXT_OFFSET_Y unless R2_DAM::ABOVE_MONSTER
    @dam_value.x = 0 if @dam_value.x < 0
    @dam_value.y = 0 if @dam_value.y < 0
    @dam_value.z = 109
  end

  def determine_dam_visible
    if !@battler.alive?
      @dam_value.visible = false
      @dam_display.visible = false
      return if !@battler.alive?
    end
    @dam_value.visible = true
    return unless SceneManager.scene.is_a?(Scene_Battle)
    return unless SceneManager.scene.enemy_window
    @dam_value.visible = SceneManager.scene.target_window_index == @battler.index
    @dam_value.visible = false if !SceneManager.scene.enemy_window.active
    @dam_display.visible = false if !@dam_value.visible
    @dam_display.visible = true if @dam_value.visible
  end

  alias dam_display_dispose dispose
  def dispose
    @dam_value.dispose if @dam_value
    @dam_display.dispose if @dam_display
    dam_display_dispose
  end

  def reveal(battler)
    return if @battler == battler
    @battler = battler
    $game_switches[R2_DAM::DAMAGE_SWITCH] = false
  end

  def draw_dam_value(dx, dy)
    return unless SceneManager.scene_is?(Scene_Battle)
    return unless SceneManager.scene.enemy_window
    reveal(SceneManager.scene.enemy_window.enemy)
    enemy = $game_troop.members[SceneManager.scene.enemy_window.enemy.index]
    user = $game_actors[BattleManager.actor.id]
    item = $data_skills[BattleManager.actor.input.item.id]
    @dam_data = [] if $game_switches[R2_DAM::DAMAGE_SWITCH] == false
    @dam_data = find_dam_value(enemy, user, item) if $game_switches[R2_DAM::DAMAGE_SWITCH] == false
    text = "#{@dam_data[0]} to #{@dam_data[1]} #{R2_DAM::TEXT}"
    $game_switches[R2_DAM::DAMAGE_SWITCH] = true
    return text
  end

  def actor; return BattleManager.actor; end
 
  def enemy; return SceneManager.scene.enemy_window.enemy; end

  def find_dam_value(enemy, user, item)
    damage = actor.find_damage_value(enemy, user, item)
    amp = [damage.abs * item.damage.variance / 100, 0].max.to_i
    low = damage * ((100.00 - item.damage.variance) / 100.00)
    low = low - amp
    low = low.to_i
    high = damage * ((100.00 + item.damage.variance) / 100.00)
    high = high + amp
    high = high.to_i
    return [low, high]
  end

end

class Game_Battler < Game_BattlerBase
  def find_damage_value(enemy, user, item)
    ovars = Marshal.load(Marshal.dump($game_variables))
    oswitchs = $game_switches.clone
    value = item.damage.eval(user, enemy, $game_variables)
    value *= item_element_rate(user, item)
    $game_variables = ovars
    $game_switches = oswitchs
    enemy_element = $data_enemies[enemy.enemy_id]
    item_element = item.damage.element_id
    enemy_element.features.each do |elem|
      if elem.data_id == item_element
        value *= elem.value
        value = value.to_i
      end
    end
    value *= pdr if item.physical?
    value *= mdr if item.magical?
    value *= rec if item.damage.recover?
    return value
  end
end
class Window_BattleEnemy < Window_Selectable
  def process_cursor_move
    super
    $game_switches[R2_DAM::DAMAGE_SWITCH] = false
  end
end
class Scene_Battle
  attr_reader  :enemy_window
  def target_window_index
    begin
    @enemy_window.enemy.index
    rescue
      return -1
    end
  end
  if !$imported["YEA-BattleEngine"]
    def on_skill_ok
      @skill = @skill_window.item
      BattleManager.actor.input.set_skill(@skill.id)
      BattleManager.actor.last_skill.object = @skill
      if !@skill.need_selection?
        @skill_window.hide
        next_command
      elsif @skill.for_opponent?
        @skill_window.hide
        select_enemy_selection
      else
        select_actor_selection
      end
      $game_switches[R2_DAM::DAMAGE_SWITCH] = false
    end
    def on_skill_cancel
      @skill_window.hide
      @actor_command_window.activate
      $game_switches[R2_DAM::DAMAGE_SWITCH] = false
    end
    def on_enemy_cancel
      @enemy_window.hide
      case @actor_command_window.current_symbol
      when :attack
        @actor_command_window.activate
      when :skill
        @skill_window.show
        @skill_window.activate
      when :item
        @item_window.activate
      end
      $game_switches[R2_DAM::DAMAGE_SWITCH] = false
    end
  end
end
Notes
If you want the skill window to be hidden, you'll have to find a script or code snippet for that.
This was bugging me so I added it in. Skill window hides when selecting the enemy.

If the text does not show up for you, adjust the numbers for width/height and location .
I thought it wasn't working in my game until I changed the numbers.
I had to change the TEXT_OFFSET_Y from 2 to 100

Update
- Added support for Yanfly Battle Engine due to conflicts

Credit and Thanks
- Roninator2
- Vlue - for replicating some code
- Tsukihime - for replicating some code

Terms of use
Free for all RPG Maker VX Ace uses
 
Last edited:

Wyrelade

Wyrelade - The one and only.
Veteran
Joined
Apr 11, 2014
Messages
72
Reaction score
26
First Language
Finnish
Primarily Uses
RMVXA
That is very neat. Actually have not seen a tooltip type damage show before. First time for me.

good job!
 

Roninator2

Gamer
Veteran
Joined
May 22, 2016
Messages
3,999
Reaction score
1,042
First Language
English
Primarily Uses
RMVXA
good job!
Thanks. I actually modified it a bit more to be turned on or off with a switch. Then using CT BOLT's state switch script, I set it so that when the actor uses a skill to apply a state (2-5 turns), the switch is turned on and then the player can see the damage.
But I did that for my game.
 

Sixth

Veteran
Veteran
Joined
Jul 4, 2014
Messages
2,201
Reaction score
858
First Language
Hungarian
Primarily Uses
RMVXA
Do note that due to how you get the damage value here, everything in the damage formula gets executed more than once, even before the skill/item is actually used. This means that it can mess up some things depending on what you use in your damage formulas (a variable/switch change is probably the most common things people use here for some special cases).

This issue is present in all of these damage prediction scripts, since all of them do the same thing (use the damage formula without accounting for these special cases). At least the variable/switch cases can be fixed easily by saving the old values before the damage calculation part and re-load it after.
 

Sixth

Veteran
Veteran
Joined
Jul 4, 2014
Messages
2,201
Reaction score
858
First Language
Hungarian
Primarily Uses
RMVXA
Ohh, I didn't even notice that part. :D

I meant this line:
Code:
value = item.damage.eval(user, enemy, $game_variables)
This will execute whatever is used in the damage formula.
For example:
Code:
dmg = v[15] % 3 == 0 ? a.atk * 10 : -a.atk; $game_variables[15] += 1; dmg
This will make the skill do 10 * ATK damage if variable 15 is divisible by 3, otherwise it heals the target.
Variable 15 is increased by 1 every time this skill is used.
That's how it should work.
I'm kinda rusty with the damage formula things, so there may be some errors in the example, but I hope you get the idea behind it.

But because you execute the damage formula to calculate the possible damage, variable 15 will be increased for every single calculation without actually using the skill, effectively breaking the skill.
This is just one example, but I imagine a lot of people who actually put some effort to come up with some more unique skills will have at least some similar cases.

To fix this, you can save the switch and variable arrays before the damage calculation, and re-load it when you are done with it. Something like:
Code:
ovars = Marshal.load(Marshal.dump($game_variables))
oswitchs = $game_switches.clone
# Insert damage calculation here
$game_variables = ovars
$game_switches = oswitchs
I used marshal for the variables because people could use other things there, like strings and even other arrays/hashes, so simply cloning it may not be enough.

Other than these cases, your script should work fine. It's only an issue when something like the example I gave is used in the damage formulas.
 

nekuzx

Villager
Member
Joined
Oct 29, 2021
Messages
15
Reaction score
10
First Language
Spanish
Primarily Uses
RMVXA
After some testing I discovered a strange bug.

If a player Actor uses a skill with a specific element; Against an enemy with an attack element of the same type, the damage preview turns into all 0. However when you attack the damage calculation is done as normal.

So for example. If Actor has a skill called "Ice slash" which has a forced "Ice" element, and they fight against some ice elemental with an attack element of "Ice", which causes any attacks with the element "Normal Attack" to have "Ice" element instead. Using the "Ice slash" against that enemy will display a preview of 0 to 0 damage, even if attacking does actually deal damage above 0.

This bug does not happen if the actor uses a skill with the "Normal attack" enemy, and then uses equipment to change its attack element to "Ice", or whatever attack element the enemy also has.

I am not knowledgeable enough with Ruby to figure out exactly what's causing this. But I at least managed to stumble across a consistent set of instructions to replicate the bug, which I hope helps you, if you decide to try to fix it.

Thanks and good evening.
 

Roninator2

Gamer
Veteran
Joined
May 22, 2016
Messages
3,999
Reaction score
1,042
First Language
English
Primarily Uses
RMVXA
So for example. If Actor has a skill called "Ice slash" which has a forced "Ice" element, and they fight against some ice elemental with an attack element of "Ice", which causes any attacks with the element "Normal Attack" to have "Ice" element instead. Using the "Ice slash" against that enemy will display a preview of 0 to 0 damage, even if attacking does actually deal damage above 0.
I cannot replicate this. I get damage values consistent with the skill formula and element resistances
Can you provide a demo or screen shot the enemy, skill and anything else you did to show this?
Thanks
 

nekuzx

Villager
Member
Joined
Oct 29, 2021
Messages
15
Reaction score
10
First Language
Spanish
Primarily Uses
RMVXA
I cannot replicate this. I get damage values consistent with the skill formula and element resistances
Can you provide a demo or screen shot the enemy, skill and anything else you did to show this?
Thanks
Strange. But I was also pondering the posibility that it's caused by a different script. I'll have to test some more to land with a culprit.
My apologies for taking your time. I'll report back if I discover something.
 

Latest Threads

Latest Profile Posts

Historically, "honor" isn't what has won fights. Being as brutally dishonorable and malicious as possible has done that. This is a tactic that works for any fight. Honor doesn't matter when you're the loser.
Mcniner wrote on Umbriel's profile.
Hello! It seems the Zelda sprites you sent me were removed by a moderator. Could you gmail them to me here: steinjaltman@gmail.com? Thanks!
Remember to do your 0,01% progress on your game today!
Went to see Jujutsu Kaisen 0 yesterday, it was cool. The movie wasnt really a masterpiece, it had some pacing and characterization problems, but overall I enjoyed it, maybe because it was the first anime film I have ever been to in the cinema lol. The battle animation & music were top-notch. I havent seen much of the anime so people who watched the entire season would probably like it more.

Forum statistics

Threads
121,996
Messages
1,145,772
Members
160,264
Latest member
diexue
Top