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!
Just edit the DIRECT_DMG_SPLIT_SKILL_IDS Constant accordingly.
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.
You are not allowed to republish this script anywhere else.
Mention me in your game credits.
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.
Version 1.0.2 has permanently dealt with such a pest once for all!
|