class << FileTest
# FileTest.exist? 无法判断含中文的文件路径……
def exist_ex?(filename)
return true if self.exist?(filename)
begin
IO.read(filename, 0)
return true
rescue
return false
end
end
end
module Key
# 主键盘的字母与数字键值的定义
10.times {|i| const_set("Num#{i}", 48 + i) }
65.upto(90) {|i| const_set(i.chr, i) }
GetAsyncKeyState = Win32API.new('user32', 'GetAsyncKeyState', 'I', 'I')
def self.trigger?(nVK)
return GetAsyncKeyState.call(nVK) == -32767
end
end
module Furniture
MAP_ID = 1
ADD_StateID = 29 #搬运家具
SUB_StateID = 30 #移除家具
Map_Key = Key::F
# 设置个名字的空公共事件
Common_EventID = 10
ItemID_map_GraphicName = {
38 => "$10_森林吊椅",
39 => "魔导书",
40 => "森林吊椅"
}
Log_Name = "furniture_config_log.txt" # 避免转码,英文文件名
# 是否检查 ItemID_map_GraphicName
Check_Settings = true
if Check_Settings == true
err = false
log = File.open(Log_Name, "w+")
log.write("Furniture::ItemID_map_GraphicName检查:\n")
time = Time.new.strftime("%Y/%m/%d--%H:%M:%S")
log.write(" #{time}\n")
path = "Graphics/Characters/"
items = load_data("Data/Items.rxdata")
ItemID_map_GraphicName.each do |id, name|
if items[id].common_event_id != Common_EventID
err = true
log.write(" 【#{id}:#{items[id].name}】 非家具物品\n")
else
filename = "#{path}#{name}.png"
unless FileTest.exist_ex?(filename)
err = true
log.write(" 【#{id}:#{items[id].name}】对应图形文件(\"#{filename}\")不存在\n")
end
end
end
if err == true
log.close
system("start #{Log_Name}")
else
log.write(" 家具物品对应图形文件设置正常。\n")
log.close
end
end
module_function
def carrying?
return $game_party.actors[0].state?(ADD_StateID)
end
def to_carry
$game_party.actors[0].add_state(ADD_StateID)
end
def carryed
$game_party.actors[0].remove_state(ADD_StateID)
end
def removing?
return $game_party.actors[0].state?(SUB_StateID)
end
def to_remove
$game_party.actors[0].add_state(SUB_StateID)
end
def removed
$game_party.actors[0].remove_state(SUB_StateID)
end
def event_trigger?
return Key.trigger?(Map_Key)
end
end
class Game_SelfSwitches
attr_reader :data
end
class Game_Player < Game_Character
attr_accessor :furniture_data
def store_graphic_data(new_character_name, new_character_hue)
@last_character_name = @character_name
@last_character_hue = @charcter_hue
@character_name = new_character_name
@character_hue = new_character_hue
end
def restore_graphic
if @last_character_name != nil
@character_name = @last_character_name
@last_character_name = nil
end
if @last_charcter_hue != nil
@character_hue = @last_charcter_hue
@last_charcter_hue = nil
end
end
end
class Scene_Item
def update_item
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
$scene = Scene_Menu.new(0)
return
end
if Input.trigger?(Input::C)
@item = @item_window.item
unless @item.is_a?(RPG::Item)
$game_system.se_play($data_system.buzzer_se)
return
end
#————————————————————
if @item.common_event_id == Furniture::Common_EventID
if Furniture.carrying?
$game_system.se_play($data_system.cancel_se)
else
if $game_map.map_id == Furniture::MAP_ID
$game_system.se_play(@item.menu_se)
if @item.consumable
$game_party.lose_item(@item.id, 1)
@item_window.draw_item(@item_window.index)
end
$game_player.furniture_data = @item.id
Furniture.to_carry
$game_player.store_graphic_data(
Furniture::ItemID_map_GraphicName[@item.id], 0)
else
$game_system.se_play($data_system.cancel_se)
$game_temp.message_proc = Proc.new { @message_waiting = false }
$game_temp.message_text = "此处不能使用家具。"
end
$scene = Scene_Map.new
end
return
end
#————————————————————
unless $game_party.item_can_use?(@item.id)
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.decision_se)
if @item.scope >= 3
@item_window.active = false
@target_window.x = (@item_window.index + 1) % 2 * 304
@target_window.visible = true
@target_window.active = true
if @item.scope == 4 || @item.scope == 6
@target_window.index = -1
else
@target_window.index = 0
end
else
if @item.common_event_id > 0
$game_temp.common_event_id = @item.common_event_id
$game_system.se_play(@item.menu_se)
if @item.consumable
$game_party.lose_item(@item.id, 1)
@item_window.draw_item(@item_window.index)
end
$scene = Scene_Map.new
return
end
end
return
end
end
end
class Sprite_Furniture < Sprite
# 图形是否“停止时动画”,以Graphic.frame_count为单位
# "$0_魔导书" 或 "魔导书" => 无动画
# "$10_魔导书" => 有动画
Anime_Reg = /^\$(\d+)_/
attr_reader :anime_count
def initialize(viewport, map_x, map_y, direction, pattern, hue, filename)
super(viewport)
self.graphic_set(direction, pattern, hue, filename)
@real_x, @real_y = map_x * 128, map_y * 128
end
def graphic_set(direction, pattern, hue, filename)
self.bitmap = RPG::Cache.character(filename, hue)
w, h = self.bitmap.width / 4, self.bitmap.height / 4
self.src_rect.set(pattern * w, (direction / 2 - 1) * h, w, h)
self.ox, self.oy = w / 2, h
@real_z = h > 32 ? 31 : 0
if (Anime_Reg =~ filename) != nil
@anime_count = $1.to_i
else
@anime_count = 0
end
end
def update_self
self.x = (@real_x - $game_map.display_x + 3) / 4 + 16
self.y = (@real_y - $game_map.display_y + 3) / 4 + 32
self.z = self.y + @real_z
if @anime_count > 0
if Graphics.frame_count % @anime_count == 0
self.src_rect.x =
(self.src_rect.x + self.src_rect.width) % (self.src_rect.width * 4)
end
end
end
end
class Spriteset_Map
#--------------------------------------------------------------------------
# ● 初始化对像
#--------------------------------------------------------------------------
def initialize
# 生成显示端口
@viewport1 = Viewport.new(0, 0, 640, 480)
@viewport2 = Viewport.new(0, 0, 640, 480)
@viewport3 = Viewport.new(0, 0, 640, 480)
@viewport2.z = 200
@viewport3.z = 5000
# 生成元件地图
@tilemap = Tilemap.new(@viewport1)
@tilemap.tileset = RPG::Cache.tileset($game_map.tileset_name)
for i in 0..6
autotile_name = $game_map.autotile_names[i]
@tilemap.autotiles[i] = RPG::Cache.autotile(autotile_name)
end
@tilemap.map_data = $game_map.data
@tilemap.priorities = $game_map.priorities
# 生成远景平面
@panorama = Plane.new(@viewport1)
@panorama.z = -1000
# 生成雾平面
@fog = Plane.new(@viewport1)
@fog.z = 3000
# 生成角色活动块
@character_sprites = []
for i in $game_map.events.keys.sort
sprite = Sprite_Character.new(@viewport1, $game_map.events[i])
@character_sprites.push(sprite)
end
@character_sprites.push(Sprite_Character.new(@viewport1, $game_player))
# 生成天气
@weather = RPG::Weather.new(@viewport1)
# 生成图片
@picture_sprites = []
for i in 1..50
@picture_sprites.push(Sprite_Picture.new(@viewport2,
$game_screen.pictures[i]))
end
# 生成计时器块
@timer_sprite = Sprite_Timer.new
#————————————————————
if $game_map.map_id == Furniture::MAP_ID
@data = ($game_self_switches.data[$game_map.map_id] ||= {})
@furniture_sprites = {}
@data.each do |k, v|
@furniture_sprites[k & 0x3FFF] = Sprite_Furniture.new(@viewport1,
(k >> 9) & 0x1FF, k & 0x1FF, *v.unpack('C3A*'))
end
end
#————————————————————
# 刷新画面
update
end
def add_furniture(dir, pattern, hue, name)
key = $game_player.x << 9 | $game_player.y
sprite = @furniture_sprites[key]
if sprite != nil
sprite.graphic_set(dir, pattern, hue, name)
else
@furniture_sprites[key] = Sprite_Furniture.new(@viewport1,
$game_player.x, $game_player.y, dir, pattern, hue, name)
end
@data[key | $game_map.map_id<<18] = [dir, pattern, hue, name].pack('C3A*')
end
def sub_furniture
key = $game_player.x << 9 | $game_player.y
@data.delete(key | $game_map.map_id << 18)
@furniture_sprites[key].dispose
@furniture_sprites.delete(key)
end
def update_furniture
if Furniture.event_trigger?
key = $game_map.map_id << 18 | $game_player.x << 9 | $game_player.y
if Furniture.removing?
return unless @data.key?(key)
$game_temp.message_text = "是否移除次家具?\n是\n否\n"
effective = true
$game_temp.choice_proc = Proc.new do |n|
if n == 0
self.sub_furniture
Furniture.removed
end
end
elsif Furniture.carrying?
return if $game_player.furniture_data == nil
$game_temp.message_text = "是否将家具放置在这里?\n是\n否\n"
effective = true
$game_temp.choice_proc = Proc.new do |n|
if n == 0
self.add_furniture(2, 0, 0, $game_player.character_name)
$game_player.restore_graphic
$game_player.move_backward
Furniture.carryed
$game_player.furniture_data = nil
end
end
end
if effective == true
$game_temp.message_proc = Proc.new { @message_waiting = false }
$game_temp.choice_start = 1
$game_temp.choice_max = 2
$game_temp.choice_cancel_type = 0
end
end
@furniture_sprites.each{|k, sprite| sprite.update_self }
end
#--------------------------------------------------------------------------
# ● 刷新画面
#--------------------------------------------------------------------------
def update
# 远景与现在的情况有差异发生的情况下
if @panorama_name != $game_map.panorama_name or
@panorama_hue != $game_map.panorama_hue
@panorama_name = $game_map.panorama_name
@panorama_hue = $game_map.panorama_hue
if @panorama.bitmap != nil
@panorama.bitmap.dispose
@panorama.bitmap = nil
end
if @panorama_name != ""
@panorama.bitmap = RPG::Cache.panorama(@panorama_name, @panorama_hue)
end
Graphics.frame_reset
end
# 雾与现在的情况有差异的情况下
if @fog_name != $game_map.fog_name or @fog_hue != $game_map.fog_hue
@fog_name = $game_map.fog_name
@fog_hue = $game_map.fog_hue
if @fog.bitmap != nil
@fog.bitmap.dispose
@fog.bitmap = nil
end
if @fog_name != ""
@fog.bitmap = RPG::Cache.fog(@fog_name, @fog_hue)
end
Graphics.frame_reset
end
# 刷新元件地图
@tilemap.ox = $game_map.display_x / 4
@tilemap.oy = $game_map.display_y / 4
@tilemap.update
# 刷新远景平面
@panorama.ox = $game_map.display_x / 8
@panorama.oy = $game_map.display_y / 8
# 刷新雾平面
@fog.zoom_x = $game_map.fog_zoom / 100.0
@fog.zoom_y = $game_map.fog_zoom / 100.0
@fog.opacity = $game_map.fog_opacity
@fog.blend_type = $game_map.fog_blend_type
@fog.ox = $game_map.display_x / 4 + $game_map.fog_ox
@fog.oy = $game_map.display_y / 4 + $game_map.fog_oy
@fog.tone = $game_map.fog_tone
# 刷新角色活动块
for sprite in @character_sprites
sprite.update
end
#————————————————————
self.update_furniture if $game_map.map_id == Furniture::MAP_ID
#————————————————————
# 刷新天候图形
@weather.type = $game_screen.weather_type
@weather.max = $game_screen.weather_max
@weather.ox = $game_map.display_x / 4
@weather.oy = $game_map.display_y / 4
@weather.update
# 刷新图片
for sprite in @picture_sprites
sprite.update
end
# 刷新计时器块
@timer_sprite.update
# 设置画面的色调与震动位置
@viewport1.tone = $game_screen.tone
@viewport1.ox = $game_screen.shake
# 设置画面的闪烁色
@viewport3.color = $game_screen.flash_color
# 刷新显示端口
@viewport1.update
@viewport3.update
end
end