Save-Point
KSplitDamage XP - Printable Version

+- Save-Point (https://www.save-point.org)
+-- Forum: Material Development (https://www.save-point.org/forum-8.html)
+--- Forum: Scripts Database (https://www.save-point.org/forum-39.html)
+---- Forum: RPGMaker XP (RGSS) Engine (https://www.save-point.org/forum-116.html)
+---- Thread: KSplitDamage XP (/thread-8460.html)



KSplitDamage XP - kyonides - 01-28-2022

KSplitDamage XP
version 1.0.2

by Kyonides Arkanthes


Introduction

This very short script allows you to create 2 New Passive skills.
  • HP Damage Splitter
  • SP Cost Splitter

And a bunch of Direct Damage Split Skills! Shocked

Just edit the DIRECT_DMG_SPLIT_SKILL_IDS Constant accordingly. Winking

Both set a very specific state on a given actor or enemy that will provide them with one of those new abilities.


The Script

Code:
# * KSplitDamage XP
#   Scripter : Kyonides Arkanthes
#   v1.0.2 - 2022-01-31

# This scriptlet allows you to setup 2 New Passive Skills:
# - HP Damage Splitter skill
# - SP Cost Splitter skill
# And some Direct Damage Split Skills!

# As it is implied, those skills set a specific status on a given actor or
# monster who can split either the damage or the mana cost among his pals.

# ** It might be incompatible with any Custom Battle System CBS. ** #

# * Overwritten Methods * #
# - Game_Battler Class -
# attack_effect skill_effect
# - Scene_Battle Class -
# make_skill_action_result

# * New Methods for Default Classes * #
# - Game_Battler -
# actor? enemy?
# - Game_Actor & Game_Enemy Classes -
# team
# - Game_Party & Game_Troop Classes -
# living_members size

module KSplitDamage
  SHOW_FAILED_ATTACK_MSG = true
  FAILED_ATTACK_MSG = "Miss"
  DIRECT_DMG_SPLIT_SKILL_IDS = [2]
  LIFE_STATE_ID  = 2
  MANA_STATE_ID  = 3
  LIFE_SKILL_IDS = [1]
  MANA_SKILL_IDS = [1]
  extend self
  def failed_message
    SHOW_FAILED_ATTACK_MSG ? FAILED_ATTACK_MSG : ""
  end

  def direct_dmg_split_skill?(skill_id)
    DIRECT_DMG_SPLIT_SKILL_IDS.include?(skill_id)
  end

  def life_exclude_skill?(skill_id)
    LIFE_EXCLUDE_SKILL_IDS.include?(skill_id)
  end

  def mana_exclude_skill?(skill_id)
    MANA_EXCLUDE_SKILL_IDS.include?(skill_id)
  end
  def clear() @total_targets = nil end
  attr_accessor :total_targets
end

class Game_Battler
  def calculate_atk_hit(attacker)
    atk = [attacker.atk - self.pdef / 2, 0].max
    @damage = atk * (20 + attacker.str) / 20
    @damage *= elements_correct(attacker.element_set)
    @damage /= 100
    if @damage > 0
      if rand(100) < 4 * attacker.dex / self.agi
        @damage *= 2
        @critical = true
      end
      @damage /= 2 if guarding?
    end
    if @damage.abs > 0
      amp = [@damage.abs * 15 / 100, 1].max
      @damage += rand(amp+1) + rand(amp+1) - amp
    end
    eva = 8 * self.agi / attacker.dex + self.eva
    hit = @damage < 0 ? 100 : 100 - eva
    hit = cant_evade? ? 100 : hit
    rand(100) < hit
  end

  def split_damage_direct?(skill_scope, skill_id)
    skill_scope == 2 and KSplitDamage.direct_dmg_split_skill?(skill_id)
  end

  def split_damage_with_state?(skill_id)
    state?(KSplitDamage::LIFE_STATE_ID) and
       !KSplitDamage.life_exclude_skill?(skill_id)
  end

  def calculate_hp_damage(skill_scope, skill_id)
    if split_damage_with_state?(skill_id)
      group = self.team.living_members
      @damage /= group.size
      group.each{|mate| mate.hp -= @damage }
      return
    elsif split_damage_direct?(skill_scope, skill_id)
      @damage /= KSplitDamage.total_targets
    end
    self.hp -= @damage
  end

  def refresh_states(attacker)
    @state_changed = false
    states_plus(attacker.plus_state_set)
    states_minus(attacker.minus_state_set)
  end

  def attack_effect(attacker)
    @critical = false
    hit_result = (rand(100) < attacker.hit)
    hit_result = calculate_atk_hit(attacker) if hit_result
    if hit_result
      remove_states_shock
      calculate_hp_damage(0, 0)
      refresh_states(attacker)
    else
      @damage = KSplitDamage.failed_message
      @critical = false
    end
    return true
  end

  def skill_hit1(user, skill)
    power = skill.power + user.atk * skill.atk_f / 100
    if power > 0
      power -= self.pdef * skill.pdef_f / 200
      power -= self.mdef * skill.mdef_f / 200
      power = [power, 0].max
    end
    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)
    @damage = power * rate / 20
    @damage *= elements_correct(skill.element_set)
    @damage /= 100
    @damage /= 2 if @damage > 0 and guarding?
    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
  end

  def hit_after_skill_evasion(user, skill)
    eva = 8 * self.agi / user.dex + self.eva
    hit = @damage < 0 ? 100 : 100 - eva * skill.eva_f / 100
    cant_evade? ? 100 : hit
  end

  def skill_hit2(skill, effective)
    if skill.power != 0 and skill.atk_f > 0
      remove_states_shock
      effective = true
    end
    last_hp = self.hp
    calculate_hp_damage(skill.scope, skill.id)
    effective |= self.hp != last_hp
    @state_changed = false
    effective |= states_plus(skill.plus_state_set)
    effective |= states_minus(skill.minus_state_set)
    if skill.power == 0
      @damage = @state_changed ? "" : "Miss"
    end
    effective
  end

  def skill_effect(user, skill)
    @critical = false
    if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or
       ((skill.scope == 5 or skill.scope == 6) and self.hp >= 1)
      return false
    end
    effective = false
    effective |= skill.common_event_id > 0
    hit = skill.hit
    hit *= user.hit / 100 if skill.atk_f > 0
    hit_result = (rand(100) < hit)
    effective |= hit < 100
    if hit_result
      skill_hit1(user, skill)
      hit = hit_after_skill_evasion(user, skill)
      hit_result = (rand(100) < hit)
      effective |= hit < 100
    end
    if hit_result
      effective = skill_hit2(skill, effective)
    else
      @damage = "Miss"
    end
    @damage = nil unless $game_temp.in_battle
    effective
  end
  def actor?() @actor_id != nil end
  def enemy?() @enemy_id != nil end
end

class Game_Actor
  def team() $game_party end
end

class Game_Enemy
  def team() $game_troop end
end

class Game_Party
  def living_members() @actors.select{|a| a.exist? } end
  def size() @actors.size end
end

class Game_Troop
  def living_members() @enemies.select{|e| e.exist? } end
  def size() @enemies.size end
end

class Scene_Battle
  def consume_mana
    if @active_battler.state?(KSplitDamage::MANA_STATE_ID) and
       !KSplitDamage.mana_exclude_skill?(@skill.id)
      team = @active_battler.living_members
      mana = @skill.sp_cost / team.size
      team.each{|mate| mate.sp -= mana }
    else
      @active_battler.sp -= @skill.sp_cost
    end
  end

  def make_skill_action_result
    skill_id = @active_battler.current_action.skill_id
    @skill = $data_skills[skill_id]
    unless @active_battler.current_action.forcing
      unless @active_battler.skill_can_use?(skill_id)
        $game_temp.forcing_battler = nil
        @phase4_step = 1
        return
      end
    end
    consume_mana
    @status_window.refresh
    @help_window.set_text(@skill.name, 1)
    @animation1_id = @skill.animation1_id
    @animation2_id = @skill.animation2_id
    @common_event_id = @skill.common_event_id
    set_target_battlers(@skill.scope)
    KSplitDamage.total_targets = @target_battlers.size
    @target_battlers.each do |target|
      target.skill_effect(@active_battler, @skill)
    end
    KSplitDamage.clear
  end
end


FAQ

Q: Have you overwritten any battle related methods in your script?

A: Yes, I have. Since RMXP code isn't really modular at all, I was in need of altering default classes like Game_Battler and Scene_Battle.

Q: Is it incompatible with any Custom Battle Systems?

A: You bet! Due to the changes I had made there, I seriously doubt it might work with any other Battle System at all.


Terms & Conditions

It is free as in Beer beer.
You are not allowed to republish this script anywhere else. Serious 
Mention me in your game credits. Winking


RE: KSplitDamage XP - kyonides - 01-30-2022

Script Update

After analyzing the situation, I discovered that a direct split damage skill would actually duplicate the damage whenever the skill could not kill the enemies the very first time. The next round would take you by surprise because some dead enemies looked quite alive even if their HP had been reduced to 0.

Version 1.0.1 fixes this issue for sure.



RE: KSplitDamage XP - kyonides - 02-01-2022

New Bug Fix

Even if the previous version of my scriptlet had smashed a bug, there was a dire need to fix another one.

As a summary, the script did split the direct skill damage among living members by applying the lost HP to all of them only once, just as expected. Nonetheless, it also ignore those team mates that had recently been killed by the skill. Thus the damage kept increasing after each iteration till it had reached 100% damage. This was not the desired behavior and had to be killed by spraying a strong insecticide on it. Laughing

Version 1.0.2 has permanently dealt with such a pest once for all! Grinning