O TEMA DO FÓRUM ESTÁ EM MANUTENÇÃO. FEEDBACKS AQUI: ACESSAR

Quest System

Iniciado por Senhor dos Grafos, 29/03/2016 às 16:21

Olá, pessoas
Tô disponibilizando aqui um plugin que eu fiz na minha fábrica (no Mundo RPG Maker) baseado em um script de quests do Masked, do Mundo RPG Maker. Divirtam-se.
 
O que o script faz?
Permite que o(a) jogador(a) abra um menu de quests apertando uma determinada tecla. O(a) desenvolvedor(a) pode criar e controlar novas quests sem precisar mexer no arquivo do plugin, apenas usando comandos de script no próprio RPG Maker MV.
 
Tem screenchots?
Tem sim:
Spoiler
[close]
 
Como usar o plugin?
O plugin tem muitos comandos, por isso eu deixei uma demo pra facilitar a vida de vocês. Deem uma olhada nela e, se surgir alguma dúvida, podem me perguntar.
 
Você cobra o seu nome nos créditos?
Se quiser botar, ótimo, mas se não quiser não faço questão. Só não copie o script e leve o crédito por ele sozinho, isso se chama plágio.
 
Cadê o link pra download?
Não tem, eu deixei um arquivo zipado em anexo. Lá vocês vão encontrar uma pasta chamada data e um arquivo chamado QuestMenu.js. Criem um novo projeto no MV, substituam a pasta data do novo projeto por essa do anexo e copiem QuestMenu.js para a pasta de plugins. Agora abra o projeto. Pronto, tá tudo no lugar, certo?

[Anexo excluído pelo administrador]
Pode me chamar de Russo

Um ótimo trabalho em Russo! Gostei da interface do seu sistema e das capacidades que ele traz, ficou muito bom!

Bacana cara, continue assim.  :XD:

Ficou muito bom.
Gostei principalmente pelo fato de mostrar o NPC, isso é bem legal.


Saudações!

Ficou muito legal esse plugin! Meus parabéns!

Estou em projeto e, como sou bem iniciante, quero aprender bem sobre o que consigo fazer com o Maker "básico", sem plugins e tudo mais.

Mas, vendo esse aqui... Ah! Que vontade de rever esse conceito para o incluir no projeto.

Novamente, meus parabéns e agradeço por compartilhar com a comunidade!

Até mais!
Canal YouTube: https://www.youtube.com/channel/UCYZbBHdVs1zKPJi-epNZB-w

Visitem também minha idéia de jogo (A Jornada): http://centrorpg.com/index.php?topic=14189.0

E...gostaria de ter um review do seu jogo/projeto? Veja como em: http://centrorpg.com/index.php?topic=14491.0

Muito show seu script!

Eu só tenho uma dúvida: haveria a possibilidade de colocá-lo como opção no menu mesmo?
Tanto faz deixá-lo apenas com o menu e também usando o comando especificado ou apenas no menu.

Obrigado!

Citação de: Darkrafa online 29/03/2016 às 21:47
Muito show seu script!

Eu só tenho uma dúvida: haveria a possibilidade de colocá-lo como opção no menu mesmo?
Tanto faz deixá-lo apenas com o menu e também usando o comando especificado ou apenas no menu.

Obrigado!

Tem sim, inclusive você vai achar essa parte "comentada" (escrita, mas desativada, entre /* e */) no meu código. Basta "desativar" o parâmetro e função que chama o menu pela tecla de atalho e "ativar" as funções que integram essa opção ao menu. Como eu não sei se você sabe mexer com isso, vou deixar aqui o código "modificado":

//=============================================================================
// QuestMenu.js
// Senhor dos Grafos (Russo)
// Mundo RPG Maker || Centro RPG Maker
//=============================================================================

/*:
 * @plugindesc
 * Chama um menu de quests ao pressionar um determinado botão
 * (inspirado no script em RGSS3 do Masked, membro do MRM)
 * @author Senhor dos Grafos (Russo)
 *
 * param Tecla
 * desc Tecla para chamar o menu de quests
 * PRECISA SER UMA LETRA
 * default T
 *
 * @param Cor
 * @desc Cor do "cabeçalho" do menu de quests
 * PRECISA SER UM NÚMERO
 * @default 23
 *
 */


//-----------------------------------------------------------------------------
// QuestManager
//
// Classe estática para controlar as quests in-game

function QuestManager()
{
	throw new Error('Esta é uma classe estática');
}

QuestManager._questList = [];
QuestManager._id = 5042;
/*
QuestManager._trigger = PluginManager.parameters('QuestMenu')['Tecla'].charCodeAt(0);
QuestManager._controle = true;
*/

QuestManager.createQuest = function(name, desc, rank, giver, face, faceId, sprite, spriteId, complete, rewardGold, rewardExp)
{
	this.load();
	if (!this.questExiste(name))
	{
		var quest = {};
		quest.name = name;
		quest.desc = desc;
		quest.rank = rank;
		quest.giver = giver;
		quest.face = face;
		quest.faceId = faceId;
		quest.sprite = sprite;
		quest.spriteId = spriteId;
		if (complete == "-")
			quest.complete = "-/-";
		else
			quest.complete = "0/" + complete.toString();
		quest.rewardGold = rewardGold.toString();
		quest.rewardExp = rewardExp.toString();
		quest.category = 'pendente'
		this._questList.push(quest);
		this.save();
	}
};

QuestManager.questExiste = function(n)
{
	return !isNaN(this.questId(n));
};

QuestManager.estaEmAndamento = function(n)
{
	n = this.questId(n);
	if (!isNaN(n))
		return this._questList[n].category == 'pendente';
	else
		return false;
};

QuestManager.foiConcluida = function(n)
{
	n = this.questId(n);
	if (!isNaN(n))
		return this._questList[n].category == 'concluida';
	else
		return false;
};

QuestManager.foiFracasso = function(n)
{
	n = this.questId(n);
	if (!isNaN(n))
		return this._questList[n].category == 'falha';
	else
		return false;
};

QuestManager.andamento = function(n)
{
	n = this.questId(n);
	if (isNaN(n))
		return "-/-"
	return this._questList[n].complete;
};

