查看: 3834|回复: 6

[原创发布] 数据库系统属性枚举接口 v1.0

[复制链接]

遠航の猫咪

梦石
3
星屑
26947
在线时间
2423 小时
注册时间
2005-10-15
回帖
987

开拓者

发表于 2018-1-17 01:56:25 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
致想用999个属性干一些羞羞事情的人儿

XP的“系统”选项卡,没有VA、MV那么丰富的用语和枚举定义,干巴巴20条用语
想要物品分类、武器分级、用语扩展等,要么脚本直接定义,要么脚本解析备注
(用备注定义的方法,可参考我发布的另一个接口插件)
虽然备注的功能更强大,但仅就枚举值而言,通过数据库的条目定义更方便合适
毕竟,设定枚举值,又有什么能比在列表中打勾来得更快一些呢?
XP的属性有999个,VA/MV都只有99个,所以必须从属性入手,也只能从属性入手

特技的设置例(当然,实装这些效果需要你自己弄):
1.png
$data_skills[3].enum_flag("特技") 将返回177
武器的设置例:
2.png
$data_weapons[6].enum_set("武器") 将返回[0]
$data_weapons[6].element_set 将返回[11],不会对你打臭鱼们造成负担哒
属性的书写方法:
3.png
交织写,几个枚举项交叉写,都是无所谓的,如果你坚持使用值名而不是真值来访问枚举的话,就连顺序都是无所谓的

纯接口,300行代码,故不提供范例工程(SEP工程及默认工程均以查无冲):

