Skip to content

Instantly share code, notes, and snippets.

@CoderPuppy
Created September 2, 2012 18:20
Show Gist options
  • Save CoderPuppy/3602570 to your computer and use it in GitHub Desktop.
Save CoderPuppy/3602570 to your computer and use it in GitHub Desktop.
RPG Maker Plugin System
# VX Ace Plugin System by CoderPuppy
module Plugins
@all = []
def self.register(plugin)
@all << plugin
@all.uniq!
self
end
def self.enabled
@all.select &:enabled?
end
module Plugin
def self.extended(mod)
Plugins.register mod
mod.send :instance_variable_set, :@_cl_attrs, {}
end
def enable
enabled
@_cl_attrs.each do |name, a|
enable_attr name
end
@enabled = true
end
def disable
disabled
@_cl_attrs.each do |name, a|
disable_attr name
end
@enabled = false
end
def enabled?
@enabled
end
def toggle
if enabled?
disable
else
enable
end
end
def attr(cl, type, name, default = nil)
@_cl_attrs[name] = [ cl, type, name, default ]
hook_initialize(cl) do
instance_variable_set "@#{name}".to_sym, default
end
enable_attr name if @enabled
end
def hook(cl, method_name, &blk)
plugin = self
method_name = "#{method_name}".to_sym
cl.class_eval do
alias_method "#{method_name}_without_plugin_#{plugin.object_id}".to_sym, :initialize
define_method(method_name) do |*a, &b|
instance_exec *a, *([b].compact), &blk if plugin.enabled?
send "#{method_name}_without_plugin_#{plugin.object_id}".to_sym, *a, &b
end
end
end
def hook_initialize(cl, &blk)
hook cl, :initialize, &blk
end
alias :hook_init :hook_initialize
def enabled; end
def disabled; end
private
def enable_attr(name)
cl, type, name, default = @_cl_attrs[name]
cl.class_eval do
send "attr_#{type}", name
end
end
def disable_attr(name)
cl, type, name, default = @_cl_attrs[name]
cl.class_eval do
if %w[accessor writer].include? "#{type}"
undef_method "#{name}=".to_sym
end
if %w[accessor reader].include? "#{type}"
undef_method "#{name}".to_sym
end
end
end
end
mapper = proc do |name|
Plugin.send(:define_method, name) {|o|}
singleton_class.send(:define_method, name) do |*a, &b|
enabled.each { |plugin| plugin.send(name, *a, &b) }
self
end
end
hooker = proc do |cl, prefix, ms|
ms.each do |name|
mapper.call "#{prefix}_#{name}".to_sym
cl.instance_eval do
define_method "#{name}_hook" do |*a, &b|
Plugins.send "#{prefix}_#{name}", self
send "#{name}_without_hook".to_sym, *a, &b
end
alias_method "#{name}_without_hook".to_sym, "#{name}".to_sym
alias_method "#{name}".to_sym, "#{name}_hook".to_sym
end
end
end
hooker.call Game_System, :system, %w[initialize]
hooker.call Scene_Base, :scene, %w[initialize start post_start update pre_terminate terminate]
hooker.call Game_Map, :map, %w[initialize setup update refresh]
end
Plugin = Plugins::Plugin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment