#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Custom Stat Growing System (CSGS) by Blizzard
# Version: 1.71b
# Type: Actor Attribute Modifier
# Date: 20.5.2006
# Date v1.1: 24.5.2006
# Date v1.3b: 26.5.2006
# Date v1.31b: 27.6.2006
# Date v1.4b: 23.2.2007
# Date v1.5b: 22.8.2007
# Date v1.6b: 12.9.2007
# Date v1.7b: 25.9.2007
# Date v1.71b: 7.6.2008
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#   
#  This work is protected by the following license:
# #----------------------------------------------------------------------------
# #  
# #  Creative Commons - Attribution-NonCommercial-ShareAlike 3.0 Unported
# #  ( http://creativecommons.org/licenses/by-nc-sa/3.0/ )
# #  
# #  You are free:
# #  
# #  to Share - to copy, distribute and transmit the work
# #  to Remix - to adapt the work
# #  
# #  Under the following conditions:
# #  
# #  Attribution. You must attribute the work in the manner specified by the
# #  author or licensor (but not in any way that suggests that they endorse you
# #  or your use of the work).
# #  
# #  Noncommercial. You may not use this work for commercial purposes.
# #  
# #  Share alike. If you alter, transform, or build upon this work, you may
# #  distribute the resulting work only under the same or similar license to
# #  this one.
# #  
# #  - For any reuse or distribution, you must make clear to others the license
# #    terms of this work. The best way to do this is with a link to this web
# #    page.
# #  
# #  - Any of the above conditions can be waived if you get permission from the
# #    copyright holder.
# #  
# #  - Nothing in this license impairs or restricts the author's moral rights.
# #  
# #----------------------------------------------------------------------------
# 
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# 
# Special Thanks to:
# 
#   Viviatus - for requesting this script =D
# 
# 
# IMPORTANT NOTE:
# 
#   This script will disable the feature of leveling up. Please be sure to use
#   a Custom Skill Learning System or have an appropriate script.
# 
# 
# Compatibilty:
# 
#   95% compatible with SDK v1.x. 60% compatible with SDK 2.x. WILL corrupt
#   your old savegames. Might cause problems with exotic CBS-es.
# 
# 
# new in v1.1:
#   - fixed bug, where dead actors gained stats.
# 
# new in v1.3b:
#   - added additional "Stat, that were raised" window.
# 
# new in v1.31b:
#   - fixed a bug
# 
# new in v1.4b:
#   - better coding, easier to configurate
#   - now compatible with Tons of Add-ons
# 
# new in v1.5b:
#   - improved coding
#   - rewritten conditions using classic syntax to avoid RGSS conditioning bug
# 
# new in v1.6b:
#   - improved coding
#   - now compatible with Blizz-ABS
# 
# new in v1.7b:
#   - removed statup window display, if you want to continue using it, get
#     Easy LvlUp Notifier 2.0 or higher and put the script BELOW this one
# 
# new in v1.71b:
#   - removed a rash bug when using Blizz-ABS
# 
# 
# Description:
# 
#   This script disables the ability to gain levels, altough EXP are still
#   being received and can be used for another purpose. It also will allow to
#   raise the character stats by other meanings than level ups.
# 
# Explanation:
# 
#   -> max HP will be raised if the character loses an ammount of HP that is
#      equal to a specific (and configurable) percentage of the max HP
#   -> max SP will be raised if the character uses an ammount of SP that is
#      equal to a specific (and configurable) percentage of the max SP
#   -> it is also possible to set up the success chance of raising max HP
#      and/or SP
#   -> STR will be raised if the character attacks often
#   -> DEX will be raised if the character lands a critical hit or evade a
#      status change
#   -> INT will be raised if the character uses magic based skills, but not if
#      skills are only STR, DEX and/or AGI based
#   -> AGI will be raised if the character manages to evade a physical attack
#      or is the very first character to act during a round
# 
# 
# Notes:
# 
#   This script has a preconfiguration, but it is highly recommended to
#   configure it to your suits. If you are using Blizz-ABS, the stats will
#   be tested and maybe increased each time they are stimulated. Note that only
#   a stat that was stimulated has a chance to be increased in this moment. RBB
#   does not work for Blizz-ABS.
# 
# 
# If you find any bugs, please report them here:
# http://www.chaosproject.co.nr
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

