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

Project1

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

[原创发布] VA冒险者公会任务交互系统/任务悬赏系统脚本

[复制链接]

Lv1.梦旅人

梦石
0
星屑
180
在线时间
33 小时
注册时间
2023-11-3
帖子
3
跳转到指定楼层
1
发表于 昨天 08:48 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 Adelina 于 2025-8-1 08:48 编辑

站内找到的任务系统似乎都是用来查看任务的,没有交互选项……
于是作为ruby萌新的自己只好结合ds的帮助写了一点,分享出来希望可以帮到有类似想法的人。虽然但是都25年了真的还有人在玩VA吗
这个任务系统有接受任务和提交、放弃的选项,比较类似于冒险者公会的悬赏面板。提交任务后可以根据需求打开开关,方便其他事件。比如想要在提交任务后,根据任务的完成情况来发放奖励的话,就可以用开关继续开启一个公共事件。
每用一次添加任务描述都会换行,同时文本内容也支持使用转义符,需要使用双反斜杠。效果和VA文本框里面的一样,具体可以看事件里的脚本指令。其他指令在脚本开头的使用方法里。
脚本里的常量配置部分是可以自行更改的,其中任务与开关映射表也需要自己编辑。修改时请务必注意格式。

新人第一次发帖,可能有bug或者其他各种问题,欢迎积极反馈,只要我看到了消息并且有空的话就会改。如果能够帮到你,希望可以评论一下~

游戏内效果如下:
  

事件范例:


