查看: 4093|回复: 8

[原创发布] 地图区域核心 v1.3 及3个相关插件

[复制链接]

遠航の猫咪

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

开拓者

发表于 2017-12-5 22:13:48 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 SailCat 于 2017-12-17 23:08 编辑

按:原来我买正版VA就是为了移植它的脚本来的……谜之尴尬……

功能很简单,脚本也不长,至于区域ID有什么用,愿意用的自然可以开发出很多用法,比如配合ULDS之类……
接口都是VA的标准写法,如$game_map.region_id(x, y), $game_player.region_id等等
[fold=0. 地图区域核心 v1.3]
版本更新:
v1.3 增强方块形、射线形的区域设置形状,默认区域ID上限改到255
v1.2 插件拆分,只留核心
v1.1 添加连续区域的批量设置功能
[pre lang="ruby"]#==============================================================================
# ■ 地图区域核心 v1.3 by SailCat
#------------------------------------------------------------------------------
#   方法:本脚本插入到Main之前使用
#   依赖:数据库通用备注接口插件(2.1版以上)
#   版本:v1.3 (Build 171208)
#   效果:能像VA一样设置XP地图的区域标记
#   配置:区域的取值范围
#   冲突:无
#   说明:
#     0. 备注写在事件的名称中
#     1. 在需要设置区域的地方,添加一个事件,事件名称为 #r=区域ID值
#        如果此处已有事件,就在这个事件上的名称后添加上述内容
#     2. 如果有连续的区域设置,可以额外追加下列备注,实现一个事件设置多格区域
#        矩形:w=宽度值;h=高度值,从本事件向右下数,省略则取1,取负会反方向数
#        方形:t=扩张度,以本事件为方块中心
#        线形:t=扩张度; o=方向(1-9);以本事件为射线端点
#        圆形:d=半径,以本事件为圆心
#        扇形:d=半径;o=方向(1-9);以本事件为圆心,方向所指为扇形覆盖范围
#        菱形:m=步长,以本事件为菱形中心
#        等腰直角三角形:m=步长;o=方向(1-9),以本事件为直角顶点,方向为展开范围
#     3. 区域指定有交叠的情况下,单独设置优先于整块设置
#        同是整块设置的情况下,事件ID靠后的优先于靠前的
#     4. 纯区域设置的事件最好留空,这样地图在加载的时候不会加载,后续也不会刷新
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
  $sailcat_import ||= {}
  #--------------------------------------------------------------------------
  # ● 脚本配置区
  #--------------------------------------------------------------------------
  module Region_Config
    REGION_MAX      = 255             # 区域ID的最大值,最多可以为32767
    REGION_MIN      = 0               # 区域ID的最小值,最少可以为-32768
    REGION_DEFAULT  = 0               # 区域ID的默认值
  end
  #--------------------------------------------------------------------------
  # ● 植入与依赖检查
  #--------------------------------------------------------------------------
  dependency = []
  unless $sailcat_import[:DataNoteCore].to_f >= 2.1
    dependency.push "[DataNoteCore] 通用数据库备注接口(v2.1以上版本)"
  end
  raise "缺少依赖插件:\n" + dependency.join("\n") unless dependency.empty?
  $sailcat_import[:MapRegion] = 1.3
end

module RPG
  #============================================================================
  # ■ RPG::Event
  #----------------------------------------------------------------------------
  #  数据库的事件类扩展
  #============================================================================
  class Event
    include SailCat::Region_Config
    #--------------------------------------------------------------------------
    # ● 备注定义
    #--------------------------------------------------------------------------
    def region_id;      _r(REGION_DEFAULT);                               end
    def region_width;   _w(1);                                            end
    def region_height;  _h(1);                                            end
    def region_extend;  _p(0).abs;                                        end
    def region_radius;  _d(0).abs;                                        end
    def region_step;    _m(0).abs;                                        end
    def region_orient;  [[_o(5), 9].min, 1].max;                          end
    #--------------------------------------------------------------------------
    # ● 无效判定
    #--------------------------------------------------------------------------
    def empty?
      pages.size == 1 and pages[0].graphic.tile_id == 0 and
        pages[0].graphic.character_name == "" and pages[0].list[0].code == 0
    end
    #--------------------------------------------------------------------------
    # ● 单格判定
    #--------------------------------------------------------------------------
    def single?
      (region_width * region_height).abs == 1 and
        region_radius == 0 and region_step == 0 and region_extend == 0
    end
    #--------------------------------------------------------------------------
    # ● 区域判定
    #--------------------------------------------------------------------------
    def region_valid?
      region_id != REGION_DEFAULT
    end
  end
