572 lines
19 KiB
JavaScript
572 lines
19 KiB
JavaScript
//=============================================================================
|
||
// MenuSubMember.js (Ver1.2.2)
|
||
//=============================================================================
|
||
// 更新履歴
|
||
// 2015.10.27 1.0 初公開(準公式プラグイン)
|
||
// 2017.06.03 1.1 マップ画面でも同行者を表示
|
||
// 2017.06.04 1.1.1 後方互換性対応。プラグイン導入前のセーブデータも読み込み可
|
||
// 2017.06.05 1.1.2 連続でメニューを開閉するとフリーズする不具合を修正
|
||
// 2017.06.17 1.2 ひきも記さんの隊列歩行プラグイン「TMFollowerEx.js」との併用が
|
||
// 可能になりました。
|
||
// 2017.06.19 1.2.1 「TMFollowerEx.js」プラグイン導入前にセーブしたデータを
|
||
// 読み込んでも、正しく隊列が表示されるようになりました。
|
||
// 逆(「TMFollowerEx.js」導入後にセーブしたデータを、導入前の
|
||
// 環境で読み込む)の場合も、正しく表示されます。
|
||
// 2018.09.18 1.2.2 メニュー画面での同行者の表示のタイプを追加
|
||
|
||
/*:
|
||
* @plugindesc display sub member at menu window and field (Ver1.2.2)
|
||
* @author Sasuke KANNAZUKI (thanks to Yoji Ojima)
|
||
*
|
||
* @param subMemberIdVal1
|
||
* @desc variable id for actor id of sub member 1
|
||
* @default 11
|
||
*
|
||
* @param subMemberIdVal2
|
||
* @desc variable id for actor id of sub member 2
|
||
* @default 12
|
||
*
|
||
* @param subMemberIdVal3
|
||
* @desc variable id for actor id of sub member 3
|
||
* @default 13
|
||
*
|
||
* @param subMemberIdVal4
|
||
* @desc variable id for actor id of sub member 4
|
||
* @default 14
|
||
*
|
||
* @param displayIfNone
|
||
* @desc when no sub members, whether display the window or not.
|
||
* (1=display, 0=not display)
|
||
* @default 0
|
||
*
|
||
* @param subMemberText
|
||
* @desc display text that means sub member
|
||
* @default Sub Members
|
||
*
|
||
* @param subMemberNoneText
|
||
* @desc text display when no sub members
|
||
* @default None
|
||
*
|
||
* @param DisplayOnMap
|
||
* @desc whether to display sub members on map at tail of party (1:yes, 0:no)
|
||
* @default 1
|
||
*
|
||
* @param MenuSubMember Display Mode
|
||
* @desc set display mode on window. 0=default, 1=without name
|
||
* @default 0
|
||
*
|
||
* @help This plugin does not provide plugin commands.
|
||
*
|
||
* this plugin displays sub members under the menu commands.
|
||
* sub member is an actor that not attend battle.
|
||
*
|
||
* [Ver1.1 additional feature]
|
||
* At map scene, it displays sub members after actors.
|
||
* *note* by option setting, this function can invalidate.
|
||
*
|
||
* if no sub members, set variables value be 0.
|
||
*
|
||
* the actors appeared on map are top 4, that attends the battle.
|
||
* sub members in the party appear always every one on map.
|
||
*
|
||
* [Ver1.2 additional feature]
|
||
* _Enables to utilize this plugin with "TMFollowerEx.js".
|
||
* http://hikimoki.sakura.ne.jp/plugin/plugin_system.html#TMFollowerEx
|
||
*
|
||
* In the case, be sure to put MenuSubMember.js below TMFollowerEx.js.
|
||
*
|
||
* *** Check points to utilize 2 plugins:
|
||
* ・You can insert NPC actor(s) either/both top or tail.
|
||
* This function is independent from MenuSubMember.
|
||
* ・You can set the max length of the followers.
|
||
* It enables you to display all actors and sub members on the map scene.
|
||
* ・"TMFollower.js" suppose menu sub members as the tail of actors.
|
||
* So you can run plugin commands for followers also to menu sub members.
|
||
* ・If the player obtain more character(actors, NPCs, and menu sub members),
|
||
* truncate actors and menu sub members from the tail.
|
||
*
|
||
* note: this plugin is only for default menu.
|
||
* it cannot use on changed layout menu(ex. AltMenuScreen.js).
|
||
*
|
||
* [License]
|
||
* this plugin is released under MIT license.
|
||
* http://opensource.org/licenses/mit-license.php
|
||
*/
|
||
|
||
/*:ja
|
||
* @plugindesc メニュー画面と隊列の最後尾に同行者を表示します(ver1.2.2)
|
||
* @author 神無月サスケ (thanks to Yoji Ojima)
|
||
*
|
||
* @param subMemberIdVal1
|
||
* @desc 同行者1のアクターIDを入れる変数ID
|
||
* @default 11
|
||
*
|
||
* @param subMemberIdVal2
|
||
* @desc 同行者2のアクターIDを入れる変数ID
|
||
* @default 12
|
||
*
|
||
* @param subMemberIdVal3
|
||
* @desc 同行者3のアクターIDを入れる変数ID
|
||
* @default 13
|
||
*
|
||
* @param subMemberIdVal4
|
||
* @desc 同行者4のアクターIDを入れる変数ID
|
||
* @default 14
|
||
*
|
||
* @param displayIfNone
|
||
* @desc 同行者がいない場合でも、ウィンドウを表示するか
|
||
* (する=1, しない=0)
|
||
* @default 0
|
||
*
|
||
* @param subMemberText
|
||
* @desc 「同行者」の意味で表示するテキスト
|
||
* @default 同行者
|
||
*
|
||
* @param subMemberNoneText
|
||
* @desc 同行者がいない時に表示するテキスト
|
||
* @default なし
|
||
*
|
||
* @param DisplayOnMap
|
||
* @desc 隊列歩行の最後尾に同行者を表示するか(1:する, 0:しない)
|
||
* @default 1
|
||
*
|
||
* @param MenuSubMember Display Mode
|
||
* @desc メニュー画面での同行者の表示方法。0=通常 1=キャラのみで名前なし
|
||
* @default 0
|
||
*
|
||
* @help このプラグインには、プラグインコマンドはありません。
|
||
*
|
||
* このプラグインは、同行者リストを、メニューコマンドの下に表示します。
|
||
* 同行者とは、戦闘に参加しないアクターです。
|
||
*
|
||
* [Ver1.1 追加要素]
|
||
* 同行者は、マップ上での隊列歩行で、アクターの最後尾に表示されます。
|
||
* オプションでマップ上で非表示にすることも可能です。
|
||
*
|
||
* 同行者を設定しない場合は、該当する変数の値を 0 にしてください。
|
||
*
|
||
* アクターが5人以上の場合でも、隊列に現れるアクターは先頭の4人だけです。
|
||
* 一方同行者は、全員(最大4人)が表示されます。
|
||
*
|
||
* [Ver1.2 追加要素]
|
||
* ひきも記さんの隊列歩行プラグイン「TMFollowerEx.js」との連携が可能に。
|
||
* http://hikimoki.sakura.ne.jp/plugin/plugin_system.html#TMFollowerEx
|
||
*
|
||
* 連携する場合、本プラグインMenuSubMember.js を、必ず下に配置してください。
|
||
*
|
||
* 連携により、例えば以下のようなことが可能になります。
|
||
* ・隊列の先頭や末尾に、メニューに現れないアクターを挿入可能です。
|
||
* この機能は、同行者とは完全に独立しています。
|
||
* ・隊列の長さを指定可能です。これにより、本プラグイン単体では先頭4人のみ
|
||
* ですが、連携することで、全てのアクター、同行者を表示することも可能です。
|
||
* ・『TMFollower.js』側から見ると同行者は「最後尾にいるフォロワー達」と
|
||
* 認識されます。このため、『TMFollower.js』側のプラグインコマンドで
|
||
* フォロワーに関する処理が同行者に対しても施されます。
|
||
* ・仮に指定した隊列表示人数より、アクターと同行者の方が多くなった場合、
|
||
* 同行者の最後尾から順に表示が省略されていきます。
|
||
*
|
||
* ■注意:このプラグインはデフォルトのメニュー画面専用です。
|
||
* プラグイン(AltMenuScreen.jsなど)でレイアウトを変更したケースでは使えません。
|
||
*
|
||
* ■ライセンス表記
|
||
* このプラグインは MIT ライセンスで配布されます。
|
||
* ご自由にお使いください。
|
||
* http://opensource.org/licenses/mit-license.php
|
||
*/
|
||
|
||
(function () {
|
||
//
|
||
// process parameters
|
||
//
|
||
var parameters = PluginManager.parameters("MenuSubMember");
|
||
var submemberVar1 = Number(parameters["subMemberIdVal1"] || 11);
|
||
var submemberVar2 = Number(parameters["subMemberIdVal2"] || 12);
|
||
var submemberVar3 = Number(parameters["subMemberIdVal3"] || 13);
|
||
var submemberVar4 = Number(parameters["subMemberIdVal4"] || 14);
|
||
var subMemberText = parameters["subMemberText"] || "Sub Members";
|
||
var subMemberNoneText = parameters["subMemberNoneText"] || "None";
|
||
var displayIfNone = !!Number(parameters["displayIfNone"]);
|
||
var DisplayOnMap = !!Number(parameters["DisplayOnMap"] || 1);
|
||
var menuDisplayMode = Number(parameters["MenuSubMember Display Mode"] || 0);
|
||
|
||
//
|
||
// process TMFollowerEx parameters
|
||
//
|
||
var tmParams = PluginManager.parameters("TMFollowerEx");
|
||
var additionalFollower = tmParams
|
||
? Number(tmParams["additionalFollower"] || 4)
|
||
: 4;
|
||
|
||
// ----------------------------------------------------------------------
|
||
// add window to menu scene (V1.0 section)
|
||
//
|
||
var _Scene_Menu_create = Scene_Menu.prototype.create;
|
||
Scene_Menu.prototype.create = function () {
|
||
_Scene_Menu_create.call(this);
|
||
this.createSubMemberWindow();
|
||
};
|
||
|
||
Scene_Menu.prototype.createSubMemberWindow = function () {
|
||
var x = 0;
|
||
var y = this._commandWindow.height;
|
||
var width = this._commandWindow.width;
|
||
var height = Graphics.height - y - this._goldWindow.height;
|
||
switch (menuDisplayMode) {
|
||
case 0:
|
||
this._subMemberWindow = new Window_SubMember(x, y, width, height);
|
||
break;
|
||
default:
|
||
this._subMemberWindow = new Window_SubMember2(x, y, width, height);
|
||
break;
|
||
}
|
||
this.addWindow(this._subMemberWindow);
|
||
};
|
||
|
||
var _Scene_Menu_start = Scene_Menu.prototype.start;
|
||
Scene_Menu.prototype.start = function () {
|
||
_Scene_Menu_start.call(this);
|
||
this._subMemberWindow.refresh();
|
||
};
|
||
|
||
//
|
||
// sub member window
|
||
//
|
||
function Window_SubMember() {
|
||
this.initialize.apply(this, arguments);
|
||
}
|
||
|
||
Window_SubMember.prototype = Object.create(Window_Base.prototype);
|
||
Window_SubMember.prototype.constructor = Window_SubMember;
|
||
|
||
Window_SubMember.prototype.initialize = function (x, y, width, height) {
|
||
Window_Base.prototype.initialize.call(this, x, y, width, height);
|
||
this.setSubMember();
|
||
this.refresh();
|
||
};
|
||
|
||
Window_SubMember.prototype.setSubMember = function () {
|
||
this.subMember1 = $gameActors.actor($gameVariables.value(submemberVar1));
|
||
this.subMember2 = $gameActors.actor($gameVariables.value(submemberVar2));
|
||
this.subMember3 = $gameActors.actor($gameVariables.value(submemberVar3));
|
||
this.subMember4 = $gameActors.actor($gameVariables.value(submemberVar4));
|
||
};
|
||
|
||
Window_SubMember.prototype.refresh = function () {
|
||
var y = 0;
|
||
var numLines = 0;
|
||
var isVisible = true;
|
||
var width = this.width - 80;
|
||
var lineHeight = this.lineHeight();
|
||
this.contents.clear();
|
||
// draw the text "sub member"
|
||
this.changeTextColor(this.systemColor());
|
||
this.drawText(subMemberText, 4, 0, width);
|
||
numLines++;
|
||
// draw sub members
|
||
this.resetTextColor();
|
||
y += lineHeight;
|
||
if (this.subMember1) {
|
||
this.drawActorName(this.subMember1, 44, y, width);
|
||
this.drawActorCharacter(this.subMember1, 24, y + 40);
|
||
y += lineHeight;
|
||
numLines++;
|
||
}
|
||
if (this.subMember2) {
|
||
this.drawActorName(this.subMember2, 44, y, width);
|
||
this.drawActorCharacter(this.subMember2, 24, y + 40);
|
||
y += lineHeight;
|
||
numLines++;
|
||
}
|
||
if (this.subMember3) {
|
||
this.drawActorName(this.subMember3, 44, y, width);
|
||
this.drawActorCharacter(this.subMember3, 24, y + 40);
|
||
y += lineHeight;
|
||
numLines++;
|
||
}
|
||
if (this.subMember4) {
|
||
this.drawActorName(this.subMember4, 44, y, width);
|
||
this.drawActorCharacter(this.subMember4, 24, y + 40);
|
||
y += lineHeight;
|
||
numLines++;
|
||
}
|
||
// if no sub members
|
||
if (y === lineHeight) {
|
||
this.drawText(subMemberNoneText, 4, y, width);
|
||
numLines++;
|
||
if (!displayIfNone) {
|
||
isVisible = false;
|
||
}
|
||
}
|
||
// fitting height
|
||
if (numLines < 5 || this.y != 324) {
|
||
this.height = this.fittingHeight(numLines) + 4;
|
||
this.y = Graphics.height - 72 - this.height;
|
||
}
|
||
// set visible status
|
||
this.visible = isVisible;
|
||
};
|
||
|
||
//
|
||
// sub member window 2 (without name)
|
||
//
|
||
function Window_SubMember2() {
|
||
this.initialize.apply(this, arguments);
|
||
}
|
||
|
||
Window_SubMember2.prototype = Object.create(Window_SubMember.prototype);
|
||
Window_SubMember2.prototype.constructor = Window_SubMember2;
|
||
|
||
Window_SubMember2.prototype.initialize = function (x, y, width, height) {
|
||
Window_SubMember.prototype.initialize.call(this, x, y, width, height);
|
||
};
|
||
|
||
Window_SubMember2.prototype.refresh = function () {
|
||
var x = 24;
|
||
var y = this.lineHeight() * 2 + 16;
|
||
var charSize = $gameMap.tileWidth();
|
||
var numMembers = 0;
|
||
var isVisible = true;
|
||
var width = this.width - 80;
|
||
this.contents.clear();
|
||
// draw the text "sub member"
|
||
this.changeTextColor(this.systemColor());
|
||
this.drawText(subMemberText, 4, 0, width);
|
||
if (this.subMember1) {
|
||
this.drawActorCharacter(this.subMember1, x, y);
|
||
x += charSize;
|
||
numMembers++;
|
||
}
|
||
if (this.subMember2) {
|
||
this.drawActorCharacter(this.subMember2, x, y);
|
||
x += charSize;
|
||
numMembers++;
|
||
}
|
||
if (this.subMember3) {
|
||
this.drawActorCharacter(this.subMember3, x, y);
|
||
x += charSize;
|
||
numMembers++;
|
||
}
|
||
if (this.subMember4) {
|
||
this.drawActorCharacter(this.subMember4, x, y);
|
||
x += charSize;
|
||
numMembers++;
|
||
}
|
||
// draw sub members
|
||
this.resetTextColor();
|
||
// if no sub members
|
||
if (x === 24) {
|
||
this.drawText(subMemberNoneText, 4, this.lineHeight() + 16);
|
||
if (!displayIfNone) {
|
||
isVisible = false;
|
||
}
|
||
}
|
||
// fitting height
|
||
this.height = this.fittingHeight(2) + 20;
|
||
this.y = Graphics.height - 72 - this.height;
|
||
// set visible status
|
||
this.visible = isVisible;
|
||
};
|
||
|
||
// ----------------------------------------------------------------------
|
||
// display sub member at screen
|
||
//
|
||
// added parameters Ver.1.1
|
||
//
|
||
var subMemberVarList = [
|
||
submemberVar1,
|
||
submemberVar2,
|
||
submemberVar3,
|
||
submemberVar4,
|
||
];
|
||
var subMembers = [];
|
||
|
||
//
|
||
// sub members definition
|
||
//
|
||
var _Game_Followers_initialize = Game_Followers.prototype.initialize;
|
||
Game_Followers.prototype.initialize = function () {
|
||
_Game_Followers_initialize.call(this);
|
||
this.createSubMembers();
|
||
};
|
||
|
||
Game_Followers.prototype.createSubMembers = function () {
|
||
for (var i = 0; i < 4; i++) {
|
||
var follower = new Game_Follower(this._data.length + 1);
|
||
this._data.push(follower);
|
||
subMembers.push(follower);
|
||
}
|
||
};
|
||
|
||
//
|
||
// at each loading, recreate followers.
|
||
//
|
||
var _DataManager_loadGame = DataManager.loadGame;
|
||
DataManager.loadGame = function (savefileId) {
|
||
var isSuccess = _DataManager_loadGame.call(this, savefileId);
|
||
if (isSuccess) {
|
||
$gamePlayer._followers.recreateFollowers();
|
||
}
|
||
return isSuccess;
|
||
};
|
||
|
||
Game_Followers.prototype.recreateFollowers = function () {
|
||
this._data = [];
|
||
for (var i = 1; i < $gameParty.maxBattleMembers(); i++) {
|
||
this._data.push(new Game_Follower(i));
|
||
}
|
||
$gameSystem._touchFollowerIncluded = null;
|
||
if ($gameSystem.TMFollowerIncluded()) {
|
||
for (i = 0; i < additionalFollower; i++) {
|
||
this._data.push(new Game_Follower($gameParty.maxBattleMembers() + i));
|
||
}
|
||
}
|
||
this.createSubMembers();
|
||
};
|
||
|
||
//
|
||
// sub members display (Game_Follower)
|
||
//
|
||
var parameterToSubMemberActor = function (index) {
|
||
var varId = subMemberVarList[index];
|
||
var subMemberID = $gameVariables.value(varId);
|
||
var subMember = $gameActors.actor(subMemberID);
|
||
if (varId > 0 && subMemberID && subMember) {
|
||
return subMember;
|
||
}
|
||
return null;
|
||
};
|
||
|
||
// skip subMember whose actorId is 0.
|
||
var subMemberPosition = function (index) {
|
||
for (var newIndex = 0, i = 0; i < 4; i++) {
|
||
var actor = parameterToSubMemberActor(i);
|
||
if (actor) {
|
||
if (newIndex++ === index) {
|
||
return actor;
|
||
}
|
||
} else {
|
||
continue;
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
|
||
//
|
||
// change subPlayer display when specified variable changes
|
||
//
|
||
var _Game_Variables_setValue = Game_Variables.prototype.setValue;
|
||
Game_Variables.prototype.setValue = function (variableId, value) {
|
||
_Game_Variables_setValue.call(this, variableId, value);
|
||
if (DisplayOnMap) {
|
||
if (subMemberVarList.contains(variableId)) {
|
||
$gameTemp.needFollowerRefresh = true;
|
||
}
|
||
}
|
||
};
|
||
|
||
var _Scene_Map_update = Scene_Map.prototype.update;
|
||
Scene_Map.prototype.update = function () {
|
||
if ($gameTemp.needFollowerRefresh) {
|
||
$gamePlayer._followers.refresh();
|
||
$gameTemp.needFollowerRefresh = false;
|
||
}
|
||
_Scene_Map_update.call(this);
|
||
};
|
||
|
||
//
|
||
// sub members display (Spriteset_Map)
|
||
//
|
||
var _Spriteset_Map_createCharacters =
|
||
Spriteset_Map.prototype.createCharacters;
|
||
Spriteset_Map.prototype.createCharacters = function () {
|
||
_Spriteset_Map_createCharacters.call(this);
|
||
for (var i = 0; i < 4; i++) {
|
||
var newCharacterSprite = new Sprite_Character(subMembers[i]);
|
||
this._characterSprites.push(newCharacterSprite);
|
||
this._tilemap.addChild(newCharacterSprite);
|
||
}
|
||
};
|
||
|
||
// ----------------------------------------------------------------------
|
||
// add compatibility with TMFollowerEx.js
|
||
//
|
||
// added features Ver.1.2
|
||
|
||
//
|
||
// read hikimoki's plugin parameters
|
||
//
|
||
Game_System.prototype.TMFollowerIncluded = function () {
|
||
if (this._touchFollowerIncluded == null) {
|
||
this._touchFollowerIncluded = "isTouchFollowerEnabled" in $gameSystem;
|
||
}
|
||
return this._touchFollowerIncluded;
|
||
};
|
||
|
||
//
|
||
// find the number of each component
|
||
//
|
||
var followerMaxSize = function () {
|
||
return (
|
||
$gameParty.maxBattleMembers() -
|
||
1 +
|
||
($gameSystem.TMFollowerIncluded() ? additionalFollower : 4)
|
||
);
|
||
};
|
||
|
||
var hasHeader = function () {
|
||
return $gameSystem.TMFollowerIncluded() && $gamePlayer.headerFollower() > 0;
|
||
};
|
||
|
||
var hasFooter = function () {
|
||
return $gameSystem.TMFollowerIncluded() && $gamePlayer.footerFollower() > 0;
|
||
};
|
||
|
||
var numDispActor = function () {
|
||
var actorFollowerNum = $gameParty.size() - 1 + (hasHeader() ? 1 : 0);
|
||
var ceil = $gameSystem.TMFollowerIncluded()
|
||
? followerMaxSize()
|
||
: $gameParty.maxBattleMembers() - 1;
|
||
return actorFollowerNum.clamp(0, ceil);
|
||
};
|
||
|
||
var numSubMembers = function () {
|
||
var num = 0;
|
||
if (DisplayOnMap) {
|
||
for (var i = 0; i < 4; i++) {
|
||
if (subMemberPosition(i)) {
|
||
num++;
|
||
}
|
||
}
|
||
}
|
||
return num.clamp(0, followerMaxSize() - numDispActor());
|
||
};
|
||
|
||
//
|
||
// find followers' character
|
||
//
|
||
// (overwritten)
|
||
Game_Follower.prototype.actor = function () {
|
||
var lastId = 0;
|
||
var headerNum = hasHeader() ? 1 : 0;
|
||
var footerNum = hasFooter() ? 1 : 0;
|
||
// footer
|
||
if (
|
||
hasFooter() &&
|
||
this._memberIndex ===
|
||
Math.min(followerMaxSize(), numDispActor() + numSubMembers() + 1)
|
||
) {
|
||
return $gameActors.actor($gamePlayer.footerFollower());
|
||
}
|
||
// normal followers.
|
||
if (this._memberIndex <= (lastId = numDispActor())) {
|
||
return $gameParty.allMembers()[this._memberIndex - headerNum];
|
||
}
|
||
// menu sub member
|
||
if (DisplayOnMap && this._memberIndex <= (lastId += numSubMembers())) {
|
||
return subMemberPosition(
|
||
this._memberIndex + numSubMembers() - lastId - 1
|
||
);
|
||
}
|
||
return null;
|
||
};
|
||
})();
|