# @taroxd metadata 1.0
# @display 事件脚本扩展
# @require taroxd_core
# @id event_helper
# @help 偷懒用的事件脚本。
# 添加了以下方法:
#
# Game_Interpreter
# this_event: 获取本事件。如果事件不在当前地图上,返回 nil。
# add_battlelog(text): 追加战斗信息。
# shake_for(power = 5, speed = 5) { block }:
# 震动画面直到 block 执行完毕。没有 block 时,画面会无限震动下去。
# 不要在 block 中 return。
# 如果一定需要的话,记得加上 stop_shake 来停止震动。
# stop_shake: 停止画面震动。
# self_switch
# self_switch(event_id)
# self_switch(event_id, map_id):
# 返回对应事件的 SelfSwitch 对象。
# fade_for(duration = 30) { block }:
# 淡出画面,执行 block 后淡入画面。
#
# SelfSwitch
# 由 Game_Interpreter#self_switch 获取。
# 方法:
# self[letter]:获取对应独立开关的值。letter: 'A'、'B'、'C'、'D' 之一。
# self[letter] = value:设置对应独立开关的值。
# 属性 a, b, c, d:分别代表对应的独立开关。
#
# Game_Switches/Game_Variables/Game_SelfSwitches
# clear / reset: 清空数据
#
# Game_CharacterBase
# zoom_x, zoom_y, angle, mirror, opacity, ox, oy 属性: 控制对应 Sprite 的属性。
# zoom=: 同时设置 zoom_x 与 zoom_y。
# force_pattern(pattern):
# 将行走图强制更改为对应的 pattern。
# pattern 从左到右分别为 0, 1, 2。
# 使用此功能时,建议勾选固定朝向,并且取消步行动画。
# force_bush_depth(depth = nil):
# 将人物的 bush_depth 属性固定为 depth,不受地形的影响。
# depth 为 nil 时取消固定
# lineto(x, y)
# 沿直线移动到 (x, y)。可用 moving? 判断是否正在移动中。
#
# Game_Character
# jump_to / jumpto(x, y): 跳跃至 x, y
#
# Game_Player
# waiting 属性:设为真值时,禁止玩家移动
# disable_scroll 属性:设为真值时,禁止地图卷动
#
# Game_Party
# +(gold), -(gold): 增加/减少金钱,并返回 self。
# <<(actor), <<(actor_id): 加入指定队员,并返回 self。
module Taroxd::EventHelper
# 定义了清除数据的方法
module ClearData
Game_Switches.send :include, self
Game_Variables.send :include, self
Game_SelfSwitches.send :include, self
def clear
@data.clear
on_change
self
end
alias_method :reset, :clear
end
# 代表独立开关的对象
SelfSwitch = Struct.new(:map_id, :event_id) do
def [](letter)
$game_self_switches[[map_id, event_id, letter]]
end
def []=(letter, value)
$game_self_switches[[map_id, event_id, letter]] = value
end
def a; self['A']; end
def b; self['B']; end
def c; self['C']; end
def d; self['D']; end
def a=(v); self['A'] = v; end
def b=(v); self['B'] = v; end
def c=(v); self['C'] = v; end
def d=(v); self['D'] = v; end
end
end
class Game_Interpreter
include Taroxd::EventHelper
def this_event
$game_map.events[@event_id] if same_map?
end
def add_battlelog(text)
if SceneManager.scene_is?(Scene_Battle)
SceneManager.scene.add_battlelog(text)
end
end
def self_switch(event_id = @event_id, map_id = @map_id)
SelfSwitch.new(map_id, event_id)
end
def stop_shake
screen.start_shake(0, 0, 0)
end
# 为了在事件解释器的 fiber 中使用,因此没有 ensure。
def shake_for(power = 5, speed = 5)
screen.start_shake(power, speed, Float::INFINITY)
return unless block_given?
yield
stop_shake
end
def fade_for(duration = 30)
Fiber.yield while $game_message.visible
screen.start_fadeout(duration)
wait(duration)
yield if block_given?
Fiber.yield while $game_message.visible
screen.start_fadein(duration)
wait(duration)
end
end
class Game_CharacterBase
attr_accessor :zoom_x, :zoom_y, :angle, :mirror, :opacity, :ox, :oy
def zoom=(zoom)
@zoom_x = @zoom_y = zoom
end
def force_pattern(pattern)
@original_pattern = @pattern = pattern
end
def force_bush_depth(depth = nil)
@force_bush_depth = depth
@bush_depth = depth if depth
end
def lineto(tx, ty)
theta = Math.atan2(ty - y, tx - x)
d = distance_per_frame
@x = tx
@y = ty
# distance per frame
@lineto_dpf = Taroxd::Point.new(d * Math.cos(theta), d * Math.sin(theta))
straighten
end
def update_lineto
@real_x = [@real_x - @lineto_dpf.x, @x].max if @x < @real_x
@real_x = [@real_x + @lineto_dpf.x, @x].min if @x > @real_x
@real_y = [@real_y - @lineto_dpf.y, @y].max if @y < @real_y
@real_y = [@real_y + @lineto_dpf.y, @y].min if @y > @real_y
if !moving?
@lineto_dpf = nil
update_bush_depth
end
end
def_unless(:update_bush_depth) { @force_bush_depth }
def_after(:update_move) { update_lineto if @lineto_dpf }
end
class Game_Character
def jumpto(tx, ty)
jump(tx - x, ty - y)
end
alias_method :jump_to, :jumpto
end
class Game_Player < Game_Character
attr_accessor :waiting, :disable_scroll
def_unless :movable?, :waiting
def_unless(:update_scroll) { |_, _| @disable_scroll }
end
class Game_Party < Game_Unit
def +(gold)
gain_gold(gold)
self
end
def -(gold)
lose_gold(gold)
self
end
def <<(actor)
add_actor(actor.id)
self
end
end
class Sprite_Character < Sprite_Base
# 更新对应属性
def_after :update_other do
self.ox = @character.ox if @character.ox
self.oy = @character.oy if @character.oy
self.zoom_x = @character.zoom_x if @character.zoom_x
self.zoom_y = @character.zoom_y if @character.zoom_y
self.angle = @character.angle if @character.angle
self.mirror = @character.mirror unless @character.mirror.nil?
end
end
class Scene_Battle < Scene_Base
def add_battlelog(text)
@log_window.add_text(text)
end
end