#============================================================================== # ** Hunger Hud #------------------------------------------------------------------------------ # Author: ForeverZer0 #============================================================================== class Hunger_HUD < Window_Base #====================================================================# # BEGIN CONFIGURATION # #====================================================================# # Define the colors used for each of the bars. HUNGER_EMPTY = Color.new(255, 0, 0) HUNGER_FULL = Color.new(0, 255, 0) THIRST_EMPTY = Color.new(96, 96, 96) THIRST_FULL = Color.new(128, 128, 255) BACKGROUND_COLOR = Color.new(0, 0, 0) # Define the type of bar used. (0 = Gradient, 1 = Transitional) # It would take longer to explain the differences than to just try each out. # There's only two as of the moment. BAR_STYLE = 0 # Define the width and height, in pixels, of the bars. BAR_WIDTH = 128 BAR_HEIGHT = 20 # Define switch for active/visibility control within game. ONOFF_SWITCH = 10 #====================================================================# # END CONFIGURATION # #====================================================================# #-------------------------------------------------------------------------- # ● New Method: initialize #-------------------------------------------------------------------------- def initialize(y = -12) super(0, y, Graphics.width, 96) # Set the windowskin's opacity to 0. @windowskin_org = self.windowskin self.windowskin = nil @colors1 = [HUNGER_EMPTY, HUNGER_FULL, BACKGROUND_COLOR] @colors2 = [THIRST_EMPTY, THIRST_FULL, BACKGROUND_COLOR] @actors = $game_party.members @function_stats ||= lambda do @actors.collect {|a| [a.hunger, a.max_hunger, a.thirst, a.max_thirst]} end @stats = @function_stats.call refresh end #-------------------------------------------------------------------------- # ● New Method: refresh #-------------------------------------------------------------------------- def refresh # Dispose the contents of the HUD. if self.contents != nil self.contents.dispose self.contents = nil end # Adjust width and location of window. self.height = @actors.size * (BAR_HEIGHT + 40) self.x = (Graphics.width - self.width) / 2 self.contents = Bitmap.new(self.width, self.height) # Iterate actors. @actors.each_index do |i| actor = @actors[i] # Calculate locations for each actor's bars. x = 0 y = i * (BAR_HEIGHT + 30) # Draw actor's name. self.contents.font.size = 16 if self.respond_to?(:draw_actor_name) begin self.windowskin = @windowskin_org if self.method(:draw_actor_name).parameters.size == 4 draw_actor_name(actor, x, y, BAR_WIDTH) draw_name = true elsif self.method(:draw_actor_name).parameters.size == 3 draw_actor_name(actor, x, y) draw_name = true end self.windowskin = nil rescue draw_name = false end end self.contents.draw_text(x, y, BAR_WIDTH, 16, actor.name) unless draw_name # Draw hunger bars. w, h, rate, max = BAR_WIDTH, 8, @stats[i][0], @stats[i][1] self.contents.draw_bar_hunger(x, 16+y, w, h, rate, max, BAR_STYLE, @colors1) # Draw thirst bars. rate, max, height = @stats[i][2], @stats[i][3], 16+8+4 self.contents.draw_bar_hunger(x, height+y, w, h, rate, max, BAR_STYLE, @colors2) end end #-------------------------------------------------------------------------- # ● New Method: update #-------------------------------------------------------------------------- def update self.visible = $game_switches[ONOFF_SWITCH] if self.visible if (@stats != @function_stats.call) || (@actors != $game_party.members) @stats, @actors = @function_stats.call, $game_party.members refresh end end end end #============================================================================== # ** Bitmap #------------------------------------------------------------------------------ # #============================================================================== class Bitmap #-------------------------------------------------------------------------- # ● New Method: draw_bar_hunger #-------------------------------------------------------------------------- def draw_bar_hunger(x, y, w, h, rate, max, style, colors = nil) # Set required instance variables. @bar_rect = Rect.new(x, y, w, h) @rate, @max, @style, @colors = rate, max, style, colors @fill_width_bar_hunger ||= lambda do ((@rate / @max.to_f) * (@bar_rect.width - 2)).round end # Define default colors if not defined. (RED <--> GREEN) @colors ||= [Color.new(255, 0, 0), Color.new(0, 255, 0), Color.new(0, 0, 0)] # Draw the background color. self.fill_rect(@bar_rect, @colors[2]) # Branch by what style is being used. case @style when 0 then gradient_bar_hunger when 1 then transition_bar_hunger end end #-------------------------------------------------------------------------- # ● New Method: gradient_bar_hunger #-------------------------------------------------------------------------- def gradient_bar_hunger # Get the bar from the cache. key = [@style, @bar_rect.width-2, @bar_rect.height-2, @colors[0], @colors[1]] bar = LiTTleDRAgo.cache.gradient_bar(*key) # Draw the gradient bar using rectangular transfer. rect = Rect.new(0, 0, @fill_width_bar_hunger.call, @bar_rect.height) self.blt(@bar_rect.x+1, @bar_rect.y+1, bar, rect) end #-------------------------------------------------------------------------- # ● New Method: transition_bar_hunger #-------------------------------------------------------------------------- def transition_bar_hunger # Returns the color for current rate. c1 = [@colors[0].red, @colors[0].green, @colors[0].blue, @colors[0].alpha] c2 = [@colors[1].red, @colors[1].green, @colors[1].blue, @colors[1].alpha] rgba, rate = [], 1 - (@rate.to_f / @max) c1.each_index {|i| rgba[i] = c2[i] - ((c2[i] - c1[i]) * rate) } # Set the bars fill rate and color depending on value. rect = Rect.new(@bar_rect.x+1, @bar_rect.y+1, @fill_width_bar_hunger.call, @bar_rect.height-2) self.fill_rect(rect, Color.new(*rgba)) end end #============================================================================== # ** Scene_Map #------------------------------------------------------------------------------ # This class performs the map screen processing. #============================================================================== class Scene_Map #-------------------------------------------------------------------------- # ● Alias Listing #-------------------------------------------------------------------------- unless method_defined?(:zer0_hunger_hud_main) alias_method :zer0_hunger_hud_main, :main alias_method :zer0_hunger_hud_upd, :update end #-------------------------------------------------------------------------- # ● Aliased Method: main #-------------------------------------------------------------------------- def main # Add the bars to Scene_Map. @hunger_hud = Hunger_HUD.new @hunger_hud.visible = $game_switches[Hunger_HUD::ONOFF_SWITCH] zer0_hunger_hud_main @hunger_hud.dispose unless @hunger_hud == nil || @hunger_hud.disposed? end #-------------------------------------------------------------------------- # ● Aliased Method: update #-------------------------------------------------------------------------- def update # Update the bars as needed. @hunger_hud.update zer0_hunger_hud_upd end end #============================================================================== # ** Cache #------------------------------------------------------------------------------ # This module loads graphics, creates bitmap objects, and retains them. # To speed up load times and conserve memory, this module holds the # created bitmap object in the internal hash, allowing the program to # return preexisting objects when the same bitmap is requested again. #============================================================================== ModCache = defined?(Window_ActorCommand) ? Cache : RPG::Cache module ModCache #-------------------------------------------------------------------------- # ● New Method: self.gradient_bar #-------------------------------------------------------------------------- def self.gradient_bar(style, width, height, color1, color2) # Create a unique key to call the bar back with. path = [style, width, height, color1, color2] @cache ||= {} # Check if cache already has bitmap defined, if not create it now. if !@cache.include?(path) || @cache[path].disposed? bitmap, rates = Bitmap.new(width, height), [] # Iterate through each pixel horizontally, setting a gradient color. c1 = [color1.red, color1.green, color1.blue, color1.alpha] c2 = [color2.red, color2.green, color2.blue, color2.alpha] # Draw the bar, having in transition from the first color to the second. c1.each_index {|i| rates[i] = (c1[i] - c2[i]).to_f / width } width.times do |i| values = [0, 1, 2, 3].collect {|j| c1[j] - (i * rates[j]) } # Set the color incrementally. This will be used later. bitmap.fill_rect(i, 0, 1, height, Color.new(*values)) end @cache[path] = bitmap end # Return the created bitmap. return @cache[path] end end