Files
Superproject1/js/plugins/MenuSubMember.js
T
2023-04-11 22:11:31 +02:00

565 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;
};
})();