QuestManager.andamentoAtual = function(n)
{
	n = this.andamento(n);
	if (n == "-/-")
		return "-"
	else
		return parseInt(n.substring(0, n.indexOf("/")));
};

QuestManager.andamentoTotal = function(n)
{
	n = this.andamento(n);
	if (n == "-/-")
		return "-"
	else
		return parseInt(n.substring(n.indexOf("/") + 1));
};

QuestManager.somarAndamento = function(n, s)
{
	n = this.questId(n);
	if (isNaN(n))
		return false;
	var a = this.andamentoAtual(n);
	if (isNaN(a))
		return true;
	a += s;
	var t = this.andamentoTotal(n);
	this._questList[n].complete = Math.min(a, t).toString() + "/" + t.toString();
	return a >= t;
};

QuestManager.andamentoEstaCompleto = function(n)
{
	return this.somarAndamento(n, 0);
};

QuestManager.concluir = function(n)
{
	n = this.questId(n);
	if (!isNaN(n))
	{
		this._questList[n].category = 'concluida';
		$gameParty.gainGold(parseInt(this._questList[n].rewardGold));
		var t = $gameParty.allMembers().length;
		for (var i = 0; i < t; i++)
			$gameParty.allMembers()[i].gainExp(parseInt(this._questList[n].rewardExp));
	}
};

QuestManager.falhar = function(n)
{
	n = this.questId(n);
	if (!isNaN(n))
		this._questList[n].category = 'falha';
};

QuestManager.questId = function(n)
{
	this.load();
	if (!isNaN(n) && n < this._questList.length)
		return n;
	else if (!isNaN(n))
		return NaN;
	var t = this._questList.length;
	for (var i = 0; i < t; i++)
		if (this._questList[i].name == n)
			return i;
	return NaN;
};

QuestManager.remove = function(name)
{
	var id = this.questId(name);
	if (id != -1)
		this._questList.splice(id, 1);
};

QuestManager.clearList = function()
{
	this._questList = [];
};

QuestManager.save = function()
{
	$gameVariables[this._id] = this._questList;
};

QuestManager.load = function()
{
	if ($gameVariables[this._id])
		this._questList = $gameVariables[this._id];
};

QuestManager.questList = function(category)
{
	this.load();
	var tempList = [];
	for (var i = 0; i < this._questList.length; i++)
		if (category && (this._questList[i].category == category || category == 'all'))
			tempList.push(this._questList[i]);
	return tempList;
};
/*
QuestManager.chamarMenuDeQuests = function(e)
{
	if (!QuestManager._controle)
		return;
	QuestManager._controle = false;
	var key = e.keyCode;
	if (key > QuestManager._trigger)
		key -= 32;
	else if (key < QuestManager._trigger)
		key += 32;
	if(key == QuestManager._trigger && SceneManager._scene.constructor.name == "Scene_Map" && $gamePlayer.canMove())
		SceneManager.push(Scene_Quest);
};

addEventListener("keydown", QuestManager.chamarMenuDeQuests);
addEventListener("keyup", function() {QuestManager._controle = true;});
*/

//-----------------------------------------------------------------------------
// Window_MenuCommand e Scene_Menu
//
// Sobrescreve funções do menu para adicionar "quests" às opções

Window_MenuCommand.prototype.addOptionsCommand = function()
{
	if (this.needsCommand('options'))
	{
		var enabled = this.isOptionsEnabled();
		this.addCommand(TextManager.options, 'options', enabled);
	}
	this.addCommand("Quests", 'quests');
};

Scene_Menu.prototype.createCommandWindow = function()
{
	this._commandWindow = new Window_MenuCommand(0, 0);
	this._commandWindow.setHandler('item',      this.commandItem.bind(this));
	this._commandWindow.setHandler('skill',     this.commandPersonal.bind(this));
	this._commandWindow.setHandler('equip',     this.commandPersonal.bind(this));
	this._commandWindow.setHandler('status',    this.commandPersonal.bind(this));
	this._commandWindow.setHandler('formation', this.commandFormation.bind(this));
	this._commandWindow.setHandler('options',   this.commandOptions.bind(this));
	this._commandWindow.setHandler('quests',    this.commandQuests.bind(this));
	this._commandWindow.setHandler('save',      this.commandSave.bind(this));
	this._commandWindow.setHandler('gameEnd',   this.commandGameEnd.bind(this));
	this._commandWindow.setHandler('cancel',    this.popScene.bind(this));
	this.addWindow(this._commandWindow);
};

Scene_Menu.prototype.commandQuests = function()
{
	SceneManager.push(Scene_Quest);
};


//-----------------------------------------------------------------------------
// Scene_Quest
//
// Cuida da inicialização e do comportamento das janelas

function Scene_Quest()
{
	this.initialize.apply(this, arguments);
}

Scene_Quest.prototype = Object.create(Scene_Base.prototype);
Scene_Quest.prototype.constructor = Scene_Quest;

Scene_Quest.prototype.initialize = function()
{
	Scene_Base.prototype.initialize.call(this);
};

Scene_Quest.prototype.create = function()
{
	Scene_Base.prototype.create.call(this);
	this.createBackground();
	this.createWindowLayers();
	this.createWindows();
};

Scene_Quest.prototype.createWindowLayers = function()
{
	var width = Graphics.boxWidth;
	var height = Graphics.boxHeight;
	var x = (Graphics.width - width) / 2;
	var y = (Graphics.height - height) / 2;
	this._Layer1 = new WindowLayer();
	this._Layer1.move(x, y, width, height);
	this.addChild(this._Layer1);
	this._Layer2 = new WindowLayer();
	this._Layer2.move(x, y, width, height);
	this.addChild(this._Layer2);
};

Scene_Quest.prototype.createBackground = function()
{
	this._backgroundSprite = new Sprite();
	this._backgroundSprite.bitmap = SceneManager.backgroundBitmap();
	this.addChild(this._backgroundSprite);
};

