//============================================================================= // TDS Omori Quest Menu // Version: 1.3 //============================================================================= // Add to Imported List var Imported = Imported || {}; Imported.TDS_QuestMenu = true; // Initialize Alias Object var _TDS_ = _TDS_ || {}; _TDS_.QuestMenu = _TDS_.QuestMenu || {}; //============================================================================= /*: * @plugindesc * Quest Menu for OMORI. * * @author TDS * * @param Opening Message * @desc The Message to show when the quest menu is called. * @default "" * * * @param World Variable ID * @desc ID of the variable used to track the current world. * @default 1 * * @help * ============================================================================ * * Script Calls * ============================================================================ * * Use this script call to call the quest menu. * * this.callQuestMenu(); * * * * Use this script call to add a quest. * * this.addQuest(ID); * * ID * ^ Id of the quest. * * Example: * * this.addQuest('Quest4'); * * * * Use this script call to remove a quest. * * this.removeQuest(ID); * * ID * ^ Id of the quest. * * Example: * * this.removeQuest('Quest4'); * * * * Use this script call to set the complete state of a quest. * * this.setQuestCompleteState(ID, STATE); * * ID * ^ Id of the quest. * * STATE * ^ State of the quest. (true/false) (Optiona: Defaults to true) * * Example: * * this.setQuestCompleteState('Quest1'); * * this.setQuestCompleteState('Quest4', true); * * this.setQuestCompleteState('Quest5', false); * * * Use this script call to set a quest's message index. * * this.setQuestMessageIndex(ID, INDEX); * * ID * ^ Id of the quest. * * INDEX * ^ Index value. * * Example: * * this.setQuestMessageIndex('Quest4', 1); * */ //============================================================================= // Node.js path var path = require('path'); // Get Parameters var parameters = PluginManager.parameters("Omori Quest Menu"); // Initialize Parameters _TDS_.QuestMenu.params = {}; _TDS_.QuestMenu.params.worldVariableID = Number(parameters['World Variable ID'] || 1); _TDS_.QuestMenu.params.openingMessage = String(parameters['Opening Message'] || ''); //============================================================================= // ** DataManager //----------------------------------------------------------------------------- // The game object class for the party. Information such as gold and items is // included. //============================================================================= // Alias Listing //============================================================================= _TDS_.QuestMenu.DataManager_loadDatabase = DataManager.loadDatabase; //============================================================================= // * Load Database //============================================================================= DataManager.loadDatabase = function () { // Run Original Function _TDS_.QuestMenu.DataManager_loadDatabase.call(this); var path = require('path'); var fs = require('fs'); var yaml = require('./js/libs/js-yaml-master') // Load Quests window['$dataQuests'] = jsyaml.load(fs.readFileSync('data/Quests.yaml', 'utf8')); }; //============================================================================= // ** Game_Party //----------------------------------------------------------------------------- // The game object class for the party. Information such as gold and items is // included. //============================================================================= // Alias Listing //============================================================================= _TDS_.QuestMenu.Game_Party_initialize = Game_Party.prototype.initialize; //============================================================================= // * Object Initialization //============================================================================= Game_Party.prototype.initialize = function () { // Run Original Function _TDS_.QuestMenu.Game_Party_initialize.call(this); // Initialize Quest List this._questList = []; // Quest Stand By Message this._questStandByMessage = null; }; //============================================================================= // * Set Stand By Message //============================================================================= Game_Party.prototype.setQuestStandByMessage = function (message) { this._questStandByMessage = message; }; //============================================================================= // * Add Quest //============================================================================= Game_Party.prototype.addQuest = function (id, data = {}) { // If You don't have quest already if (!this.hasQuest(id, false)) { // Get World var world = $dataQuests.quests[id].world; // Create Quest Object var quest = { id: id, messageIndex: 0, world: world, complete: false }; // Assign Data to Quest Object.assign(quest, data); // Add Quest to Quest List this._questList.push(quest) // Return Added Quest return quest; }; // Return False return false; }; //============================================================================= // * Remove Quest //============================================================================= Game_Party.prototype.removeQuest = function (id) { // Get List of Quests to remove var list = this._questList.filter(function (quest) { return quest.id === id; }) // Go Through List for (var i = 0; i < list.length; i++) { // Get Index of Quest to remove var index = this._questList.indexOf(list[i]); // Remove Quest if (index >= 0) { this._questList.splice(index, 1); }; }; }; //============================================================================= // * Determine if you have quest already //============================================================================= Game_Party.prototype.hasQuest = function (id, completed = true) { return this._questList.some(function (quest) { return quest.id === id }); }; //============================================================================= // * Get Completed Quest List //============================================================================= Game_Party.prototype.completedQuestList = function (world = 0) { return this._questList.filter(function (quest) { return quest.complete && quest.world === world; }); }; //============================================================================= // * Get Incomplete Quest List //============================================================================= Game_Party.prototype.incompleteQuestList = function (world = 0) { return this._questList.filter(function (quest) { return !quest.complete && quest.world === world; }); }; //============================================================================= // * Set Quest Complete State //============================================================================= Game_Party.prototype.setQuestCompleteState = function (id, state = true) { for (var i = 0; i < this._questList.length; i++) { var quest = this._questList[i]; if (quest.id === id) { quest.complete = state; }; }; }; //============================================================================= // * Set Quest Message Index //============================================================================= Game_Party.prototype.setQuestMessageIndex = function (id, index) { // Get Quest var quest = this._questList.find(function (q) { return q.id === id; }); // Set Quest Message Index if (quest) { quest.messageIndex = index; }; }; //============================================================================= // ** Game_Interpreter //----------------------------------------------------------------------------- // The interpreter for running event commands. //============================================================================= // * Call Quest Menu //============================================================================= Game_Interpreter.prototype.callQuestMenu = function () { SceneManager.push(Scene_OmoriQuest); }; //============================================================================= // * Add Quest //============================================================================= Game_Interpreter.prototype.addQuest = function (id, data) { $gameParty.addQuest(id, data); }; //============================================================================= // * Remove Quest //============================================================================= Game_Interpreter.prototype.removeQuest = function (id) { $gameParty.removeQuest(id); }; //============================================================================= // * Set Quest Complete State //============================================================================= Game_Interpreter.prototype.setQuestCompleteState = function (id, state) { $gameParty.setQuestCompleteState(id, state); }; //============================================================================= // * Set Quest Message Index //============================================================================= Game_Interpreter.prototype.setQuestMessageIndex = function (id, index) { $gameParty.setQuestMessageIndex(id, index); }; //============================================================================= // ** Scene_OmoriQuest //----------------------------------------------------------------------------- // Base Class for Omori Menu Scenes //============================================================================= function Scene_OmoriQuest() { this.initialize.apply(this, arguments); } Scene_OmoriQuest.prototype = Object.create(Scene_Base.prototype); Scene_OmoriQuest.prototype.constructor = Scene_OmoriQuest; //============================================================================= // * Object Initialization //============================================================================= Scene_OmoriQuest.prototype.initialize = function () { // Super Call Scene_Base.prototype.initialize.call(this); // Update Window Cursors Flag this._updateWindowCursors = false; }; //============================================================================= // * Create //============================================================================= Scene_OmoriQuest.prototype.create = function () { // Super Call Scene_Base.prototype.create.call(this); // Create Background this.createBackground(); // Create Quest Windows this.createQuestWindows(); // Create Message Window this.createMessageWindow(); }; //============================================================================= // * Create Background //============================================================================= Scene_OmoriQuest.prototype.start = function () { // Super Call Scene_Base.prototype.start.call(this); // If there's an opening message if (_TDS_.QuestMenu.params.openingMessage.length > 0) { // Set Starting Message $gameMessage.showLanguageMessage(_TDS_.QuestMenu.params.openingMessage); }; // Set Update Wait Cursors Flag to true this._updateWindowCursors = true; this._questListWindow.updateCustomCursorRectSprite(); this._questTypesWindows.updateCustomCursorRectSprite(); }; //============================================================================= // * Create Background //============================================================================= Scene_OmoriQuest.prototype.createBackground = function () { this._backgroundSprite = new Sprite(); this._backgroundSprite.bitmap = SceneManager.backgroundBitmap(); this.addChild(this._backgroundSprite); }; //============================================================================= // * Create Quest Windows //============================================================================= Scene_OmoriQuest.prototype.createQuestWindows = function () { // Create Quest Header Window this._questHeaderWindow = new Window_OmoriQuestHeader() this.addChild(this._questHeaderWindow); // Create Quest Types Window this._questTypesWindows = new Window_OmoriQuestTypes(); this._questTypesWindows.y = this._questHeaderWindow.y + this._questHeaderWindow.height + 2; this._questTypesWindows.setHandler('ok', this.onQuestTypesOk.bind(this)); this._questTypesWindows.setHandler('cancel', this.popScene.bind(this)); this.addChild(this._questTypesWindows); // Create Quest List Window this._questListWindow = new Window_OmoriQuestList(); this._questListWindow.x = this._questTypesWindows.x + this._questTypesWindows.width + 2; this._questListWindow.y = this._questTypesWindows.y; this._questListWindow.setHandler('ok', this.onQuestListOk.bind(this)); this._questListWindow.setHandler('cancel', this.onQuestListCancel.bind(this)); this.addChild(this._questListWindow); // Set Quest List Window this._questTypesWindows._questlistWindow = this._questListWindow; this._questTypesWindows.callUpdateHelp(); }; //============================================================================= // * Create Message Window //============================================================================= Scene_OmoriQuest.prototype.createMessageWindow = function () { this._messageWindow = new Window_OmoriQuestMessage(); this.addChild(this._messageWindow); this._messageWindow.subWindows().forEach(function (window) { this.addChild(window); }, this); // Add Facebox Window Container as a Child this.addChild(this._messageWindow._faceBoxWindowContainer); }; //============================================================================= // * [OK] Quest Type //============================================================================= Scene_OmoriQuest.prototype.onQuestTypesOk = function () { this._questListWindow.select(0); this._questListWindow.activate(); }; //============================================================================= // * [OK] Quest List //============================================================================= Scene_OmoriQuest.prototype.onQuestListOk = function () { this._questListWindow.activate(); this._messageWindow._setStandbyMessage = true; // Get Messages var messages = this._questListWindow.selectedQuestMessages(); $gameMessage.showLanguageMessage(messages[0]); // Clear Message List this._messageWindow.clearMessageList(); for (var i = 1; i < messages.length; i++) { this._messageWindow.addMessage(messages[i]); }; // Set Update Wait Cursors Flag to true this._updateWindowCursors = true; this._questListWindow.updateCustomCursorRectSprite(); this._questTypesWindows.updateCustomCursorRectSprite(); }; //============================================================================= // * [Cancel] Quest List //============================================================================= Scene_OmoriQuest.prototype.onQuestListCancel = function () { // Activate Quest Types Window this._questTypesWindows.activate(); this._questListWindow.deselect(); }; //============================================================================= // * Frame Update //============================================================================= Scene_OmoriQuest.prototype.update = function () { // Super Call Scene_Base.prototype.update.call(this); if (this._updateWindowCursors && !$gameMessage.isBusy()) { this._updateWindowCursors = false; this._questListWindow.updateCustomCursorRectSprite(); this._questTypesWindows.updateCustomCursorRectSprite(); }; // if (Input.isTriggered('control')) { // } }; //============================================================================= // ** Window_OmoriQuestHeader //----------------------------------------------------------------------------- // This window displays the quest list header. //============================================================================= function Window_OmoriQuestHeader() { this.initialize.apply(this, arguments); } Window_OmoriQuestHeader.prototype = Object.create(Window_Base.prototype); Window_OmoriQuestHeader.prototype.constructor = Window_OmoriQuestHeader; //============================================================================= // * Initialize Object //============================================================================= Window_OmoriQuestHeader.prototype.initialize = function () { // Super Call Window_Base.prototype.initialize.call(this, 12, 12, this.windowWidth(), this.windowHeight()); // // Close Window // this.openness = 0; // Draw Contents this.refresh(); }; //============================================================================= // * Settings //============================================================================= Window_OmoriQuestHeader.prototype.standardPadding = function () { return 0; }; Window_OmoriQuestHeader.prototype.windowWidth = function () { return 164; }; Window_OmoriQuestHeader.prototype.windowHeight = function () { return 44; }; //============================================================================= // * Refresh //============================================================================= Window_OmoriQuestHeader.prototype.refresh = function () { // Clear Contents this.contents.clear(); // Draw Header this.contents.drawText(LanguageManager.getPluginText('questMenu', 'header'), 0, -6, this.contents.width, this.contents.height, 'center'); }; //============================================================================= // ** Window_OmoriQuestTypes //----------------------------------------------------------------------------- // This window displays quest types (Completed, Incomplete). //============================================================================= function Window_OmoriQuestTypes() { this.initialize.apply(this, arguments); } Window_OmoriQuestTypes.prototype = Object.create(Window_Command.prototype); Window_OmoriQuestTypes.prototype.constructor = Window_OmoriQuestTypes; //============================================================================= // * Initialize Object //============================================================================= Window_OmoriQuestTypes.prototype.initialize = function () { // Super Call Window_Command.prototype.initialize.call(this, 12, 0); this.activate(); this.select(0); }; //============================================================================= // * Settings //============================================================================= Window_OmoriQuestTypes.prototype.isUsingCustomCursorRectSprite = function () { return true; }; Window_OmoriQuestTypes.prototype.windowWidth = function () { return 184; }; Window_OmoriQuestTypes.prototype.windowHeight = function () { return 81; }; Window_OmoriQuestTypes.prototype.standardPadding = function () { return 8; }; Window_OmoriQuestTypes.prototype.customCursorRectTextXOffset = function () { return 35; }; Window_OmoriQuestTypes.prototype.customCursorRectXOffset = function () { return 10; }; Window_OmoriQuestTypes.prototype.lineHeight = function () { return 28; }; Window_OmoriQuestTypes.prototype.standardFontSize = function () { return 24; }; //============================================================================= // * Get Current World //============================================================================= Window_OmoriQuestTypes.prototype.currentWorld = function () { return $gameVariables.value(_TDS_.QuestMenu.params.worldVariableID); }; //============================================================================= // * Make Command List //============================================================================= Window_OmoriQuestTypes.prototype.makeCommandList = function () { var world = this.currentWorld(); let questStates = LanguageManager.getPluginText('questMenu', 'questStates'); this.addCommand(questStates[0], 'incomplete', $gameParty.incompleteQuestList(world).length > 0); this.addCommand(questStates[1], 'complete', $gameParty.completedQuestList(world).length > 0); }; //============================================================================= // * Draw Item //============================================================================= Window_OmoriQuestTypes.prototype.drawItem = function (index) { // Get Item Rect var rect = this.itemRectForText(index); var align = this.itemTextAlign(); this.resetTextColor(); // Set Text Color this.changeTextColor(index === 1 ? 'rgba(0, 161, 4, 1)' : 'rgba(228, 50, 14, 1)'); this.changePaintOpacity(this.isCommandEnabled(index)); this.drawText(this.commandName(index), rect.x, rect.y, rect.width, align); }; //============================================================================= // * Call Update Help //============================================================================= Window_OmoriQuestTypes.prototype.callUpdateHelp = function () { // Run Original Function Window_Command.prototype.callUpdateHelp.call(this); // if Quest List Window Exists if (this._questlistWindow) { var world = this.currentWorld(); // Get List var list = this.index() === 0 ? $gameParty.incompleteQuestList(world) : $gameParty.completedQuestList(world); // Set Quest List this._questlistWindow.setQuestList(list); }; }; //============================================================================= // * Process Cursor Move //============================================================================= Window_OmoriQuestTypes.prototype.processCursorMove = function () { // If a message is displaying if ($gameMessage.isBusy()) { return; }; // Run Original Function Window_Command.prototype.processCursorMove.call(this); }; //============================================================================= // * Process Handling //============================================================================= Window_OmoriQuestTypes.prototype.processHandling = function () { // If a message is displaying if ($gameMessage.isBusy()) { return; }; // Run Original Function Window_Command.prototype.processHandling.call(this); }; //============================================================================= // * Update Custom Cursor Rect Sprite //============================================================================= Window_OmoriQuestTypes.prototype.updateCustomCursorRectSprite = function (sprite, index) { // Set Sprite sprite = this._customCursorRectSprite; // If Custom Rect Sprite Exists if (sprite && $gameMessage.isBusy()) { // Set Sprite Tone Color sprite.setColorTone([-80, -80, -80, 255]); // Set Sprite active flag sprite._active = false; return; }; // Run Original Function Window_Command.prototype.updateCustomCursorRectSprite.call(this, sprite, index); }; //============================================================================= // ** Window_OmoriQuestList //----------------------------------------------------------------------------- // This window displays the list of available and completed quests //============================================================================= function Window_OmoriQuestList() { this.initialize.apply(this, arguments); } Window_OmoriQuestList.prototype = Object.create(Window_Command.prototype); Window_OmoriQuestList.prototype.constructor = Window_OmoriQuestList; //============================================================================= // * Initialize Object //============================================================================= Window_OmoriQuestList.prototype.initialize = function () { // Quest List this._questList = []; // Super Call Window_Command.prototype.initialize.call(this, 12, 0); // this.openness = 0; this.deactivate(); this.deselect(); }; //============================================================================= // * Settings //============================================================================= Window_OmoriQuestList.prototype.isUsingCustomCursorRectSprite = function () { return true; }; Window_OmoriQuestList.prototype.windowWidth = function () { return 360 }; Window_OmoriQuestList.prototype.windowHeight = function () { return 177; }; Window_OmoriQuestList.prototype.standardPadding = function () { return 8; }; Window_OmoriQuestList.prototype.customCursorRectTextXOffset = function () { return 35; }; Window_OmoriQuestList.prototype.lineHeight = function () { return 25; }; Window_OmoriQuestList.prototype.standardFontSize = function () { return 24; }; //============================================================================= // * Set Quest List //============================================================================= Window_OmoriQuestList.prototype.setQuestList = function (list) { // Set List this._questList = list; // Refresh this.refresh(); // Reset Scroll this.resetScroll(); }; //============================================================================= // * Get Selected Quest Messages //============================================================================= Window_OmoriQuestList.prototype.selectedQuestMessages = function (index = this._index) { // Get Quest var quest = this._questList[index]; // Return Quest return $dataQuests.quests[quest.id].text[quest.messageIndex]; }; //============================================================================= // * Make Command List //============================================================================= Window_OmoriQuestList.prototype.makeCommandList = function () { // Get Language var language = LanguageManager._language; // Go Through Quest List for (var i = 0; i < this._questList.length; i++) { // Get Quest var quest = this._questList[i]; // Get Data const loc = LanguageManager.getMessageData("XX_BLUE.Quest_Names")[quest.id] var data = $dataQuests.quests[quest.id]; const questname = !loc ? data.name[language] : loc this.addCommand(questname, 'quest', true, quest) }; }; //============================================================================= // * Draw Item //============================================================================= Window_OmoriQuestList.prototype.drawItem = function (index) { // Run Original Function Window_Command.prototype.drawItem.call(this, index); // Get Item Rect var rect = this.itemRect(index); }; //============================================================================= // * Refresh Arrows //============================================================================= Window_OmoriQuestList.prototype._refreshArrows = function () { // Super Call Window_Command.prototype._refreshArrows.call(this); var w = this._width; var h = this._height; var p = 24; var q = (p / 2) + 5; this._downArrowSprite.move(w - q, h - q); this._upArrowSprite.move(w - q, q); }; //============================================================================= // * Process Cursor Move //============================================================================= Window_OmoriQuestList.prototype.processCursorMove = function () { // If a message is displaying if ($gameMessage.isBusy()) { return; }; // Run Original Function Window_Command.prototype.processCursorMove.call(this); }; //============================================================================= // * Process Handling //============================================================================= Window_OmoriQuestList.prototype.processHandling = function () { // If a message is displaying if ($gameMessage.isBusy()) { return; }; // Run Original Function Window_Command.prototype.processHandling.call(this); }; //============================================================================= // * Update Custom Cursor Rect Sprite //============================================================================= Window_OmoriQuestList.prototype.updateCustomCursorRectSprite = function (sprite, index) { // Set Sprite sprite = this._customCursorRectSprite; // If Custom Rect Sprite Exists if (sprite && $gameMessage.isBusy()) { // Set Sprite Tone Color sprite.setColorTone([-80, -80, -80, 255]); // Set Sprite active flag sprite._active = false; return; }; // Run Original Function Window_Command.prototype.updateCustomCursorRectSprite.call(this, sprite, index); }; //============================================================================= // ** Window_OmoriQuestMessage //----------------------------------------------------------------------------- // This window displays quest message dialogue. //============================================================================= function Window_OmoriQuestMessage() { this.initialize.apply(this, arguments); } Window_OmoriQuestMessage.prototype = Object.create(Window_Message.prototype); Window_OmoriQuestMessage.prototype.constructor = Window_OmoriQuestMessage; //============================================================================= // * Initialize Object //============================================================================= Window_OmoriQuestMessage.prototype.initialize = function () { // Clear Message List this.clearMessageList(); // Set Standby Message Flag this._setStandbyMessage = false; // Super Call Window_Message.prototype.initialize.call(this); }; //============================================================================= // * Clear Message List //============================================================================= Window_OmoriQuestMessage.prototype.clearMessageList = function () { this._messageList = []; }; //============================================================================= // * Clear Message List //============================================================================= Window_OmoriQuestMessage.prototype.addMessage = function (message) { this._messageList.push(message); }; //============================================================================= // * Set Stand By Message //============================================================================= Window_OmoriQuestMessage.prototype.setStandByMessage = function () { this._setStandbyMessage = true; } //============================================================================= // * Terminate Message //============================================================================= Window_OmoriQuestMessage.prototype.terminateMessage = function () { // Clear Game Message $gameMessage.clear(); // If Message List Length is more than 0 if (this._messageList.length > 0) { // Get Message var message = this._messageList.shift(); // Show Language Message $gameMessage.showLanguageMessage(message); return; }; // If set Standy Message Flag is true if (this._setStandbyMessage) { // If Stand By Message for Quests Exist if ($gameParty._questStandByMessage) { // Set Quest Standby Message $gameMessage.showLanguageMessage($gameParty._questStandByMessage); } // Set Standby Message to false this._setStandbyMessage = false; }; };