end

#==============================================================================
# ■ Game_Event
#==============================================================================
class Game_Event
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_reader   :event                # 事件(RPG::Event)
end

#==============================================================================
# ■ Game_Map
#==============================================================================
class Game_Map
  include SailCat::Region_Config
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_mapregion_setup)
    alias sailcat_mapregion_setup setup
  end
  #--------------------------------------------------------------------------
  # ● 设置
  #     map_id : 地图 ID
  #--------------------------------------------------------------------------
  def setup(map_id)
    # 初始设置
    sailcat_mapregion_setup(map_id)
    # 初始化区域ID
    @region_set = Table.new(width, height)
    for i in 0...width
      for j in 0...height
        @region_set[i, j] = REGION_DEFAULT
      end
    end
    # 块状设置区域ID
    @events.values.sort_by {|v| v.event.id}.each do |v|
      e = v.event
      set_region_block(e) if e.region_valid? and not e.single?
    end
    # 单格设置区域ID
    @events.each_value do |v|
      e = v.event
      set_region_id(e.x, e.y, e.region_id) if e.region_valid? and e.single?
    end
    @events.reject! {|k, v| v.event.empty?}
  end
  #--------------------------------------------------------------------------
  # ● 设定区域ID值
  #--------------------------------------------------------------------------
  def set_region_id(x, y, id)
    @region_set[x, y] = [[id, REGION_MAX].min, REGION_MIN].max
  end
  #--------------------------------------------------------------------------
  # ● 区块批量设置
  #     e : 事件
  #--------------------------------------------------------------------------
  def set_region_block(e)
    # 矩形的情况下
    if e.region_width.abs > 1 or e.region_height.abs > 1
      dx = e.region_width <=> 0
      dy = e.region_height <=> 0
      for ox in 0...e.region_width.abs
        for oy in 0...e.region_height.abs
          set_region_id(e.x + ox * dx, e.y + oy * dy, e.region_id)
        end
      end
    # 菱形或三角的情况下
    elsif e.region_step > 0
      ox_min = e.region_orient % 3 != 0 ? -e.region_step : 0
      ox_max = e.region_orient % 3 != 1 ? +e.region_step : 0
      oy_min = (e.region_orient - 1) / 3 != 0 ? -e.region_step : 0
      oy_max = (e.region_orient - 1) / 3 != 2 ? +e.region_step : 0
      for ox in ox_min..ox_max
        for oy in oy_min..oy_max
          if ox.abs + oy.abs <= e.region_step
            set_region_id(e.x + ox, e.y + oy, e.region_id)
          end
        end
      end
    # 圆形或扇形的情况下
    elsif e.region_radius > 0
      ox_min = e.region_orient % 3 != 0 ? -e.region_radius : 0
      ox_max = e.region_orient % 3 != 1 ? +e.region_radius : 0
      oy_min = (e.region_orient - 1) / 3 != 0 ? -e.region_radius : 0
      oy_max = (e.region_orient - 1) / 3 != 2 ? +e.region_radius : 0
      for ox in ox_min..ox_max
        for oy in oy_min..oy_max
          if Math.hypot(ox, oy).round <= e.region_radius
            set_region_id(e.x + ox, e.y + oy, e.region_id)
          end
        end
      end
    # 方形或线形的情况下
    elsif e.region_extend > 0
      ox_step = [1, -1, 0][e.region_orient % 3]
      oy_step = [1, 0, -1][(e.region_orient - 1) / 3]
      if ox_step == 0 and oy_step == 0
        for ox in -e.region_extend..e.region_extend
          for oy in -e.region_extend..e.region_extend
            set_region_id(e.x + ox, e.y + oy, e.region_id)
          end
        end
      else
        for i in 0..e.region_extend
          set_region_id(e.x + ox_step * i, e.y + oy_step * i, e.region_id)
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 获取区域ID
  #--------------------------------------------------------------------------
  def region_id(x, y)
    valid?(x, y) ? @region_set[x, y] : DEFAULT_REGION
  end
end

#==============================================================================
# ■ Game_Character
#==============================================================================
class Game_Character
  #--------------------------------------------------------------------------
  # ● 取得区域ID
  #--------------------------------------------------------------------------
  def region_id
    return $game_map.region_id(@x, @y)
  end