Scene_Quest.prototype.createWindows = function()
{
	this._questOption = new Window_QuestCommand(0, 0);
	this._questSelect = new Window_QuestList(0, this._questOption.height);
	this._questOption.setHandler('cancel',     this.popScene.bind(this));
	this._questOption.setHandler('pendentes',  this.selectCurrent.bind(this));
	this._questOption.setHandler('concluidas', this.selectFinished.bind(this));
	this._questOption.setHandler('falhas',     this.selectFailed.bind(this));
	this._questSelect.setHandler('cancel',     this.selectReturn.bind(this));
	this._Layer1.addChild(this._questOption);
	this._Layer1.addChild(this._questSelect);
	this._Layer1.addChild(this._questSelect._helpWindow);
	this._Layer2.addChild(this._questSelect._helpWindow._faceWindow);
	this._Layer2.addChild(this._questSelect._helpWindow._charWindow);
};

Scene_Quest.prototype.select = function()
{
	this._questSelect.clearCommandList();
	this._questOption.deactivate();
	this._questSelect.select(0);
	this._questSelect.activate();
};

Scene_Quest.prototype.selectCurrent = function()
{
	this.select();
	this._questSelect.updateCommandList('pendente');
};

Scene_Quest.prototype.selectFinished = function()
{
	this.select();
	this._questSelect.updateCommandList('concluida');
};

Scene_Quest.prototype.selectFailed = function()
{
	this.select();
	this._questSelect.updateCommandList('falha');
};

Scene_Quest.prototype.selectReturn = function()
{
	this._questSelect.updateCommandList('');
	this._questSelect.deactivate();
	this._questSelect.deselect();
	this._questOption.activate();
};


//-----------------------------------------------------------------------------
// Window_QuestCommand
//
// Janela para filtrar o tipo de quest (pendente, concluída ou que falhou)

function Window_QuestCommand()
{
	this.initialize.apply(this, arguments);
}

Window_QuestCommand.prototype = Object.create(Window_Command.prototype);
Window_QuestCommand.prototype.constructor = Window_QuestCommand;

Window_QuestCommand.prototype.makeCommandList = function()
{
	this.addCommand("Pendentes", 'pendentes');
	this.addCommand("Concluídas", 'concluidas');
	this.addCommand("Falhas", 'falhas');
};

Window_QuestCommand.prototype.initialize = function(x, y)
{
	Window_Command.prototype.initialize.call(this, x, y);
};

Window_QuestCommand.prototype.windowWidth = function()
{
	return SceneManager._screenWidth;
};

Window_QuestCommand.prototype.windowHeight = function()
{
	return this.lineHeight() + this.standardPadding() * 2;
};

Window_QuestCommand.prototype.maxCols = function()
{
	return 3;
};

Window_QuestCommand.prototype.itemTextAlign = function()
{
	return 'center';
};


//-----------------------------------------------------------------------------
// Window_QuestList
//
// Janela com a lista das quests e a função de escrever o texto

function Window_QuestList()
{
	this.initialize.apply(this, arguments);
}

Window_QuestList.prototype = Object.create(Window_Command.prototype);
Window_QuestList.prototype.constructor = Window_QuestList;

Window_QuestList.prototype.initialize = function(x, y)
{
	Window_Command.prototype.initialize.call(this, x, y);
	this._helpWindow = new Window_QuestDetail(0, this.height * 2);
	this.deselect();
};

Window_QuestList.which = '';

Window_QuestList.prototype.makeCommandList = function()
{
	var tempList = QuestManager.questList(this.which);
	for (var i = 0; i < tempList.length; i++)
		this.addCommand(tempList[i].name, '');
};

Window_QuestList.prototype.updateCommandList = function(which)
{
	this.which = which;
	this.refresh();
};

Window_QuestList.prototype.isOkEnabled = function()
{
	return false;
};

Window_QuestList.prototype.processCursorMove = function()
{
	Window_Selectable.prototype.processCursorMove.call(this);
	var tempList;
	if (this.which)
		tempList = QuestManager.questList(this.which);
	if ((Input.isRepeated('down') || Input.isRepeated('up') || this._helpWindow._text == '') && tempList && tempList[0])
	{
		var cor = "\\c[" + PluginManager.parameters('QuestMenu')['Cor'].toString() + "]";
		var texto = "";
		var desc = this._helpWindow.forceLineBreak("Descrição: " + tempList[this._index].desc);
		texto += cor + "Descrição: \\c[0]" + desc.substring("Descrição: ".length) + "\\}\n\n\\{";// tempList[this._index].desc + "\\}\n\n\\{" + "\n\n\n\n";
		texto += cor + "Dificuldade: \\c[0]" + tempList[this._index].rank + "\\}\n\n\\{";
		texto += cor + "Cliente: \\c[0]" + tempList[this._index].giver + "\\}\n\n\\{";
		texto += cor + "Andamento: \\c[0]" + tempList[this._index].complete + "\\}\n\n\\{";
		texto += cor + "Recompensa: \\c[0]" + tempList[this._index].rewardGold + cor + " \\G\\c[0]\\}\n\n\\{";
		texto += cor + "Experiência: \\c[0]" + tempList[this._index].rewardExp;
		this._helpWindow.setText(texto);
	}
	else if (Input.isRepeated('down') || Input.isRepeated('up') || !this.which)
	{
		this._helpWindow._faceWindow.contents.clear();
		this._helpWindow.setText('');
	}
	if (tempList && tempList[0])
	{
		this._helpWindow.drawFace(tempList[this._index].face, tempList[this._index].faceId);
		this._helpWindow.drawCharacter(tempList[this._index].sprite, tempList[this._index].spriteId);//, Window_Base._faceWidth / 2, Window_Base._faceHeight);
	}
	else
	{
		this._helpWindow._faceWindow.contents.clear();
		this._helpWindow._charWindow.contents.clear();
	}
};

Window_QuestList.prototype.windowWidth = function()
{
	return SceneManager._screenWidth;
};

Window_QuestList.prototype.windowHeight = function()
{
	return this.lineHeight() + this.standardPadding() * 2;
};

Window_QuestList.prototype.itemTextAlign = function()
{
	return 'center';
};


