#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # Pay to Heal by Blizzard # Version: 2.0 # Type: Healing System # Date v2.0: 29.7.2009 #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # # 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. # # # #---------------------------------------------------------------------------- # #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # # Compatibility: # # 99% compatible with SDK v1.x. 90% compatible with SDK v2.x. # # # Features: # # - allows healing of HP, SP and states separately # - gold-per-HP cost # - gold-per-SP cost # - different cost for each state # - every undefined state is treated as "positive" state and will not be # removed upon healing # # new in v2.0: # - completely improved # # # Instructions: # # - Explanation: # # This script will allow you to heal your characters as you see fit and pay # only for the healing you have made use of. # You can call the Scene by using a "Call script" event command. Type into # the editor window this text: # # $scene = Scene_PayToHeal.new(HP_COST, SP_COST) # # HP_COST and SP_COST are optional parameters. If you specify them, they will # override your default configuration. # # - Configuration: # # ONE_HEAL_SOUND - defines the sound effect file with volume and pitch to # play when one actor is healed # ALL_HEAL_SOUND - defines the sound effect file with volume and pitch to # play when all actors are healed # FULL_HEAL_SOUND - defines the sound effect file with volume and pitch to # play when all actors are healed completely # HEAL_COMMANDS - list of healing commands in the menu # RIGHT_HEAL_WINDOWS - shows command windows on the right # HP_COST - how much healing 1 HP costs # SP_COST - how much healing 1 SP costs # # # Note: # # After the HP healing and SP healing costs have been calculated, they will # rounded up if the numbers are not integers. # # # If you find any bugs, please report them here: # http://www.chaosproject.co.nr #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= module BlizzCFG #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # START Configuration #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ONE_HEAL_SOUND = RPG::AudioFile.new('107-Heal03', 80, 100) ALL_HEAL_SOUND = RPG::AudioFile.new('108-Heal04', 80, 100) FULL_HEAL_SOUND = RPG::AudioFile.new('109-Heal05', 80, 100) HEAL_COMMANDS = ['Heal HP', 'Heal SP', 'States', 'Heal all HP', 'Heal all SP', 'All states', 'Full Heal', 'Exit'] RIGHT_HEAL_WINDOWS = true HP_COST = 0.2 SP_COST = 2.0 def self.state_cost(id) case id # START state costs # when STATE_ID then return COST_TO_HEAL when 2 then return 100 when 3 then return 50 when 4 then return 50 when 5 then return 50 when 6 then return 50 when 7 then return 100 when 8 then return 100 when 9 then return 200 when 10 then return 200 when 11 then return 200 when 12 then return 200 # END state costs end return 0 end #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # END Configuration #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: end #============================================================================== # Array #============================================================================== class Array def sum sum = 0 self.each {|i| sum += i if i.is_a?(Numeric)} return sum end end #============================================================================== # Game_Battler #============================================================================== class Game_Battler def remove_negative_states @states.clone.each {|id| remove_state(id) if BlizzCFG.state_cost(id) > 0} end def has_negative_states? return @states.any? {|id| BlizzCFG.state_cost(id) > 0} end def recover_all @hp = maxhp @sp = maxsp remove_negative_states end end #============================================================================== # Window_Dialog #============================================================================== class Window_Dialog < Window_Command def initialize(width, commands = ['Yes', 'No'], caption = 'Are you sure?') commands.push('') @caption = caption @cursor_width = 32 super(width, commands) if $fontface != nil self.contents.font.name = $fontface self.contents.font.size = $fontsize elsif $defaultfonttype != nil self.contents.font.name = $defaultfonttype self.contents.font.size = $defaultfontsize end self.x, self.y, self.z = 320 - self.width/2, 200 - self.height/2, 1500 @item_max, self.opacity = commands.size - 1, 192 commands.each {|c| w = self.contents.text_size(c).width @cursor_width = w if @cursor_width < w} @cursor_width += 32 refresh update_cursor_rect end def refresh super self.contents.font.color = system_color self.contents.draw_text(4, 0, self.width-40, 32, @caption, 1) end def draw_item(index, color) self.contents.font.color = color rect = Rect.new(4, 32 * (index+1), self.contents.width - 8, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) self.contents.draw_text(rect, @commands[index], 1) end def update_cursor_rect if @index < 0 || @item_max == 0 self.cursor_rect.empty else x = (self.contents.width - @cursor_width) / 2 self.cursor_rect.set(x, (@index + 1) * 32, @cursor_width, 32) end end end #============================================================================== # Window_GoldCost #============================================================================== class Window_GoldCost < Window_Base attr_reader :cost def initialize super(0, 0, 160, 96) self.contents = Bitmap.new(width - 32, height - 32) if $fontface != nil self.contents.font.name = $fontface self.contents.font.size = $fontsize elsif $defaultfonttype != nil self.contents.font.name = $defaultfonttype self.contents.font.size = $defaultfontsize end self.cost = 0 end def cost=(val) if @cost != val @cost = val refresh end end def refresh self.contents.clear cx = contents.text_size($data_system.words.gold).width self.contents.font.color = normal_color self.contents.draw_text(4, 32, 120 - cx - 2, 32, @cost.to_s, 2) self.contents.font.color = system_color self.contents.draw_text(4, 0, 120, 32, 'Cost') self.contents.draw_text(124 - cx, 32, cx, 32, $data_system.words.gold, 2) end end #============================================================================== # Scene_PayToHeal #============================================================================== class Scene_PayToHeal def initialize(hp_cost = BlizzCFG::HP_COST, sp_cost = BlizzCFG::SP_COST) @hp_cost, @sp_cost = hp_cost, sp_cost end def main @command_window = Window_Command.new(160, BlizzCFG::HEAL_COMMANDS) @command_window.index = 0 @command_window.x = 480 if BlizzCFG::RIGHT_HEAL_WINDOWS @cost_window = Window_GoldCost.new @cost_window.x = 480 if BlizzCFG::RIGHT_HEAL_WINDOWS @cost_window.y = 320 @gold_window = Window_Gold.new @gold_window.x = 480 if BlizzCFG::RIGHT_HEAL_WINDOWS @gold_window.y = 416 @status_window = Window_MenuStatus.new @status_window.x = 160 if !BlizzCFG::RIGHT_HEAL_WINDOWS calculate_costs Graphics.transition loop do Graphics.update Input.update update break if $scene != self end Graphics.freeze @command_window.dispose @status_window.dispose @gold_window.dispose @cost_window.dispose end def update if @command_window.active update_command elsif @status_window.active update_status elsif @dialog_window != nil && @dialog_window.active update_dialog end if Input.repeat?(Input::C) || Input.repeat?(Input::B) || Input.repeat?(Input::DOWN) || Input.repeat?(Input::LEFT) || Input.repeat?(Input::RIGHT) || Input.repeat?(Input::UP) @cost_window.cost = get_cost end end def update_command @command_window.update if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) $scene = Scene_Map.new elsif Input.trigger?(Input::C) case @command_window.index when 0, 1, 2 $game_system.se_play($data_system.decision_se) @command_window.active = false @status_window.active = true @status_window.index = 0 when 3 if $game_party.gold < @cost_window.cost || !$game_party.actors.any? {|actor| actor.hp != actor.maxhp} $game_system.se_play($data_system.buzzer_se) return end $game_system.se_play($data_system.decision_se) create_dialog when 4 if $game_party.gold < @cost_window.cost || !$game_party.actors.any? {|actor| actor.sp != actor.maxsp} $game_system.se_play($data_system.buzzer_se) return end $game_system.se_play($data_system.decision_se) create_dialog when 4 if $game_party.gold < @cost_window.cost || !$game_party.actors.any? {|actor| actor.sp != actor.maxsp} $game_system.se_play($data_system.buzzer_se) return end $game_system.se_play($data_system.decision_se) create_dialog when 6 if $game_party.gold < @cost_window.cost || !$game_party.actors.any? {|actor| actor.sp != actor.maxsp || actor.hp != actor.maxhp} $game_system.se_play($data_system.buzzer_se) return end $game_system.se_play($data_system.decision_se) create_dialog when 7 $game_system.se_play($data_system.decision_se) $scene = Scene_Map.new end end end def update_status @status_window.update if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) @command_window.active = true @status_window.active = false @status_window.index = -1 elsif Input.trigger?(Input::C) actor = $game_party.actors[@status_window.index] if $game_party.gold < @cost_window.cost || @command_window.index == 0 && actor.maxhp == actor.hp || @command_window.index == 1 && actor.maxsp == actor.sp || @command_window.index == 2 && !actor.has_negative_states? $game_system.se_play($data_system.buzzer_se) return end $game_system.se_play($data_system.decision_se) @status_window.active = false create_dialog end end def create_dialog @command_window.active = @status_window.active = false @dialog_window = Window_Dialog.new(256, ['Yes', 'No'], "This will cost #{@cost_window.cost} #{$data_system.words.gold}.") end def update_dialog @dialog_window.update if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) if @status_window.index >= 0 @status_window.active = true else @command_window.active = true end @dialog_window.dispose @dialog_window = nil elsif Input.trigger?(Input::C) $game_system.se_play($data_system.decision_se) process_heal if @dialog_window.index == 0 if @status_window.index >= 0 @status_window.active = true else @command_window.active = true end @dialog_window.dispose @dialog_window = nil end end def process_heal case @command_window.index when 0 $game_system.se_play(BlizzCFG::ONE_HEAL_SOUND) actor = $game_party.actors[@status_window.index] actor.hp = actor.maxhp calculate_costs(@status_window.index) when 1 $game_system.se_play(BlizzCFG::ONE_HEAL_SOUND) actor = $game_party.actors[@status_window.index] actor.sp = actor.maxsp calculate_costs(@status_window.index) when 2 $game_system.se_play(BlizzCFG::ONE_HEAL_SOUND) $game_party.actors[@status_window.index].remove_negative_states calculate_costs(@status_window.index) when 3 $game_system.se_play(BlizzCFG::ALL_HEAL_SOUND) $game_party.actors.each {|actor| actor.hp = actor.maxhp} calculate_costs when 4 $game_system.se_play(BlizzCFG::ALL_HEAL_SOUND) $game_party.actors.each {|actor| actor.sp = actor.maxsp} calculate_costs when 5 $game_system.se_play(BlizzCFG::ALL_HEAL_SOUND) $game_party.actors.each {|actor| actor.remove_negative_states} calculate_costs when 6 $game_system.se_play(BlizzCFG::FULL_HEAL_SOUND) $game_party.actors.each {|actor| actor.recover_all} calculate_costs end $game_party.lose_gold(@cost_window.cost) @cost_window.cost = 0 @gold_window.refresh @status_window.refresh end def calculate_costs(index = nil) if index == nil @hp_costs = [] @sp_costs = [] @state_costs = [] $game_party.actors.each {|actor| @hp_costs.push((actor.maxhp - actor.hp) * @hp_cost) @sp_costs.push((actor.maxsp - actor.sp) * @sp_cost) cost = 0.0 actor.states.each {|id| cost += BlizzCFG.state_cost(id)} @state_costs.push(cost)} else actor = $game_party.actors[index] @hp_costs[index] = (actor.maxhp - actor.hp) * @hp_cost @sp_costs[index] = (actor.maxsp - actor.sp) * @sp_cost @state_costs[index] = 0.0 actor.states.each {|id| @state_costs[index] += BlizzCFG.state_cost(id)} end end def get_cost cost = 0.0 if @status_window.index >= 0 case @command_window.index when 0 then cost = @hp_costs[@status_window.index] when 1 then cost = @sp_costs[@status_window.index] when 2 then cost = @state_costs[@status_window.index] end else case @command_window.index when 3 then cost = @hp_costs.map {|c| c.ceil}.sum when 4 then cost = @sp_costs.map {|c| c.ceil}.sum when 5 then cost = @state_costs.map {|c| c.ceil}.sum when 6 then cost = (@hp_costs + @sp_costs + @state_costs).map {|c| c.ceil}.sum end end return cost.ceil end end