end[/pre][/fold][fold=1. 区域通行 v1.1]
版本更新:
v1.1 通行度可四方向设定
[pre lang="ruby"]#==============================================================================
# ■ 地图区域-区域通行 v1.1 by SailCat
#------------------------------------------------------------------------------
#   方法:本脚本插入到Main之前使用,并依赖以下脚本:
#   依赖:地图区域核心(1.3版以上)
#   版本:v1.1 (Build 171208)
#   效果:区域可以覆盖地图的通行设置
#   配置:区域的通行度,前四项设置互斥,区域值不能交叠,后八项不同方向可以交叠
#   冲突:无
#   说明:无,完成配置项并在地图上设定区域即可
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
  $sailcat_import ||= {}
  #--------------------------------------------------------------------------
  # ● 脚本配置区
  #--------------------------------------------------------------------------
  module Region_Config
    REGION_IMPASSABLES    = [63]         # 当区域ID在此表中时,强制四方不能通行
    REGION_PASSABLES      = [62]         # 当区域ID在此表中时,强制四方可以通行
    REGION_PASSABLES_H    = [61]         # 当区域ID在此表中时,强制仅限上下通行
    REGION_PASSABLES_V    = [60]         # 当区域ID在此表中时,强制仅限左右通行
    REGION_PASSABLES_L    = [1]          # 当区域ID在此表中时,强制左方可以通行
    REGION_PASSABLES_R    = [2]          # 当区域ID在此表中时,强制右方可以通行
    REGION_PASSABLES_U    = [3]          # 当区域ID在此表中时,强制上方可以通行
    REGION_PASSABLES_D    = [4]          # 当区域ID在此表中时,强制下方可以通行
    REGION_IMPASSABLES_L  = [5]          # 当区域ID在此表中时,强制左方不能通行
    REGION_IMPASSABLES_R  = [6]          # 当区域ID在此表中时,强制右方不能通行
    REGION_IMPASSABLES_U  = [7]          # 当区域ID在此表中时,强制上方不能通行
    REGION_IMPASSABLES_D  = [8]          # 当区域ID在此表中时,强制下方不能通行
  end
  #--------------------------------------------------------------------------
  # ● 植入与依赖检查
  #--------------------------------------------------------------------------
  dependency = []
  unless $sailcat_import[:MapRegion].to_f >= 1.3
    dependency.push "[MapRegion] 地图区域核心(v1.3以上版本)"
  end
  raise "缺少依赖插件:\n" + dependency.join("\n") unless dependency.empty?
  $sailcat_import[:RegionPassable] = 1.1
end

#==============================================================================
# ■ Game_Map
#==============================================================================
class Game_Map
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_maprp_passable?)
    alias sailcat_maprp_passable? passable?
  end
  #--------------------------------------------------------------------------
  # ● 可以通行判定
  #--------------------------------------------------------------------------
  def passable?(x, y, d, self_event = nil)
    # 被给予的坐标地图外的情况下,不能通行
    return false unless valid?(x, y)
    # 区域ID是强制不可通行的情况下,不能通行
    return false if REGION_IMPASSABLES.include?(region_id(x, y))
    # 区域ID是强制四方通行的情况下,可以通行
    return true if REGION_PASSABLES.include?(region_id(x, y))
    # 区域ID是强制上下通行的情况下,上下通行
    return (d == 2 or d == 8) if REGION_PASSABLES_V.include?(region_id(x, y))
    # 区域ID是强制左右通行的情况下,左右通行
    return (d == 4 or d == 6) if REGION_PASSABLES_H.include?(region_id(x, y))
    # 区域ID限制不能左方通行,试图左方通行的况下,不能通行
    return false if REGION_IMPASSABLES_L.include?(region_id(x, y)) and d == 4
    # 区域ID限制可以左方通行,试图左方通行的况下,可以通行
    return true if REGION_PASSABLES_L.include?(region_id(x, y)) and d == 4
    # 区域ID限制不能右方通行,试图右方通行的况下,不能通行
    return false if REGION_IMPASSABLES_R.include?(region_id(x, y)) and d == 6
    # 区域ID限制可以右方通行,试图右方通行的况下,可以通行
    return true if REGION_PASSABLES_R.include?(region_id(x, y)) and d == 6
    # 区域ID限制不能上方通行,试图上方通行的况下,不能通行
    return false if REGION_IMPASSABLES_U.include?(region_id(x, y)) and d == 8
    # 区域ID限制可以上方通行,试图上方通行的况下,可以通行
    return true if REGION_PASSABLES_U.include?(region_id(x, y)) and d == 8
    # 区域ID限制不能下方通行,试图下方通行的况下,不能通行
    return false if REGION_IMPASSABLES_D.include?(region_id(x, y)) and d == 2
    # 区域ID限制可以下方通行,试图下方通行的况下,可以通行
    return true if REGION_PASSABLES_D.include?(region_id(x, y)) and d == 2
    # 进行原来的判定
    return sailcat_maprp_passable?(x, y, d, self_event)
  end