//-----------------------------------------------------------------------------
// Window_QuestDetail
//
// Janela com os detalhes de cada quest e funções importantes de formatação

function Window_QuestDetail()
{
	this.initialize.apply(this, arguments);
}

Window_QuestDetail.prototype = Object.create(Window_Base.prototype);
Window_QuestDetail.prototype.constructor = Window_QuestDetail;

Window_QuestDetail.prototype.initialize = function(x, y)
{
	var width = SceneManager._screenWidth;
	var height = SceneManager._screenHeight - y;
	Window_Base.prototype.initialize.call(this, x, y, width, height);
	this._text = [];
	subWindowWidth  = Window_Base._faceWidth  + this.standardPadding() * 2;
	subWindowHeight = Window_Base._faceHeight + this.standardPadding() * 2;
	this._faceWindow = new Window_Base(x + width - subWindowWidth,        y + height - subWindowHeight, subWindowWidth,        subWindowHeight);
	this._charWindow = new Window_Base(x + width - subWindowWidth * 1.75, y + height - subWindowHeight, subWindowWidth * 0.75, subWindowHeight);
	this._faceWindow.windowskin = ImageManager.loadEmptyBitmap();
	this._charWindow.windowskin = ImageManager.loadEmptyBitmap();
};

Window_QuestDetail.prototype.setText = function(text)
{
	this._text = text;
	this.refresh();
};

Window_QuestDetail.prototype.clear = function()
{
	this.setText('');
};

Window_QuestDetail.prototype.refresh = function()
{
	this.contents.clear();
	this.drawTextEx(this._text, this.textPadding(), 0);
};

Window_QuestDetail.prototype.drawFace = function(face, faceId)
{
	var w = Window_Base._faceWidth;
	var h = Window_Base._faceHeight;
	this._faceWindow.contents.clear();
	this._faceWindow.drawFace(face, faceId, 0, 0, w, h);
}

Window_QuestDetail.prototype.drawCharacter = function(characterName, characterIndex)
{
	this._charWindow.contents.clear();
	var bitmap = ImageManager.loadCharacter(characterName);
	var big = ImageManager.isBigCharacter(characterName);
	var pw = bitmap.width / (big ? 3 : 12);
	var ph = bitmap.height / (big ? 4 : 8);
	var n = characterIndex;
	var f = Math.floor((Graphics.frameCount / 16) % 4);
	if (f == 3)
		f = 1;
	var sx = (n % 4 * 3 + f) * pw;
	var sy = (Math.floor(n / 4) * 4) * ph;
	var x = (this._charWindow.width  - pw) / 2 - this.standardPadding();
	var y = (this._charWindow.height - ph) - this.standardPadding() * 2;
	this._charWindow.contents.blt(bitmap, sx, sy, pw, ph, x, y);
};

Window_QuestDetail.prototype.descMaxLines = function()
{
	return Math.floor(this.contentsHeight() / this.lineHeight()) - 8;
};

Window_QuestDetail.prototype.textWidth = function(text)
{
	if (!Graphics._hiddenCanvas)
		Graphics._hiddenCanvas = document.createElement('canvas');
	var context = Graphics._hiddenCanvas.getContext('2d');
	context.font = this.standardFontSize().toString() + 'px ' + this.standardFontFace();
	return context.measureText(text).width;
};

Window_QuestDetail.prototype.forceLineBreak = function(text)
{
	var i = text.indexOf(" ");
	var j = 0;
	var line = 0;
	var newtext = text.substring(line, i);
	var frmtdtext = "";
	var maxWidth = this.contentsWidth();
	while (text.indexOf(" ", i + 1) > i)
	{
		if (this.textWidth(text.substring(line, text.indexOf(" ", i + 1))) > maxWidth)
		{
			frmtdtext += newtext + '\n';
			if (++j > this.descMaxLines())
				return frmtdtext.substring(0, frmtdtext.length - 1) + "...";
			newtext = "";
			line = i;
		}
		newtext += text.substring(i, text.indexOf(" ", i + 1));
		i = text.indexOf(" ", i + 1);
	}
	frmtdtext += newtext + text.substring(i);
	j = this.descMaxLines() - j;
	for (i = 0; i < j; i++)
		frmtdtext += '\n';
	return frmtdtext;
};
Pode me chamar de Russo

Citação de: Senhor dos Grafos online 29/03/2016 às 22:17
Citação de: Darkrafa online 29/03/2016 às 21:47
Muito show seu script!

Eu só tenho uma dúvida: haveria a possibilidade de colocá-lo como opção no menu mesmo?
Tanto faz deixá-lo apenas com o menu e também usando o comando especificado ou apenas no menu.

Obrigado!

Tem sim, inclusive você vai achar essa parte "comentada" (escrita, mas desativada, entre /* e */) no meu código. Basta "desativar" o parâmetro e função que chama o menu pela tecla de atalho e "ativar" as funções que integram essa opção ao menu. Como eu não sei se você sabe mexer com isso, vou deixar aqui o código "modificado":

//=============================================================================
// QuestMenu.js
// Senhor dos Grafos (Russo)
// Mundo RPG Maker || Centro RPG Maker
//=============================================================================

/*:
 * @plugindesc
 * Chama um menu de quests ao pressionar um determinado botão
 * (inspirado no script em RGSS3 do Masked, membro do MRM)
 * @author Senhor dos Grafos (Russo)
 *
 * param Tecla
 * desc Tecla para chamar o menu de quests
 * PRECISA SER UMA LETRA
 * default T
 *
 * @param Cor
 * @desc Cor do "cabeçalho" do menu de quests
 * PRECISA SER UM NÚMERO
 * @default 23
 *
 */


//-----------------------------------------------------------------------------
// QuestManager
//
// Classe estática para controlar as quests in-game

function QuestManager()
{
	throw new Error('Esta é uma classe estática');
}

QuestManager._questList = [];
QuestManager._id = 5042;
/*
QuestManager._trigger = PluginManager.parameters('QuestMenu')['Tecla'].charCodeAt(0);
QuestManager._controle = true;
*/