代码请点击
[pre lang="ruby"]#==============================================================================
# ■ 数据库系统属性枚举接口 v1.0 by SailCat
#------------------------------------------------------------------------------
#   方法:本脚本插入到Main之前使用,且需在所有依赖此脚本的其他插件之前
#   依赖:无
#   版本:v1.0 (Build 180116)
#   效果:数据库的属性可以用于定义枚举和用语
#   配置:前导字符
#   冲突:无
#   说明:
#
#   1. 枚举的定义很简单:将属性的首个字符写成前导字符即可
#      系统识别到前导字符,就认为这是一个枚举项,而不是用于战斗的属性
#      战斗系统的属性攻击,属性防御等丝毫不会受影响
#      此外,空字符串的属性值,也不会植入战斗系统中
#
#   2. 前导符是"["时,表示这是一个枚举项,后续写法:类名]值名(=真值)
#      例如:[武器]长刀=2,[防具]女盾=9,[特技]必杀=4,[Aa]5678=0
#      枚举类和值名,随便书写,反正都会当作字符串来处理
#      真值必须是个0以上的数字,可以省略不写,不写会自动加到最后一项去
#      连续书写同一个枚举类时,除第一项外的类名可以省略,用"."代替,如
#      [武器]朴刀=1
#      .长刀
#      .太刀=5
#      .细剑
#      .长枪=4
#      .短剑
#      .......
#      这样长刀、太刀等都是武器枚举中的值名,长刀真值2,细剑真值6,短剑真值7
#
#   3. 前导符是"<"时,表示这是一个用语项,后续写法:标识符>用语字符串
#      例如:<gold2>美元,<male>男,<armor5>鞋子,<skill4>阴阳术,<exit>退出
#      标识符必须是合法的ruby变量名称,这些用语的调用方法:
#      a) SEP插件公共核心的Vocab模块,Vocab.标识符(如果你使用了这个插件)
#      b) 默认系统的$data_system,调用如$data_system.words.标识符
#
#   4. 枚举的脚本调用法:
#      特技数据、物品数据、武器数据、防具数据、状态数据调用枚举:
#      a) 数据对象.enum_set(枚举类名) => 勾选项的数组
#         注:若枚举类名不存在,或未勾选任何此类项时,返回一个空数组
#      b) 数据对象.enum_check?(枚举类名, 枚举值名或枚举真值) => true/false
#      c) 数据对象.enum_flag(枚举类名) => 勾选项数组按位和
#         注:若枚举类名不存在,或未勾选任何此类项时,返回0
#      职业数据、敌人数据调用枚举:
#      a) 数据对象.enum_set(枚举类名) => 由0-6的数(有效度)构成的数组
#         注:若枚举类名不存在返回空数组,若枚举真值不连续,跳过的位置值为0
#      b) 数据对象.enum_rank(枚举类名, 枚举值名或真值)=> 0-6的数值
#      系统数据:
#      a) $data_system.enum_set(枚举类名) => 枚举值名字符串数组
#      b) $data_system.enum_ids(枚举类名) => 各枚举项属性ID数组
#         注:若枚举类名不存在返回空数组,若枚举真值不连续,跳过的位置为nil
#      c) $data_system.find_enum(属性ID) => 枚举类、值名、真值数据 hash
#
#   5. 如果调用类似.element_set, .guard_element_set这样的方法,仅返回战斗属性
#      因此,使用枚举不会对战斗系统构成影响
#
#   6. 如同数据库通用备注接口一样,这个脚本只提供接口,并无任何实际功能
#
#   7. 同一类中,枚举值名和枚举真值不得重复,否则后出者无效
#
#   8. 所有用语的标识符不得重复,否则先出者无效(因此,系统默认用语可以被覆盖)
#
#   9. 属性文字限为20汉字或40字符,本接口不提供突破方案(应该不会不够吧)
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
  $sailcat_import ||= {}
  #--------------------------------------------------------------------------
  # ● 脚本配置区
  #--------------------------------------------------------------------------
  module ElementEnum_Config
    ENUM_MARKER = ?[              # 枚举项 前导符号
    WORD_MARKER = ?<              # 用语串 前导符号
    ENUM_CLOSER = ?]              # 枚举项 后置符号
    WORD_CLOSER = ?>              # 用语串 后置符号
    ELLI_MARKER = ?.              # 省略号 前导符号
    VALUE_SPLIT = ?=              # 真值数 分隔符号
    #--------------------------------------------------------------------------
    # ● 配置检查,请勿更改
    #--------------------------------------------------------------------------
    raise "枚举项前导符与用语串前导符不得一致" if ENUM_MARKER == WORD_MARKER
    raise "枚举项前导符与省略号前导符不得一致" if ENUM_MARKER == ELLI_MARKER
    raise "用语串前导符与省略号前导符不得一致" if WORD_MARKER == ELLI_MARKER
    raise "枚举项后置符与真值数分隔符不得一致" if ENUM_CLOSER == VALUE_SPLIT
  end
  #--------------------------------------------------------------------------
  # ● 植入
  #--------------------------------------------------------------------------
  $sailcat_import[:ElementEnumCore] = 1.0
end

#==============================================================================
# ■ EnumAccessor
#------------------------------------------------------------------------------
#   以下处理枚举值的检定和非战斗属性的排除。
#==============================================================================
module EnumAccessor
  #--------------------------------------------------------------------------
  # ● 非战斗属性集
  #--------------------------------------------------------------------------
  def wild_element_set
    if respond_to?(:element_set)
      @element_set - self.element_set
    else
      @guard_element_set - self.guard_element_set
    end
  end
  #--------------------------------------------------------------------------
  # ● 枚举集
  #     type : 枚举类名
  #--------------------------------------------------------------------------
  def enum_set(type)
    result = []
    wild_element_set.each do |i|
      data = $data_system.find_enum(i)
      result.push(data[:value]) if data and data[:type] == type
    end
    result
  end
  #--------------------------------------------------------------------------
  # ● 枚举集设置标记(按位和)
  #     type : 枚举类名
  #--------------------------------------------------------------------------
  def enum_flag(type)
    enum_set(type).inject(0){|n, i| n + 2 ** i}
  end
  #--------------------------------------------------------------------------
  # ● 枚举判定
  #     type  : 枚举类名
  #     value : 枚举值(值名或真值)
  #--------------------------------------------------------------------------
  def enum_check?(type, value)
    wild_element_set.any? do |i|
      data = $data_system.find_enum and data[:type] == type and
      (data[:value] == value or data[:name] == value)
    end
  end
