KItemRefill XP
#1
KItemRefill XP

by Kyonides

Introduction

This script will let your heroes depend on a flask or potion bottle to get healed, it can be refilled at anytime or you could break it on purpose... MWAHAHAHAHA! Laughing

Since version 1.2.0, the potion or flask can be destroyed. Metalhead 
Just add the item ID to the TOTAL_LOSS_IDS Constant and that's it! Laughing

Scripts

Latest Version

Code:
# * KItemRefill XP
#  Scripter : Kyonides-Arkanthes
#  v 1.2.0 - 2024-05-03

# * Script Calls *
# - Just refill the flask with whatever you want to.
#    KItemRefill.refill(ID)
# - Increase the number of sips. Hiccup! XD
#    KItemRefill.improve(ID)
# - Break the darn flask because you are evil!
#    KItemRefill.break(ID)
# - Is the flask broken?
#    KItemRefill.broken?(ID)
# - Fix the broken flask.
#    KItemRefill.replace(ID)
# - Heal depending on its mode
#    KItemRefill.new_mode(ID, MODE)
#  Modes: nil : Database setup, :hp & :mp are self evident
#  Many calls are optional, you are not forced to improve it or change its mode
#  so use your preferred calls instead.

#  Recommended Object Description:
#    Some Description. Uses Left:\u
#  The label should appear on the opposite side of the hero selection window.

#  SETTINGS

#  Pick one or more Non Consumable items, add them to the IDS array.
#  ITEM_KIND defines how the item will be used (1 out of 3 options)
#  Without ID nor any value or ID => nil : Based on Database settings
#  :hp => HP, :sp => SP or MP
#  USAGE_LIMITS: set ID => Maximum Number of Uses for each ID.
#  USAGE_INCREASE: set ID => Increase Uses for each ID.
#  MAX_LEVEL: set ID => Maximum Level (0 or higher) for each ID.
#  Don't forget to add as many commas as deemed necessary as a separator for
#  all key value pairs: 36 => 8, 37 => 5
#  REFILL_AFTER_IMPROVEMENT: set if you want the flask to be refilled or not
#  whenever it gets improved.
#  FILL_EMPTY_ITEM: set if the item should be filled at the beginning.

module KItemRefill
  IDS = [33]
  TOTAL_LOSS_IDS = [33]
  # Kind of Usage: ID => Use (nil, :hp, :sp)
  ITEM_KIND = { 33 => :hp }
  # Initial Maximum Level: ID => Level
  USAGE_LIMITS = { 33 => 8 }
  # Maximum Number of Improvements: ID => Maximum Number of Improvements
  USAGE_INCREASE = { 33 => 3 }
  # Maximum Level (0 or higher) : ID => Maximum Level
  MAX_LEVEL = { 33 => 4 }
  # Refill item after improving it? true OR false
  REFILL_AFTER_IMPROVEMENT = true
  # Refill item after getting it from some NPC? true OR false
  FILL_EMPTY_ITEM = true
  extend self
  def refill(id)
    $game_system.refill_items[id].refill
  end

  def improve(id)
    $game_system.refill_items[id].improve
  end

  def break(id)
    $game_system.refill_items[id].broken = true
  end

  def broken?(id)
    $game_system.refill_items[id].broken
  end

  def replace(id)
    $game_system.refill_items[id].broken = nil
  end

  def new_mode(id,mode)
    $game_system.refill_items[id].change_mode(mode)
  end
end

module ItemAddOns
  attr_accessor :sips, :broken
  attr_reader :sip_max, :level, :mode
  def level_max
    KItemRefill::MAX_LEVEL[@id]
  end

  def change_mode(new_mode)
    @mode = new_mode
  end

  def lose_refill?
    KItemRefill::TOTAL_LOSS_IDS.include?(@id)
  end
 
  def refill_empty?
    @sips == 0
  end

  def consume
    @sips -= 1 if @sips > 0
    $game_party.lose_item(@id, 1) if lose_refill? and refill_empty?
  end

  def fill
    @level = 0
    @mode = KItemRefill::ITEM_KIND[@id]
    refill_item
    @sips = KItemRefill::FILL_EMPTY_ITEM ? @sip_max : 0
  end

  def refill
    return @sips if @broken
    refill_item
    @sips = @sip_max
  end

  def improve
    return  @sips if @broken
    @level += 1 if @level < KItemRefill::MAX_LEVEL[@id]
    limit = KItemRefill::USAGE_LIMITS[@id]
    @sip_max = (limit + (@level * KItemRefill::USAGE_INCREASE[@id]))
    @sips = @sip_max if KItemRefill::REFILL_AFTER_IMPROVEMENT
  end
  private
  def refill_item
    limit = KItemRefill::USAGE_LIMITS[@id]
    @sip_max = (limit + (@level * KItemRefill::USAGE_INCREASE[@id]))
  end
