设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 427|回复: 1
打印 上一主题 下一主题

[原创发布] 仿《泰拉瑞亚》装备重铸系统

[复制链接]

Lv3.寻梦者

梦石
1
星屑
1174
在线时间
58 小时
注册时间
2023-9-8
帖子
35
跳转到指定楼层
1
发表于 2026-4-8 00:12:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 Ruigi 于 2026-4-17 01:02 编辑

RUBY 代码复制
  1. #==============================================================================
  2. # ■ 泰拉瑞亚风格重铸系统 v3.0
  3. #==============================================================================
  4. # 作者:MrRuigi
  5. # 功能:为武器/防具随机附加前缀,改变名称、属性、价格、稀有度
  6. # 兼容:RPG Maker VX Ace,使用别名链避免冲突
  7. #==============================================================================
  8.  
  9. #==============================================================================
  10. # ■ 配置模块
  11. #==============================================================================
  12. module Reroll_Config
  13.   REROLL_COST_RATE = 1.6          # 重铸费用倍率(基于物品原价)
  14.   DISCOUNT_VARIABLE_ID = 10       # 打折变量ID(>0时8折)
  15.   DISCOUNT_RATE = 0.8
  16.   MAX_RARITY_FOR_REROLL = 0       # 0 = 无限制
  17.  
  18.   HELP_TEXT = "选择一件武器或防具进行重铸"
  19.   COST_TEXT = "重铸费用:"
  20.   DISCOUNT_TEXT = " (已打折)"
  21.   NO_ITEM_TEXT = "请选择装备"
  22.   SUCCESS_TEXT = "重铸成功!获得前缀:「%s」"
  23.   NO_REROLL_TEXT = "这件装备无法重铸(稀有度过高)"
  24.   NO_MONEY_TEXT = "金钱不足!需要 %d G"
  25. end
  26.  
  27. #==============================================================================
  28. # ■ 前缀数据模块
  29. #==============================================================================
  30. module Prefix_Data
  31.   # 前缀ID => [名称, 攻击, 防御, 魔防, 敏捷, 价格倍率, 稀有度变化]
  32.   PREFIX_LIST = {
  33.     1 => ["碎裂的",  -10, 0,  -5, 0, 0.69, -2],
  34.     2 => ["破损的",   -8, 0,  -3, 0, 0.74, -2],
  35.     3 => ["糟糕的",   -6, 0,  -2, 0, 0.79, -1],
  36.     4 => ["恶毒的",    5, 0,   2, 0, 1.05,  0],
  37.     5 => ["精良的",    8, 0,   3, 0, 1.10,  1],
  38.     6 => ["强力的",   10, 0,   0, 0, 1.12,  1],
  39.     7 => ["超神的",   15, 0,   5, 0, 1.20,  2],
  40.     8 => ["神级的",   15, 0,   4, 0, 1.20,  2],
  41.     9 => ["恶魔的",   15, 0,   0, 0, 1.15,  2],
  42.     10=> ["传说的",   18, 0,   5, 5, 1.25,  2],
  43.     11=> ["坚固的",    0, 5,   0, 0, 1.05,  1],
  44.     12=> ["保护的",    0, 8,   0, 0, 1.10,  1],
  45.     13=> ["守卫的",    0, 3,   0, 0, 1.02,  0],
  46.     14=> ["幸运的",    0, 0,   5, 5, 1.08,  1],
  47.     15=> ["快速的",    0, 0,   0, 8, 1.05,  1],
  48.     16=> ["耐心的",    0, 0,   0, 0, 1.00,  0],
  49.     17=> ["凶猛的",    7, 0,   0, 0, 1.08,  1],
  50.     18=> ["致命的",   10, 0,   3, 0, 1.12,  1],
  51.     19=> ["灵活的",    5, 0,   2, 3, 1.05,  1],
  52.     20=> ["熟练的",    6, 0,   4, 0, 1.06,  1],
  53.   }
  54.  
  55.   def self.random_prefix_id
  56.     PREFIX_LIST.keys.sample
  57.   end
  58.  
  59.   def self.prefix_data(prefix_id)
  60.     PREFIX_LIST[prefix_id] || PREFIX_LIST[1]
  61.   end
  62.  
  63.   def self.prefix_name(prefix_id)
  64.     prefix_data(prefix_id)[0]
  65.   end
  66.  
  67.   # param_id 对应 params 数组索引:0=MHP,1=MMP,2=ATK,3=DEF,4=MAT,5=MDF,6=AGI,7=LUK
  68.   def self.get_param_bonus(prefix_id, param_id)
  69.     data = prefix_data(prefix_id)
  70.     return 0 unless data
  71.     case param_id
  72.     when 2 then data[1]  # ATK
  73.     when 3 then data[2]  # DEF
  74.     when 5 then data[3]  # MDF
  75.     when 6 then data[4]  # AGI
  76.     else 0
  77.     end
  78.   end
  79.  
  80.   def self.price_rate(prefix_id)
  81.     prefix_data(prefix_id)[5]
  82.   end
  83.  
  84.   def self.rarity_change(prefix_id)
  85.     prefix_data(prefix_id)[6]
  86.   end
  87. end
  88.  
  89. #==============================================================================
  90. # ■ 前缀存储模块(基于类型+ID,支持存档)
  91. #==============================================================================
  92. module PrefixStorage
  93.   @prefix_map = {}
  94.  
  95.   def self.key(item)
  96.     "#{item.class.name}_#{item.id}"
  97.   end
  98.  
  99.   def self.get_prefix(item)
  100.     @prefix_map[key(item)] || 0
  101.   end
  102.  
  103.   def self.set_prefix(item, prefix_id)
  104.     @prefix_map[key(item)] = prefix_id.to_i
  105.   end
  106.  
  107.   def self.remove_prefix(item)
  108.     @prefix_map.delete(key(item))
  109.   end
  110.  
  111.   def self.save_data
  112.     @prefix_map
  113.   end
  114.  
  115.   def self.load_data(data)
  116.     @prefix_map = data.is_a?(Hash) ? data : {}
  117.   end
  118. end
  119.  
  120. #==============================================================================
  121. # ■ 扩展 RPG::BaseItem(定义基础稀有度)
  122. #==============================================================================
  123. class RPG::BaseItem
  124.   # 默认稀有度,可从备注中解析(如 <rarity: 2>)
  125.   def rarity
  126.     # 示例:self.note =~ /<rarity:\s*(\d+)>/i ? $1.to_i : 0
  127.     0
  128.   end
  129. end
  130.  
  131. #==============================================================================
  132. # ■ 扩展 RPG::Weapon(名称、价格、稀有度)
  133. #==============================================================================
  134. class RPG::Weapon
  135.   alias reroll_original_name name
  136.  
  137.   def name
  138.     prefix_id = PrefixStorage.get_prefix(self)
  139.     if prefix_id > 0
  140.       "#{Prefix_Data.prefix_name(prefix_id)}#{reroll_original_name}"
  141.     else
  142.       reroll_original_name
  143.     end
  144.   end
  145.  
  146.   def display_name
  147.     name
  148.   end
  149.  
  150.   alias reroll_price price
  151.   def real_price
  152.     prefix_id = PrefixStorage.get_prefix(self)
  153.     (reroll_price * (prefix_id > 0 ? Prefix_Data.price_rate(prefix_id) : 1.0)).to_i
  154.   end
  155.  
  156.   def rarity
  157.     base = super
  158.     prefix_id = PrefixStorage.get_prefix(self)
  159.     base + (prefix_id > 0 ? Prefix_Data.rarity_change(prefix_id) : 0)
  160.   end
  161. end
  162.  
  163. #==============================================================================
  164. # ■ 扩展 RPG::Armor(同上)
  165. #==============================================================================
  166. class RPG::Armor
  167.   alias reroll_original_name name
  168.  
  169.   def name
  170.     prefix_id = PrefixStorage.get_prefix(self)
  171.     if prefix_id > 0
  172.       "#{Prefix_Data.prefix_name(prefix_id)}#{reroll_original_name}"
  173.     else
  174.       reroll_original_name
  175.     end
  176.   end
  177.  
  178.   def display_name
  179.     name
  180.   end
  181.  
  182.   alias reroll_price price
  183.   def real_price
  184.     prefix_id = PrefixStorage.get_prefix(self)
  185.     (reroll_price * (prefix_id > 0 ? Prefix_Data.price_rate(prefix_id) : 1.0)).to_i
  186.   end
  187.  
  188.   def rarity
  189.     base = super
  190.     prefix_id = PrefixStorage.get_prefix(self)
  191.     base + (prefix_id > 0 ? Prefix_Data.rarity_change(prefix_id) : 0)
  192.   end
  193. end
  194.  
  195. #==============================================================================
  196. # ■ 核心:在 Game_BattlerBase 中注入前缀属性加成(仅角色)
  197. #==============================================================================
  198. class Game_BattlerBase
  199.   alias reroll_param_plus param_plus
  200.   def param_plus(param_id)
  201.     base = reroll_param_plus(param_id)
  202.     base + (is_a?(Game_Actor) ? equip_prefix_bonus(param_id) : 0)
  203.   end
  204.  
  205.   def equip_prefix_bonus(param_id)
  206.     return 0 unless is_a?(Game_Actor)
  207.     equips.compact.inject(0) do |sum, item|
  208.       if item.is_a?(RPG::Weapon) || item.is_a?(RPG::Armor)
  209.         prefix_id = PrefixStorage.get_prefix(item)
  210.         sum + Prefix_Data.get_param_bonus(prefix_id, param_id)
  211.       else
  212.         sum
  213.       end
  214.     end
  215.   end
  216. end
  217.  
  218. #==============================================================================
  219. # ■ 修正 Game_Party 的装备列表方法
  220. #==============================================================================
  221. class Game_Party
  222.   def all_weapons
  223.     result = []
  224.     @weapons.each do |item_id, count|
  225.       weapon = $data_weapons[item_id]
  226.       next unless weapon
  227.       count.times { result << weapon }
  228.     end
  229.     result
  230.   end
  231.  
  232.   def all_armors
  233.     result = []
  234.     @armors.each do |item_id, count|
  235.       armor = $data_armors[item_id]
  236.       next unless armor
  237.       count.times { result << armor }
  238.     end
  239.     result
  240.   end
  241.  
  242.   def all_reroll_items
  243.     all_weapons + all_armors
  244.   end
  245. end
  246.  
  247. #==============================================================================
  248. # ■ 重铸场景(已修复确认卡死)
  249. #==============================================================================
  250. class Scene_Reroll < Scene_Base
  251.   def start
  252.     super
  253.     create_help_window
  254.     create_item_window
  255.     create_cost_window
  256.     @last_item = nil
  257.   end
  258.  
  259.   def create_help_window
  260.     @help_window = Window_Help.new
  261.     @help_window.set_text(Reroll_Config::HELP_TEXT)
  262.   end
  263.  
  264.   def create_item_window
  265.     wy = @help_window.height
  266.     wh = Graphics.height - wy - 80
  267.     wh = 0 if wh < 0
  268.     @item_window = Window_RerollItem.new(0, wy, Graphics.width, wh)
  269.     @item_window.set_handler(:ok, method(:on_reroll_ok))
  270.     @item_window.set_handler(:cancel, method(:return_scene))
  271.     @item_window.help_window = @help_window
  272.     @item_window.activate
  273.   end
  274.  
  275.   def create_cost_window
  276.     y = Graphics.height - 80
  277.     @cost_window = Window_Base.new(0, y, Graphics.width, 80)
  278.     update_cost_display
  279.   end
  280.  
  281.   def update_cost_display
  282.     @cost_window.contents.clear
  283.     item = @item_window.current_item
  284.     if item && (item.is_a?(RPG::Weapon) || item.is_a?(RPG::Armor))
  285.       cost = reroll_cost(item)
  286.       discount_text = discount_active? ? Reroll_Config::DISCOUNT_TEXT : ""
  287.       @cost_window.draw_text(0, 0, Graphics.width, 24,
  288.         "#{Reroll_Config::COST_TEXT}#{cost} G#{discount_text}", 1)
  289.     else
  290.       @cost_window.draw_text(0, 0, Graphics.width, 24, Reroll_Config::NO_ITEM_TEXT, 1)
  291.     end
  292.   end
  293.  
  294.   def update
  295.     super
  296.     if @item_window.active && @item_window.current_item != @last_item
  297.       update_cost_display
  298.       @last_item = @item_window.current_item
  299.     end
  300.   end
  301.  
  302.   def on_reroll_ok
  303.     item = @item_window.current_item
  304.     unless item && (item.is_a?(RPG::Weapon) || item.is_a?(RPG::Armor))
  305.       Sound.play_buzzer
  306.       @item_window.activate
  307.       return
  308.     end
  309.  
  310.     unless can_reroll?(item)
  311.       Sound.play_buzzer
  312.       @help_window.set_text(Reroll_Config::NO_REROLL_TEXT)
  313.       @item_window.activate
  314.       return
  315.     end
  316.  
  317.     cost = reroll_cost(item)
  318.     if $game_party.gold < cost
  319.       Sound.play_buzzer
  320.       @help_window.set_text(sprintf(Reroll_Config::NO_MONEY_TEXT, cost))
  321.       @item_window.activate
  322.       return
  323.     end
  324.  
  325.     $game_party.lose_gold(cost)
  326.     new_prefix = Prefix_Data.random_prefix_id
  327.     begin
  328.       PrefixStorage.set_prefix(item, new_prefix)
  329.       Sound.play_shop
  330.       @help_window.set_text(sprintf(Reroll_Config::SUCCESS_TEXT, Prefix_Data.prefix_name(new_prefix)))
  331.     rescue => e
  332.       @help_window.set_text("重铸出现异常,请检查前缀配置")
  333.       p "Reroll Error: #{e.message}"
  334.     end
  335.  
  336.     @item_window.refresh
  337.     update_cost_display
  338.     @item_window.activate
  339.     @item_window.update
  340.     Graphics.frame_reset
  341.   end
  342.  
  343.   def can_reroll?(item)
  344.     return false unless item.is_a?(RPG::Weapon) || item.is_a?(RPG::Armor)
  345.     return true if Reroll_Config::MAX_RARITY_FOR_REROLL == 0
  346.     item.rarity <= Reroll_Config::MAX_RARITY_FOR_REROLL
  347.   end
  348.  
  349.   def reroll_cost(item)
  350.     base = (item.price * Reroll_Config::REROLL_COST_RATE).to_i
  351.     discount_active? ? (base * Reroll_Config::DISCOUNT_RATE).to_i : base
  352.   end
  353.  
  354.   def discount_active?
  355.     $game_variables[Reroll_Config::DISCOUNT_VARIABLE_ID] > 0
  356.   end
  357.  
  358.   def return_scene
  359.     SceneManager.return
  360.   end
  361. end
  362.  
  363. #==============================================================================
  364. # ■ 重铸物品选择窗口
  365. #==============================================================================
  366. class Window_RerollItem < Window_Selectable
  367.   def initialize(x, y, width, height)
  368.     super
  369.     @data = []
  370.     refresh
  371.   end
  372.  
  373.   def current_item
  374.     @data && @index >= 0 ? @data[@index] : nil
  375.   end
  376.  
  377.   def item_max
  378.     @data ? @data.size : 0
  379.   end
  380.  
  381.   def refresh
  382.     @data = $game_party.all_reroll_items
  383.     create_contents
  384.     draw_all_items
  385.   end
  386.  
  387.   def draw_item(index)
  388.     item = @data[index]
  389.     return unless item
  390.     rect = item_rect(index)
  391.     change_color(normal_color)
  392.     draw_text(rect.x, rect.y, rect.width - 60, line_height, item.display_name)
  393.     draw_text(rect.x, rect.y, rect.width - 24, line_height, item.real_price, 2)
  394.   end
  395.  
  396.   def update_help
  397.     item = current_item
  398.     if item
  399.       text = "#{item.display_name}\n"
  400.       text += "原价:#{item.price} G  现价:#{item.real_price} G\n"
  401.       text += "稀有度:#{item.rarity}"
  402.       @help_window.set_text(text)
  403.     else
  404.       @help_window.set_text("")
  405.     end
  406.   end
  407. end
  408.  
  409. #==============================================================================
  410. # ■ 存档/读档支持(前缀数据存入存档)
  411. #==============================================================================
  412. module DataManager
  413.   class << self
  414.     alias reroll_make_save_contents make_save_contents
  415.     alias reroll_extract_save_contents extract_save_contents
  416.   end
  417.  
  418.   def self.make_save_contents
  419.     contents = reroll_make_save_contents
  420.     contents[:prefixes] = PrefixStorage.save_data
  421.     contents
  422.   end
  423.  
  424.   def self.extract_save_contents(contents)
  425.     reroll_extract_save_contents(contents)
  426.     PrefixStorage.load_data(contents[:prefixes])
  427.   end
  428. end

3_[L]8O4YLIA5HUD`E9R9V0.png (62.25 KB, 下载次数: 21)

3_[L]8O4YLIA5HUD`E9R9V0.png

PULD6%_IFLAE{SJBX8R}V7R.png (24.73 KB, 下载次数: 18)

PULD6%_IFLAE{SJBX8R}V7R.png

JJ62`M`43ZUM8I7KZU2OWF8.png (32.84 KB, 下载次数: 21)

JJ62`M`43ZUM8I7KZU2OWF8.png

@WG9%F}F][email protected] (14.31 KB, 下载次数: 20)

@WG9%F}F]XTI3DW@2A8TAZB.png

Lv3.寻梦者

梦石
1
星屑
1174
在线时间
58 小时
注册时间
2023-9-8
帖子
35
2
 楼主| 发表于 2026-4-8 00:14:30 | 只看该作者
进入重铸的指令
  1. SceneManager.call(Scene_Reroll)
复制代码
回复 支持 反对

使用道具 举报

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2026-6-4 21:33

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表