Perishable Items
Version: 1.0
Author: modern algebra
Date: August 10, 2011
Version History
- <Version 1.0> 2011.08.10 - Original Release
Description
This script allows you to make items (and weapons or armors) that have a lifespan and will turn into another item eventually. Ie, a player could get a warm milk that has special properties if drunk within 60 seconds. Otherwise, it would become a cold milk and be worse. You can also make it so that the item will be destroyed when it perishes.
Features
- Allows you to set some items so that they transform after a certain amount of time
- Easy to configure
- Can set in which scenes the timer should count down
- Plays an SE upon perishing
- Can use Zeriab's Dialog System to also show a message upon perishing
Screenshots Instructions
This script
REQUIRES Item Instances Base and MUST be placed below it (though still above Main). If using Zeriab's Dialog System, this script also needs to be below that.
For instructions on using the script, please see the header.
Script
#==============================================================================
# Perishable Items
# Version: 1.0
# Author: modern algebra (rmrk.net)
# Date: August 10, 2011
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Description:
#
# This script allows you to make items (and weapons or armors) that have a
# lifespan and will turn into another item eventually. Ie, a player could
# get a warm milk that has special properties if drunk within 60 seconds.
# Otherwise, it would become a cold milk and be worse. You can also make it
# so that the item will be destroyed when it perishes.
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Instructions:
#
# This script REQUIRES my Instance Items Base script, which you can retrieve
# from: http://rmrk.net/index.php/topic,43441.0.html. If you want to enable
# the feature to show a message when items perish, then you will need
# Zeriab's Dialog System, from: http://rmrk.net/index.php/topic,24828.0.html
#
# Paste this script into its own slot somewhere above Main and below the
# Instance Items Base and Dialog System (if using) scripts.
#
# To set an item to perish, all you need to do is put the following code in
# its notebox:
# \perish[time, replacement]
# time : the number of seconds from its creation before the
# item perishes
# replacement : the item perished into. It is a letter representing
# type of item (I => Item; W => Weapon; A => Armor)
# succeeded by the ID. So I12 would be the 12 item in the
# database, A4 would be the 4th armor in the database,
# etc. This can be excluded altogether and then the
# perishing item will simply be destroyed.
#
# EXAMPLES:
# \perish[120, W5]
# An item with this in its notebox would perish 2 minutes after being
# received, and it would turn into the 5th weapon in the database.
#
# \perish[80]
# An item with this in its notebox would be destroyed after 80 seconds.
#
# If you have the Dialog system and opt to show a message, then you can
# customize the message that is shown with the following code in the
# perishing item's notebox:
# \perish_message[text]
# text : the message you want displayed. The code: \oi will be
# replaced with the name of the perishing item wile \ni will be
# replaced with the name of the new item.
#
# You can also set which scenes the script updates in, what SE plays when an
# item perishes, whether a message is shown and various aspects of that. Read
# the instructions in the Editable Region at line 62.
#==============================================================================
if $imported && $imported["MAInstanceItemsBase"]
$imported["MAPerishableItems"] = true
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
# EDITABLE REGION
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# In this array, put the scenes in which the perishing timer will count down.
# Ie. if you want opening the menu to pause the perish timer, then don't put it
# in the array.
MAPI_PERISH_COUNTDOWN_SCENES = [Scene_Map]
# SE to be played when an item perishes. If you want to also set volume and
# pitch, you can set it as an array: ["filename", volume, pitch]
MAPI_ITEM_PERISH_SE = ["Down"]
# Whether to show a message when messages perish. If true, you need to put
# Zeriab's Dialog system somewhere above this script in the editor. It can be
# found at:
MAPI_SHOW_MESSAGE = true
# The following options only apply if MAPI_USE_DIALOG is true
MAPI_USE_DIM_BACKGROUND = false # Whether to dim the background when showing
MAPI_WINDOW_OPACITY = 200 # The opacity of the window that shows the message
# The alignment of the text in the window. 0 => Left, 1 => Centre; 2 => Right
MAPI_WINDOW_ALIGN = 1
# The default message format for perishing. \\OI will be replaced by the
# name of the perishing item while \\NI will be replaced by the name of the
# replacing item.
MAPI_VOCAB_PERISH_INTO = "Your \\oi has become \\ni!"
# Same as above, but MAPI_VOCAB_PERISH_DESTROY is for when the perishing
# item doesn't turn into anything and is simply destroyed.
MAPI_VOCAB_PERISH_DESTROY = "Your \\oi has perished!"
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# END EDITABLE_REGION
#//////////////////////////////////////////////////////////////////////////////
#==============================================================================
# ** RPG::BaseItem
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new method - get_perishablity
#==============================================================================
class RPG::BaseItem
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * CONSTANTS
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MA_INSTANCE_CHECKS << /\\PERISH\[\s*\d+[,\s]*[WAI]?\d*\s*\]/i
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Perish Time
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def get_perishability
if !@perishability
@perishability = [-1, -1, -1]
if self.note[/\\PERISH\[\s*(\d+)[,\s]*([WAI]?)(\d*)\s*\]/i] != nil
type = case $2.upcase
when "I" then 0
when "W" then 1
when "A" then 2
else
type = -1
end
@perishability = [$1.to_i, type, $3.empty? ? -1 : $3.to_i]
end
end
return @perishability
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Perish Message
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def perish_message
return @perish_message if @perish_message
if self.note[/\\PERISH_MESSAGE\[(.+?)\]/im]
@perish_message = $1.gsub (/\r\n/) { " " }
return @perish_message
end
perish = get_perishability
return perish[1] != -1 && perish[2] != -1 ? MAPI_VOCAB_PERISH_INTO : MAPI_VOCAB_PERISH_DESTROY
end
end
#==============================================================================
# *** II_BaseItem
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new attributes - perish_time; perish_item_type; perish_item_id
# aliased method - setup
#==============================================================================
module II_BaseItem
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_accessor :perish_time # The number of frames before this perishes
attr_accessor :perish_item_type # The type (Item, Weapon, Armor) it becomes
attr_accessor :perish_item_id # Once perished, ID of the item it becomes
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Setup
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias malg_iiperish_setup_8gm2 setup
def setup (item, *args, &block)
malg_iiperish_setup_8gm2 (item, *args, &block) # Run Original Method
@perish_time, @perish_item_type, @perish_item_id = *item.get_perishability
$game_system.perishing_items << self if self.perish_time > 0
end
end
#==============================================================================
# ** Game_System
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new attribute - perishing_items
#==============================================================================
class Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_accessor :perishing_items
attr_accessor :perish_frame_timer
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias mg_perishit_initz_5tc2 initialize
def initialize (*args, &block)
@perishing_items = []
@perish_frame_timer = 0
mg_perishit_initz_5tc2 (*args, &block) # Run Original Method
end
end
#==============================================================================
# Scene Base
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased method - update
#==============================================================================
class Scene_Base
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Update
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias moalg_perishitem_upd_6yh1 update
def update (*args, &block)
# Run Original Method
moalg_perishitem_upd_6yh1 (*args, &block)
return unless MAPI_PERISH_COUNTDOWN_SCENES.include? (self.class)
$game_system.perish_frame_timer += 1
return if $game_system.perish_frame_timer < 60
lines = []
perished = []
# Update perishables every second
$game_system.perishing_items.each { |item|
item.perish_time -= 1
if item.perish_time <= 0
data_type = case item
when RPG::Item then $data_items
when RPG::Weapon then $data_weapons
when RPG::Armor then $data_armors
end
# Convert (or Destroy) the Item
if $game_party.has_item? (item, true)
perish_msg = item.perish_message.gsub (/\\[Oo][Ii]/) { item.name }
if item.perish_item_type != -1 && item.perish_item_id > 0
item2_data = $game_system.instance_items[item.perish_item_type]
if item2_data.size > item.perish_item_id
item2 = item2_data[item.perish_item_id]
$game_party.gain_item (item2, 1)
perish_msg.gsub! (/\\[Nn][Ii]/) { item2.name }
# If the perishing item was equipped
if $game_party.item_number (item) <= 0 && !item2.is_a? (RPG::Item) && data_type == item2_data
for actor in $game_party.members
index = actor.equips.index (item)
if index != nil
actor.change_equip (index, item2) if actor.equippable? (item2)
break
end
end
end
end
end
# Lose and destroy the perished item
$game_party.ii_destroy_lost_instances = true
$game_party.lose_item (item, 1, true)
$game_party.ii_destroy_lost_instances = false
else
data_type.destroy_instance (item.id)
end
lines << perish_msg if perish_msg
perished << item
end
}
perished.each { |item| $game_system.perishing_items.delete (item) }
unless lines.empty?
# Play SE
if !MAPI_ITEM_PERISH_SE.empty?
se = MAPI_ITEM_PERISH_SE.is_a? (String) ? [MAPI_ITEM_PERISH_SE] : MAPI_ITEM_PERISH_SE
RPG::SE.new (*se).play
end
Dialog_PerishedItems.show (lines) if Object.constants.include? ("Dialog_PerishedItems")
end
$game_system.perish_frame_timer = 0 # Reset Frame Timer
end
end
if MAPI_SHOW_MESSAGE && Object.constants.include? ("Dialog") # If the Dialog system is installed
#==============================================================================
# ** Window_PerishedItems
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This window just shows all items that perished this frame
#==============================================================================
class Window_PerishedItems < Window_Base
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialize
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (lines)
hght = 32 + (lines.size * WLH)
super (0, (Graphics.height - hght) / 2, Graphics.width, hght)
self.opacity = MAPI_WINDOW_OPACITY
for i in 0...lines.size
draw_line (i*WLH, lines[i])
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Line
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_line (y, line)
self.contents.draw_text (0, y, contents.width, WLH, line, MAPI_WINDOW_ALIGN)
end
end
#==============================================================================
# ** Dialog_PerishedItems
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This dialog processes showing perished items
#==============================================================================
class Dialog_PerishedItems < Dialog
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (lines)
super ()
@lines = lines
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Create Window
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def main_window
@notify_window = Window_PerishedItems.new (@lines)
@notify_window.z = STARTING_Z_VALUE + 1
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Dispose Windows
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def main_dispose
@notify_window.dispose
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Frame Update
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update
if Input.trigger?(Input::B) || Input.trigger? (Input::C)
Sound.play_cancel
mark_to_close
end
end
unless MAPI_USE_DIM_BACKGROUND
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Create Background
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def create_background
@background_sprite = Sprite.new # Create dummy sprite for disposing
end
end
end
end
else
p "Perishable Items requires the Item Instances Base script, which can be found at RMRK:\nhttp://rmrk.net/index.php/topic,43441.0.html"
end
Credit
Thanks
- Zeriab, for the Dialog System
Support
Please post in this topic at RMRK if you have any bug reports or suggestions.
Known Compatibility Issues
Perishable Items
REQUIRES Instance Items Base and must be below it (though still above Main). If using Zeriab's Dialog System, this script also needs to be below that.
If you are using any custom scenes that you add to the timer array, then those scripts also need to be above Perishable Items in order in the Script Editor.
Demo
Mitsarugi made this
demo so you can see how the script works.