QuestManager.createQuest = function(name, desc, rank, giver, face, faceId, sprite, spriteId, complete, rewardGold, rewardExp)
{
	this.load();
	if (!this.questExiste(name))
	{
		var quest = {};
		quest.name = name;
		quest.desc = desc;
		quest.rank = rank;
		quest.giver = giver;
		quest.face = face;
		quest.faceId = faceId;
		quest.sprite = sprite;
		quest.spriteId = spriteId;
		if (complete == "-")
			quest.complete = "-/-";
		else
			quest.complete = "0/" + complete.toString();
		quest.rewardGold = rewardGold.toString();
		quest.rewardExp = rewardExp.toString();
		quest.category = 'pendente'
		this._questList.push(quest);
		this.save();
	}
};

QuestManager.questExiste = function(n)
{
	return !isNaN(this.questId(n));
};

QuestManager.estaEmAndamento = function(n)
{
	n = this.questId(n);
	if (!isNaN(n))
		return this._questList[n].category == 'pendente';
	else
		return false;
};

QuestManager.foiConcluida = function(n)
{
	n = this.questId(n);
	if (!isNaN(n))
		return this._questList[n].category == 'concluida';
	else
		return false;
};

QuestManager.foiFracasso = function(n)
{
	n = this.questId(n);
	if (!isNaN(n))
		return this._questList[n].category == 'falha';
	else
		return false;
};

QuestManager.andamento = function(n)
{
	n = this.questId(n);
	if (isNaN(n))
		return "-/-"
	return this._questList[n].complete;
};

QuestManager.andamentoAtual = function(n)
{
	n = this.andamento(n);
	if (n == "-/-")
		return "-"
	else
		return parseInt(n.substring(0, n.indexOf("/")));
};

QuestManager.andamentoTotal = function(n)
{
	n = this.andamento(n);
	if (n == "-/-")
		return "-"
	else
		return parseInt(n.substring(n.indexOf("/") + 1));
};

QuestManager.somarAndamento = function(n, s)
{
	n = this.questId(n);
	if (isNaN(n))
		return false;
	var a = this.andamentoAtual(n);
	if (isNaN(a))
		return true;
	a += s;
	var t = this.andamentoTotal(n);
	this._questList[n].complete = Math.min(a, t).toString() + "/" + t.toString();
	return a >= t;
};

QuestManager.andamentoEstaCompleto = function(n)
{
	return this.somarAndamento(n, 0);
};

QuestManager.concluir = function(n)
{
	n = this.questId(n);
	if (!isNaN(n))
	{
		this._questList[n].category = 'concluida';
		$gameParty.gainGold(parseInt(this._questList[n].rewardGold));
		var t = $gameParty.allMembers().length;
		for (var i = 0; i < t; i++)
			$gameParty.allMembers()[i].gainExp(parseInt(this._questList[n].rewardExp));
	}
};

QuestManager.falhar = function(n)
{
	n = this.questId(n);
	if (!isNaN(n))
		this._questList[n].category = 'falha';
};

QuestManager.questId = function(n)
{
	this.load();
	if (!isNaN(n) && n < this._questList.length)
		return n;
	else if (!isNaN(n))
		return NaN;
	var t = this._questList.length;
	for (var i = 0; i < t; i++)
		if (this._questList[i].name == n)
			return i;
	return NaN;
};

QuestManager.remove = function(name)
{
	var id = this.questId(name);
	if (id != -1)
		this._questList.splice(id, 1);
};

QuestManager.clearList = function()
{
	this._questList = [];
};

QuestManager.save = function()
{
	$gameVariables[this._id] = this._questList;
};

QuestManager.load = function()
{
	if ($gameVariables[this._id])
		this._questList = $gameVariables[this._id];
};

QuestManager.questList = function(category)
{
	this.load();
	var tempList = [];
	for (var i = 0; i < this._questList.length; i++)
		if (category && (this._questList[i].category == category || category == 'all'))
			tempList.push(this._questList[i]);
	return tempList;
};
/*
QuestManager.chamarMenuDeQuests = function(e)
{
	if (!QuestManager._controle)
		return;
	QuestManager._controle = false;
	var key = e.keyCode;
	if (key > QuestManager._trigger)
		key -= 32;
	else if (key < QuestManager._trigger)
		key += 32;
	if(key == QuestManager._trigger && SceneManager._scene.constructor.name == "Scene_Map" && $gamePlayer.canMove())
		SceneManager.push(Scene_Quest);
};

addEventListener("keydown", QuestManager.chamarMenuDeQuests);
addEventListener("keyup", function() {QuestManager._controle = true;});
*/

//-----------------------------------------------------------------------------
// Window_MenuCommand e Scene_Menu
//
// Sobrescreve funções do menu para adicionar "quests" às opções

Window_MenuCommand.prototype.addOptionsCommand = function()
{
	if (this.needsCommand('options'))
	{
		var enabled = this.isOptionsEnabled();
		this.addCommand(TextManager.options, 'options', enabled);
	}
	this.addCommand("Quests", 'quests');
};

Scene_Menu.prototype.createCommandWindow = function()
{
	this._commandWindow = new Window_MenuCommand(0, 0);
	this._commandWindow.setHandler('item',      this.commandItem.bind(this));
	this._commandWindow.setHandler('skill',     this.commandPersonal.bind(this));
	this._commandWindow.setHandler('equip',     this.commandPersonal.bind(this));
	this._commandWindow.setHandler('status',    this.commandPersonal.bind(this));
	this._commandWindow.setHandler('formation', this.commandFormation.bind(this));
	this._commandWindow.setHandler('options',   this.commandOptions.bind(this));
	this._commandWindow.setHandler('quests',    this.commandQuests.bind(this));
	this._commandWindow.setHandler('save',      this.commandSave.bind(this));
	this._commandWindow.setHandler('gameEnd',   this.commandGameEnd.bind(this));
	this._commandWindow.setHandler('cancel',    this.popScene.bind(this));
	this.addWindow(this._commandWindow);
};

Scene_Menu.prototype.commandQuests = function()
{
	SceneManager.push(Scene_Quest);
};


//-----------------------------------------------------------------------------
// Scene_Quest
//
// Cuida da inicialização e do comportamento das janelas