MISS_DAMAGE = 'Miss' # which text is displayed when you miss the target
HP_CHANCE = 50 # % chance of HP raising if 50% of max HP value were lost
SP_CHANCE = 50 # % chance of SP raising if 50% of max SP value were used
HP_RATE = 100 # how many additional HP
SP_RATE = 100 # how many additional SP
HP_LOST = 50 # how many % of max HP must be lost, so max HP will increase
SP_USED = 50 # how many % of max SP must be used, so max SP will increase
STR_CHANCE = 100 # % chance of STR raising
DEX_CHANCE = 70 # % chance of DEX raising
INT_CHANCE = 70 # % chance of INT raising
AGI_CHANCE = 70 # % chance of AGI raising
STRRATE = 7 # how many additional STR points
DEXRATE = 7 # how many additional DEX points
INTRATE = 7 # how many additional INT points
AGIRATE = 7 # how many additional AGI points
STRRATE_MIN = 10 # min xstr needed to raise STR
DEXRATE_MIN = 10 # min xstr needed to raise DEX
INTRATE_MIN = 10 # min xstr needed to raise INT
AGIRATE_MIN = 10 # min xstr needed to raise AGI

# In the part below you can activate or deactivate the RBB - "Reset Before
# Battle" feature, that will reset the "counters", that are counting how many
# times a stat was stimulated. Only activate this if you want that counters ARE
# RESETED TO ZERO before every fight. This will have the effect that not MANY
# battles will raise the stats, but LONG battles.
RBB = false

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

#==============================================================================
# Game_Temp
#==============================================================================

class Game_Temp
  
  attr_accessor :all_data
  
end

#==============================================================================
# Game_Actor
#==============================================================================

class Game_Actor < Game_Battler

  attr_accessor :dmghp
  attr_accessor :usesp
  attr_accessor :xstr
  attr_accessor :xdex
  attr_accessor :xint
  attr_accessor :xagi
  
  alias setup_csgs_later setup
  def setup(actor_id)
    setup_csgs_later(actor_id)
    @dmghp = @usesp = @xstr = @xdex = @xint = @xagi = 0
  end
  
  def exp=(exp) # disabling level up
    @exp = [[exp, 9999999].min, 0].max
    @hp, sp = [@hp, self.maxhp].min, [@sp, self.maxsp].min
  end
 
end

#==============================================================================
# Game_Battler
#==============================================================================

class Game_Battler

  alias attack_effect_csgs_later attack_effect
  def attack_effect(attacker)
    last_hp = self.hp
    result = attack_effect_csgs_later(attacker)
    if self.is_a?(Game_Actor)
      self.dmghp += last_hp - self.hp if last_hp > self.hp
      self.xagi += 1 if self.damage == MISS_DAMAGE
    end
    if attacker.is_a?(Game_Actor)
      attacker.xstr += 1 if last_hp > self.hp
      attacker.xdex += 1 if self.critical
    end
    return result
  end
  
  alias skill_effect_csgs_later skill_effect
  def skill_effect(user, skill)
    last_hp = self.hp
    result = skill_effect_csgs_later(user, skill)
    if self.is_a?(Game_Actor)
      self.dmghp += last_hp - self.hp if last_hp > self.hp
      self.xdex += 1 unless @state_changed
    end
    if user.is_a?(Game_Actor)
      user.usesp += skill.sp_cost
      user.xint += 1 if skill.int_f != 0
    end
    return result
  end
  
  alias slip_damage_effect_csgs_later slip_damage_effect
  def slip_damage_effect
    last_hp = self.hp
    result = slip_damage_effect_csgs_later
    if self.is_a?(Game_Actor) && last_hp > self.hp
      self.dmghp += last_hp - self.hp
    end
    return result
  end

end

#==============================================================================
# Window_BattleStatus
#==============================================================================

class Window_BattleStatus < Window_Base
  
  alias refresh_csgs_later refresh
  def refresh
    refresh_csgs_later
    $game_party.actors.each_index {|i|
        if $tons_version != nil && $tons_version >= 3.71 &&
            $game_system.CENTER_BATTLER
          actor_x = case $game_party.actors.size
          when 1 then 4 + 240
          when 2 then 4 + 80 + i * 320
          when 3 then 4 + 80 + i * 160
          when 4 then 4 + i * 160
          end
        else
          actor_x = i * 160
        end
        if @level_up_flags[i] && !$game_party.actors[i].dead?
          self.contents.fill_rect(actor_x, 96, 120, 32, Color.new(0, 0, 0, 0))
          self.contents.font.color = normal_color
          self.contents.draw_text(actor_x, 96, 120, 32, 'STATS UP!')
        end}
  end
  
end

#==============================================================================
# Scene_Battle
#==============================================================================