end
[/pre][/fold][fold=2. 区域闪烁 v1.0]
初期版本
[pre lang="ruby"]#==============================================================================
# ■ 地图区域-区域闪烁 v1.0 by SailCat
#------------------------------------------------------------------------------
#   方法:本脚本插入到Main之前使用,并依赖以下脚本:
#   依赖:地图区域核心(1.2版以上)
#   版本:v1.0 (Build 171208)
#   效果:区域可以闪烁,不同区域可以闪烁不同的颜色
#   配置:要闪烁的区域及闪烁色
#   冲突:无
#   说明:无
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
  $sailcat_import ||= {}
  #--------------------------------------------------------------------------
  # ● 脚本配置区
  #--------------------------------------------------------------------------
  module Region_Config
    REGION_FLASHES  = [59, 60, 61]            # 当区域ID在此表中时,此格闪烁
    FLASH_COLORS    = [0xe22, 0x4f3, 0x209]   # 和上表一一对应的闪烁色(RGB12)
    FLASH_SWITCH    = 0                       # 控制闪烁的开关,0为总是闪烁
  end
  #--------------------------------------------------------------------------
  # ● 植入与依赖检查
  #--------------------------------------------------------------------------
  dependency = []
  unless $sailcat_import[:MapRegion].to_f >= 1.2
    dependency.push "[MapRegion] 地图区域核心(v1.2以上版本)"
  end
  raise "缺少依赖插件:\n" + dependency.join("\n") unless dependency.empty?
  $sailcat_import[:RegionFlash] = 1.0
end

#==============================================================================
# ■ Game_Map
#==============================================================================
class Game_Map
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_reader   :flash_data          # 闪光数据
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_maprf_set_region_id)
    alias sailcat_maprf_set_region_id set_region_id
  end
  #--------------------------------------------------------------------------
  # ● 设定区域ID值
  #--------------------------------------------------------------------------
  def set_region_id(x, y, id)
    sailcat_maprf_set_region_id(x, y, id)
    if fid = REGION_FLASHES.index(id)
      @flash_data ||= Table.new(width, height)
      @flash_data[x, y] = FLASH_COLORS[fid] || 0x0
    end
  end
end

#==============================================================================
# ■ Spriteset_Map
#==============================================================================
class Spriteset_Map
  include SailCat::Region_Config
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_mapf_initialize)
    alias sailcat_maprf_initialize initialize
    alias sailcat_maprf_update update
  end
  #--------------------------------------------------------------------------
  # ● 初始化对像
  #--------------------------------------------------------------------------
  def initialize
    sailcat_maprf_initialize
    set_flash_data
  end
  #--------------------------------------------------------------------------
  # ● 设置闪烁数据
  #--------------------------------------------------------------------------
  def set_flash_data
    if FLASH_SWITCH == 0 or $game_switches[FLASH_SWITCH]
      @tilemap.flash_data = $game_map.flash_data unless @tilemap.flash_data
    else
      @tilemap.flash_data = nil if @tilemap.flash_data
    end
  end
  #--------------------------------------------------------------------------
  # ● 刷新画面
  #--------------------------------------------------------------------------
  def update
    set_flash_data
    sailcat_maprf_update
  end