function Scene_Quest()
{
	this.initialize.apply(this, arguments);
}

Scene_Quest.prototype = Object.create(Scene_Base.prototype);
Scene_Quest.prototype.constructor = Scene_Quest;

Scene_Quest.prototype.initialize = function()
{
	Scene_Base.prototype.initialize.call(this);
};

Scene_Quest.prototype.create = function()
{
	Scene_Base.prototype.create.call(this);
	this.createBackground();
	this.createWindowLayers();
	this.createWindows();
};

Scene_Quest.prototype.createWindowLayers = function()
{
	var width = Graphics.boxWidth;
	var height = Graphics.boxHeight;
	var x = (Graphics.width - width) / 2;
	var y = (Graphics.height - height) / 2;
	this._Layer1 = new WindowLayer();
	this._Layer1.move(x, y, width, height);
	this.addChild(this._Layer1);
	this._Layer2 = new WindowLayer();
	this._Layer2.move(x, y, width, height);
	this.addChild(this._Layer2);
};

Scene_Quest.prototype.createBackground = function()
{
	this._backgroundSprite = new Sprite();
	this._backgroundSprite.bitmap = SceneManager.backgroundBitmap();
	this.addChild(this._backgroundSprite);
};

Scene_Quest.prototype.createWindows = function()
{
	this._questOption = new Window_QuestCommand(0, 0);
	this._questSelect = new Window_QuestList(0, this._questOption.height);
	this._questOption.setHandler('cancel',     this.popScene.bind(this));
	this._questOption.setHandler('pendentes',  this.selectCurrent.bind(this));
	this._questOption.setHandler('concluidas', this.selectFinished.bind(this));
	this._questOption.setHandler('falhas',     this.selectFailed.bind(this));
	this._questSelect.setHandler('cancel',     this.selectReturn.bind(this));
	this._Layer1.addChild(this._questOption);
	this._Layer1.addChild(this._questSelect);
	this._Layer1.addChild(this._questSelect._helpWindow);
	this._Layer2.addChild(this._questSelect._helpWindow._faceWindow);
	this._Layer2.addChild(this._questSelect._helpWindow._charWindow);
};

Scene_Quest.prototype.select = function()
{
	this._questSelect.clearCommandList();
	this._questOption.deactivate();
	this._questSelect.select(0);
	this._questSelect.activate();
};

Scene_Quest.prototype.selectCurrent = function()
{
	this.select();
	this._questSelect.updateCommandList('pendente');
};

Scene_Quest.prototype.selectFinished = function()
{
	this.select();
	this._questSelect.updateCommandList('concluida');
};

Scene_Quest.prototype.selectFailed = function()
{
	this.select();
	this._questSelect.updateCommandList('falha');
};

Scene_Quest.prototype.selectReturn = function()
{
	this._questSelect.updateCommandList('');
	this._questSelect.deactivate();
	this._questSelect.deselect();
	this._questOption.activate();
};


//-----------------------------------------------------------------------------
// Window_QuestCommand
//
// Janela para filtrar o tipo de quest (pendente, concluída ou que falhou)

function Window_QuestCommand()
{
	this.initialize.apply(this, arguments);
}

Window_QuestCommand.prototype = Object.create(Window_Command.prototype);
Window_QuestCommand.prototype.constructor = Window_QuestCommand;

Window_QuestCommand.prototype.makeCommandList = function()
{
	this.addCommand("Pendentes", 'pendentes');
	this.addCommand("Concluídas", 'concluidas');
	this.addCommand("Falhas", 'falhas');
};

Window_QuestCommand.prototype.initialize = function(x, y)
{
	Window_Command.prototype.initialize.call(this, x, y);
};

Window_QuestCommand.prototype.windowWidth = function()
{
	return SceneManager._screenWidth;
};

Window_QuestCommand.prototype.windowHeight = function()
{
	return this.lineHeight() + this.standardPadding() * 2;
};

Window_QuestCommand.prototype.maxCols = function()
{
	return 3;
};

Window_QuestCommand.prototype.itemTextAlign = function()
{
	return 'center';
};


//-----------------------------------------------------------------------------
// Window_QuestList
//
// Janela com a lista das quests e a função de escrever o texto

function Window_QuestList()
{
	this.initialize.apply(this, arguments);
}

Window_QuestList.prototype = Object.create(Window_Command.prototype);
Window_QuestList.prototype.constructor = Window_QuestList;

Window_QuestList.prototype.initialize = function(x, y)
{
	Window_Command.prototype.initialize.call(this, x, y);
	this._helpWindow = new Window_QuestDetail(0, this.height * 2);
	this.deselect();
};

Window_QuestList.which = '';

Window_QuestList.prototype.makeCommandList = function()
{
	var tempList = QuestManager.questList(this.which);
	for (var i = 0; i < tempList.length; i++)
		this.addCommand(tempList[i].name, '');
};

Window_QuestList.prototype.updateCommandList = function(which)
{
	this.which = which;
	this.refresh();
};

Window_QuestList.prototype.isOkEnabled = function()
{
	return false;
};

Window_QuestList.prototype.processCursorMove = function()
{
	Window_Selectable.prototype.processCursorMove.call(this);
	var tempList;
	if (this.which)
		tempList = QuestManager.questList(this.which);
	if ((Input.isRepeated('down') || Input.isRepeated('up') || this._helpWindow._text == '') && tempList && tempList[0])
	{
		var cor = "\\c[" + PluginManager.parameters('QuestMenu')['Cor'].toString() + "]";
		var texto = "";
		var desc = this._helpWindow.forceLineBreak("Descrição: " + tempList[this._index].desc);
		texto += cor + "Descrição: \\c[0]" + desc.substring("Descrição: ".length) + "\\}\n\n\\{";// tempList[this._index].desc + "\\}\n\n\\{" + "\n\n\n\n";
		texto += cor + "Dificuldade: \\c[0]" + tempList[this._index].rank + "\\}\n\n\\{";
		texto += cor + "Cliente: \\c[0]" + tempList[this._index].giver + "\\}\n\n\\{";
		texto += cor + "Andamento: \\c[0]" + tempList[this._index].complete + "\\}\n\n\\{";
		texto += cor + "Recompensa: \\c[0]" + tempList[this._index].rewardGold + cor + " \\G\\c[0]\\}\n\n\\{";
		texto += cor + "Experiência: \\c[0]" + tempList[this._index].rewardExp;
		this._helpWindow.setText(texto);
	}
	else if (Input.isRepeated('down') || Input.isRepeated('up') || !this.which)
	{
		this._helpWindow._faceWindow.contents.clear();
		this._helpWindow.setText('');
	}
	if (tempList && tempList[0])
	{
		this._helpWindow.drawFace(tempList[this._index].face, tempList[this._index].faceId);
		this._helpWindow.drawCharacter(tempList[this._index].sprite, tempList[this._index].spriteId);//, Window_Base._faceWidth / 2, Window_Base._faceHeight);
	}
	else
	{
		this._helpWindow._faceWindow.contents.clear();
		this._helpWindow._charWindow.contents.clear();
	}
};

