じ☆ve冰风 发表于 2025-8-1 08:32:50

VA冒险者公会任务交互系统/任务悬赏系统脚本

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

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

游戏内效果如下:


事件范例:


脚本代码:
RUBY 代码
#===============================================================================
#
# ■ 公会任务系统 - By Adelina
#
#===============================================================================

#===============================================================================
# ● 事件指令使用方法
#===============================================================================
# 1. 打开公会面板: open_quest_board
# 2. 创建任务:   $game_party.create_quest(任务id, "任务标题")
# 3. 添加任务描述: $game_party.add_quest_text(任务id, "描述文本")
# 4. 设置任务可见: $game_party.set_quest_visible(任务id, true/false)
# 5. 接取任务:   $game_party.accept_quest(任务id)# 可在事件中使用
# 6. 完成任务:   $game_party.finish_quest(任务id)# 可在事件中使用

#===============================================================================
# ● 常量配置
#===============================================================================
module QuestConfig
# 窗口尺寸比例
LEFT_WINDOW_WIDTH_RATIO= 0.4   # 左侧窗口宽度比例
RIGHT_WINDOW_HEIGHT_RATIO = 0.827# 右侧窗口高度比例

# 状态字体与文本设置
STATUS_FONT_SIZE = 18                         # 状态文字大小
AVAILABLE_STATUS= "可接取 - 按Enter接取任务"# 可接取状态提示
ACCEPTED_STATUS   = "进行中 - 按Enter管理任务"# 进行中状态提示
ACCEPTED_COLOR   = Color.new(255, 255, 0)   # 进行中状态文本颜色

# 无任务时显示的文本内容
NO_QUEST_TEXT= "暂无任务"

# 可接受任务选项文本
ACCEPT_TEXT   = "接受任务"
DECLINE_TEXT= "取消"

# 进行中任务选项文本
SUBMIT_TEXT   = "提交任务"# 打开对应开关后,从系统中删除任务
ABANDON_TEXT= "放弃任务"# 直接从系统中删除任务
end


# 任务ID与开关映射表
# 提交任务后会打开对应的开关,可以接各种事件
QUEST_SWITCH_MAP = {
# 格式:任务ID => 开关ID
1 => 10,   # 任务1完成时打开开关10
2 => 11,   # 同理,任务2完成时打开开关11
3 => 12
}



#===============================================================================
#===============================================================================
#
# ★ 请尽量不要修改以下内容
#
#===============================================================================
#===============================================================================

class Quest
attr_reader :id
attr_reader :name
attr_accessor :accepted
attr_accessor :visible
attr_reader :content

def initialize(id, name)
    @id = id
    @name = name
    @accepted = false
    @visible = true# 默认可见
    @content = []
end

def add_text(text)
    @content0
end

end


class Window_QuestRight < Window_Base
include QuestConfig

def initialize
    left_width = (Graphics.width * LEFT_WINDOW_WIDTH_RATIO).to_i
    width = Graphics.width - left_width
    height = (Graphics.height * RIGHT_WINDOW_HEIGHT_RATIO).to_i
    super(left_width, 0, width, height)
    @quest = nil
end

def set_quest(quest)
    @quest = quest
    refresh
end

def refresh
    returnif disposed? || contents.disposed?

    contents.clear

    if@quest.nil?
      contents.font.color = system_color
      rect = Rect.new(0, 0, contents_width, contents_height)
      draw_text(rect, NO_QUEST_TEXT, 1)
      contents.font.color = normal_color
      return
    end

    original_size = contents.font.size

    draw_text(0, 0, contents_width, line_height, @quest.name, 1)
    y = line_height + 10

    @quest.content.eachdo |text|
      draw_text_ex(0, y, text)
      y += line_height * 1.2
    end

    contents.font.size = STATUS_FONT_SIZE

    status_text = @quest.accepted ? ACCEPTED_STATUS : AVAILABLE_STATUS
    status_color = @quest.accepted ? ACCEPTED_COLOR : normal_color

    contents.font.color = status_color
    draw_text(0, contents_height - line_height, contents_width,
            line_height, status_text, 1)

    contents.font.color = normal_color
    contents.font.size = original_size
end
end


class Window_QuestOption < Window_Command
include QuestConfig

attr_reader :closed

def initialize(quest)
    @quest = quest
    @closed = false
    super(0, 0)
    update_placement
    self.openness = 255
    activate
end

def window_width
    return Graphics.width - (Graphics.width * LEFT_WINDOW_WIDTH_RATIO).to_i
end