end

#==============================================================================
# ■ EnumParser
#------------------------------------------------------------------------------
#   枚举解析器模块。
#==============================================================================
module EnumParser
  include SailCat::ElementEnum_Config
  @@type = ""
  #--------------------------------------------------------------------------
  # ● 枚举解析
  #     str : 属性字符串
  #--------------------------------------------------------------------------
  def self.parse(str)
    # 如果是枚举类名开头
    if str[0] == ENUM_MARKER
      # 截取类名
      return nil unless x = str.index(ENUM_CLOSER)
      return nil if (@@type = str[1...x]).empty?
      # 截取名称和真值
      y = str.index(VALUE_SPLIT) || 0
      return nil if (name = str[(x + 1)..(y > x + 1 ? y - 1 : -1)]).empty?
      value = y > 0 ? str[(y + 1)..-1].to_i : -1
    # 如果是省略号开头
    elsif str[0] == ELLI_MARKER
      return nil if @@type.empty?
      # 截取名称和真值
      y = str.index(VALUE_SPLIT) || 0
      return nil if (name = str[1..(y - 1)]).empty?
      value = y > 0 ? str[(y + 1)..-1].to_i : -1
    # 如果不是枚举值
    else
      return nil
    end
    [@@type, name, value]
  end
end

#==============================================================================
# ■ WordParser
#------------------------------------------------------------------------------
#   用语解析器模块。
#==============================================================================
module WordParser
  include SailCat::ElementEnum_Config
  #--------------------------------------------------------------------------
  # ● 用语解析
  #     str : 属性字符串
  #--------------------------------------------------------------------------
  def self.parse(str)
    # 截取标识符和用语
    return nil unless x = str.index(WORD_CLOSER)
    return nil unless /[a-z_]\w*/ =~ (word_key = str[1...x])
    word_value = str[(x + 1)..-1] || ""
    [word_key, word_value]
  end
end

#==============================================================================
# ■ RPG 模块的植入
#------------------------------------------------------------------------------
#   以下植入8个数据库内容模块(职业、特技、物品、武器、防具、敌人、状态、系统)
#==============================================================================
module RPG
  class System
    include SailCat::ElementEnum_Config
    #--------------------------------------------------------------------------
    # ● 战斗用属性ID集
    #--------------------------------------------------------------------------
    def element_set
      @element_set ||= (1...@elements.size).to_a.select do |i|
        @elements != "" and @elements[0] != ENUM_MARKER and
        @elements[0] != WORD_MARKER and @elements[0] != ELLI_MARKER
      end
    end
    #--------------------------------------------------------------------------
    # ● 获得全类枚举值名集
    #     type : 枚举类名
    #--------------------------------------------------------------------------
    def enum_ids(type)
      enum_initialize unless @enum_init
      @enum[type].map {|d| d && d[0]} || []
    end
    #--------------------------------------------------------------------------
    # ● 获得全类枚举属性ID集
    #     type : 枚举类名
    #--------------------------------------------------------------------------
    def enum_set(type)
      enum_initialize unless @enum_init
      @enum[type].map {|d| d && d[1]} || []
    end
    #--------------------------------------------------------------------------
    # ● 查找枚举数据
    #     element_id : 属性ID
    #--------------------------------------------------------------------------
    def find_enum(element_id)
      enum_initialize unless @enum_init
      @data[element_id]
    end
    #--------------------------------------------------------------------------
    # ● 获得用语
    #--------------------------------------------------------------------------
    def words
      words_initialize unless @words_init
      @words
    end
    #--------------------------------------------------------------------------
    # ● 初始化枚举数据
    #--------------------------------------------------------------------------
    def enum_initialize
      @enum = {}
      @data = {}
      @elements.each_with_index do |str, i|
        next unless e = EnumParser.parse(str)
        # 设置枚举值
        set = (@enum[e[0]] ||= [])
        next if set.index(e[1])
        value = [i, e[1]]
        e[2] >= 0 ? set[e[2]] = value : set.push(value)
        @data = {:type => e[0], :name => e[1], :value => set.index(value)}
      end
      @enum_init = true
    end
    #--------------------------------------------------------------------------
    # ● 初始化用语数据
    #--------------------------------------------------------------------------
    def words_initialize
      @elements.select {|str| str[0] == WORD_MARKER}.each do |str|
        next unless w = WordParser.parse(str)
        # 注入系统用语对象
        @words.instance_variable_set("@#{w[0]}", w[1])
        @words.class.send :define_method, w[0] do
          instance_variable_get("@#{w[0]}")
        end
        @words.class.send :define_method, "#{w[0]}=" do |value|
          instance_variable_set("@#{w[0]}", value)
        end
      end
      @words_init = true
    end
  end
  #--------------------------------------------------------------------------
  # ● 其他模块的植入
  #--------------------------------------------------------------------------
  [Skill, Item, Weapon].each do |c|
    c.send :include, EnumAccessor
    c.send :define_method, :element_set do
      @element_set & $data_system.element_set
    end
    c.send :define_method, :element_set= do |value|
      @element_set = value + wild_element_set
    end
  end
  [Armor, State].each do |c|
    c.send :include, EnumAccessor
    c.send :define_method, :guard_element_set do
      @guard_element_set & $data_system.element_set
    end
    c.send :define_method, :guard_element_set= do |value|
      @guard_element_set = value + wild_element_set
    end
  end
  [Class, Enemy].each do |c|
    c.send :define_method, :enum_set do |type|
      $data_system.enum_ids(type).map {|i| @element_ranks[i || 0]}
    end
    c.send :define_method, :enum_rank do |type, value|
      unless value.is_a?(Numeric)
        value = $data_system.enum_set(type).index(value)
      end
      value ? enum_set(type)[value] : 0
    end
  end
