#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Hunger/Thirst
# Initial Author: ForeverZer0
# Date: 5.14.2010 (MM/DD/YYYY)
# Version: 1.0
# Revision Author DerVVulfman
# Date: 12.20.2016 (MM/DD/YYYY)
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# * Cleaned. Added proper coding throughout the script and fixed script order.
# Separated the Zer0 module into two separate units, one to handle
# all configurations and extracted them from clumsy 'methods'.
# Broken down methods for easier aliasing if new plugins wanted.
# * Added. New facility for system to work with only the lead actor.
# Includes the command_355 'Script System Fix' - Optimal Version.
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# Features:
# - Easy to use
# - MUCH less complicated than many other similar scripts, yet it has more
# features and less code
# - Can have hunger and thirst decrease by time intervals or by steps walked
# by the player
# - Ability to have each character's 'Max Hunger' increase so they can go
# longer in between food and drinks as they gain in power
# - Can use script calls to easily change hunger/thirst values and to disable
# the system for long cutscenes, etc. so that nothing decreases while the
# player does not have control
# - Automatically added states if hunger/thirst is at specific rates.
#
# Compatibility:
# - If using Zero Add-On Collection, place this script below it. There is a
# minor issue with the Chemist Class script, but placing this script below
# it will solve the problem.
#
# Instructions:
# - Place script below debug, and above main (below Zer0 Add-Ons, if present)
# - All configuration is below and described fully in its respective section
# - The following script calls can be used in game:
#
# * $game_system.hunger_actor = true
# - If this script call is used, the system will be set to only affect
# the lead actor of the party. If set to false, it affects the entire
# party.
#
# * Zer0.hunger_system(true/false)
# - If false, hunger/thirst rates will not decrease. Good for long scenes
# where the player isn't in control, etc. The system will remain ON/OFF
# until it is changed.
#
# * Zer0.set_hunger(ACTOR_ID, AMOUNT)
# * Zer0.set_thirst(ACTOR_ID, AMOUNT)
# - Sets the hunger/thirst of actor in your database with ACTOR_ID to the
# number specified by AMOUNT
#
# * Zer0.set_max_hunger(ACTOR_ID, AMOUNT)
# * Zer0.set_max_thirst(ACTOR_ID, AMOUNT)
# - Sets the MAX hunger/thirst of actor in your database by ACTOR_ID to
# the number specified by AMOUNT
#
# * Zer0.recover_hunger(ACTOR_ID)
# - Will recover all hunger/thirst to actor by ACTOR_ID. If you omit the
# ( ) at the end of the script call, it will recover the entire party.
#
# * Zer0.actor_hunger_id(ACTOR_ID)
# - Returns the current hunger of actor with ACTOR_ID
#
# * Zer0.actor_thirst_id(ACTOR_ID)
# - Returns the current thirst of actor with ACTOR_ID
#
# * Zer0.actor_hunger_pos(POSITION)
# - Return the current hunger of actor at party POSITION
# (0 is the leader, 1 is actor 2, etc)
#
# * Zer0.actor_thirst_pos(POSITION)
# - Return the current thist of actor at party POSITION
# (0 is the leader, 1 is actor 2, etc)
#
# * Zer0.hunger_debugger
# - Displays info on-screen of each characters hunger/thirst, current
# count for steps and time, and shows which features are currently ON.
#
# Special Thanks:
# - kukusu, whose request gave me the inspiration for the script
# - SBR*, for pointing out a stupid error I made with the stepcount
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#==============================================================================
# ** Zer0
#------------------------------------------------------------------------------
# A module containing ForeverZer0's Hunger/Thirst Configuration Section
#==============================================================================
module Zer0
#--------------------------------------------------------------------------
FOOD_ITEM = {} # Do Not Edit This Line
STATE_AILMENTS = {} # Do Not Edit This Line
#--------------------------------------------------------------------------
# DEFAULT HUNGER AND THIRST
# =========================
# This sets the base MAX values for the actors. It can be altered in-game.
#
DEFAULT_HUNGER = 100
DEFAULT_THIRST = 100
# INCREMENT SYSTEM BOOLS
# ======================
# This determines if the hunger/thirst system works by calculating the
# number of steps the player has taken and/or the amount of time that passes.
# Both may function, however it is suggested to only have one turned on.
#
BY_TIME = true
BY_STEPS = true
# STEPS BEFORE DECREASE
# Determines how many steps are taken before hunger/thirst decreases.
# Hunger and thirst decrease by 1 point for each iteration.
# IE: If STEPS_HUNGER_DOWN is 20, the hunger score reduces 1 per 20 steps.
#
STEPS_HUNGER_DOWN = 100
STEPS_THIRST_DOWN = 80
# SECS BEFORE DECREASE
# Determines how many seconds pass before hunger/thirst decreases.
# Hunger and thirst decrease by 1 point for each iteration.
# IE: If SECS_HUNGER_DOWN is 5, the hunger score reduces 1 every 5 seconds.
#
SECS_HUNGER_DOWN = 1
SECS_THIRST_DOWN = 1
# LEVEL UP INCREASE
# If enabled, actor's Hunger and thirst scores can increase with each level.
#
LVL_UP_INCREASE = true
# LEVEL UP AMOUNT
# This defines how many points an actor's Hunger/Thirst can increase with
# each level (dependant on LVL_UP_INCREASE above).
#
LVL_UP_AMOUNT = 5
# RECOVER BY PERCENTAGE
# Food items can heal an actor when consumed. This switch determines if
# the healing is point based (if false) or is a percentage of the actor's
# total score (if true)
#
RECOVER_BY_PERCENT = true
# RECOVERY FOOD ITEMS
# Below you can set food items by ID to sate an actor's hunger and/or thirst.
# Each item is as follows: FOOD ITEM[item_id] = [hunger, thirst]
# Positive hunger or thirst values allow the actor to recover points while
# negative values can harm the actor, making them hungrier or thirstier.
#
# Do NOT have food/drink items do anything other than recover hunger/thirst.
# Effects such as HP/MP recovery will have no effect. It is NOT possible to
# make a healing potion that quenches the actor's thirst.
#
FOOD_ITEM[1] = [15,25]
FOOD_ITEM[2] = [20,35]
FOOD_ITEM[3] = [25,45]
FOOD_ITEM[4] = [35,35]
FOOD_ITEM[5] = [45,45]
FOOD_ITEM[6] = [95,55]
# STATE AILMENT RANGE
# Here, you can set up states that will be applied when an actor's hunger
# or thirst fall reach a specific point. This can let you apply states
# such as 'Starvation' or 'Dehydration'.
#
# State ailments are set based upon the point score reached. If a state
# ailment is defined as STATE_AILMENTS[5] = [4,6], any actor who has
# a hunger or thirst score that reached '5' or below will suffer the
# status effects defined in the array.
#
# This method is refreshed every time the system decreases an actor's hunger
# and thirst score.
#
# Keep in mind that these states will not automatically be cured if the
# actor's hunger/thirst rises above these scores. Suitable Food/Drink items
# are needed to cure these states.
#
#
STATE_AILMENTS[0] = [1,1]
STATE_AILMENTS[9] = [2,2]
STATE_AILMENTS[15] = [3,3]
end
#==============================================================================
# ** Zer0
#------------------------------------------------------------------------------
# A module containing ForeverZer0's Hunger/Thirst calculation methods
#==============================================================================
module Zer0
#--------------------------------------------------------------------------
# * Get hunger sate value from food item
# item_id : item ID
#--------------------------------------------------------------------------
def self.food(item_id)
return nil unless FOOD_ITEM.has_key?(item_id)
return FOOD_ITEM[item_id][0]
end
#--------------------------------------------------------------------------
# * Get thirst sate value from food item
# item_id : item ID
#--------------------------------------------------------------------------
def self.drink(item_id)
return nil unless FOOD_ITEM.has_key?(item_id)
return FOOD_ITEM[item_id][1]
end
#--------------------------------------------------------------------------
# * Get status effect ID for Hunger
# current_hunger : hunger score
#--------------------------------------------------------------------------
def self.hunger_states(current_hunger)
states = STATE_AILMENTS.sort
for key in states
keyval = key[0]
return key[1][0] if current_hunger <= keyval
end
return nil
end
#--------------------------------------------------------------------------
# * Get status effect ID for Thirst
# current_thirst : thirst score
#--------------------------------------------------------------------------
def self.thirst_states(current_thirst)
states = STATE_AILMENTS.sort
for key in states
keyval = key[0]
return key[1][1] if current_thirst <= keyval
end
return nil
end
#--------------------------------------------------------------------------
# * Set Hunger by value
# value : value
#--------------------------------------------------------------------------
def self.hunger_system(value)
$game_party.hunger = value
return true
end
#--------------------------------------------------------------------------
# * Set actor hunger value
# actor_id : Actor ID
# amount : hunger amount
#--------------------------------------------------------------------------
def self.set_hunger(actor_id, amount)
$game_party.actors.each {|a| a.hunger = amount if a.id == actor_id}
end
#--------------------------------------------------------------------------
# * Set actor thirst value
# actor_id : Actor ID
# amount : thirst amount
#--------------------------------------------------------------------------
def self.set_thirst(actor_id, amount)
$game_party.actors.each {|a| a.thirst = amount if a.id == actor_id}
end
#--------------------------------------------------------------------------
# * Set maximum hunger value for actor
# actor_id : Actor ID
# amount : new maximum hunger value
#--------------------------------------------------------------------------
def self.set_max_hunger(actor_id, amount)
$game_party.actors.each {|a| a.max_hunger = amount if a.id == actor_id}
end
#--------------------------------------------------------------------------
# * Set maximum thirst value for actor
# actor_id : Actor ID
# amount : new maximum thirst value
#--------------------------------------------------------------------------
def self.set_max_thirst(actor_id, amount)
$game_party.actors.each {|a| a.max_thirst = amount if a.id == actor_id}
end
#--------------------------------------------------------------------------
# * Get actor hunger value
# actor_id : Actor ID
#--------------------------------------------------------------------------
def self.actor_hunger_id(actor_id)
$game_party.actors.each {|a| return a.hunger if a.id == actor_id}
end
#--------------------------------------------------------------------------
# * Get actor thirst value
# actor_id : Actor ID
#--------------------------------------------------------------------------
def self.actor_thirst_id(actor_id)
$game_party.actors.each {|a| return a.thirst if a.id == actor_id}
end
#--------------------------------------------------------------------------
# * Get party member's hunger value
# pos : game party index value (0 = party leader)
#--------------------------------------------------------------------------
def self.actor_hunger_pos(pos = 0)
return $game_party.actors[pos].hunger if $game_party.actors[pos] != nil
end
#--------------------------------------------------------------------------
# * Get party member's thirst value
# pos : game party index value (0 = party leader)
#--------------------------------------------------------------------------
def self.actor_thist_pos(position = 0)
return $game_party.actors[pos].thirst if $game_party.actors[pos] != nil
end
#--------------------------------------------------------------------------
# * Recover all hunger/thirst for actor
# actor_id : Actor ID (or nil for all party member)
#--------------------------------------------------------------------------
def self.recover_hunger(actor_id = nil)
$game_party.actors.each {|actor|
if actor_id == nil
actor.hunger = actor.max_hunger
actor.thirst = actor.max_thirst
elsif actor.id == actor_id
actor.hunger = actor.max_hunger
actor.thirst = actor.max_thirst
end
}
end
#--------------------------------------------------------------------------
# * Show Party Hunger/Thirst Values in debugger call
#--------------------------------------------------------------------------
def self.hunger_debugger
sys = "System ON: #{$game_party.hunger}\n\n" +
"By Time: #{BY_TIME}\n" +
"By Steps: #{BY_STEPS}\n\n"
actors = ''
$game_party.actors.each {|actor| actors +=
"#{actor.name}\nHunger: #{actor.hunger}\\#{actor.max_hunger}\n" +
"Thirst: #{actor.thirst}\\#{actor.max_thirst}\n\n"}
ht = "HungerTime: #{$game_party.time_hunger/40}\\#{SECS_HUNGER_DOWN}\n"
tt = "ThirstTime: #{$game_party.time_thirst/40}\\#{SECS_THIRST_DOWN}\n"
hs = "HungerStep: #{$game_party.steps}\\#{$game_party.step_hunger}\n"
ts = "ThirstStep: #{$game_party.steps}\\#{$game_party.step_thirst}\n"
print(sys + actors + ht + tt + hs + ts)
end
end
#==============================================================================
# ** Game_System
#------------------------------------------------------------------------------
# This class handles data surrounding the system. Backround music, etc.
# is managed here as well. Refer to "$game_system" for the instance of
# this class.
#==============================================================================
class Game_System
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :hunger_actor # Hunger for Lead Actor Only flag
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias zer0_hunger_initialize initialize
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
zer0_hunger_initialize
@hunger_actor = false
end
end
#==============================================================================
# ** Game_Battler
#------------------------------------------------------------------------------
# This class deals with battlers. It's used as a superclass for the Game_Actor
# and Game_Enemy classes.
#==============================================================================
class Game_Battler
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias zero_hunger_item_effect item_effect
#--------------------------------------------------------------------------
# * Application of Item Effects
# item : item
#--------------------------------------------------------------------------
def item_effect(item)
food_item = false
hunger_plus = Zer0.food(item.id)
thirst_plus = Zer0.drink(item.id)
return true if food_item_effect(hunger_plus, thirst_plus) == true
return zero_hunger_item_effect(item)
end
#--------------------------------------------------------------------------
# * Application of Food Item Effects
# hunger_plus : hunger sate effect value
# thirst_plus : thirst sate effect value
#--------------------------------------------------------------------------
def food_item_effect(hunger_plus, thirst_plus)
return false unless self.is_a?(Game_Actor)
food_item = false
if hunger_plus != nil
if Zer0::RECOVER_BY_PERCENT
hunger_plus = (self.max_hunger * (hunger_plus * 0.01)).ceil
end
self.hunger += hunger_plus
self.hunger = [[self.hunger, self.max_hunger].min, 0].max
food_item = true
end
if thirst_plus != nil
if Zer0::RECOVER_BY_PERCENT
thirst_plus = (self.max_thirst * (thirst_plus * 0.01)).ceil
end
self.thirst += thirst_plus
self.thirst = [[self.thirst, self.max_thirst].min, 0].max
food_item = true
end
return false unless food_item
states_plus(item.plus_state_set)
states_minus(item.minus_state_set)
return true
end
end
#==============================================================================
# ** Game_Actor
#------------------------------------------------------------------------------
# This class handles the actor. It's used within the Game_Actors class
# ($game_actors) and refers to the Game_Party class ($game_party).
#==============================================================================
class Game_Actor < Game_Battler
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :hunger # hunger
attr_accessor :max_hunger # max hunger
attr_accessor :thirst # thirst
attr_accessor :max_thirst # max thirst
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias zer0_hunger_setup setup
alias zer0_hunger_level_up exp=
#--------------------------------------------------------------------------
# * Setup
# actor_id : actor ID
#--------------------------------------------------------------------------
def setup(actor_id)
zer0_hunger_setup(actor_id)
@hunger = @max_hunger = Zer0::DEFAULT_HUNGER
@thirst = @max_thirst = Zer0::DEFAULT_THIRST
if Zer0::LVL_UP_INCREASE && @level > 1
increase = Zer0::LVL_UP_AMOUNT
@hunger = @max_hunger = (@level - 1) * increase + Zer0::DEFAULT_HUNGER
@thirst = @max_thirst = (@level - 1) * increase + Zer0::DEFAULT_THIRST
end
end
#--------------------------------------------------------------------------
# * Change EXP
# exp : new EXP
#--------------------------------------------------------------------------
def exp=(exp)
level = @level
zer0_hunger_level_up(exp)
if Zer0::LVL_UP_INCREASE && level != @level
lvls = @level - level
@max_hunger += (Zer0::LVL_UP_AMOUNT * lvls)
@max_thirst += (Zer0::LVL_UP_AMOUNT * lvls)
end
end
end
#==============================================================================
# ** Game_Party
#------------------------------------------------------------------------------
# This class handles the party. It includes information on amount of gold
# and items. Refer to "$game_party" for the instance of this class.
#==============================================================================
class Game_Party
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :hunger # hunger
attr_accessor :time_hunger # time hunger
attr_accessor :time_thirst # time thirst
attr_accessor :step_hunger # step hunger
attr_accessor :step_thirst # step thirst
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias zer0_hunger_system_init initialize
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
zer0_hunger_system_init
@hunger = true
@time_hunger = @time_thirst = 0
@step_hunger = Zer0::STEPS_HUNGER_DOWN
@step_thirst = Zer0::STEPS_THIRST_DOWN
end
#--------------------------------------------------------------------------
# * Determine Hunger States
#--------------------------------------------------------------------------
def check_hunger_states
if $game_system.hunger_actor == true
check_actor_hunger_states(@actors[0])
else
check_party_hunger_states
end
end
#--------------------------------------------------------------------------
# * Determine Hunger States for Party
#--------------------------------------------------------------------------
def check_party_hunger_states
@actors.each {|actor|check_actor_hunger_states(actor)}
end
#--------------------------------------------------------------------------
# * Determine Hunger States for Actor
# actor : actor
#--------------------------------------------------------------------------
def check_actor_hunger_states(actor)
state_id = Zer0.hunger_states(actor.hunger)
actor.add_state(state_id) if state_id != nil
end
#--------------------------------------------------------------------------
# * Determine Thirst States
#--------------------------------------------------------------------------
def check_thirst_states
if $game_system.thirst_actor == true
check_actor_thirst_states(@actors[0])
else
check_party_thirst_states
end
end
#--------------------------------------------------------------------------
# * Determine Hunger States for Party
#--------------------------------------------------------------------------
def check_party_thirst_states
@actors.each {|actor|check_actor_thirst_states(actor)}
end
#--------------------------------------------------------------------------
# * Determine Hunger States for Actor
# actor : actor
#--------------------------------------------------------------------------
def check_actor_thirst_states(actor)
state_id = Zer0.thirst_states(actor.thirst)
actor.add_state(state_id) if state_id != nil
end
end
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
# This interpreter runs event commands. This class is used within the
# Game_System class and the Game_Event class.
#==============================================================================
class Interpreter
#--------------------------------------------------------------------------
# * Script
#--------------------------------------------------------------------------
def command_355
# Set first line to script
script = @list[@index].parameters[0] + "\n"
# Loop
loop do
# If next event command is second line of script or after
break unless @list[@index+1].code == 655
# Add second line or after to script
script += @list[@index+1].parameters[0] + "\n"
# Advance index
@index += 1
end
# Evaluation
result = eval(script)
# If return value is false (must test with false class)
return false if result == FalseClass
# Continue
return true
end
end
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# This class performs map screen processing.
#==============================================================================
class Scene_Map
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias zer0_hunger_map_upd update
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# The original call
zer0_hunger_map_upd
# The hunger/thirst system if turned on
update_hunger if $game_party.hunger
end
#--------------------------------------------------------------------------
# * Frame Update (hunger/thirst evaluation)
#--------------------------------------------------------------------------
def update_hunger
update_hunger_by_time if Zer0::BY_TIME
update_hunger_by_steps if Zer0::BY_STEPS
end
#--------------------------------------------------------------------------
# * Frame Update (handling hunger/thirst by time)
#--------------------------------------------------------------------------
def update_hunger_by_time
# Add 1 to hunger and thirst timers
$game_party.time_hunger += 1
$game_party.time_thirst += 1
# Perform if hunger timer reach 40 frames (1 second)
if $game_party.time_hunger == (Zer0::SECS_HUNGER_DOWN * 40)
($game_system.hunger_actor == true) ? hunger_actor : hunger_party
# Reset timer
$game_party.time_hunger = 0
end
# Perform if thirst timer reach 40 frames (1 second)
if $game_party.time_thirst == (Zer0::SECS_THIRST_DOWN * 40)
($game_system.hunger_actor == true) ? thirst_actor : thirst_party
# Reset timer
$game_party.time_thirst = 0
end
end
#--------------------------------------------------------------------------
# * Frame Update (handling hunger/thirst by steps)
#--------------------------------------------------------------------------
def update_hunger_by_steps
# Perform if hunger steps counter reached
if $game_party.steps == $game_party.step_hunger
($game_system.hunger_actor == true) ? hunger_actor : hunger_party
# Reset hunger steps
$game_party.step_hunger = $game_party.steps + Zer0::STEPS_HUNGER_DOWN
end
# Perform if thirst steps counter reached
if $game_party.steps == $game_party.step_thirst
($game_system.hunger_actor == true) ? thirst_actor : thirst_party
# Reset thirst steps
$game_party.step_thirst = $game_party.steps + Zer0::STEPS_THIRST_DOWN
end
end
#--------------------------------------------------------------------------
# * Party Hunger Update
#--------------------------------------------------------------------------
def hunger_party
# Cycle through party and handle hunger
$game_party.actors.each {|actor|
actor.hunger -= 1 unless actor.dead? || actor.hunger == 0}
$game_party.check_hunger_states
end
#--------------------------------------------------------------------------
# * Actor Hunger Update
#--------------------------------------------------------------------------
def hunger_actor
# Get party leader and handle hunger
actor = $game_party.actors[0]
actor.hunger -= 1 unless actor.dead? || actor.hunger == 0
$game_party.check_hunger_states
end
#--------------------------------------------------------------------------
# * Party Thirst Update
#--------------------------------------------------------------------------
def thirst_party
# Cycle through party and handle thirst
$game_party.actors.each {|actor|
actor.thirst -= 1 unless actor.dead? || actor.thirst == 0}
$game_party.check_hunger_states
end
#--------------------------------------------------------------------------
# * Actor Thirst Update
#--------------------------------------------------------------------------
def thirst_actor
# Get party leader and handle thirst
actor = $game_party.actors[0]
actor.thirst -= 1 unless actor.dead? || actor.thirst == 0
$game_party.check_hunger_states
end
end