def update_placement
    left_width = (Graphics.width * LEFT_WINDOW_WIDTH_RATIO).to_i
    self.x = left_width
    self.y = (Graphics.height * RIGHT_WINDOW_HEIGHT_RATIO).to_i
    self.width = Graphics.width - left_width
end

def make_command_list
    if@quest.accepted
      add_command(SUBMIT_TEXT, :submit)
      add_command(ABANDON_TEXT, :abandon)
    else
      add_command(ACCEPT_TEXT, :accept)
      add_command(DECLINE_TEXT, :decline)
    end
end

def close_window
    @closed = true
    deactivate
    self
end
end


class Scene_QuestBoard < Scene_Base
include QuestConfig

def start
    super
    create_left_window
    create_right_window
    @option_window = nil
    select_first_quest
end

def select_first_quest
    if@left_window.item_max > 0
      @left_window.select(0)
      update_right_window
    else
      @right_window.set_quest(nil)
    end
end

def create_left_window
    @left_window = Window_QuestLeft.new
    @left_window.set_handler(:ok, method(:on_quest_ok))
    @left_window.set_handler(:cancel, method(:return_scene))
    @left_window.set_handler(:up, method(:on_selection_change))
    @left_window.set_handler(:down, method(:on_selection_change))
end

def create_right_window
    left_width = (Graphics.width * LEFT_WINDOW_WIDTH_RATIO).to_i
    width = Graphics.width - left_width
    height = (Graphics.height * RIGHT_WINDOW_HEIGHT_RATIO).to_i
    @right_window = Window_QuestRight.new
end

def on_selection_change
    update_right_window
    close_option_window if@option_window
end

def update_right_window
    quest = @left_window.quest
    @right_window.set_quest(quest)if quest
end

def on_quest_ok
    close_option_window if@option_window
    @quest = @left_window.quest
    returnunless@quest
    returnunless$game_party.quest(@quest.id)
    create_option_window
end

def update
    super
    returnif@left_window.disposed?
    if !@option_window && @left_window.active
      @right_window.set_quest(@left_window.quest)
      update_right_window
    end

    if@option_window && @option_window.closed
      @option_window.dispose
      @option_window = nil
      @left_window.activateif@left_window && !@left_window.disposed?
    end
end

def create_option_window
    returnunless@quest && $game_party.quest(@quest.id)

    @option_window = Window_QuestOption.new(@quest)
    if@quest.accepted
      @option_window.set_handler(:submit, method(:submit_quest))
      @option_window.set_handler(:abandon, method(:abandon_quest))
    else
      @option_window.set_handler(:accept, method(:accept_quest))
      @option_window.set_handler(:decline, method(:close_option_window))
    end
    @option_window.set_handler(:cancel, method(:close_option_window))
    @left_window.deactivate
end

def accept_quest
    $game_party.accept_quest(@quest.id)
    Sound.play_ok
    @left_window.refresh
    update_right_window
    @option_window.close_windowif@option_window
end

def submit_quest
    switch_id = QUEST_SWITCH_MAP[@quest.id]
    if switch_id
      $game_switches = true
      $game_party.finish_quest(@quest.id)
      Sound.play_ok

      @left_window.refresh
      if@left_window.item_max > 0
      @left_window.select(0)
      quest = @left_window.quest
      @right_window.set_quest(quest)
      else
      @right_window.set_quest(nil)
      end
    else
      Sound.play_buzzer
      show_error_message("该任务尚未配置完成开关!")
    end
    @option_window.close_windowif@option_window
    update_right_window
end

def abandon_quest
    $game_party.abandon_quest(@quest.id)
    Sound.play_cancel

    @left_window.refresh
    if@left_window.item_max > 0
      @left_window.select(0)
      quest = @left_window.quest
      @right_window.set_quest(quest)
    else
      @right_window.set_quest(nil)
    end
    @option_window.close_windowif@option_window
    update_right_window
end

def show_error_message(text)
    $game_message.add(text)
    SceneManager.call(Scene_Message)
end

def safe_close_option_window
    returnunless@option_window

    @option_window.close_window
    @option_window.dispose
    @option_window = nil

    @left_window.activateif@left_window && !@left_window.disposed?
end

def close_option_window
    @option_window.close_windowif@option_window
    update_right_window
end

def terminate
    super
    close_option_window
    @option_window.disposeif@option_window
end
end

def open_quest_board
SceneManager.call(Scene_QuestBoard)
end

            本帖来自P1论坛作者Adelina,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=497831若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页: [1]
查看完整版本: VA冒险者公会任务交互系统/任务悬赏系统脚本