end

#==============================================================================
# ■ Vocab
#------------------------------------------------------------------------------
#   所有用语的整合模块,由SEP 插件公共核心定义。
#==============================================================================
if $sailcat_import[:CoreEngine]
  module Vocab
    class << self
      def method_missing(name, *args, &block)
        if $data_system and $data_system.words.respond_to?(name)
          self.send :define_method, name do; $data_system.words.send(name); end
          $data_system.words.send(name)
        else
          super
        end
      end
    end
  end
end
[/pre]
SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
梦石
0
星屑
9292
在线时间
2504 小时
注册时间
2011-5-20
回帖
14521

开拓者

发表于 2018-1-17 13:39:24 | 显示全部楼层
那屬性有效度裏面也可以利用起來了?
不過屬性有效度的ABCDEF-拿來做什麼比較合適呢?顯示分類的順序?

点评

也可以让这些属性有效度就表示原来的意思,比如敌人的吸血有效度为E时会免疫吸血攻击等等,但是需要自己写,不适宜整合到原始属性修正当中  发表于 2018-1-17 13:48
随意,比如职业对刀枪剑戈设为ABCD表示武器熟练度,敌人可以通过物品分类和有效度来设置随机掉落等……这个脚本只是接口,具体功能自行想象……  发表于 2018-1-17 13:46
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复

使用道具 举报

老黄鸡

梦石
4
星屑
45700
在线时间
7948 小时
注册时间
2009-7-6
回帖
13338

MZ评测员RM创作大赛01组委会开拓者贵宾

发表于 2018-1-17 18:50:39 | 显示全部楼层
XP最呆的地方就是无论有没有勾选都会显示所有属性……蛋疼

点评

VX也是啊,到VA才改掉……  发表于 2018-1-17 19:47
RGDirect - DirectX驱动的RGSS,点我了解.
(排满,暂停)RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复

使用道具 举报

梦石
0
星屑
504
在线时间
43 小时
注册时间
2018-2-19
回帖
60
发表于 2018-2-21 20:37:36 | 显示全部楼层
不错,感谢楼主分享。
梦想是谁创造的,梦想是自己创造的。站起来吧。
                      梦想由我们自己来创造。
  无论未来有多么困难,在下都会尽全力走下去。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部