=begin
#==============================================================================
** Map Drops
Выброс предметов из инвентаря
# ================================================= =============================
Автор: Hime
Дата: 10 августа 2013
Перевод: Yuryol
-------------------------------------------------- ----------------------------
-------------------------------------------------- ----------------------------
Этот сценарий позволяет выбросить предметы из своего инвентаря и поместите их
на карту. После выброса вы вполне можете забрать их обратно.
-------------------------------------------------- ----------------------------
Чтобы указать время исчезновения выброшенных предметов напишите тег в
примечание к предмету:
<drop-decay: n>
где n - время исчезновения предмета (измеряется в секундах)
Если вы не хотите, чтобы предмет исчезал, напишите тег:
<drop-decay: 0>
На 91-ой строчке данного скрипта можно указать время исчезновения по умолчанию.
-------------------------------------------------- ----------------------------
Есть два способа для указания ГДЕ вы можете
выбрасывать элементы на карте:
1) Вы можете разрешить/запретить выброс предметов на всей крате путем
вызова скрипта
$game_system.mapdrop_disabled = true/false
2) Вы можете разрешить выброс только на определенных картах, написав
Enable_All = false на 79-ой строчке и указав ID крат на 80-ой строке
-------------------------------------------------- ----------------------------
Есть два способа, чтобы выбросить предмет из инвентаря:
1) Выброс вручную через меню путём нажатия кнопки? указанной на 82-ой строке скрипта
2) Выброс через вызов скрипта.
drop_item(item_string, amount)
где item_string - ID вещи, amount - кол-во данной вещи.
Например:
drop_item("i2", 2)
Вы можете вбыросить не толкьо вещь, но и оружие или броню,
Например, чтобы выбросить оружие с ID 2 следует вызвать скрпит:
drop_item("w2", 1)
Чтобы выбросить броню с ID 2 следует вызвать скрпит:
drop_item("a2", 1)
По умолчанию предмет выбрасывается на ту клетку,где стоит персонаж.
Но вы также можете вызвать выброс предмета в определенное место опеределенной
карты следующими скриптами:
add_map_drop(item_string, amount, x, y, map_id)
add_map_drop('i1', amount, x, y)
где item_string - ID вещи, amount - кол-во данной вещи, х - координата х
карты, у - координата у карты, map_id - ID карты
#==============================================================================
=end
$imported = {} if $imported.nil?
$imported["TH_MapDrops"] = true
#==============================================================================
# ** Configuration
#==============================================================================
module TH
module Map_Drops
Default_Disable = false # ЗАПРЕТ выброса предмета из меню инвентаря
Enable_All = true # выброс возможен на всех картах
Enable_Maps = [1,2,3,4] # выброс возможен на данных картах
Drop_Item_Key = :X # клавиша выброса предмета из меню инвентаря
# Отображение сообщение при взятии выброшенного предмета
Found_Message = "Подобран %s!"
# Включение/отключение функции исчезновения предмета через определенное время
Can_Decay = true
# кол-во секунд, через которое предмет исчезнет (0 - предмет не исчезнет)
Decay_Time = 0
# СПРАЙТЫ ДЛЯ ЧЕГО-ТО, НЕ ПОНЛЯ ДЛЯ ЧЕГО.
# Drop_Sheet = "!Chest"
# Drop_Index = 4
# звук при поднятии выброшенного предмета
Obtain_SE = "Item1"
#==============================================================================
# ** Rest of the script
#==============================================================================
Decay_Regex = /<drop[-_ ]decay:?\s*(\d+)\s*>/i
Undroppable_Regex = /<undroppable>/i
end
end
module RPG
class EquipItem < BaseItem
def decay_time
return @decay_time unless @decay_time.nil?
res = TH::Map_Drops::Decay_Regex.match(self.note)
return @decay_time = res ? res[1].to_i : TH::Map_Drops::Decay_Time
end
def undroppable?
return @undroppable unless @undroppable.nil?
res = self.note.match(TH::Map_Drops::Undroppable_Regex)
return @undroppable = !res.nil?
end
end
class Item < UsableItem
def decay_time
return @decay_time unless @decay_time.nil?
res = TH::Map_Drops::Decay_Regex.match(self.note)
return @decay_time = res ? res[1].to_i : (key_item? ? 0 : TH::Map_Drops::Decay_Time)
end
def undroppable?
return @undroppable unless @undroppable.nil?
res = self.note.match(TH::Map_Drops::Undroppable_Regex)
return @undroppable = !res.nil?
end
end
end
class Game_System
attr_reader :map_drops
attr_accessor :mapdrop_disabled
alias :th_map_drop_init_system :initialize
def initialize
th_map_drop_init_system
@map_drops = {}
@mapdrop_disabled = TH::Map_Drops::Default_Disable
end
def add_map_drop(map_id, drop)
@map_drops[map_id] = [] if @map_drops[map_id].nil?
@map_drops[map_id] << drop
end
def get_map_drops(map_id)
@map_drops[map_id] ? @map_drops[map_id] : []
end
def delete_map_drop(map_id, id)
@map_drops[map_id].delete_if {|drop| drop.event.id == id}
end
def update_map_drops(map_id)
return unless @map_drops[map_id]
@map_drops[map_id].each do |drop|
$game_map.delete_event(drop.event.id) if drop.decayed?
end
end
end
class Game_Drop
attr_reader :x
attr_reader :y
attr_reader :name
attr_accessor :item
def initialize(item, count=1, x=$game_player.x, y=$game_player.y, map_id=$game_map.map_id)
@x = x
@y = y
@map_id = map_id
@item = item
@count = count
@name = item.name
end
end
class Game_MapDrop < Game_Drop
attr_reader :event
attr_reader :icon_index
def initialize(item, count=1, x=$game_player.x, y=$game_player.y, map_id=$game_map.map_id)
super
@drop_time = Graphics.frame_count
@decay_time = item.decay_time
@icon_index = item.icon_index
setup_event(x, y)
end
def decayed?
return false if @decay_time == 0
@drop_time + @decay_time*Graphics.frame_rate <= Graphics.frame_count
end
def display
if @count == 1
return "%d %s" %[@count, @item.name]
else
return "%d %ss" %[@count, @item.name]
end
end
def setup_event(x, y)
@event = RPG::Event.new(x, y)
event.pages[0].trigger = 0
event.pages[0].direction_fix = true
event.pages[0].priority_type = 0
#~ event.pages[0].graphic.character_name = TH::Map_Drops::Drop_Sheet
#~ event.pages[0].graphic.character_index = TH::Map_Drops::Drop_Index
event.pages[0].list = []
add_event_commands(event.pages[0].list)
end
def add_event_commands(list)
if @item.is_a?(RPG::Item)
cmd = 126
elsif @item.is_a?(RPG::Weapon)
cmd = 127
elsif @item.is_a?(RPG::Armor)
cmd = 128
end
list << RPG::EventCommand.new(250, 0, [RPG::SE.new(TH::Map_Drops::Obtain_SE, 100, 80)])
list << RPG::EventCommand.new(cmd, 0, [@item.id, 0, 0, @count, false])
list << RPG::EventCommand.new(101, 0, ["", 0, 0, 2])
list << RPG::EventCommand.new(401, 0, [sprintf(TH::Map_Drops::Found_Message, display)])
list << RPG::EventCommand.new(215, 0, [])
list << RPG::EventCommand.new
end
end
# A Map Drop Event object. Easier to identify.
class Game_DropEvent < Game_Event
attr_reader :icon_index
attr_reader :drop
def initialize(map_id, event, drop)
super(map_id, event)
@drop = drop
@icon_index = drop.icon_index
end
end
class Game_Map
alias :th_map_drop_init_map :initialize
def initialize
th_map_drop_init_map
@map_drops = []
end
alias :th_map_drop_setup_map :setup
def setup(map_id)
th_map_drop_setup_map(map_id)
setup_map_drops
end
def setup_map_drops
index = @events.empty? ? 1 : @events.keys.max + 1
clear_map_drops
$game_system.get_map_drops(@map_id).each_with_index do |drop, i|
drop.event.id = index + i
@events[index+i] = Game_DropEvent.new(@map_id, drop.event, drop)
@map_drops << index + i
end
SceneManager.scene.refresh_spriteset if SceneManager.scene_is?(Scene_Map)
end
# add the event directly into the map
def add_map_drop(map_id=@map_id, drop)
$game_system.add_map_drop(map_id, drop)
setup_map_drops
end
# refreshing map drops
def clear_map_drops
@map_drops.each {|id| @events.delete(id)}
@map_drops = []
@events.delete_if {|id, evt| evt.is_a?(Game_DropEvent)}
end
def delete_event(id)
@events.delete(id)
$game_system.delete_map_drop(@map_id, id)
SceneManager.scene.refresh_spriteset if SceneManager.scene_is?(Scene_Map)
end
def update_map_drops
$game_system.update_map_drops(@map_id)
end
end
#this is a silly hack to get it to draw icons rather than characters
class Sprite_Character < Sprite_Base
def initialize(viewport, character = nil)
super(viewport)
@character = character
@balloon_duration = 0
update
end
alias :th_map_drop_update_char_bitmap :update_bitmap
def update_bitmap
#if graphic_changed? && @character.is_a?(Game_DropEvent)
if @character.is_a?(Game_DropEvent)
set_drop_item_bitmap
else
th_map_drop_update_char_bitmap
end
end
def set_drop_item_bitmap
bitmap = Cache.system("Iconset")
rect = Rect.new(@character.icon_index % 16 * 24, @character.icon_index / 16 * 24, 24, 24)
self.bitmap = Bitmap.new(24, 24)
self.ox = 12
self.oy = 24
self.bitmap.blt(0, 0, bitmap, rect, 255)
end
end
class Window_ItemList < Window_Selectable
alias :th_map_drops_process_handling :process_handling
def process_handling
return unless open? && active
return process_drop_item if handle?(:drop) && Input.trigger?(TH::Map_Drops::Drop_Item_Key)
th_map_drops_process_handling
end
def process_drop_item
Sound.play_cursor
Input.update
deactivate
call_handler(:drop)
end
end
class Game_Party < Game_Unit
def can_drop?(item)
return false unless item
return false if $game_system.mapdrop_disabled
return false if item.is_a?(RPG::Item) && item.key_item?
return false if item.undroppable?
return false unless has_item?(item)
return false unless TH::Map_Drops::Enable_All || TH::Map_Drops::Enable_Maps.include?($game_map.map_id)
return true
end
def drop_item(item, amount=1)
return unless can_drop?(item)
drop_amount = [amount, item_number(item)].min
drop = Game_MapDrop.new(item, drop_amount)
$game_map.add_map_drop(drop)
$game_party.lose_item(item, drop_amount)
end
end
class Scene_Item < Scene_ItemBase
alias :th_map_drops_item_window :create_item_window
def create_item_window
th_map_drops_item_window
@item_window.set_handler(:drop, method(:on_item_drop))
end
def on_item_drop
# should give confirmation and input
drop_item
end
def drop_item
item = @item_window.item
if $game_party.can_drop?(item)
$game_party.drop_item(item)
@item_window.refresh
else
Sound.play_buzzer
end
@item_window.activate
end
end
class Scene_Map
def refresh_spriteset
@spriteset.refresh_characters
end
alias :th_map_drops_update_map_scene :update
def update
th_map_drops_update_map_scene
update_map_drops if TH::Map_Drops::Can_Decay
end
def update_map_drops
$game_map.update_map_drops
end
end
class Game_Interpreter
def get_item(string)
type = string[0].downcase
id = Integer(string[1..-1]) rescue nil
case type
when 'w'
return $data_weapons[id]
when 'a'
return $data_armors[id]
when 'i'
return $data_items[id]
else
return nil
end
end
# permanently erase event
def command_215
$game_map.delete_event(@event_id) if same_map? && @event_id > 0
end
# drop an item from the party
def drop_item(string, amount)
item = get_item(string)
return unless item
$game_party.drop_item(item, amount)
end
# add a drop to the map
def add_map_drop(string, amount, x=$game_player.x, y=$game_player.y, map_id=$game_map.map_id)
item = get_item(string)
return unless item
drop = Game_MapDrop.new(item, amount.abs, x, y, map_id)
$game_map.add_map_drop(map_id, drop)
end
end