=begin
事件管理器+事件复制功能
2014/2/4 v1.2 添加复制事件保存功能
2013/12/13 v1.1 bug 修正
功能
1. 优化默认脚本事件运行效率
2. 可以从其它地图复制事件;删除事件等
使用说明
v1.2 新增
save_copy_events
保存从其它地图复制过来的事件
remove_all_copy_events
移除该地图全部从其它地图复制过来的事件,保存的事件也删除
v1.1
copy_map_event(map_id, event_id, x, y)
复制特定地图的特定事件 到坐标 x y
如果 x y 坐标不填,事件就复制到原本的坐标
例 copy_map_event(2, 1) # 复制地图2的事件1到它原本地图的坐标
copy_map_event(3, 2, 0, 0) # 复制地图3的事件2到坐标(0,0)
关于独立开关
现在每个“复制事件”有各自的独立开关
“复制事件”的独立开关优先级高于“源事件”的独立开关
也就是说一旦通过“复制事件”操作独立开关,“源事件”的独立开关就不再
对“复制事件”有效了
要开/关“源事件”的某个独立开关可以用脚本
$game_self_switch[[map_id, event_id, "A"]] = true / false
remove_copy_event(map_id, event_id)
移除从特定地图复制过来的事件,如果复制了多个则全部移除
需要一个一个移除使用下面的方法
remove_map_event(事件id)
移除指定id的事件
复制过来的事件id为 当前地图事件id最大值 + 1
=end
class Game_Event
attr_reader\
:copy_id,
:map_id
attr_accessor\
:copy_self_switch
# 开始 >-------
# 默认脚本距离屏幕比较远的事件是不会自主移动的
# 这段脚本让全屏的事件都可以按照设置好的自身移动路线前进,如果静止的事件比较多会
# 比较省资源。如果不需要这个功能,就删除 开始 ~ 结束 之间的脚本
def update_self_movement
if @stop_count > stop_count_threshold
case @move_type
when 1; move_type_random
when 2; move_type_toward_player
when 3; move_type_custom
end
end
end
# 结束 -------<
def event_copy_setup(id, x, y)
@copy_id = @id
@id = id
moveto(x, y) if x && y
end
def update #覆盖
super
check_event_trigger_auto
return unless @interpreter
@interpreter.setup(@list, @id) unless @interpreter.running? #@event.id-@id
@interpreter.update
end
def conditions_met?(page) #覆盖
c = page.condition
if c.switch1_valid
return false unless $game_switches[c.switch1_id]
end
if c.switch2_valid
return false unless $game_switches[c.switch2_id]
end
if c.variable_valid
return false if $game_variables[c.variable_id] < c.variable_value
end
if c.self_switch_valid #改了这里
return false unless @copy_self_switch ?
@copy_self_switch[c.self_switch_ch] :
$game_self_switches[[@map_id, @event.id, c.self_switch_ch]]
end
if c.item_valid
item = $data_items[c.item_id]
return false unless $game_party.has_item?(item)
end
if c.actor_valid
actor = $game_actors[c.actor_id]
return false unless $game_party.members.include?(actor)
end
return true
end
alias_method :sEventManager_init_public_members, :init_public_members
def init_public_members #覆盖
@gridding = $game_map.gridding
sEventManager_init_public_members
end
def moveto(x, y) #修改父类方法
gridding_remove
super
gridding_insert
end
def move_straight(d, turn_ok = true) #修改父类方法
gridding_remove
super
gridding_insert
end
def move_diagonal(horz, vert) #修改父类方法
gridding_remove
super
gridding_insert
end
def gridding_remove
@gridding[@x][@y].delete(self)
end
def gridding_insert
@gridding[@x][@y].push(self)
end
#
def saved_copy_load
@gridding = $game_map.gridding
gridding_insert
end
end
class Game_Map
attr_reader\
:copy_map_events,
:gridding
def prepare_copy_event(event)
@copy_map_events ||= {}
@copy_map_events[event] = true
end
def prepare_remove_event(event)
@copy_map_events ||= {}
event.gridding_remove
@copy_map_events[event] = false
end
alias_method :sEventManager_update_events, :update_events
def update_events
sEventManager_update_events
if @copy_map_events
delete_ids = []
in_map = SceneManager.scene_is?(Scene_Map)
@copy_map_events.each {|event, copy|
if copy
@events[event.id] = event
SceneManager.scene.spriteset.add_event_sprite(event) if in_map
else
delete_ids.push(event.id)
SceneManager.scene.spriteset.remove_event_sprite(event) if in_map
end
}
delete_ids.each {|id| @events.delete(id)}
@copy_map_events = nil
end
end
alias_method :sEventManager_setup_events, :setup_events
def setup_events
@saved_copy_events ||= {}
@gridding = Array.new(width + 1) { Array.new(height + 1) {[]} }
sEventManager_setup_events
load_saved_copy_events
end
#
def refresh_tile_events #覆盖
end
def events_xy(x, y) #覆盖
@gridding[x][y]
end
def events_xy_nt(x, y) #覆盖
@gridding[x][y].select {|event| !event.through}
end
def tile_events_xy(x, y) #覆盖
@gridding[x][y].select {|event| event.tile? && !event.through}
end
def event_id_xy(x, y) #覆盖
list = events_xy(x, y)
list.empty? ? 0 : list[0].id
end
# 保存复制的事件
def save_copy_events
copy_events = []
@events.each_value {|event| copy_events.push(event) if event.copy_id}
@saved_copy_events[@map_id] = copy_events
end
# 读取保存的复制事件
def load_saved_copy_events
saved_copy_events = @saved_copy_events[@map_id]
saved_copy_events.each {|event|
event.saved_copy_load
@events[event.id] = event
} if saved_copy_events
end
# 移除所有复制事件
def remove_all_copy_events
@events.each_value {|event|
$game_map.prepare_remove_event(event) if event.copy_id
}
@saved_copy_events.delete @map_id
end
end
# 事件页脚本添加复制事件功能
class Game_Interpreter
def copy_map_event(map_id, event_id, x = nil, y = nil)
map_filename = sprintf("Data/Map%03d.rvdata2", map_id)
if File.exist?(map_filename)
event = load_data(map_filename).events[event_id]
if event
event = Game_Event.new(map_id, event)
event_id = $game_map.events.keys.max + 1
event_id += $game_map.copy_map_events.size if $game_map.copy_map_events
event.event_copy_setup(event_id, x, y)
$game_map.prepare_copy_event(event)
elsif $TEST
msgbox("复制<地图#{map_id}>的<事件#{event_id}>失败,该事件不存在。")
exit
end
elsif $TEST
msgbox("从<地图#{map_id}>复制事件失败,该地图不存在。")
exit
end
end
#
def save_copy_events
$game_map.save_copy_events
end
def remove_all_copy_events
$game_map.remove_all_copy_events
end
def remove_copy_event(map_id, event_id)
$game_map.events.each_value {|event|
if event.copy_id == event_id && event.map_id == map_id
$game_map.prepare_remove_event(event)
end
}
end
def remove_map_event(event_id)
event = $game_map.events[event_id]
$game_map.prepare_remove_event(event) if event
end
#
alias_method :sEventManager_command_123, :command_123
def command_123
if @event_id > 0
event = get_character(@event_id)
event.copy_id ?
process_copy_self_switch(event) :
sEventManager_command_123
end
end
def process_copy_self_switch(event)
event.copy_self_switch ||= {}
event.copy_self_switch[@params[0]] = (@params[1] == 0)
all_off = true
event.copy_self_switch.each_value {|key| break all_off = false if key}
event.copy_self_switch = nil if all_off
$game_map.need_refresh = true
end
end
#
# 精灵管理
class Spriteset_Map
EventRadius = 1
def add_event_sprite(event)
@events_sprites[event] = nil
end
def remove_event_sprite(event)
sprite = @events_sprites.delete(event)
sprite.dispose if sprite
end
alias_method :sEventManager_create_characters, :create_characters
def create_characters
sEventManager_create_characters
setup_event_sprites
end
def setup_event_sprites
@events_sprites = {}
@character_sprites.each {|sp|
@events_sprites[sp.character] = sp if sp.character.class == Game_Event
}
@events_sprites.each_value {|sp| @character_sprites.delete(sp)}
end
alias_method :sEventManager_dispose_characters, :dispose_characters
def dispose_characters
@events_sprites.each_value {|sprite| sprite.dispose if sprite}
sEventManager_dispose_characters
end
alias_method :sEventManager_update_characters, :update_characters
def update_characters
sEventManager_update_characters
update_event_sprites
end
def update_event_sprites
ox = $game_map.display_x - EventRadius
ex = $game_map.display_x + Graphics.width / 32.0 + EventRadius - 1
oy = $game_map.display_y - EventRadius
ey = $game_map.display_y + Graphics.height / 32.0 + EventRadius - 0.875
mw = $game_map.width
mh = $game_map.height
lv = $game_map.loop_vertical?
lh = $game_map.loop_horizontal?
@events_sprites.each {|event, sprite|
x = event.real_x
y = event.real_y
if (x > ox && x < ex || lv && x + mw > ox && x + mw < ex) &&
(y > oy && y < ey || lh && y + mh > oy && y + mh < ey)
sprite ? sprite.update :
@events_sprites[event] = Sprite_Character.new(@viewport1, event)
elsif sprite
sprite.dispose
@events_sprites[event] = nil
end
}
end
end
class Scene_Map
attr_reader :spriteset
end