Window_QuestList.prototype.windowWidth = function()
{
	return SceneManager._screenWidth;
};

Window_QuestList.prototype.windowHeight = function()
{
	return this.lineHeight() + this.standardPadding() * 2;
};

Window_QuestList.prototype.itemTextAlign = function()
{
	return 'center';
};


//-----------------------------------------------------------------------------
// Window_QuestDetail
//
// Janela com os detalhes de cada quest e funções importantes de formatação

function Window_QuestDetail()
{
	this.initialize.apply(this, arguments);
}

Window_QuestDetail.prototype = Object.create(Window_Base.prototype);
Window_QuestDetail.prototype.constructor = Window_QuestDetail;

Window_QuestDetail.prototype.initialize = function(x, y)
{
	var width = SceneManager._screenWidth;
	var height = SceneManager._screenHeight - y;
	Window_Base.prototype.initialize.call(this, x, y, width, height);
	this._text = [];
	subWindowWidth  = Window_Base._faceWidth  + this.standardPadding() * 2;
	subWindowHeight = Window_Base._faceHeight + this.standardPadding() * 2;
	this._faceWindow = new Window_Base(x + width - subWindowWidth,        y + height - subWindowHeight, subWindowWidth,        subWindowHeight);
	this._charWindow = new Window_Base(x + width - subWindowWidth * 1.75, y + height - subWindowHeight, subWindowWidth * 0.75, subWindowHeight);
	this._faceWindow.windowskin = ImageManager.loadEmptyBitmap();
	this._charWindow.windowskin = ImageManager.loadEmptyBitmap();
};

Window_QuestDetail.prototype.setText = function(text)
{
	this._text = text;
	this.refresh();
};

Window_QuestDetail.prototype.clear = function()
{
	this.setText('');
};

Window_QuestDetail.prototype.refresh = function()
{
	this.contents.clear();
	this.drawTextEx(this._text, this.textPadding(), 0);
};

Window_QuestDetail.prototype.drawFace = function(face, faceId)
{
	var w = Window_Base._faceWidth;
	var h = Window_Base._faceHeight;
	this._faceWindow.contents.clear();
	this._faceWindow.drawFace(face, faceId, 0, 0, w, h);
}

Window_QuestDetail.prototype.drawCharacter = function(characterName, characterIndex)
{
	this._charWindow.contents.clear();
	var bitmap = ImageManager.loadCharacter(characterName);
	var big = ImageManager.isBigCharacter(characterName);
	var pw = bitmap.width / (big ? 3 : 12);
	var ph = bitmap.height / (big ? 4 : 8);
	var n = characterIndex;
	var f = Math.floor((Graphics.frameCount / 16) % 4);
	if (f == 3)
		f = 1;
	var sx = (n % 4 * 3 + f) * pw;
	var sy = (Math.floor(n / 4) * 4) * ph;
	var x = (this._charWindow.width  - pw) / 2 - this.standardPadding();
	var y = (this._charWindow.height - ph) - this.standardPadding() * 2;
	this._charWindow.contents.blt(bitmap, sx, sy, pw, ph, x, y);
};

Window_QuestDetail.prototype.descMaxLines = function()
{
	return Math.floor(this.contentsHeight() / this.lineHeight()) - 8;
};

Window_QuestDetail.prototype.textWidth = function(text)
{
	if (!Graphics._hiddenCanvas)
		Graphics._hiddenCanvas = document.createElement('canvas');
	var context = Graphics._hiddenCanvas.getContext('2d');
	context.font = this.standardFontSize().toString() + 'px ' + this.standardFontFace();
	return context.measureText(text).width;
};

Window_QuestDetail.prototype.forceLineBreak = function(text)
{
	var i = text.indexOf(" ");
	var j = 0;
	var line = 0;
	var newtext = text.substring(line, i);
	var frmtdtext = "";
	var maxWidth = this.contentsWidth();
	while (text.indexOf(" ", i + 1) > i)
	{
		if (this.textWidth(text.substring(line, text.indexOf(" ", i + 1))) > maxWidth)
		{
			frmtdtext += newtext + '\n';
			if (++j > this.descMaxLines())
				return frmtdtext.substring(0, frmtdtext.length - 1) + "...";
			newtext = "";
			line = i;
		}
		newtext += text.substring(i, text.indexOf(" ", i + 1));
		i = text.indexOf(" ", i + 1);
	}
	frmtdtext += newtext + text.substring(i);
	j = this.descMaxLines() - j;
	for (i = 0; i < j; i++)
		frmtdtext += '\n';
	return frmtdtext;
};


Perfeito demais, Russo!
Muito obrigado!

Ótimo plugin, vi muita gente precisando de um ao estilo, é excelente pra quem quer fazer projetos maiores com muita exploração, quests são essenciais para um RPG

Citação de: Senhor dos Grafos online 29/03/2016 às 16:21
Olá, pessoas
Tô disponibilizando aqui um plugin que eu fiz na minha fábrica (no Mundo RPG Maker) baseado em um script de quests do Masked, do Mundo RPG Maker. Divirtam-se.