end

class Game_System
  attr_reader :refill_items
  alias kyon_item_refill_gm_sys_init initialize
  def initialize
    @refill_items = {}
    KItemRefill::IDS.each do |id|
      item = $data_items[id].dup
      item.extend(ItemAddOns)
      item.fill
      @refill_items[id] = item
    end
    kyon_item_refill_gm_sys_init
  end
end

class Game_Actor
  alias :kitemrefill_gm_actor_item_effect :item_effect
  def item_effect(item)
    refill_items = $game_system.refill_items
    refill_item = refill_items[item.id]
    if !refill_item or !refill_item.mode
      effective = kitemrefill_gm_actor_item_effect(item)
    else
      effective = refill_item_effect(refill_item)
      refill_item.consume if effective
    end
    effective
  end

  def refill_item_effect(item)
    @critical = false
    if ((item.scope == 3 or item.scope == 4) and self.hp == 0) or
      ((item.scope == 5 or item.scope == 6) and self.hp >= 1)
      return false
    end
    effective = false
    # Set effective flag if common ID is effective
    effective |= item.common_event_id > 0
    hit_result = (rand(100) < item.hit)
    unless hit_result
      @damage = $game_temp.in_battle ? "Miss" : nil
      return false
    end
    # Set effective flag is skill is uncertain
    effective |= item.hit < 100
    if item.mode == :hp
      return effective = refill_hp_effect(item, effective)
    elsif item.mode == :sp
      return effective = refill_sp_effect(item, effective)
    end
  end

  def refill_hp_effect(item, effective)
    # Calculate amount of recovery
    recover_hp = maxhp * item.recover_hp_rate / 100 + item.recover_hp
    if recover_hp < 0
      recover_hp += self.pdef * item.pdef_f / 20
      recover_hp += self.mdef * item.mdef_f / 20
      recover_hp = [recover_hp, 0].min
    end
    # Element correction
    recover_hp *= elements_correct(item.element_set)
    recover_hp /= 100
    # Dispersion
    if item.variance > 0 and recover_hp.abs > 0
      amp = [recover_hp.abs * item.variance / 100, 1].max
      recover_hp += rand(amp+1) + rand(amp+1) - amp
    end
    # If recovery code is negative, guard correction
    recover_hp /= 2 if recover_hp < 0 and self.guarding?
    # Set damage value and reverse HP recovery amount
    @damage = -recover_hp
    # HP recovery
    last_hp = self.hp
    self.hp += recover_hp
    effective |= self.hp != last_hp
    # State change
    @state_changed = false
    effective |= states_plus(item.plus_state_set)
    effective |= states_minus(item.minus_state_set)
    # If parameter value increase is effective
    if item.parameter_type > 0 and item.parameter_points != 0
      case item.parameter_type
      when 1  # Max HP
        @maxhp_plus += item.parameter_points
      when 2  # Max SP
        @maxsp_plus += item.parameter_points
      when 3  # Strength
        @str_plus += item.parameter_points
      when 4  # Dexterity
        @dex_plus += item.parameter_points
      when 5  # Agility
        @agi_plus += item.parameter_points
      when 6  # Intelligence
        @int_plus += item.parameter_points
      end
      effective = true
    end
    if item.recover_hp_rate == 0 and item.recover_hp == 0
      # Set damage to empty string
      @damage = ""
      # If recovery amount is 0, and parameter increase value is ineffective.
      if item.parameter_type == 0 or item.parameter_points == 0
        # If state is unchanged Set damage to "Miss"
        @damage = "Miss" unless @state_changed
      end
    end
    return effective
  end

  def refill_sp_effect(item, effective)
    # Calculate amount of recovery
    recover_sp = maxsp * item.recover_sp_rate / 100 + item.recover_sp
    recover_sp *= elements_correct(item.element_set)
    recover_sp /= 100
    # Dispersion
    if item.variance > 0 and recover_sp.abs > 0
      amp = [recover_sp.abs * item.variance / 100, 1].max
      recover_sp += rand(amp+1) + rand(amp+1) - amp
    end
    # SP recovery
    last_sp = self.sp
    self.sp += recover_sp
    effective |= self.sp != last_sp
    # State change
    @state_changed = false
    effective |= states_plus(item.plus_state_set)
    effective |= states_minus(item.minus_state_set)
    # If parameter value increase is effective
    if item.parameter_type > 0 and item.parameter_points != 0
      case item.parameter_type
      when 1  # Max HP
        @maxhp_plus += item.parameter_points
      when 2  # Max SP
        @maxsp_plus += item.parameter_points
      when 3  # Strength
        @str_plus += item.parameter_points
      when 4  # Dexterity
        @dex_plus += item.parameter_points
      when 5  # Agility
        @agi_plus += item.parameter_points
      when 6  # Intelligence
        @int_plus += item.parameter_points
      end
      effective = true
    end
    if item.recover_sp_rate == 0 and item.recover_sp == 0
      # Set damage to empty string
      @damage = ""
      # If SP recovery rate / recovery amount are 0, and parameter increase
      # value is ineffective.
      if item.parameter_type == 0 or item.parameter_points == 0
        # If state is unchanged # Set damage to "Miss"
        @damage = "Miss" unless @state_changed
      end
    end
    return effective
  end