end
[/pre][/fold][fold=3. 分区遇敌 v1.0]
初期版本
[pre lang="ruby"]#==============================================================================
# ■ 地图区域-分区遇敌 v1.0 by SailCat
#------------------------------------------------------------------------------
#   方法:本脚本插入到Main之前使用,并依赖以下脚本:
#   依赖:地图区域核心(1.2版以上)
#   版本:v1.0 (Build 171207)
#   效果:遇敌可以分区,遇敌机率可以分区设定
#   配置:遇敌机率的设定项
#   冲突:无
#   说明:
#     0. 备注写在队伍数据中,战斗事件第一页(不论条件)开始的注释事件中
#     1. 全局指定区域:#region=[区域ID集],只限1个区域的话括号省略
#     2. 分地图指定区域:#map_region={[地图ID集] => [区域ID集]}的Hash形式
#     3. 拒绝指定区域:#ban_region=[区域ID集]
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
  $sailcat_import ||= {}
  #--------------------------------------------------------------------------
  # ● 脚本配置区
  #--------------------------------------------------------------------------
  module Region_Config
    # 按不同区域ID设定遇敌率,不设定的都默认为100,设为0会禁止遇敌
    REGION_ENCOUNTER_RATES = {61 => 50, 62 => 0, 0 => 200}
  end
  #--------------------------------------------------------------------------
  # ● 植入与依赖检查
  #--------------------------------------------------------------------------
  dependency = []
  unless $sailcat_import[:MapRegion].to_f >= 1.2
    dependency.push "[MapRegion] 地图区域核心(v1.2以上版本)"
  end
  raise "缺少依赖插件:\n" + dependency.join("\n") unless dependency.empty?
  $sailcat_import[:TroopByRegion] = 1.0
end

module RPG
  #============================================================================
  # ■ RPG::Troop
  #----------------------------------------------------------------------------
  #  数据库的队伍类扩展
  #============================================================================
  class Troop
    #--------------------------------------------------------------------------
    # ● 备注定义
    #--------------------------------------------------------------------------
    def region_set;     flat_array(_region([]));                          end
    def region_map_set; _map_region({});                                  end
    def region_ban_set; flat_array(_ban_region([]));                      end
    #--------------------------------------------------------------------------
    # ● 区域符合判定
    #--------------------------------------------------------------------------
    def region_match?(map_id, region_id)
      return false if region_ban_set.include?(region_id)
      return true if region_set.include?(region_id)
      region_map_set.each do |k, v|
        if flat_array(k).include?(map_id)
          value = flat_array(v)
          return value.empty? || value.include?(region_id)
        end
      end
      return region_set.empty?
    end
  end
end

#==============================================================================
# ■ Game_Map
#==============================================================================
class Game_Map
  #--------------------------------------------------------------------------
  # ● 获取遇敌列表
  #--------------------------------------------------------------------------
  def encounter_list
    return [] if REGION_ENCOUNTER_RATES[$game_player.region_id] == 0
    @map.encounter_list.select do |n|
      $data_troops[n].region_match?(self.map_id, $game_player.region_id)
    end
  end
  #--------------------------------------------------------------------------
  # ● 获取遇敌步数
  #--------------------------------------------------------------------------
  def encounter_step
    rate = REGION_ENCOUNTER_RATES[$game_player.region_id] || 100
    rate == 0 ? 1 : [@map.encounter_step * 100 / rate, 1].max
  end
end[/pre][/fold]

评分

参与人数 1赞 +1 收起 理由
灯笼菜刀王 + 1 好东西,就是不能直接用只能偷学方法=v=.

查看全部评分

SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
梦石
0
星屑
9292
在线时间
2504 小时
注册时间
2011-5-20
回帖
14521

开拓者

发表于 2017-12-7 09:20:42 | 显示全部楼层
···区域内只遇到指定敌群是最常规的用法吧(那不就要用id判定了吗···)···

点评

影响掉率和行动机率连VA都不默认植入的吧……这需求有点诡异……地形伤害用地形标志做用地形标志做用地形标志做。区域和地形的区别就是图块绑定  发表于 2017-12-8 21:50
还有影响物品掉率和敌人行动几率、地形伤害之类的用途,这类标记用法其实还是很多的  发表于 2017-12-8 20:56
已更新,太容易了  发表于 2017-12-7 23:18
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复

使用道具 举报

梦石
0
星屑
3947
在线时间
1591 小时
注册时间
2006-5-5
回帖
2564
发表于 2017-12-7 09:24:55 | 显示全部楼层
感觉这个功能是以前2003版上的,虽然我一直不喜欢
步兵中尉
回复

使用道具 举报

遠航の猫咪

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

开拓者

 楼主| 发表于 2017-12-7 23:23:08 | 显示全部楼层
更新区块(没有链!)设置的主引擎以及地图分区遇敌设置功能。
SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
回复

使用道具 举报

遠航の猫咪

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

开拓者

 楼主| 发表于 2017-12-17 23:07:58 | 显示全部楼层
更新1.3版引擎
回复

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部