RSQS: Reedo's Simple Quest System (beta)

Reedo

Coder
Veteran
Joined
Sep 17, 2013
Messages
71
Reaction score
38
First Language
English
Primarily Uses
Reedo's Simple Quest System (RSQS)

Version 0.3 (beta)

September 23, 2013

By Reedo

References

None. This is an original script by Reedo.

Description

RSQS is an easy-to-use quest system.  The RSQS script is purely about managing quests and is not a quest journal.  The RQJS (Reedo's Quest Journal Scene) script found later in this post can be used in conjunction with RSQS to add a scene for viewing quests (RQJS is in testing).

A quest system itself is about assigning quests, tracking their status, turning them in, and giving rewards.  All of this can be done without any kind of quest journal for viewing existing quests.  A quest journal is an additional script which can work in conjunction with a quest system.

So to be clear, the RSQS script is on a quest system, and the RQJS is only a quest journal scene.  In my estimation, this design (featuring a separation of concerns between the quest system and the quest journal) results in a cleaner and easier to use quest system and journal.

This quest system is easily utilized by installing the script, using the attached RSQS Editor to configure your quests, and then using simple script commands in events to assign and turn in quests.

Features

  • Easy-to-use quest system
  • Unlimited quests with unlimited categories
  • Multi-stage quests, unlimited stages per quest (minimum one)
  • Unlimited number of requirements per stage
  • -- party has certain number of items in inventory
  • -- collect specified number of virtual item drops from battle
  • -- kill specified number of certain enemy
  • -- specified switch is set or not set
  • -- specified variable equals the given value
  • Unlimited number of rewards per stage
  • -- award gold
  • -- award experience
  • -- award items
  • -- award armor
  • -- award weapons
  • Automatic quest updates at end of battle
  • Simple event script command interface using $game_reedo_quests
  • assign quests from an event
  • provide quest status feedback from an event
  • turn in a quest from an event
  • Quest configuration via easy-to-write secondary script
  • Quest configuration via easy-to-use editor
  • Separate "Quest Journal" scene for viewing quest status in game


Virtual Items

A virtual item is one that does not exist in the database.  It is not a real game item.  Virtual items are dropped by monsters after battle and while a quest tracks the number of virtual items received, there are never any actual items in the player's inventory.  This makes it very easy to collect items for quest turn-in purposes only, without having to create anything in the database ahead of time.

When you create a new virtual item, in addition to giving it a name, you will also assign the enemy ID and drop chance for each enemy that can drop the virtual item after a battle.  Virtual items are awarded after a battle, along with any other normal enemy drop items.

Known Bugs

None at this time.

Please report any bugs found.

Requirements

  • Requires the RSQS Editor application (or separate configuration script) to setup quests.
  • Requires on-map events and/or common events to manage quests.
Installation

Plug-and-Play* (see requirements)

Just insert a new script directly under Materials, name it RSQS, and paste in the script code.

Configuration

  -- New! --

There is now an editor available for RSQS! (updated to version 1.1 on 9/23)

Attached to this post you will find a zip file containing a small VB.Net application which will allow you to easily create quests to be used with RSQS.  The program will allow you to create a working data file that you can use to define and modify quests.  You can save and load your work at any time.  When you are ready, you can export your quests to a ReedoQuestData.rvdata2 file that the script will load automatically from your games Data directory.

To use this application, you'll need to have .Net Framework 4.0 and Ruby 1.9x (or later I assume).  The editor's installer will grab the .Net framework automatically if you need it, so nothing to do there.  To get Ruby you can use the link above or go to the downloads section of the Ruby website.  When installing Ruby, be sure to select the option to add Ruby to your path.  Just pay attention to the installer screens and you'll see it.

The editor contains a fairly detailed help document (available from Help on the menu) so please read that completely before asking any questions.  The editor should be easy to use, but if you still have questions after reading the help file, please post them here.

The Old Way

If you don't want to use the editor, you can still use the old way of providing a ReedoQuestManager script.  You can actually use both ways, but the data file will load first, so the first quest defined in the script will have an ID equal to the number of quests defined in the data file.

After inserting the main script, insert a second script beneath RSQS and name it ReedoQuestManager (this name isn't actually important).  This script will be used to load all of your quest definitions.  It contains a single module which must be named "ReedoQuestManager" and which must contain the single method "self.load_quests".

module ReedoQuestManager def self.load_quests endend
Within the self.load_quests method you will create and configure instances of Reedo_Quest and supporting objects.  Each quest will receive an ID number in the order it is added to the $data_reedo_quests collection, so it is good to add comments to each quest so you can easily recognize the quest ID.

A complete ReedoQuestManager example, with comments, follows:

module ReedoQuestManager def self.load_quests#01 add a comment to remind yourself of the ID number #ID 0#02 create a new quest instance with the given name and category quest = Reedo_Quest.new("Slimy Balls", "Side Quest")#03 create a new stage instance - every quest needs at least one stage stage = Reedo_Quest_Stage.new#04 optionally, add a short reminder text about the quest;# only shown in game optionally - mostly meant for quest journal add-on,# or for events which show quest status. stage.story_text = "There are too many slimes!\nKill at least 8 and bring\nback 4 Slime Balls."#05 create a requirement which must be met to turn the quest in requirement = Reedo_Quest_Requirement.new#06 configure the requirement by calling any of the following methods: # add_item(itemId, reqCount) - must have specified qty of item in inventory# add_virtual(item, reqCount) - must collect specified qty of virtual items# add_kill(enemyId, reqCount) - must kill specified number of enemy# add_switch(switchId, state) - switch must equal state# add_variable(variableId, value) - variable must equal value requirement.add_kill(1, 8) # kill 8 slimes#06.a virtual items are defined first, then assigned to the requirement vitem = Reedo_Quest_Virtual_Item.new vitem.set_name("Slime Ball") vitem.set_provider(1, 0.5) # slimes have 50% chance to drop "Slime Ball" requirement.add_virtual(vitem, 4) # requires 4 "Slime Ball" virtual items#07 once configured, add requirement to quest stage stage.requirements.push(requirement)#07.a repeat from #5 to add additional requirements#08 create a reward for completing this stage reward = Reedo_Quest_Reward.new#09 configure the reward by calling any of the following methods:# award_gold(value) - give amount of gold# award_exp(value) - reward amount of experience to living party members# award_item(itemId, count) - add count of item to inventory# award_armor(armorId, count) - add count of armor to inventory# award_weapon(weaponId, count) - add count of weapon to inventory reward.award_gold(25) reward.award_exp(20)#10 once configured, add reward to quest stage stage.rewards.push(reward)#10.a repeat from #8 to add additional rewards if needed#11 once configured, add the stage to the quest quest.add_stage(stage)#11.a repeat from #3 to add additional stages if desired#13 once configured, add the quest to the global quest repository $data_reedo_quests.push(quest)#14 repeat from #1 to add additional quests until complete endend# Once all of your quests are defined, you can use simple events in the game# to assign quests to the player, give feed-back to the player on the status# of a quest, and turn a completed quest in.## A basic event page for a quest giver and turn in might look like:## @>Conditional Branch: Script: $game_reedo_quests.contains?(0)# @>Conditional Branch: Script: $game_reedo_quests.get_quest(0).turn_in# @> (show text to tell any story that goes along with finsihing the quest)# @>Control Self Switch: A=ON (disable the event)# : Else# @> (show text to tell the player that they aren't finished yet)# : Branch End# : Else# @> (show text to offer the player the quest)# @>Script: $game_reedo_quests.assign_quest(0)# : Branch End
Event Screen Shot

Here is an example of an event which gives a quest, provides quest status, and turns in the quest when

complete.  Note the simple script commands used to branch the event to first either assign the quest or update it and then to either thank the player for finishing the quest or provide them with their status so far.

RSQS1.jpg

Detail Usage Information

A detailed help document is available within the RSQS Editor from the Help menu.  This document contains information about using the editor and creating quests, using map events to control quests, and reference information for the RSQS quest objects.  Please consult this document before posting support questions.

Compatibility

Should be compatible with most other scripts.

 

Script

Here is the complete RSQS script:

################################################################################# RSQS - Reedo's Simple Quest System## Version 0.3 (beta)## September 23, 2013## By Reedo################################################################################# REFERENCES#### None. This is an original script by Reedo.################################################################################# FEATURES#### + Easy-to-use quest system## + Unlimited quests with unlimited categories## + Multi-stage quests, unlimited stages per quest (minimum one)## + Unlimited number of requirements per stage## - Party has certain number of items in inventory## - Collect specified number of virtual item drops from battle## - Kill specified number of certain enemy## - Specified switch is set or not set## - Specified variable equals the given value## + Unlimited number of rewards per stage## - award gold## - award experience## - award items## - award armor## - award weapons## + Automatic quest updates at end of battle## + Simple event script command interface using $game_reedo_quests## - assign quests from an event## - provide quest status feedback from an event## - turn in a quest from an event## + Quest configuration via easy-to-write secondary script################################################################################### COMPATIBILITY#### Should be compatible with most other scripts.################################################################################# REQUIREMENTS#### 1) Requires RSQS Editor available at:## or seperate configuration script to setup quests.#### 2) Requires on-map events and/or common events to manage quests.################################################################################# INSTALLATION#### Plug-and-play*(see requirements)#### Insert below Materials, above other add-on scripts.################################################################################# RIGHTS & RESTRICTIONS#### As with most Reedo scripts, this script is free to re-use, as-is, ## in personal, educational, and commercial RPGVX Ace development projects, ## providing that: this script is credited in writing displayed readily ## to the user of the final compiled code assembly.#### Reedo retains all rights of intellect and ownership.## You forego all rights of warranty by utilizing this script.################################################################################################################################################################ USER OPTIONS###############################################################################module RSQS STAGE_COMPLETE_MESSAGE_FORMAT = "Stage Complete: %s" STAGE_WORKING_MESSAGE_FORMAT = "You are still working on %s." STAGE_WORKING_USE_STORY = true QUEST_ITEM_UPDATE_MESSAGE_FORMAT = "Found Quest Item: %s" QUEST_REQUIREMENT_MET_MESSAGE_FORMAT = "You've met the requirements for: %s" QUEST_COMPLETE_ME_NAME = "fanfare1" QUEST_COMPLETE_ME_PITCH = 100 QUEST_COMPLETE_ME_VOLUME = 100end################################################################################# MAIN SCRIPT################################################################################# EDITS BEYOND THIS POINT ARE AT YOUR OWN RISK!!!###############################################################################module DataManager class << self alias reedo_sqs_dm_load_normal_database load_normal_database alias reedo_sqs_dm_create_game_objects create_game_objects alias reedo_sqs_dm_make_save_contents make_save_contents alias reedo_sqs_dm_extract_save_contents extract_save_contents end def self.load_normal_database reedo_sqs_dm_load_normal_database begin $data_reedo_quests = load_data("Data/ReedoQuestData.rvdata2") rescue $data_reedo_quests = [] end end def self.create_game_objects reedo_sqs_dm_create_game_objects $game_reedo_quests = Reedo_Quests.new begin qm = ReedoQuestManager rescue qm = nil end qm.load_quests if qm end def self.make_save_contents contents = reedo_sqs_dm_make_save_contents contents[:reedo_quests] = $game_reedo_quests contents end def self.extract_save_contents(contents) reedo_sqs_dm_extract_save_contents(contents) $game_reedo_quests = contents[:reedo_quests] $game_reedo_quests = Reedo_Quests.new if !$game_reedo_quests endendmodule BattleManager class << self alias reedo_sqs_bm_gain_drop_items gain_drop_items end def self.gain_drop_items reedo_gain_quest_updates reedo_sqs_bm_gain_drop_items end def self.reedo_gain_quest_updates $game_troop.dead_members.each do |enemy| $game_reedo_quests.active_quests.each do |quest| if quest.current_stage if !quest.current_stage.complete? quest.current_stage.requirements.each do |requirement| requirement.kills.each_key do |enemyid| requirement.kill_count[enemyid] += 1 if enemyid == enemy.enemy_id end requirement.virtual.each_key do |item| if item.providers.keys.include?(enemy.enemy_id) if rand(0) <= item.providers[enemy.enemy_id] requirement.virtual_count[item] += 1 $game_message.add(sprintf(RSQS::QUEST_ITEM_UPDATE_MESSAGE_FORMAT, item.name)) end end end end if quest.current_stage.complete? $game_message.add(sprintf(RSQS::QUEST_REQUIREMENT_MET_MESSAGE_FORMAT, quest.current_stage.name)) end end end end end endendclass Reedo_Quest_Virtual_Item attr_reader :name # name of virtual item attr_reader :providers # hash of enemy ID and drop chance def initialize @name = "" @providers = {} end def set_name(itemName) @name = itemName end def add_provider(enemyId, chance) @providers[enemyId] = chance endendclass Reedo_Quest_Requirement attr_reader :items # hash of item ID and required count attr_reader :virtual # hash of virtual item and required count attr_reader :kills # hash of enemy ID and required count attr_reader :switches # hash of switch id and state flag attr_reader :variables # hash of variable name and value attr_reader :virtual_count # hash of virtual item and current count attr_reader :kill_count # hash of enemy ID and current count def initialize @items = {} @virtual = {} @kills = {} @switches = {} @variables = {} @virtual_count = {} @kill_count = {} end def add_item(itemId, reqCount) @items[itemId] = reqCount end def add_virtual(item, reqCount) @virtual[item] = reqCount @virtual_count[item] = 0 end def add_kill(enemyId, reqCount) @kills[enemyId] = reqCount @kill_count[enemyId] = 0 end def add_switch(switchId, state) @switches[switchId] = state end def add_variable(variableId, value) @variables[variableId] = value end def kills_left(enemyId) result = @kills[enemyId] - @kill_count[enemyId] return result if result > -1 return 0 end def virtual_left(orderId) item = @virtual.keys[orderId] result = @virtual[item] - @virtual_count[item] return result if result > -1 return 0 end def items_left(itemId) result = @items[itemId] - $game_party.item_number($data_items[itemId]) return result if result > -1 return 0 end def complete? @items.each do |key, value| return false if $game_party.item_number($data_items[key]) < value end @virtual.each do |key, value| return false if @virtual_count[key] < value end @kills.each do |key, value| return false if @kill_count[key] < value end @switches.each do |key, value| return false if !$game_switches[key] == value end @variables.each do |key, value| return false if !$game_variables[key] == value end return true end def reset @virtual.each_key do |key| @virtual_count[key] = 0 end @kills.each_key do |key| @kill_count[key] = 0 end endendclass Reedo_Quest_Reward attr_reader :gold # amount of gold rewarded attr_reader :exp # amount of experience rewarded attr_reader :items # hash of reward item id and count attr_reader :armors # hash of reward armor id and count attr_reader :weapons # hash of reward weapon id and count def initialize @gold = 0 @exp = 0 @items = {} @armors = {} @weapons = {} end def award_gold(value) @gold = value end def award_exp(value) @exp = value end def award_item(itemId, count) @items[itemId] = count end def award_armor(armorId, count) @armors[armorId] = count end def award_weapon(weaponId, count) @weapons[weaponId] = cout endendclass Reedo_Quest_Stage #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_reader :quest # the quest the stage belongs to attr_accessor :stage_number # order of stage in quest line attr_accessor :stage_name # name of the stage (optional) attr_reader :requirements # array of requirements to complete stage attr_reader :rewards # array of rewards for completing stage attr_accessor :story_text # message to display def initialize @quest = nil @stage_number = 0 @stage_name = nil @requirements = [] @rewards = [] @story_text = "" end def complete? @requirements.each do |requirement| return false if !requirement.complete? end return true end def name return @stage_name if @stage_name and @stage_name.size > 0 return @quest.quest_name if @quest and @quest.quest_name and @quest.quest_name.size > 0 return "(???)" end def reset @requirements.each do |requirement| requirement.reset end end def set_story(text) story_text = text end def set_owner(ownerQuest) @quest = ownerQuest endendclass Reedo_Quest #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_reader :category # quest type category name (unique id) attr_reader :quest_name # name of the quest (unique id) attr_reader :description # brief description of quest attr_reader :stages # array of stages attr_reader :stage_index # index of active quest stage def initialize @category = "Quest" @name = "" @description = "" @stages = [] @stage_index = 0 end def initialize(name, cat) @category = cat @quest_name = name @description = "" @stages = [] @stage_index = 0 end def add_stage(stage) stage.set_owner(self) @stages.push(stage) end def set_description(text) @description = text end def get_description return @description if @description && @description.size > 0 return current_stage.story_text if current_stage.story_text && !complete? return "" end def assign_rewards(show) if current_stage current_stage.rewards.each do |reward| if reward.gold > 0 $game_party.gain_gold(reward.gold) msg = sprintf(Vocab::obtainGold, reward.gold) if show $game_message.add('\.' + msg) if show end if reward.exp > 0 $game_party.alive_members.each do |member| member.gain_exp(reward.exp) end msg = sprintf(Vocab::obtainExp, reward.exp) if show $game_message.add('\.' + msg) if show end reward.items.each_key do |itemId| item = $data_items[itemId] $game_party.gain_item(item, reward.items[itemId]) $game_message.add(sprintf(Vocab::obtainItem, item.name)) if show end reward.armors.each_key do |itemId| item = $data_armors[itemId] $game_party.gain_item(item, reward.armors[itemId]) $game_message.add(sprintf(Vocab::obtainItem, item.name)) if show end reward.weapons.each_key do |itemId| item = $data_weapons[itemId] $game_party.gain_item(item, reward.weapons[itemId]) $game_message.add(sprintf(Vocab::obtainItem, item.name)) if show end end end end # determines if quest is completed def complete? @stage_index >= stages.size end # gets the currently active quest stage def current_stage @stages.sort_by{|item| item.stage_number}[stage_index] end def reset @stage_index = 0 @stages.each do |stage| stage.reset end end # attempts to turn in the current quest stage if the quest is not complete; returns true/false indicating success def turn_in(showComplete = true, showWorking = false) if !complete? if current_stage.complete? if showComplete $game_reedo_quests.play_quest_complete_me msg = sprintf(RSQS::STAGE_COMPLETE_MESSAGE_FORMAT, current_stage.name) $game_message.add('\.' + msg) end assign_rewards(showComplete) @stage_index += 1 return true end if showWorking if RSQS::STAGE_WORKING_USE_STORY msg = sprintf(current_stage.story_text, current_stage.name) $game_message.add('\.' + msg) else msg = sprintf(RSQS::STAGE_WORKING_MESSAGE_FORMAT, current_stage.name) $game_message.add('\.' + msg) end end end return false endendclass Reedo_Quests def initialize @quests = [] @quest_ids = [] @quest_complete_me = RPG::ME.new(RSQS::QUEST_COMPLETE_ME_NAME, RSQS::QUEST_COMPLETE_ME_VOLUME, RSQS::QUEST_COMPLETE_ME_PITCH) end def active_quests @quests.select {|quest| !quest.complete? } end def known_quests @quests end def assign_quest(questId) @quests.push($data_reedo_quests[questId]) @quest_ids.push(questId) end def contains?(questId) @quest_ids.include?(questId) end def get_quest(questId) @quests[@quest_ids.index(questId)] end def play_quest_complete_me @quest_complete_me.play endend
Reedo's Quest Journal Scene (RQJS)

If you would like your game to provide a scene for the player to view quest status, you can install the following RQJS script below the RSQS script.

The RQJS script will provide a simple journal scene accessible from the menu via a "Quests" entry.  The first window will display quests organized by category.  The player can select a quest to view a list of stages known so far.  The journal will only show completed stages and the currently active stage.  Remaining stages will not be shown until they become active. 

The player can then select a stage to view two windows with scrolling lists for the requirements (top) and rewards (bottom).  The select button will pass focus between the two windows.  The cancel button will back out of any window.

Requirements show for items, virtual items, and kills and display the current amount and amount required.  Stages without requirements just show a general "Complete the stage objectives." message, and the stage's name and/or story text is expected to tell the player what they need to do.

Rewards show as "?" until a stage is completed.  There will be a "?" shown for each kind of reward the quest offers, so the player has some idea of what they will get (gold, experience, items, etc) but they do not know how much/many or which item/armor/weapon.  After the stage is completed and the reward has been given, the window shows the actual rewards and amounts.

Install this script directly below the RSQS script.  No other configuration is required.

################################################################################# RQJS - Reedo's Quest Journal Scene## Version 0.02 (beta)## September 23, 2013## By Reedo################################################################################# REFERENCES#### None. This is an original script by Reedo.################################################################################# FEATURES#### + Journal Scene for RSQS (Reedo's Simple Quest System)## + Displays quests orgainized by category## + Selecting a quest shows stage details## + Selecting a stage shows requirement and reward details################################################################################### COMPATIBILITY#### Should be compatible with most other scripts.################################################################################# REQUIREMENTS#### RSQS - Reedo's Simple Quest System v0.3 or later################################################################################# INSTALLATION#### Plug-and-play*(see requirements)#### Insert below RSQS, above other add-on scripts.################################################################################# RIGHTS & RESTRICTIONS#### As with most Reedo scripts, this script is free to re-use, as-is, ## in personal, educational, and commercial RPGVX Ace development projects, ## providing that: this script is credited in writing displayed readily ## to the user of the final compiled code assembly.#### Reedo retains all rights of intellect and ownership.## You forego all rights of warranty by utilizing this script.################################################################################################################################################################ MAIN SCRIPT################################################################################# EDITS BEYOND THIS POINT ARE AT YOUR OWN RISK!!!###############################################################################class Window_Base alias reedo_sqs_wb_convert_escape_characters convert_escape_characters def convert_escape_characters(text) result = reedo_sqs_wb_convert_escape_characters(text) result.gsub!(/\r/) { "\n" } result end endclass Window_MenuCommand alias rqjs_wmc_add_original_commands add_original_commands def add_original_commands rqjs_wmc_add_original_commands add_command("Quests", :quests, main_commands_enabled) endendclass Window_QuestCategory < Window_Command #-------------------------------------------------------------------------- # * Initialize Command Selection Position (Class Method) #-------------------------------------------------------------------------- def self.init_command_position @@last_command_symbol = nil end #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize super(0, 0) select_last #set_handler:)cancel, method:)process_cancel)) end def window_height return Graphics.height end #-------------------------------------------------------------------------- # * Get Window Width #-------------------------------------------------------------------------- def window_width return 160 end #-------------------------------------------------------------------------- # * Get Number of Lines to Show #-------------------------------------------------------------------------- def visible_line_number item_max end #-------------------------------------------------------------------------- # * Create Command List #-------------------------------------------------------------------------- def make_command_list add_main_commands end #-------------------------------------------------------------------------- # * Add Main Commands to List #-------------------------------------------------------------------------- def add_main_commands categories = {} $game_reedo_quests.known_quests.each do |quest| if !categories.has_key?(quest.category) categories[quest.category] = [] end categories[quest.category].push(quest) end categories.each do |category, questlist| add_command(category, :process_category, true, questlist) end end #-------------------------------------------------------------------------- # * Processing When OK Button Is Pressed #-------------------------------------------------------------------------- def process_ok @@last_command_symbol = current_symbol super end #def process_cancel #@@last_command_symbol = nil #end #-------------------------------------------------------------------------- # * Restore Previous Selection Position #-------------------------------------------------------------------------- def select_last select_symbol(@@last_command_symbol) end endclass Window_Rewards < Window_Selectable attr_reader :stage def initialize(x, y) super(x, y, window_width, window_height) @quest = nil @stage = nil @stageindex = nil @items = [] set_handler:)ok, method:)do_process_ok)) set_handler:)cancel, method:)do_process_cancel)) end def gather_items @items = [] if @stage flag = (@quest.stage_index > @stageindex) @stage.rewards.each do |reward| if reward.gold > 0 unit = "?" unit = reward.gold.to_s if flag entry = "\e{\eC[6]" + Vocab.currency_unit + ": " + unit @items.push(entry) end if reward.exp > 0 unit = "?" unit = reward.exp.to_s if flag entry = "\e{\eC[6]Exp: " + unit @items.push(entry) end reward.items.keys.each do |itemId| unit = "?" unit = $data_items[itemId].name if flag entry = "\e{\eC[6]Item: " + unit @items.push(entry) end reward.armors.keys.each do |itemId| unit = "?" unit = $data_armors[itemId].name if flag entry = "\e{\eC[6]Armor: " + unit @items.push(entry) end reward.weapons.keys.each do |itemId| unit = "?" unit = $data_weapons[itemId].name if flag entry = "\e{\eC[6]Weapon: " + unit @items.push(entry) end end end @items.push("No rewards given.") if @items.size == 0 end def set_stage(quest, index) @quest = quest @stage = @quest.stages[index] @stageindex = index gather_items refresh end def window_width Graphics.width end def window_height Graphics.height / 2 end def item_max return @items.size if @items return 0 end def item_height (height - standard_padding * 2) / 6 end def draw_item(index) return if index >= @items.size rect = item_rect(index) y = rect.y text = @items[index] draw_text_ex(rect.x + 2, y, text) end def do_process_ok SceneManager.scene.focus_requirements end def do_process_cancel SceneManager.scene.activate_stage_status_window(@quest, @stageindex) endendclass Window_Requirements < Window_Selectable attr_reader :stage def initialize(x, y) super(x, y, window_width, window_height) @quest = nil @stage = nil @stageindex = nil @items = [] set_handler:)ok, method:)do_process_ok)) set_handler:)cancel, method:)do_process_cancel)) end def gather_items @items = [] if @stage @stage.requirements.each do |requirement| requirement.items.keys.each do |itemId| entry = "\e{\eC[6]Inventory Item: " + $data_items[itemId].name entry += "\n\e}\eC[4] (" + $game_party.item_number($data_items[itemId]).to_s entry += " of " + requirement.items[itemId].to_s + ")" @items.push(entry) end requirement.virtual.keys.each do |vitem| entry = "\e{\eC[6]Quest Item: " + vitem.name entry += "\n\e}\eC[4] (" + requirement.virtual_count[vitem].to_s entry += " of " + requirement.virtual[vitem].to_s + ")" @items.push(entry) end requirement.kills.keys.each do |enemyId| entry = "\e{\eC[6]Kill: " + $data_enemies[enemyId].name entry += "\n\e}\eC[4] (" + requirement.kill_count[enemyId].to_s entry += " of " + requirement.kills[enemyId].to_s + ")" @items.push(entry) end end end @items.push("Compelte the stage objective.") if @items.size == 0 end def set_stage(quest, index) @quest = quest @stage = @quest.stages[index] @stageindex = index gather_items refresh end def window_width Graphics.width end def window_height Graphics.height / 2 end def item_max return @items.size if @items return 0 end def item_height (height - standard_padding * 2) / 3 end def draw_item(index) return if index >= @items.size rect = item_rect(index) y = rect.y text = @items[index] draw_text_ex(rect.x + 2, y, text) end def do_process_ok SceneManager.scene.focus_rewards end def do_process_cancel SceneManager.scene.activate_stage_status_window(@quest, @stageindex) endendclass Window_StageStatus < Window_Selectable attr_reader :quest def initialize(x, y) super(x, y, window_width, window_height) @quest = nil set_handler:)ok, method:)do_process_ok)) set_handler:)cancel, method:)do_process_cancel)) refresh end def quest=(value) @quest = value refresh end def window_width Graphics.width end def window_height Graphics.height end def item_max if @quest then return @quest.stage_index + 1 unless @quest.complete? return @quest.stage_index else return 0 end end def item_height (height - standard_padding * 2) / 3 end def draw_item(index) return if index >= @quest.stages.size return if index > @quest.stage_index rect = item_rect(index) y = rect.y text = "\e{\eC[6]" + @quest.stages[index].name delta = calc_line_height(text) draw_text_ex(rect.x + 2, y, text) y += delta text = @quest.stages[index].story_text delta = calc_line_height(text) draw_text_ex(rect.x + 2, y, text) y = rect.y + rect.height - calc_line_height("X") - 2 if @quest.complete? text = "\eC[7][Complete]" else if @quest.stage_index > index text = "\eC[7][Complete]" else if @quest.stages[index].complete? text = "\eC[14][Ready!]" else text = "\eC[4][Active]" end end end draw_text_ex(rect.x + 2, y, text) end def do_process_ok SceneManager.scene.activate_requirements_window(@quest, self.index) end def do_process_cancel SceneManager.scene.activate_quest_status_window endendclass Window_QuestStatus < Window_Selectable attr_reader :quest_list def initialize(x, y) super(x, y, window_width, window_height) @quest_list = [] set_handler:)ok, method:)do_process_ok)) set_handler:)cancel, method:)do_process_cancel)) refresh end def quest_list=(value) @quest_list = value refresh end #-------------------------------------------------------------------------- # * Get Window Width #-------------------------------------------------------------------------- def window_width Graphics.width - 160 end #-------------------------------------------------------------------------- # * Get Window Height #-------------------------------------------------------------------------- def window_height Graphics.height end #-------------------------------------------------------------------------- # * Get Number of Items #-------------------------------------------------------------------------- def item_max if @quest_list then @quest_list.size else 0 end end #-------------------------------------------------------------------------- # * Get Item Height #-------------------------------------------------------------------------- def item_height (height - standard_padding * 2) / 2 end #-------------------------------------------------------------------------- # * Draw Item #-------------------------------------------------------------------------- def draw_item(index) rect = item_rect(index) y = rect.y text = "\e{\eC[6]" + @quest_list[index].quest_name delta = calc_line_height(text) draw_text_ex(rect.x + 2, y, text) y += delta text = @quest_list[index].description draw_text_ex(rect.x + 2, y, text) y = rect.y + rect.height - calc_line_height("X") - 2 if @quest_list[index].complete? draw_text_ex(rect.x + 2, y, "\eC[7]Complete") else draw_text_ex(rect.x + 2, y, "\eC[4]Active - Stage " + (@quest_list[index].stage_index + 1).to_s) end end #-------------------------------------------------------------------------- # * Processing When OK Button Is Pressed #-------------------------------------------------------------------------- def do_process_ok q = @quest_list[self.index] if self.index > -1 SceneManager.scene.activate_stage_status_window(q, nil) end def do_process_cancel SceneManager.scene.activate_category_window endendclass Scene_Menu alias rqjs_sm_create_command_window create_command_window def create_command_window rqjs_sm_create_command_window @command_window.set_handler:)quests, method:)command_reedo_show_journal)) end def command_reedo_show_journal SceneManager.call(Scene_Reedo_Journal) endendclass Scene_Reedo_Journal < Scene_Base #-------------------------------------------------------------------------- # * Start Processing #-------------------------------------------------------------------------- def start super Window_QuestCategory.init_command_position create_background create_category_window create_quest_status_window create_stage_status_window create_requirements_window create_rewards_window end #-------------------------------------------------------------------------- # * Termination Processing #-------------------------------------------------------------------------- def terminate super dispose_background end #-------------------------------------------------------------------------- # * Create Background #-------------------------------------------------------------------------- def create_background @background_sprite = Sprite.new @background_sprite.bitmap = SceneManager.background_bitmap @background_sprite.color.set(16, 16, 16, 128) end #-------------------------------------------------------------------------- # * Free Background #-------------------------------------------------------------------------- def dispose_background @background_sprite.dispose end #-------------------------------------------------------------------------- # * Create Help Window #-------------------------------------------------------------------------- def create_help_window @help_window = Window_Help.new @help_window.viewport = @viewport end def create_category_window @command_window = Window_QuestCategory.new @command_window.set_handler:)process_category, method:)command_category)) @command_window.set_handler:)cancel, method:)return_scene)) end def create_quest_status_window @quest_status_window = Window_QuestStatus.new(160,0) end def create_stage_status_window @stage_status_window = Window_StageStatus.new(0, 0) @stage_status_window.visible = false end def create_requirements_window @requirements_window = Window_Requirements.new(0, 0) @requirements_window.visible = false end def create_rewards_window @rewards_window = Window_Rewards.new(0, Graphics.height / 2) @rewards_window.visible = false end def command_category quests = @command_window.current_data[:ext] @quest_status_window.quest_list = quests @quest_status_window.activate @quest_status_window.select(0) end def activate_category_window @quest_status_window.unselect @quest_status_window.deactivate @quest_status_window.quest_list = [] @command_window.activate end def activate_quest_status_window @stage_status_window.unselect @stage_status_window.deactivate @stage_status_window.quest = nil @stage_status_window.visible = false @command_window.visible = true @quest_status_window.visible = true @command_window.select(@command_window.index) @quest_status_window.quest_list = @command_window.current_data[:ext] @command_window.deactivate @quest_status_window.activate @quest_status_window.select(@quest_status_index) end def activate_stage_status_window(quest, index) @quest_status_index = @quest_status_window.index @command_window.visible = false @quest_status_window.visible = false @requirements_window.unselect @requirements_window.deactivate @requirements_window.visible = false @rewards_window.unselect @rewards_window.deactivate @rewards_window.visible = false @stage_status_window.quest = quest if quest @stage_status_window.visible = true @stage_status_window.activate index = 0 if !index @stage_status_window.select(index) end def activate_requirements_window(quest, index) @stage_status_window.unselect @stage_status_window.deactivate @stage_status_window.visible = false @requirements_window.set_stage(quest, index) @requirements_window.visible = true @requirements_window.activate @rewards_window.set_stage(quest, index) @rewards_window.visible = true end def focus_requirements @rewards_window.deactivate @requirements_window.activate end def focus_rewards @requirements_window.deactivate @rewards_window.activate endend

Summary

With this script you can have a simple quest system for your game with a variety of quest requirements, including number of monsters killed and collecting virtual quest items, and a variety of quest rewards.  There are many possible ways for events to interact with the quest system using simple method calls on the $game_reedo_quests and subordinate objects.

By also using the RQJS script, you can easily add a simple journal scene to let players view their quests and quest status.

As always, comments and/or suggestions are welcome.

RSQSEditor.zip
 

Attachments

Last edited by a moderator:

ShinGamix

DS Style 4Ever!
Veteran
Joined
Mar 18, 2012
Messages
3,906
Reaction score
448
First Language
April Fools
Primarily Uses
N/A
A new quest system. I am gonna check this out!!!
 

Reedo

Coder
Veteran
Joined
Sep 17, 2013
Messages
71
Reaction score
38
First Language
English
Primarily Uses
Ok folks some fancy updates here... I hope they all work!!  :D

The SRQS script has been updated to version 0.2 with some minor tweaks.

The big editions are the RSQS Editor and RQJS Quest Journal Scene!!

Now, instead of writing a long script file to create all of your quests, you can use a simple editor program to design all of the quests for your game and then export them to a single "rvdata2" data file that you can drop into your game's Data folder.  The RSQS script will then automatically load all of the quests for your game.

I've also begun work on a quest journal scene (RQJS) that can be used with the RSQS script.  The journal scene is currently very basic, and only goes as far as showing quests and stages.  Next I have to add a window for viewing requirements and their status.  This one will be a little tricky and I'm still trying to determine which windows will work best for it.  But I figure while I work on that, you all can have a chance to play with what I've got so far.  :D

I'm quite excited about this script and the simplicity of adding quests and then working with them via events.  I'm hoping all of you RPG Makers can help me make this into one kick'n little set of tools for easy questing in our games.
 
Last edited by a moderator:

ShadowFox

Adventurer
Member
Joined
Mar 13, 2012
Messages
255
Reaction score
10
First Language
English
Primarily Uses
That sounds promising.

Need to know if this script system will allow repeatable quests.
 

Reedo

Coder
Veteran
Joined
Sep 17, 2013
Messages
71
Reaction score
38
First Language
English
Primarily Uses
That sounds promising.

Need to know if this script system will allow repeatable quests.
Hiya, yes, this is completely possible.  I'll be sure to add a command to reset a quest in one shot.  Its just a matter of resetting the requirements and the stage index.

I'll get this in the next release along with any additional bug fixes, and hopefully a complete (functionally anyway) journal scene.
 

ShadowFox

Adventurer
Member
Joined
Mar 13, 2012
Messages
255
Reaction score
10
First Language
English
Primarily Uses
Awesome. And will there be a feature within the journal scene that will show any and all repeatable quests?

Because I am thinking of using this script for the quests within my project. There will be a some quests that will be repeatable and some that won't be, and I am hoping to have all the quests in categories. Main quest and a subquest and repeatable quests.

I have noticed that with the editor if one opens the helop and then closes it and reopens it later, it comes up with an error that deals with the help window.

And lastly is there a way to have a description for each stage?

And if so how would that be done?

I'm currently using the editor.
 
Last edited by a moderator:

Reedo

Coder
Veteran
Joined
Sep 17, 2013
Messages
71
Reaction score
38
First Language
English
Primarily Uses
All code has been updated and is nearing release.  The editor has been updated as well, so please uninstall the previous version and download and install the 1.1 version.

The RQJS journal scene script now shows all relevant quest information with basic color formatting.  See the main post for further details.

Also note that a fair amount of work was done to the help window in the editor and it now contains a lot of information about not only the editor, but the entire quest system.
 

Reedo

Coder
Veteran
Joined
Sep 17, 2013
Messages
71
Reaction score
38
First Language
English
Primarily Uses
Awesome. And will there be a feature within the journal scene that will show any and all repeatable quests?

Because I am thinking of using this script for the quests within my project. There will be a some quests that will be repeatable and some that won't be, and I am hoping to have all the quests in categories. Main quest and a subquest and repeatable quests.

I have noticed that with the editor if one opens the helop and then closes it and reopens it later, it comes up with an error that deals with the help window.

And lastly is there a way to have a description for each stage?

And if so how would that be done?

I'm currently using the editor.
There is no special flag dedicated to marking a quest as 'repeatable" at this time.  If it turns out to be required, such a thing could be added (though it would change the data file format and make current data files invalid).  Right now from the way you describe it, it sounds like you can use a category named "Repeatable" for each of your repeatable quests.  That would give it its own selection item in the main journal window.  We'll have to see how this goes and decide what the best solution should be.

Thanks for the catch on the help window!  I knew exactly what I did (or forgot to do!) as soon as I read that.  :p Problem solved.

For your final question, every stage has a description via the story_text property.  The previous version may have been misleading you if you had a blank stage name (there was a bug), but it all works correctly now and any text you put in the story text box will show as the stage description.  This text supports the various slash commands that any message window supports (as does the quest description).
 

ShinGamix

DS Style 4Ever!
Veteran
Joined
Mar 18, 2012
Messages
3,906
Reaction score
448
First Language
April Fools
Primarily Uses
N/A
Now even better!!
 

ShadowFox

Adventurer
Member
Joined
Mar 13, 2012
Messages
255
Reaction score
10
First Language
English
Primarily Uses
There is no special flag dedicated to marking a quest as 'repeatable" at this time.  If it turns out to be required, such a thing could be added (though it would change the data file format and make current data files invalid).  Right now from the way you describe it, it sounds like you can use a category named "Repeatable" for each of your repeatable quests.  That would give it its own selection item in the main journal window.  We'll have to see how this goes and decide what the best solution should be.

Thanks for the catch on the help window!  I knew exactly what I did (or forgot to do!) as soon as I read that.  :p Problem solved.

For your final question, every stage has a description via the story_text property.  The previous version may have been misleading you if you had a blank stage name (there was a bug), but it all works correctly now and any text you put in the story text box will show as the stage description.  This text supports the various slash commands that any message window supports (as does the quest description).
I see. And yes that is what I had in mind. 3 quest categories.  The first being the main story. The second being a side quest and the last being a repeatable quest.

I hope that something can be tweaked to allow a quest to show as a repeatable in the repeatable category within the journal screen.

I'm glad that I was able to help you with the help glitch.

And I see. I was using the old one and it seems to not work as such. I shall download the new download and try it.
 

Reedo

Coder
Veteran
Joined
Sep 17, 2013
Messages
71
Reaction score
38
First Language
English
Primarily Uses
I see. And yes that is what I had in mind. 3 quest categories.  The first being the main story. The second being a side quest and the last being a repeatable quest.

I hope that something can be tweaked to allow a quest to show as a repeatable in the repeatable category within the journal screen.

I'm glad that I was able to help you with the help glitch.

And I see. I was using the old one and it seems to not work as such. I shall download the new download and try it.
Keep in mind that you could do something like make the last word of the description text "(Repeatable)" or put a "®" at the beginning or end of the quest name.  There are a number of things you could do within the quest content itself.

But since the user is going to select "Repeatable" from the category list, I'm not sure that you need any other indicator within the quest detail view itself.
 

Venka

Veteran
Veteran
Joined
Jun 20, 2012
Messages
945
Reaction score
365
First Language
English
Primarily Uses
Not sure if I'm misising a step. I've downloaded the Quest Editor, Ruby, and Net Framework.  I can use the editor to save/edit files but I can't export it. It tells me "The system cannot find the filespecified".

I'm a winXP user if this makes a difference
 

buliwyf

Warper
Member
Joined
Jan 2, 2014
Messages
3
Reaction score
1
First Language
danish
Primarily Uses
hello nice script so far i have manage to make my first quest in the app i downloadet

but my big question is how do i make a npc give me thad quest i made in the program

can you please explaine it to me how it is done

regards buliwyf
 

aoiaoi

Warper
Member
Joined
Jan 13, 2014
Messages
1
Reaction score
0
Primarily Uses
I create the event like the image but the game crash and give me this error

script 'game_interpreter' line 450:Nomethoderror occurred

error undefined method 'contains?' for Nill:class

What can i do???
 
Last edited by a moderator:

buliwyf

Warper
Member
Joined
Jan 2, 2014
Messages
3
Reaction score
1
First Language
danish
Primarily Uses
I create the event like the image but the game crash and give me this error

script 'game_interpreter' line 450:Nomethoderror occurred

error undefined method 'contains?' for Nill:class

What can i do???
i get the same when i test it
 

Reedo

Coder
Veteran
Joined
Sep 17, 2013
Messages
71
Reaction score
38
First Language
English
Primarily Uses
The error indicates that $game_reedo_quests is null and so the script is not installed correctly or is not running.  Please ensure that you have installed the script according to the instructions; if you are using other scripts, start a new test game and install only the quest script to ensure that you are not facing a compatibility issue with some other script.
 

Reedo

Coder
Veteran
Joined
Sep 17, 2013
Messages
71
Reaction score
38
First Language
English
Primarily Uses
Those of you who get "The System Cannot Find the Specified File" when exporting have most likely skipped the step during RUBY installation when you are asked if you want to add RUBY to your PATH.  You must have the RUBY folder in your Windows PATH setting (this is mentioned in the post, please re-read the instructions above).
 
Joined
Mar 2, 2014
Messages
1
Reaction score
0
First Language
Portuguese
Primarily Uses
Hey man when finish a quest a get this message: "Script 'Game_Interpreter' line 454: ArgumentError Ocurred. too few Argument. what I did wrong?
 

newbielol123

Villager
Member
Joined
Aug 12, 2013
Messages
19
Reaction score
1
First Language
English
Primarily Uses
I cant export the quest data. How do I fix this!
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

I've wondered for a while now... what is it about the YED SV plugin that just doesn't do transformations... I feel it's how it looks up the battlers honestly.
To actually work on my game, or browse these forums about creating my game? Hmmm....
Tanning beds are actually vampire traps. Coffin shaped but the minute they're inside... BAM UV Rays. Dead Vampire.
https://forums.rpgmakerweb.com/index.php?threads/restrictions-limited-move-sets.117489/ A new blog discussion thread draws near! Command?

What do you think of Limited Move Sets?
RPG maker Dev pro tips: 1, back up your project. 2, take care of your back. 3, back up your project again.

Forum statistics

Threads
93,490
Messages
912,914
Members
123,026
Latest member
eveelynn
Top