O que o script faz?
Permite que o(a) jogador(a) abra um menu de quests apertando uma determinada tecla. O(a) desenvolvedor(a) pode criar e controlar novas quests sem precisar mexer no arquivo do plugin, apenas usando comandos de script no próprio RPG Maker MV.

Tem screenchots?
Tem sim:
Spoiler
[close]

Como usar o plugin?
O plugin tem muitos comandos, por isso eu deixei uma demo pra facilitar a vida de vocês. Deem uma olhada nela e, se surgir alguma dúvida, podem me perguntar.

Você cobra o seu nome nos créditos?
Se quiser botar, ótimo, mas se não quiser não faço questão. Só não copie o script e leve o crédito por ele sozinho, isso se chama plágio.

Cadê o link pra download?
Não tem, eu deixei um arquivo zipado em anexo. Lá vocês vão encontrar uma pasta chamada data e um arquivo chamado QuestMenu.js. Criem um novo projeto no MV, substituam a pasta data do novo projeto por essa do anexo e copiem QuestMenu.js para a pasta de plugins. Agora abra o projeto. Pronto, tá tudo no lugar, certo?

Esse plugin é essencial para o meu jogo, eu estou tentando simular um RPG Classico só que não online +1 Ouro, uma pergunta, precisa creditar o criador desse plugin (ou seja, você)?

O que ta acontecendo no meu menu, quando eu coloco o plugin aparece 2 comandos de opção

Citação de: HeroVini314 online 14/07/2016 às 23:16
Citação de: Senhor dos Grafos online 29/03/2016 às 16:21
Olá, pessoas
Tô disponibilizando aqui um plugin que eu fiz na minha fábrica (no Mundo RPG Maker) baseado em um script de quests do Masked, do Mundo RPG Maker. Divirtam-se.

O que o script faz?
Permite que o(a) jogador(a) abra um menu de quests apertando uma determinada tecla. O(a) desenvolvedor(a) pode criar e controlar novas quests sem precisar mexer no arquivo do plugin, apenas usando comandos de script no próprio RPG Maker MV.

Tem screenchots?
Tem sim:
Spoiler
[close]

Como usar o plugin?
O plugin tem muitos comandos, por isso eu deixei uma demo pra facilitar a vida de vocês. Deem uma olhada nela e, se surgir alguma dúvida, podem me perguntar.

Você cobra o seu nome nos créditos?
Se quiser botar, ótimo, mas se não quiser não faço questão. Só não copie o script e leve o crédito por ele sozinho, isso se chama plágio.

Cadê o link pra download?
Não tem, eu deixei um arquivo zipado em anexo. Lá vocês vão encontrar uma pasta chamada data e um arquivo chamado QuestMenu.js. Criem um novo projeto no MV, substituam a pasta data do novo projeto por essa do anexo e copiem QuestMenu.js para a pasta de plugins. Agora abra o projeto. Pronto, tá tudo no lugar, certo?

Esse plugin é essencial para o meu jogo, eu estou tentando simular um RPG Classico só que não online +1 Ouro, uma pergunta, precisa creditar o criador desse plugin (ou seja, você)?

Olha, eu geralmente não sou chato com esse tipo de coisa, afinal eu tô fazendo esses sistemas na fábrica pra ajudar um monte de pessoas aleatórias, então não ligo se você não quiser botar o meu nome nos créditos, mas seria legal

Citação de: HeroVini314 online 14/07/2016 às 23:25
O que ta acontecendo no meu menu, quando eu coloco o plugin aparece 2 comandos de opção

Eu realmente não faço ideia, acabei de baixar o sistema de novo e tá funcionando 100% no meu computador. Talvez seja alguma incompatibilidade?
Pode me chamar de Russo

Olá Russo, muito obrigado por este Plugin incrível. Realmente ele é muito bom, mas sinto falta do tutorial de como utiliza-lo, se possível poderia me enviar como fazer ele funcionar?   :o:): 

Citação de: Jingoku online 05/08/2016 às 19:48
Olá Russo, muito obrigado por este Plugin incrível. Realmente ele é muito bom, mas sinto falta do tutorial de como utiliza-lo, se possível poderia me enviar como fazer ele funcionar?   :o:):

Desculpa, mas eu realmente não sei mais o que fazer pra deixar mais claro, porque eu deixei vários comentários na demo. Basta abrir o projeto e olhar cada evento no mapa, eles vão ter um comando "chamar script" com tudo explicadinho. Se você baixou o sistema e tem alguma dúvida específica sobre alguma coisa, me manda uma mensagem ou pode me responder aqui no tópico mesmo.
Pode me chamar de Russo

Citação de: Senhor dos Grafos online 07/08/2016 às 16:13
Citação de: Jingoku online 05/08/2016 às 19:48
Olá Russo, muito obrigado por este Plugin incrível. Realmente ele é muito bom, mas sinto falta do tutorial de como utiliza-lo, se possível poderia me enviar como fazer ele funcionar?   :o:):

Desculpa, mas eu realmente não sei mais o que fazer pra deixar mais claro, porque eu deixei vários comentários na demo. Basta abrir o projeto e olhar cada evento no mapa, eles vão ter um comando "chamar script" com tudo explicadinho. Se você baixou o sistema e tem alguma dúvida específica sobre alguma coisa, me manda uma mensagem ou pode me responder aqui no tópico mesmo.
Bem, começando que eu não baixei a DEMO, pois o link que está anexado só possui a pasta "data" e o Plugin ultilizado no sistema. Onde posso baixar a DEMO?

12/08/2016 às 11:27 #14 Última edição: 12/08/2016 às 11:32 por Senhor dos Grafos
Ahhh sim. A demo é isso aí, o arquivo completo é muito pesado pra anexar então eu deixei só o essencial. Você tem que criar um novo projeto e copiar esses arquivos pra pasta do projeto, substituindo a pasta data original e colocando o arquivo QuestMenu.js dentro de js/plugins/. Me desculpa, eu achei que todos estavam cientes de como isso funcionava, vou atualizar o post pra não ter mais nenhuma confusão.
Edit: acabei de ler o post original e acontece que essa informação já tava ali embaixo :v
Pode me chamar de Russo