end

class Window_Help
  def set_text(item_id, text=nil, align=0)
    if text.is_a?(String)
      text = text.gsub(/\\[Uu]/){$game_system.refill_items[item_id].sips.to_s}
    elsif text.is_a?(Integer)
      align = text
      text = item_id
    else
      text = item_id
    end
    if text != @text or align != @align
      self.contents.clear
      self.contents.font.color = normal_color
      self.contents.draw_text(4, 0, self.width - 40, 32, text, align)
      @text = text
      @align = align
      @actor = nil
    end
    self.visible = true
  end
end

class Window_Item
  def update_help
    a = @index % 2 == 0 ? 0 : 2
    obj = self.item
    id, desc = self.item ? [obj.id, obj.description] : ["", nil]
    @help_window.set_text(id, desc, a)
  end
end

class Scene_Item
  def update_item
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = Scene_Menu.new(0)
      return
    elsif Input.trigger?(Input::C)
      @item = @item_window.item
      if !@item.is_a?(RPG::Item) or !$game_party.item_can_use?(@item.id)
        return $game_system.se_play($data_system.buzzer_se)
      end
      $game_system.se_play($data_system.decision_se)
      @infinite_potion = KItemRefill::IDS.include?(@item.id)
      if @item.scope >= 3 or @infinite_potion
        if @infinite_potion
          @item = $game_system.refill_items[@item.id]
          if @item.sips == 0
            $game_system.se_play($data_system.buzzer_se)
            @infinite_potion = nil
            return
          end
        end
        @item_window.active = false
        @target_window.x = (@item_window.index + 1) % 2 * 304
        @target_window.visible = true
        @target_window.active = true
        if @item.scope == 4 || @item.scope == 6
          @target_window.index = -1
        else
          @target_window.index = 0
        end
      else
        if @item.common_event_id > 0
          $game_temp.common_event_id = @item.common_event_id
          $game_system.se_play(@item.menu_se)
          if @item.consumable
            $game_party.lose_item(@item.id, 1)
            $game_system.map_interpreter.update
            @item_window.draw_item(@item_window.index)
          end
          $scene = Scene_Map.new
        end
      end
      return
    end
  end

  def update_target
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @item_window.refresh unless $game_party.item_can_use?(@item.id)
      @infinite_potion = nil
      @item_window.active = true
      @target_window.visible = false
      @target_window.active = false
      return
    elsif Input.trigger?(Input::C)
      if $game_party.item_number(@item.id) == 0
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      if @target_window.index == -1
        used = false
        for i in $game_party.actors
          used |= i.item_effect(@item)
        end
      end
      if @target_window.index >= 0
        if @infinite_potion
          if @item.sips == 0
            $game_system.se_play($data_system.buzzer_se)
            return
          end
        end
        target = $game_party.actors[@target_window.index]
        used = target.item_effect(@item)
        @item_window.update_help if @infinite_potion and used
      end
      if used
        $game_system.se_play(@item.menu_se)
        if @item.consumable
          $game_party.lose_item(@item.id, 1)
          @item_window.draw_item(@item_window.index)
        end
        @target_window.refresh
        if $game_party.all_dead?
          $scene = Scene_Gameover.new
          return
        end
        if @item.common_event_id > 0
          $game_temp.common_event_id = @item.common_event_id
          $scene = Scene_Map.new
          return
        end
      end
      $game_system.se_play($data_system.buzzer_se) unless used
      return
    end
  end
end

Old Scripts


Terms & Conditions

Free for use in ANY Gamer game.
Due credit is mandatory.
That's it! Tongue sticking out
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply }
#2
Special Update

After so many but many years, I have revisited my script once again to add an old feature back: the special potion will be deleted if the number of uses left reaches 0.

Just add the item ID to the TOTAL_LOSS_IDS Constant and that's it! [Image: laughing.gif]

I also updated the terms of use here. Winking
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply }




Users browsing this thread: 2 Guest(s)