脚本代码:
RUBY 代码复制
  1. #===============================================================================
  2. #
  3. # ■ 公会任务系统 - By Adelina
  4. #
  5. #===============================================================================
  6.  
  7. #===============================================================================
  8. # ● 事件指令使用方法
  9. #===============================================================================
  10. # 1. 打开公会面板: open_quest_board
  11. # 2. 创建任务:     $game_party.create_quest(任务id, "任务标题")
  12. # 3. 添加任务描述: $game_party.add_quest_text(任务id, "描述文本")
  13. # 4. 设置任务可见: $game_party.set_quest_visible(任务id, true/false)
  14. # 5. 接取任务:     $game_party.accept_quest(任务id)  # 可在事件中使用
  15. # 6. 完成任务:     $game_party.finish_quest(任务id)  # 可在事件中使用
  16.  
  17. #===============================================================================
  18. # ● 常量配置
  19. #===============================================================================
  20. module QuestConfig
  21.   # 窗口尺寸比例
  22.   LEFT_WINDOW_WIDTH_RATIO  = 0.4     # 左侧窗口宽度比例
  23.   RIGHT_WINDOW_HEIGHT_RATIO = 0.827  # 右侧窗口高度比例
  24.  
  25.   # 状态字体与文本设置
  26.   STATUS_FONT_SIZE = 18                         # 状态文字大小
  27.   AVAILABLE_STATUS  = "可接取 - 按Enter接取任务" # 可接取状态提示
  28.   ACCEPTED_STATUS   = "进行中 - 按Enter管理任务" # 进行中状态提示
  29.   ACCEPTED_COLOR   = Color.new(255, 255, 0)     # 进行中状态文本颜色
  30.  
  31.   # 无任务时显示的文本内容
  32.   NO_QUEST_TEXT  = "暂无任务"  
  33.  
  34.   # 可接受任务选项文本
  35.   ACCEPT_TEXT   = "接受任务"
  36.   DECLINE_TEXT  = "取消"
  37.  
  38.   # 进行中任务选项文本
  39.   SUBMIT_TEXT   = "提交任务"  # 打开对应开关后,从系统中删除任务
  40.   ABANDON_TEXT  = "放弃任务"  # 直接从系统中删除任务
  41. end
  42.  
  43.  
  44. # 任务ID与开关映射表
  45. # 提交任务后会打开对应的开关,可以接各种事件
  46. QUEST_SWITCH_MAP = {
  47.   # 格式:任务ID => 开关ID
  48.   1 => 10,   # 任务1完成时打开开关10
  49.   2 => 11,   # 同理,任务2完成时打开开关11
  50.   3 => 12
  51. }
  52.  
  53.  
  54.  
  55. #===============================================================================
  56. #===============================================================================
  57. #
  58. # ★ 请尽量不要修改以下内容
  59. #
  60. #===============================================================================
  61. #===============================================================================
  62.  
  63. class Quest
  64.   attr_reader :id
  65.   attr_reader :name
  66.   attr_accessor :accepted
  67.   attr_accessor :visible
  68.   attr_reader :content
  69.  
  70.   def initialize(id, name)
  71.     @id = id
  72.     @name = name
  73.     @accepted = false
  74.     @visible = true  # 默认可见
  75.     @content = []
  76.   end
  77.  
  78.   def add_text(text)
  79.     @content << text
  80.   end
  81.  
  82.   def available?
  83.     !accepted && visible
  84.   end
  85. end
  86.  
  87.  
  88. class Game_Party < Game_Unit
  89.   alias quest_init initialize
  90.   def initialize
  91.     quest_init
  92.     @quests = {}
  93.   end
  94.  
  95.   def create_quest(id, name)
  96.     @quests[id] = Quest.new(id, name)
  97.   end
  98.  
  99.   def add_quest_text(id, text)
  100.     quest = @quests[id]
  101.     quest.add_text(text) if quest
  102.   end
  103.  
  104.   def set_quest_visible(id, visible)
  105.     quest = @quests[id]
  106.     quest.visible = visible if quest
  107.   end
  108.  
  109.   def accept_quest(id)
  110.     quest = @quests[id]
  111.     return unless quest && quest.available?
  112.     quest.accepted = true
  113.   end
  114.  
  115.   def finish_quest(id)
  116.     @quests.delete(id)
  117.   end
  118.  
  119.   def abandon_quest(id)
  120.     @quests.delete(id)
  121.   end
  122.  
  123.   def all_quests
  124.     accepted_quests = @quests.values.select(&:accepted)
  125.     available_quests = @quests.values.select(&:available?)
  126.     accepted_quests + available_quests
  127.   end
  128.  
  129.   def quest(id)
  130.     @quests[id]
  131.   end
  132. end
  133.  
  134.  
  135. class Window_QuestLeft < Window_Selectable
  136.   include QuestConfig
  137.  
  138.   def initialize
  139.     width = (Graphics.width * LEFT_WINDOW_WIDTH_RATIO).to_i
  140.     height = Graphics.height
  141.     super(0, 0, width, height)
  142.     refresh
  143.     activate
  144.   end
  145.  
  146.   def item_max
  147.     $game_party.all_quests.size
  148.   end
  149.  
  150.   def quest
  151.     $game_party.all_quests[@index]
  152.   end
  153.  
  154.   def refresh
  155.     make_item_list
  156.     create_contents
  157.     draw_all_items
  158.   end
  159.  
  160.   def make_item_list
  161.     @data = $game_party.all_quests
  162.   end
  163.  
  164.   def draw_item(index)
  165.     quest = @data[index]
  166.     return unless quest
  167.     rect = item_rect(index)
  168.  
  169.     if quest.accepted
  170.       contents.font.color = ACCEPTED_COLOR
  171.     else
  172.       contents.font.color = normal_color
  173.     end
  174.  
  175.     draw_text(rect, quest.name)
  176.     contents.font.color = normal_color
  177.   end
  178.  
  179.   def ok_enabled?
  180.     item_max > 0
  181.   end
  182.  
  183. end
  184.  
  185.  
  186. class Window_QuestRight < Window_Base
  187.   include QuestConfig
  188.  
  189.   def initialize
  190.     left_width = (Graphics.width * LEFT_WINDOW_WIDTH_RATIO).to_i
  191.     width = Graphics.width - left_width
  192.     height = (Graphics.height * RIGHT_WINDOW_HEIGHT_RATIO).to_i
  193.     super(left_width, 0, width, height)
  194.     @quest = nil
  195.   end
  196.  
  197.   def set_quest(quest)
  198.     @quest = quest
  199.     refresh
  200.   end
  201.  
  202.   def refresh
  203.     return if disposed? || contents.disposed?
  204.  
  205.     contents.clear
  206.  
  207.     if @quest.nil?
  208.       contents.font.color = system_color
  209.       rect = Rect.new(0, 0, contents_width, contents_height)
  210.       draw_text(rect, NO_QUEST_TEXT, 1)
  211.       contents.font.color = normal_color
  212.       return
  213.     end
  214.  
  215.     original_size = contents.font.size
  216.  
  217.     draw_text(0, 0, contents_width, line_height, @quest.name, 1)
  218.     y = line_height + 10
  219.  
  220.     @quest.content.each do |text|
  221.       draw_text_ex(0, y, text)
  222.       y += line_height * 1.2
  223.     end
  224.  
  225.     contents.font.size = STATUS_FONT_SIZE
  226.  
  227.     status_text = @quest.accepted ? ACCEPTED_STATUS : AVAILABLE_STATUS
  228.     status_color = @quest.accepted ? ACCEPTED_COLOR : normal_color
  229.  
  230.     contents.font.color = status_color
  231.     draw_text(0, contents_height - line_height, contents_width,
  232.               line_height, status_text, 1)
  233.  
  234.     contents.font.color = normal_color
  235.     contents.font.size = original_size
  236.   end
  237. end
  238.  
  239.  
  240. class Window_QuestOption < Window_Command
  241.   include QuestConfig
  242.  
  243.   attr_reader :closed
  244.  
  245.   def initialize(quest)
  246.     @quest = quest
  247.     @closed = false
  248.     super(0, 0)
  249.     update_placement
  250.     self.openness = 255
  251.     activate
  252.   end
  253.  
  254.   def window_width
  255.     return Graphics.width - (Graphics.width * LEFT_WINDOW_WIDTH_RATIO).to_i
  256.   end
  257.  
  258.   def update_placement
  259.     left_width = (Graphics.width * LEFT_WINDOW_WIDTH_RATIO).to_i
  260.     self.x = left_width
  261.     self.y = (Graphics.height * RIGHT_WINDOW_HEIGHT_RATIO).to_i
  262.     self.width = Graphics.width - left_width
  263.   end
  264.  
  265.   def make_command_list
  266.     if @quest.accepted
  267.       add_command(SUBMIT_TEXT, :submit)
  268.       add_command(ABANDON_TEXT, :abandon)
  269.     else
  270.       add_command(ACCEPT_TEXT, :accept)
  271.       add_command(DECLINE_TEXT, :decline)
  272.     end
  273.   end
  274.  
  275.   def close_window
  276.     @closed = true
  277.     deactivate
  278.     self
  279.   end
  280. end
  281.  
  282.  
  283. class Scene_QuestBoard < Scene_Base
  284.   include QuestConfig
  285.  
  286.   def start
  287.     super
  288.     create_left_window
  289.     create_right_window
  290.     @option_window = nil
  291.     select_first_quest
  292.   end
  293.  
  294.   def select_first_quest
  295.     if @left_window.item_max > 0
  296.       @left_window.select(0)
  297.       update_right_window
  298.     else
  299.       @right_window.set_quest(nil)
  300.     end
  301.   end
  302.  
  303.   def create_left_window
  304.     @left_window = Window_QuestLeft.new
  305.     @left_window.set_handler(:ok, method(:on_quest_ok))
  306.     @left_window.set_handler(:cancel, method(:return_scene))
  307.     @left_window.set_handler(:up, method(:on_selection_change))
  308.     @left_window.set_handler(:down, method(:on_selection_change))
  309.   end
  310.  
  311.   def create_right_window
  312.     left_width = (Graphics.width * LEFT_WINDOW_WIDTH_RATIO).to_i
  313.     width = Graphics.width - left_width
  314.     height = (Graphics.height * RIGHT_WINDOW_HEIGHT_RATIO).to_i
  315.     @right_window = Window_QuestRight.new
  316.   end
  317.  
  318.   def on_selection_change
  319.     update_right_window
  320.     close_option_window if @option_window
  321.   end
  322.  
  323.   def update_right_window
  324.     quest = @left_window.quest
  325.     @right_window.set_quest(quest) if quest
  326.   end
  327.  
  328.   def on_quest_ok
  329.     close_option_window if @option_window
  330.     @quest = @left_window.quest
  331.     return unless @quest
  332.     return unless $game_party.quest(@quest.id)
  333.     create_option_window
  334.   end
  335.  
  336.   def update
  337.     super
  338.     return if @left_window.disposed?
  339.     if !@option_window && @left_window.active
  340.       @right_window.set_quest(@left_window.quest)
  341.       update_right_window
  342.     end
  343.  
  344.     if @option_window && @option_window.closed
  345.       @option_window.dispose
  346.       @option_window = nil
  347.       @left_window.activate if @left_window && !@left_window.disposed?
  348.     end
  349.   end
  350.  
  351.   def create_option_window
  352.     return unless @quest && $game_party.quest(@quest.id)
  353.  
  354.     @option_window = Window_QuestOption.new(@quest)
  355.     if @quest.accepted
  356.       @option_window.set_handler(:submit, method(:submit_quest))
  357.       @option_window.set_handler(:abandon, method(:abandon_quest))
  358.     else
  359.       @option_window.set_handler(:accept, method(:accept_quest))
  360.       @option_window.set_handler(:decline, method(:close_option_window))
  361.     end
  362.     @option_window.set_handler(:cancel, method(:close_option_window))
  363.     @left_window.deactivate
  364.   end
  365.  
  366.   def accept_quest
  367.     $game_party.accept_quest(@quest.id)
  368.     Sound.play_ok
  369.     @left_window.refresh
  370.     update_right_window
  371.     @option_window.close_window if @option_window
  372.   end
  373.  
  374.   def submit_quest
  375.     switch_id = QUEST_SWITCH_MAP[@quest.id]
  376.     if switch_id
  377.       $game_switches[switch_id] = true
  378.       $game_party.finish_quest(@quest.id)
  379.       Sound.play_ok
  380.  
  381.       @left_window.refresh
  382.       if @left_window.item_max > 0
  383.         @left_window.select(0)
  384.         quest = @left_window.quest
  385.         @right_window.set_quest(quest)
  386.       else
  387.         @right_window.set_quest(nil)
  388.       end
  389.     else
  390.       Sound.play_buzzer
  391.       show_error_message("该任务尚未配置完成开关!" )
  392.     end
  393.     @option_window.close_window if @option_window
  394.     update_right_window
  395.   end
  396.  
  397.   def abandon_quest
  398.     $game_party.abandon_quest(@quest.id)
  399.     Sound.play_cancel
  400.  
  401.     @left_window.refresh
  402.     if @left_window.item_max > 0
  403.       @left_window.select(0)
  404.       quest = @left_window.quest
  405.       @right_window.set_quest(quest)
  406.     else
  407.       @right_window.set_quest(nil)
  408.     end
  409.     @option_window.close_window if @option_window
  410.     update_right_window
  411.   end
  412.  
  413.   def show_error_message(text)
  414.     $game_message.add(text)
  415.     SceneManager.call(Scene_Message)
  416.   end
  417.  
  418.   def safe_close_option_window
  419.     return unless @option_window
  420.  
  421.     @option_window.close_window
  422.     @option_window.dispose
  423.     @option_window = nil
  424.  
  425.     @left_window.activate if @left_window && !@left_window.disposed?
  426.   end
  427.  
  428.   def close_option_window
  429.     @option_window.close_window if @option_window
  430.     update_right_window
  431.   end
  432.  
  433.   def terminate
  434.     super
  435.     close_option_window
  436.     @option_window.dispose if @option_window
  437.   end
  438. end
  439.  
  440. def open_quest_board
  441.   SceneManager.call(Scene_QuestBoard)
  442. end

评分

参与人数 1+1 收起 理由
涅炎 + 1 精品文章

查看全部评分

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

本版积分规则

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

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

GMT+8, 2025-8-2 20:23

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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