class Scene_Battle
  
  alias main_csgs_later main
  def main
    $game_party.actors.each {|actor|
        actor.dmghp = actor.usesp = 0
        actor.xstr = actor.xdex = actor.xint = actor.xagi = 0 if RBB}
    main_csgs_later
    @statsup_windows.each {|win| win.dispose} if @statsup_windows != nil
  end
  
  alias start_phase5_csgs_later start_phase5
  def start_phase5
    start_phase5_csgs_later
    $game_party.actors.each_index {|i|
        actor = $game_party.actors[i]
        unless actor.dead?
          if actor.dmghp >= actor.maxhp * HP_LOST / 100 && rand(100) < HP_CHANCE
            actor.maxhp += HP_RATE
            @status_window.level_up(i)
          end
          if actor.usesp >= actor.maxsp * SP_USED / 100 && rand(100) < SP_CHANCE
            actor.maxsp += SP_RATE
            @status_window.level_up(i)
          end
          if actor.xstr >= STRRATE_MIN && rand(100) < STR_CHANCE
            actor.str += STRRATE
            actor.xstr = 0
            @status_window.level_up(i)
          end
          if actor.xdex >= DEXRATE_MIN && rand(100) < DEX_CHANCE
            actor.dex += DEXRATE
            actor.xdex = 0
            @status_window.level_up(i)
          end
          if actor.xagi >= AGIRATE_MIN && rand(100) < AGI_CHANCE
            actor.agi += AGIRATE
            actor.xagi = 0
            @status_window.level_up(i)
          end
          if actor.xint >= INTRATE_MIN && rand(100) < INT_CHANCE
            actor.int += INTRATE
            actor.xint = 0
            @status_window.level_up(i)
          end
        end}
  end
  
  alias make_action_orders_csgs_later make_action_orders
  def make_action_orders
    make_action_orders_csgs_later
    @action_battlers[0].xagi += 1 if @action_battlers[0].is_a?(Game_Actor)
  end
  
end

#==============================================================================
# Scene_Map
#==============================================================================

class Scene_Map
  
  alias main_csgs_later main
  def main
    if $BlizzABS
      $game_temp.all_data = {} if $game_temp.all_data == nil
      (1...$data_actors.size).each {|i| reset_testers($game_actors[i])}
    end
    main_csgs_later
  end
  
  alias upd_csgs_later update
  def update
    test_on_stats if $BlizzABS
    upd_csgs_later
  end
  
  def reset_testers(actor)
    $game_temp.all_data[actor] = [actor.dmghp, actor.usesp, actor.xstr,
        actor.xdex, actor.xint, actor.xagi]
  end
      
  def test_on_stats
    $game_party.actors.each {|actor|
        unless actor.dead?
          actor.hp, actor.sp = actor.hp, actor.sp
          if actor.dmghp != $game_temp.all_data[actor][0] &&
              actor.dmghp >= actor.maxhp * HP_LOST / 100 && rand(100) < HP_CHANCE
            actor.maxhp += HP_RATE
            actor.dmghp, actor.damage = 0, "#{$data_system.words.hp[0, 3]}Up"
          end
          if actor.usesp != $game_temp.all_data[actor][1] &&
              actor.usesp >= actor.maxsp * SP_USED / 100 && rand(100) < SP_CHANCE
            actor.maxsp += SP_RATE
            actor.usesp, actor.damage = 0, "#{$data_system.words.sp[0, 3]}Up"
          end
          if actor.xstr != $game_temp.all_data[actor][2] &&
              actor.xstr >= STRRATE_MIN && rand(100) < STR_CHANCE
            actor.str += STRRATE
            actor.xstr, actor.damage = 0, "#{$data_system.words.str[0, 3]}Up"
          end
          if actor.xdex != $game_temp.all_data[actor][3] &&
              actor.xdex >= DEXRATE_MIN && rand(100) < DEX_CHANCE
            actor.dex += DEXRATE
            actor.xdex, actor.damage = 0, "#{$data_system.words.dex[0, 3]}Up"
          end
          if actor.xagi != $game_temp.all_data[actor][5] &&
              actor.xagi >= AGIRATE_MIN && rand(100) < AGI_CHANCE
            actor.agi += AGIRATE
            actor.xagi, actor.damage = 0, "#{$data_system.words.agi[0, 3]}Up"
          end
          if actor.xint != $game_temp.all_data[actor][4] &&
              actor.xint >= INTRATE_MIN && rand(100) < INT_CHANCE
            actor.int += INTRATE
            actor.xint, actor.damage = 0, "#{$data_system.words.int[0, 3]}Up"
          end
          reset_testers(actor)
        end}
  end
  
end
