# @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
事件脚本扩展
事件寻路
# @taroxd metadata 1.0
# @id event_astar
# @require taroxd_core
# @require astar
# @display 事件寻路
Taroxd::EventAStar = true
class Game_Character < Game_CharacterBase
def find_path_toward(x, y)
return @find_path if @find_path_xy == [x, y, @x, @y]
@find_path = Taroxd::AStar.path(self, x, y)
@find_path_xy = x, y, @x, @y
@find_path
end
# 保留原方法,以备需要的时候使用。
alias_method :move_toward_character_directly, :move_toward_character
def move_toward_character(character)
dir = find_path_toward(character.x, character.y).shift
return move_toward_character_directly(character) unless dir
move_straight(dir)
@find_path_xy[2, 2] = @x, @y if @move_succeed
end
# 使用此方法 require 坐标类
def move_toward_point(x, y)
move_toward_character Taroxd::Point[x, y]
end
end
class Game_Event < Game_Character
alias_method :move_type_toward_player, :move_toward_player
end
脚本快捷方式
# @taroxd metadata 1.0
# @require taroxd_core
# @id eval
# @display 脚本快捷方式
# @deprecated
module Taroxd::Eval
Game_Character.send :include, self
Game_Interpreter.send :include, self
# 脚本中的简称列表
SCRIPT_ABBR_LIST = {
'V' => '$game_variables',
'S' => '$game_switches',
'N' => '$game_actors',
'A' => '$game_actors',
'P' => '$game_party',
'G' => '$game_party.gold',
'E' => '$game_troop'
}
# 处理脚本用的正则表达式
words = SCRIPT_ABBR_LIST.keys.join('|')
SCRIPT_ABBR_RE = /(?<!::|['"\\\.])\b(?:#{words})\b(?! *[(@$\w'"])/
module_function
def process_script(script)
script.gsub(SCRIPT_ABBR_RE, SCRIPT_ABBR_LIST)
end
def eval(script, *args)
v = $game_variables
s = $game_switches
n = $game_actors
a = $game_actors
p = $game_party
g = $game_party.gold
e = $game_troop
script = process_script(script)
if args.empty?
instance_eval(script, __FILE__, __LINE__)
else
Kernel.eval(script, *args)
end
end
end
class RPG::UsableItem::Damage
def eval(a, b, v)
value = Taroxd::Eval.eval(@formula, b.formula_binding(a, b, v))
value > 0 ? value * sign : 0
end
end
class Game_BattlerBase
def formula_binding(a, b, v)
s = $game_switches
n = $game_actors
p = $game_party
g = $game_party.gold
e = $game_troop
binding
end
end
class Window_Base < Window
# 对 #{} 的处理
process_expression = Proc.new do |old|
old.gsub(/\e?#(?<brace>\{([^{}]|\g<brace>)*\})/) do |code|
next code if code.slice!(0) == "\e"
Taroxd::Eval.eval code[1..-2]
end
end
def_with :convert_escape_characters, process_expression
end