#-----------------------------------------------------------------------------
# 游戏任务事件对象
#-----------------------------------------------------------------------------
class Game_EventVariables
attr_accessor :Chapter #进行了的章节
attr_accessor :Last_Chapter #正在进行的章节
def initialize
@Chapter = []
@Last_Chapter = -1
end
# 新的一章开始时调用
# 此调用必须!! 否则保存的事件薄数据将会错误
# 最好在新章节开始时过场事件内调用
def StartChapter(name)
chapter = EventBookDef.getChapter(name)
if !EventBookDef.has_Chapter?(chapter.id)
msgbox("使用了未定义的章节名<#{name}>")
return
end
if @Chapter.include?(chapter.id)
msgbox("已经进行过了此章节<#{name}>")
return
end
@Chapter[chapter.id] = Game_SaveChapter.new(chapter.id)
@Last_Chapter = chapter.id
end
# 获得一个案件的线索时调用 传入案件名字以及对应的线索名字
def FindKey(caseName,keyName)
chapter = EventBookDef.getChapterByIndex(@Last_Chapter)
if chapter == nil
msgbox("获得线索时未找到当前章节,确认是否在章节开始时调用过StartChapter脚本")
return
end
caseName.gsub!(/\n/) {""} #去掉脚本输入框带来的\n
caseTemp = chapter.getCase(caseName)
if caseTemp == nil
msgbox("未在当前章节找到案件<#{caseName}>")
return
end
keyName.gsub!(/\n/) {""} #去掉脚本输入框带来的\n
keyIndex = caseTemp.getKeyIndex(keyName)
if keyIndex == -1
msgbox("未在当前章节案件<#{caseName}>中找到线索<#{keyName}>")
return
end
@Chapter[@Last_Chapter].getCase(caseTemp.id).addKey(keyIndex)
end
end
# 用来保存的数据
class Game_SaveChapter
attr_accessor :id
attr_accessor :case
def initialize(id)
@id = id
@case = [] # 正在进行中的案件,保存index
end
def getCase(index)
return @case[index] if @case.size > index
@case[index] = Game_SaveCase.new(index)
return @case[index]
end
end
class Game_SaveCase
attr_accessor :id
attr_accessor :Keys # 已获得的Key,保存index
def initialize(id)
@id = id
@Keys = []
end
def addKey(key_id)
@Keys.push key_id unless @Keys.include?(key_id)
end
end
# 用来显示的数据
class Game_Chapter
attr_accessor :name
attr_accessor :id
def initialize(name,id)
@name = name
@id = id
@case = {}
end
def addCase(name)
return @case[name] if @case.include?(name)
@case[name] = Game_Case.new(name,@case.size)
end
def getCase(name)
return nil unless @case.include?(name)
return @case[name]
end
def getCaseName(index)
@case.each { |p| return p[1].name if p[1].id == index}
return "未知案件"
end
end
class Game_Case
attr_accessor :name
attr_accessor :id
def initialize(name,id)
@name = name
@id = id
[url=home.php?mod=space&uid=20462]@KEY[/url] = []
end
def Key(index)
return nil unless @key.size > index
return @key[index]
end
def addKey(keyname, keydetail)
@key.each{|p| return if p.name == keyname }
@key.push(Game_EventKey.new(keyname,keydetail))
end
def getKeyIndex(keyname)
i = 0
until i >= @key.size
return i if @key[i].name == keyname
i += 1
end
return -1
end
end
class Game_EventKey
attr_accessor :name
attr_accessor :detail
def initialize(name,detail)
@name = name
@detail = detail
end
end
#-----------------------------------------------------------------------------
# 事件薄系统宏
#-----------------------------------------------------------------------------
module EventBookDef
def self.init()
@Chapter = {}
create_all_chapter
@ChapterCount = @Chapter.size
end
Menu = "事件薄"
# 文件存放路径
ResFolder = "Graphics/EventBook/"
# 事件薄封面图
ResCover = "cover"
# 标签图
ResTag = "tag"
# 事件薄侧标签最大显示个数
BookTagPreCount = 5
# 这里最好自己用注释做一些分类,按章节,按案件内容随个人喜好, 这里并不需要顺序的添加
# 章节里线索信息
def self.create_all_chapter
addKey("章节1","案件1","线索1","看看这里能不能编辑需要显示的文字,看看这里能不能编辑需要显示的
文字.看看这里能不能编辑需要显示的文字,看看这里能不能编辑需要
显示的文字")
addKey("章节1","案件1","线索2","测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行")
addKey("章节1","案件1","线索3","测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行")
addKey("章节1","案件2","线索1","测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行")
addKey("章节1","案件2","线索1","测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行")
addKey("章节1","案件2","线索1","测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行")
addKey("章节1","案件3","线索1","测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行测试多行")
end
def self.addChapter(chapter)
@Chapter[chapter] = Game_Chapter.new(chapter,@Chapter.size) unless @Chapter.include?(chapter)
return @Chapter[chapter]
end
def self.getChapter(chapter)
return @Chapter[chapter] if @Chapter.include?(chapter)
return addChapter(chapter)
end
def self.has_Chapter?(index)
@ChapterCount > index
end
def self.getChapterByIndex(index)
@Chapter.each do |p|
return p[1] if p[1].id == index
end
return nil
end
def self.getChapterName(index)
@Chapter.each do |p|
return p[1].name if p[1].id == index
end
return "未知章节"
end
def self.getCaseName(chapter,case_id)
return "未知案件" unless @Chapter.include?(chapter)
return @Chapter[chapter].getCaseName(case_id)
end
def self.addKey(chapter,_case,key,detail)
getChapter(chapter).addCase(_case).addKey(key,detail)
end
def self.setDetailData(data)
@detailData = data
end
def self.getDetailData()
return @detailData
end
PointText = "..."
end
#-----------------------------------------------------------------------------
# 事件薄主界面
#-----------------------------------------------------------------------------
# 事件薄标签
class EventNoteTag < Sprite
attr_accessor:info
def initialize(viewport = nil)
super(viewport)
create_tag
end
def dispose
self.bitmap.dispose if bitmap
super
end
def selected
self.zoom_x = 1.1
self.zoom_y = 1.1
end
def unselected
self.zoom_x = 1
self.zoom_y = 1
end
def create_tag
self.bitmap = Cache.load_bitmap(EventBookDef::ResFolder,EventBookDef::ResTag).clone
end
def setPos(x,y)
self.x = x
self.y = y
end
def update
super
end
def info=(info)
@info = info
update_info
end
def update_info
#self.contents.draw_text(self.bitmap.rect,"",1)
self.bitmap.clear
self.bitmap = Cache.load_bitmap(EventBookDef::ResFolder,EventBookDef::ResTag).clone
self.bitmap.draw_text(self.bitmap.rect,info,1)
end
end
# 事件薄标签菜单
class EventNoteMenu < Window
attr_accessor:preCount #一页可显示标签数
attr_accessor:index #当前光标所在位置
attr_reader:startIndex #当前页开始位置
attr_reader:endIndex #当前页结束位置
def initialize(preCount = 1,x,y,w,h)
super(x,y,w,h)
@preCount = preCount
@viewport = Viewport.new
@tags = []
@tagsData = []
@pointTag = []
@index = -1
@last_index = -2
@maxSize = 0
@startIndex = 0
@last_startIndex = -1
@maxSize > @preCount ? @endIndex = @preCount : @endIndex = @maxSize
create_onePageTags
create_pointTags
update_tagsContent
update_tags
#select(0)
end
def dispose
@viewport.dispose if @viewport
super
end
def create_onePageTags
count = 0
until count == @preCount || count == @maxSize
@tags.push(EventNoteTag.new(@viewport))
count+=1
end
@startIndex = 0 if @maxSize
end
def create_pointTags
return unless @maxSize > @preCount
@pointTag[0] = EventNoteTag.new(@viewport)
@pointTag[0].x = x
@pointTag[0].y = y
@pointTag[0].info = EventBookDef::PointText
@pointTag[1] = EventNoteTag.new(@viewport)
@pointTag[1].info = EventBookDef::PointText
@pointTag[1].x = x
@pointTag[1].y = y
end
def setData(tagsData)
@tagsData.clear if @tagsData
@tagsData = tagsData
@maxSize = @tagsData.size
@maxSize > @preCount ? @endIndex = @preCount : @endIndex = @maxSize
@tags.each {|tag| tag.dispose}
@tags.clear
@pointTag.each{|tag| tag.dispose }
@pointTag.clear
create_onePageTags
create_pointTags
update_tagsContent
@index = -1
@last_index = -2
update_tags
select(0)
end
def getData
return @tagsData[@startIndex + @index] if @index && @startIndex
return nil
end
def cursor_movable?
@index >= 0 && @index < @preCount
end
def cursor_up(wrap = false)
@index -= 1
select(@index)
end
def cursor_down(wrap = false)
@index += 1
select(@index)
end
def pageUp
@index -= @preCount
select([@index,@startIndex].max)
end
def pageDown
@index += @preCount
select([@index,@endIndex].min)
end
def select(index)
return unless @maxSize != 0
@index = index
if @index < 0
if @startIndex > 0
@startIndex -= 1
@endIndex -= 1
else
Sound.play_buzzer
end
@index = 0
update_tagsContent
Sound.play_cursor
else
if @index == (@endIndex - @startIndex)
if @endIndex != @maxSize
@startIndex += 1
@endIndex += 1
else
Sound.play_buzzer
end
@index -= 1
update_tagsContent
Sound.play_cursor
end
end
@tags[@index].selected if @index >= 0
@tags[@last_index].unselected if @last_index >= 0 && @index != @last_index
update_tags
end
def process_cursor_move
return unless cursor_movable?
@last_index = @index
cursor_down (Input.trigger?(:DOWN)) if Input.repeat?(:DOWN)
cursor_up (Input.trigger?(:UP)) if Input.repeat?(:UP)
pageUp if Input.trigger?(:R)
pageDown if Input.trigger?(:L)
Sound.play_cursor if @index != @last_index
end
def update
super
process_cursor_move
end
def update_tags
#return unless @index != @last_index
index = 0
height = 0
until index == @preCount || index == @maxSize
@tags[index].setPos(x,(index+1) * @tags[index].height + y) if index != @index
@tags[index].setPos(x, @tags[index-1].height * index+@tags[index].height + y) if index > 0
height = @tags[index].y
index += 1
end
update_pointTags(height)
end
def update_pointTags(height)
return unless @maxSize > @preCount
@startIndex == 0 ? @pointTag[0].visible = false : @pointTag[0].visible = true
@endIndex == @maxSize ? @pointTag[1].visible = false : @pointTag[1].visible = true
@pointTag[1].setPos(x,height+@pointTag[1].height)
end
def update_tagsContent
index = 0
until index == @preCount || index == @maxSize
@tags[index].info = @tagsData[@startIndex + index][:text]
index += 1
end
end
end
#--------------------------------------------------------------------------------
# 事件薄详细内容窗口
#--------------------------------------------------------------------------------
class Window_EventBook < Window_Selectable
#--------------------------------------------------------------------------
# ● 定义实例变量
#--------------------------------------------------------------------------
attr_accessor :BGSprite
attr_accessor :type
def initialize
@BGSprite = Sprite.new(Viewport.new)
@BGSprite.bitmap = Cache.load_bitmap(EventBookDef::ResFolder,EventBookDef::ResCover)
bitmapTemp = Cache.load_bitmap(EventBookDef::ResFolder,EventBookDef::ResTag)
if @BGSprite != nil
super(([email]Graphics.width-@BGSprite.width[/email] - bitmapTemp.width)/2,(Graphics.height - @BGSprite.height)/2, @BGSprite.width, @BGSprite.height)
else
super(([email]Graphics.width-@BGSprite.width[/email] - bitmapTemp.width)/2,(Graphics.height - @BGSprite.height)/2, Graphics.width, Graphics.height)
end
@BGSprite.x = self.x
@BGSprite.y = self.y
self.windowskin = nil
preCount = EventBookDef::BookTagPreCount + 2#@BGSprite.height / bitmapTemp.height
book_x = x + @BGSprite.width
book_y = y + (@BGSprite.height - bitmapTemp.height*preCount)/2
preCount -= 2 #这里减去上下翻页提示数量
@book_menu = EventNoteMenu.new(preCount,book_x,book_y,bitmapTemp.width,bitmapTemp.height*preCount)
bitmapTemp.dispose
@type = 0
@dirty = true
activate
end
def Type?(type)
@type == type
end
def type=(type)
@type = type
@dirty = true
end
def switchChapters
return unless @book_menu != nil
if @type == 0 && @dirty
data = []
i = 0
if $game_eventVar.Last_Chapter == -1
msgbox("未调用任何StartChapter")
@dirty = false
return
end
until i > $game_eventVar.Last_Chapter
data.push({:text=>EventBookDef.getChapterByIndex(i).name,:context => i})
i+=1
end
@book_menu.setData(data)
@dirty = false
end
end
def switchEvent
return unless @book_menu != nil
if @type == 1 && @dirty
@dirty = false
data = []
@chapter = @book_menu.getData
if @chapter == nil
@type = 0
Sound.play_buzzer
return
end
caseTemp = $game_eventVar.Chapter[@book_menu.getData[:context]].case
if caseTemp.size == 0
@type = 0
Sound.play_buzzer
return
end
caseTemp.each {|p| data.push({:text=>EventBookDef.getCaseName(@chapter[:text],p.id),:context=>p.id})}
@book_menu.setData(data)
end
end
def update
super
@book_menu.update
switchChapters
switchEvent
end
def selectEvent
data = {:chapter=>@chapter,:case=>@book_menu.getData}
EventBookDef.setDetailData(data)
end
end
#-------------------------------------------------------------------------
# 事件薄界面
#-------------------------------------------------------------------------
class Scene_EventBook < Scene_MenuBase
def start
super
create_book
end
def create_book
@book_window = Window_EventBook.new
@book_window.set_handler(:cancel, method(:on_cancel))
@book_window.set_handler(:ok, method(:on_ok))
end
def on_cancel
case @book_window.type
when 1
@book_window.type = 0
@book_window.activate
when 0
return_scene
end
end
def on_ok
case @book_window.type
when 0
@book_window.type = 1
@book_window.activate
when 1
@book_window.selectEvent
SceneManager.call(Scene_EventDetail)
end
end
end
#------------------------------------------------------------------------------
# 事件薄案件详细内容场景
#------------------------------------------------------------------------------
class Scene_EventDetail < Scene_Base
def start
super
create_detailWindow
end
def create_detailWindow
@detail_window = Window_EventDetail.new()
@detail_window.set_handler(:cancel,method(:return_scene))
end
end
#------------------------------------------------------------------------------
# 事件薄案件详细内容窗口
#------------------------------------------------------------------------------
class Window_EventDetail < Window_Selectable
def initialize
super(0, 0, Graphics.width, Graphics.height)
@data = EventBookDef.getDetailData
@line = 0
create_tile
create_key_content
activate
end
def create_tile
str = @data[:case][:text]
p str
draw_text_ex((Graphics.width-text_size(str).width)/2,Font.default_size * @line,str)
@line += 1
end
def create_key_content
# 画线索的名字
chapter = @data[:chapter]
castTemp = $game_eventVar.Chapter[chapter[:context]].getCase(@data[:case][:context])
i = 0
until i >= castTemp.Keys.size
chapterIns = EventBookDef.getChapterByIndex(chapter[:context])
caseIns = chapterIns.getCase(@data[:case][:text])
keyIns = caseIns.Key(castTemp.Keys[i])
draw_text_ex(4, Font.default_size*@line,keyIns.name)
@line += 1
draw_text_ex(20,Font.default_size*@line,keyIns.detail)
@line += 1
i+=1
end
end
# 难道需要自动换行?
#--------------------------------------------------------------------------
# ● 文字的处理
# c : 文字
# text : 绘制处理中的字符串缓存(字符串可能会被修改)
# pos : 绘制位置 {:x, :y, :new_x, :height}
#--------------------------------------------------------------------------
alias parent_process_character process_character
def process_character(c, text, pos)
case c
when "\r" # 回车
return
when "\n" # 换行
return
when "\f" # 翻页
return
when "\e" # 控制符
process_escape_character(obtain_escape_code(text), text, pos)
else # 普通文字
process_normal_character(c,pos)
process_next_character(text.slice(0,1),text,pos)
end
end
def process_next_character(c,text,pos)
case c
when "\r"
return
when "\n"
return
when "\f"
return
when "\e"
return
else
next_pos = pos[:x] + text_size(c).width * 2 + self.padding
if next_pos > width
process_new_line(text,pos)
@line += 1
end
end
end
end