Code:
# * KoolDownBreak XP Turns Edition
# Scripter : Kyonides Arkanthes
# 2019-12-10
# This scriptlet allows the game developers to set a list of skill cooldowns
# that might appear suddenly as a result of casting such spells.
# Monsters can use a special Cooldown Skill that you can customize a little bit.
# Heroes can now get their skills frozen for a couple of rounds, but a special
# item or skill or even a Cooldown Breaker Button Combo might help them get them
# back the next turn.
# Skill Hit Rates DO MATTER here!
# Both Monsters and Heroes have a cd_breaker_hit_rate modifier method!
# * Script Call Examples * # They are Optional
# $game_troop.enemies[Index].cd_breaker_hit_rate = 5
# $game_party.actors[Index].cd_breaker_hit_rate = 10
# += operator increases the rate, -= is its opposite.
# Check FILENAME constant to get the filename that you will use in order to make
# a new TXT file. Then save the cooldowns and cooldown breakers data there.
module KoolDown
CD_ROUNDS_MAX = 4 # Maximum Number of Extra Skill CD Spell Rounds
CD_SKILL_ID = 81 # Monster's CD Skill
BREAKER_SKILL_ID = 82 # Skill CD Remover
BREAKER_ITEM_ID = 33 # Item CD Remover
EXCEPTIONS = [nil, "Miss"] # They won't trigger a cooldown
FILENAME = 'cooldowns.txt'
# * End of Configuration Section * #
SKIP_CHARS = ["\n", "#"]
class Data
attr_accessor :turns, :repeats, :breaker
end
class Breaker
attr_accessor :buttons, :repeats
end
@cooldowns = {}
@breakers = {}
class << self
attr_reader :cooldowns, :breakers, :names, :values
def include?(sid, dmg) @cooldowns[id] and !EXCEPTIONS.include?(dmg) end
def start_parsing
if $DEBUG
File.readlines(FILENAME).each{|line| parse_cooldowns(line) }
save_data(@cooldowns, "Data/KoolDownCD.rxdata")
save_data(@breakers, "Data/KoolDownCDB.rxdata")
else
@cooldowns = load_data("Data/KoolDownCD.rxdata")
@breakers = load_data("Data/KoolDownCDB.rxdata")
end
end
def parse_cooldowns(line)
return if SKIP_CHARS.include?(line[0])
if line[0..2] =~ /sid/i
id, turns, repeats = line.scan(/\d+/).map{|d| d.to_i }
data = Data.new
data.turns = turns || 1
data.repeats = repeats || 1
@cooldowns[id] = data
return
elsif line[0..2] =~ /aid/i
id = line.scan(/\d+/)[0].to_i
buttons = line.sub(/aid/i, '').upcase.split(' ')
unless Input.constants.include?(buttons[0])
buttons.map!{|b| Input.const_get(b.to_sym) } rescue nil
else
buttons.map!{|b| Input.const_get(b) } rescue nil
end
data = Breaker.new
data.buttons = buttons
@breakers[id] = data
end
end
end
start_parsing
end
class Game_Battler
alias :kyon_kdb_gm_battler_init :initialize
alias :kyon_kdb_gm_battler_scu? :skill_can_use?
alias :kyon_kdb_gm_battler_se :skill_effect
alias :kyon_kdb_gm_battler_ie :item_effect
def initialize
kyon_kdb_gm_battler_init
@cooldowns = {}
@cd_breaker_hit_rate = 0
end
def skill_can_use?(skill_id)
return false if @cooldown[skill_id]
kyon_kdb_gm_battler_scu?(skill_id)
end
def skill_effect(user, skid)
return trigger_skill_cooldown(user, skid) if KoolDown::CD_SKILL_ID == skid
return cd_breaker_skill(user, skid) if KoolDown::BREAKER_SKILL_ID == skid
result = kyon_kdb_gm_battler_se
user.skill_cd(skid) if KoolDown.include?(skid, @damage)
result
end
def trigger_skill_cooldown(user, skill_id)
hit = [$data_skills[skill_id].hit + user.cd_breaker_hit_rate, 100].min
return false if @skills.empty? or rand(100) >= hit
pos = rand(@skills.size)
@cooldowns[@skills[pos]] = rand(KoolDown::CD_ROUNDS_MAX) + 1
true
end
def cd_breaker_skill(user, skill_id)
hit = [$data_skills[skill_id].hit + user.cd_breaker_hit_rate, 100].min
return false if rand(100) >= hit
@cooldowns.clear
true
end
def item_effect(item)
if KoolDown::BREAKER_ITEM_ID == item.id
return false if @cooldowns.empty?
if rand(100) < item.hit
keys = @cooldowns.keys
pos = rand(keys.size)
@cooldowns[keys[pos]] = 0
return true
end
return false
end
kyon_kdb_gm_battler_ie(item)
end
def skill_cd(sid) @cooldowns[sid] = KoolDown.cooldowns[sid].turns end
def remove_skill_cd(sid) @cooldowns[sid] = 0 end
def update_cooldowns() @cooldowns.keys.each{|k| @cooldowns[k] -= 1 } end
def check_cooldown_turns() @cooldowns.delete_if{|k,v| v < 1 } end
attr_accessor :cd_breaker_hit_rate
end
class Game_Actor
alias :kyon_kdb_gm_actor_init :initialize
def initialize
kyon_kdb_gm_actor_init
@cd_breakers = KoolDown.breakers[@actor_id].dup
clear_cd_breakers
end
def test_cd_breakers
@cd_breakers.buttons.each{|b| return false unless Input.press?(b) }
@cd_breakers.repeats += 1
cd = @cooldowns
cd.each{|k,v| cd[k] -= 2 if cd[k].repeats == @cd_breakers.repeats }
end
def clear_cooldowns
clear_cd_breakers
@cooldowns.clear
end
def clear_cd_breakers() @cd_breakers.repeats = 0 end
attr_accessor :cd_breakers
end
class Game_Enemy
def clear_cooldowns() @cooldowns.clear end
end
class Game_Party
def clear_cd_breakers() @actors.each{|a| a.clear_cd_breakers } end
def test_cd_breakers() @actors.each{|a| a.test_cd_breakers } end
end
class Scene_Battle
#alias :kyon_kdb_scn_battle_up :update
alias :kyon_kdb_scn_battle_ups1 :update_phase4_step1
alias :kyon_kdb_scn_battle_msar :make_skill_action_result
alias :kyon_kdb_scn_battle_end :battle_end
def update_phase4_step1
$game_party.clear_cd_breakers
kyon_kdb_scn_battle_ups1
$game_party.test_cd_breakers
@action_battlers.each{|ab| ab.update_cooldowns }
end
def make_skill_action_result
kyon_kdb_scn_battle_msar
@action_battlers.each{|ab| ab.check_cooldown_turns }
end
def battle_end(result)
$game_party.actors.each{|a| a.clear_cooldowns }
kyon_kdb_scn_battle_end(result)
end
end