查看: 1533|回复: 1

[有事请教] 求一个NPC跟随队伍的插件?

[复制链接]
梦石
0
星屑
5269
在线时间
733 小时
注册时间
2013-1-18
回帖
525
发表于 2023-6-20 09:01:05 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
之前好像看到有大佬发过。
比如做护送任务,一个纯NPC跟在队伍里,不参加战斗。
找了半天也找不到了,请大佬们指条明路。
梦石
0
星屑
10175
在线时间
1096 小时
注册时间
2016-8-22
回帖
59

开拓者

发表于 2023-6-20 11:02:50 | 显示全部楼层
楼主看下 Triacontane 的 NpcFollower 插件合适不
草草翻译了一下
[pre lang="javascript" line="1" file="NpcFollower.js"]//=============================================================================
// NpcFollower.js
// ----------------------------------------------------------------------------
// (C) 2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.1.2 2022/05/10 パラメータの説明文を修正
// 1.1.1 2019/11/02 1.1.0の修正でメンバーの入れ替えを実施すると表示が不正になる場合がある問題を修正
// 1.1.0 2019/01/27 通常のフォロワーを表示せず、NPCフォロワーのみを表示できる機能を追加
// 1.0.3 2018/08/06 コアスクリプトが1.6.0より古い場合にエラーになる記述を修正
// 1.0.2 2017/01/17 プラグインコマンドが小文字でも動作するよう修正(byこまちゃん先輩)
// 1.0.1 2016/07/17 セーブデータをロードした際のエラーになる現象の修正
// 1.0.0 2016/07/14 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
* @plugindesc NPC 跟随插件
* @author triacontane
*
* @param MaxNpcNumber
* @desc 队列中可以同时存在的 npc 的最大数量。
* @default 1
*
* @param HideNormalFollower
* @desc 不显示常规跟随者,仅显示 npc 跟随者。启用数据库列队行走。
* @default false
* @type boolean
*
* @help 将队员以外的NPC添加到地图上排中的任何位置。
* NPC 在数据库中由 Actor 定义,然后从插件命令中添加或删除。
* 因为不是战斗员,所以不会影响菜单画面和战斗画面。
* 此外,如果不显示编队,则不会显示任何内容。
*
* 您还可以添加具有相同 ID 的多个角色。
*
* 插件命令详细信息
*  从事件命令“插件命令”运行。
*  (参数之间用半角空格分隔)
*
* NF_NPC追加 4 1 # 增加ID为[4]的角色为NPC,加入队伍第1个人后面
* NF_ADD_NPC 5 3 # 将角色 ID [5]作为 npc 添加到队伍第3个人后面
* NF_NPC削除 1   # [1]番目に追加したNPCを全て削除
* NF_REM_NPC 3   # [3]番目に追加したNPCを全て削除
*
* 索引指定与添加的NPC无关,而是与队伍的顺序有关(1... 战斗成员的数量)。。
*
* This plugin is released under the MIT License.
*/
/*:ja
* @plugindesc NPCフォロワープラグイン
* @author トリアコンタン
*
* @param 最大同時NPC数
* @desc 同時に隊列に存在できるNPCの最大数です。
* @default 1
* @type number
* @min 1
*
* @param 通常フォロワーを表示しない
* @desc 通常のフォロワーを一切表示せず、NPCフォロワーのみを表示します。データベースの隊列歩行は有効にしてください。
* @default false
* @type boolean
*
* @help マップ上の隊列の好きな位置にパーティメンバー以外のNPCを追加します。
* NPCはデータベース上はアクターで定義してプラグインコマンドから追加、削除します。
* 戦闘員ではないので、メニュー画面や戦闘画面には影響を与えません。
* また、隊列表示していない場合は何も表示されません。
*
* 同一IDのアクターを複数追加することもできます。
*
* プラグインコマンド詳細
*  イベントコマンド「プラグインコマンド」から実行。
*  (パラメータの間は半角スペースで区切る)
*
* NF_NPC追加 4 1 # アクターID[4]をNPCとしてパーティの[1]番目の後ろに追加
* NF_ADD_NPC 5 3 # アクターID[5]をNPCとしてパーティの[3]番目の後ろに追加
* NF_NPC削除 1   # [1]番目に追加したNPCを全て削除
* NF_REM_NPC 3   # [3]番目に追加したNPCを全て削除
*
* インデックスの指定は追加したNPCとは関係なく、
* パーティの並び順(1...バトルメンバー数)を指定してください。
*
* 利用規約:
*  作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等)
*  についても制限はありません。
*  このプラグインはもうあなたのものです。
*/

(function() {
    'use strict';
    var pluginName    = 'NpcFollower';
    var metaTagPrefix = 'NF';

    var getCommandName = function(command) {
        return (command || '').toUpperCase();
    };

    var getParamOther = function(paramNames) {
        if (!Array.isArray(paramNames)) paramNames = [paramNames];
        for (var i = 0; i < paramNames.length; i++) {
            var name = PluginManager.parameters(pluginName)[paramNames];
            if (name) return name;
        }
        return null;
    };

    var getParamBoolean = function(paramNames) {
        var value = getParamOther(paramNames);
        return (value || '').toUpperCase() === 'TRUE';
    };

    var getParamNumber = function(paramNames, min, max) {
        var value = getParamOther(paramNames);
        if (arguments.length < 2) min = -Infinity;
        if (arguments.length < 3) max = Infinity;
        return (parseInt(value, 10) || 0).clamp(min, max);
    };

    var getArgNumberWithEval = function(arg, min, max) {
        if (arguments.length < 2) min = -Infinity;
        if (arguments.length < 3) max = Infinity;
        return (parseInt(eval(convertEscapeCharacters(arg)), 10) || 0).clamp(min, max);
    };

    var convertEscapeCharacters = function(text) {
        if (text == null) text = '';
        var windowLayer = SceneManager._scene._windowLayer;
        return windowLayer ? windowLayer.children[0].convertEscapeCharacters(text) : text;
    };

    //=============================================================================
    // パラメータの取得と整形
    //=============================================================================
    var paramMaxNpcNumber       = getParamNumber(['MaxNpcNumber', '最大同時NPC数']);
    var paramHideNormalFollower = getParamBoolean(['HideNormalFollower', '通常フォロワーを表示しない']);

    //=============================================================================
    // Game_Interpreter
    //  プラグインコマンドを追加定義します。
    //=============================================================================
    var _Game_Interpreter_pluginCommand      = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
        _Game_Interpreter_pluginCommand.apply(this, arguments);
        this.pluginCommandNpcFollower(command.replace(new RegExp(metaTagPrefix, 'i'), ''), args);
    };

    Game_Interpreter.prototype.pluginCommandNpcFollower = function(command, args) {
        switch (getCommandName(command)) {
            case '_NPC追加' :
            case '_ADD_NPC' :
                var actorId = getArgNumberWithEval(args[0]);
                $gameParty.addNpc(actorId, getArgNumberWithEval(args[1], 1));
                break;
            case '_NPC削除' :
            case '_REM_NPC' :
                $gameParty.removeNpc(getArgNumberWithEval(args[0], 1));
                break;
        }
    };

    //=============================================================================
    // Game_Party
    //  NPCの追加と削除を追加定義します。
    //=============================================================================
    var _Game_Party_initialize      = Game_Party.prototype.initialize;
    Game_Party.prototype.initialize = function() {
        _Game_Party_initialize.apply(this, arguments);
        this.initNpc();
    };

    Game_Party.prototype.initNpc = function() {
        this._npcs       = [];
        this._npcIndexes = [];
    };

    Game_Party.prototype.isNpcInvalid = function() {
        return !this._npcs;
    };

    Game_Party.prototype.initNpcIfNeed = function() {
        if (this.isNpcInvalid()) {
            this.initNpc();
            $gamePlayer.followers().initNpc();
        }
    };

    Game_Party.prototype.addNpc = function(actorId, index) {
        if (this._npcs.length < paramMaxNpcNumber) {
            this._npcs.push(actorId);
            this._npcIndexes.push(index);
            $gamePlayer.refresh();
            $gameMap.requestRefresh();
        } else {
            throw new Error('登録可能な最大数を超えています。');
        }
    };

    Game_Party.prototype.removeNpc = function(index) {
        for (var i = 0, n = this._npcs.length; i < n; i++) {
            if (this._npcIndexes === index) {
                this._npcs.splice(i, 1);
                this._npcIndexes.splice(i, 1);
                i--;
            }
        }
        $gamePlayer.refresh();
        $gameMap.requestRefresh();
    };

    Game_Party.prototype.npcMembers = function() {
        return this._npcs.map(function(id) {
            return $gameActors.actor(id);
        });
    };

    Game_Party.prototype.visibleMembers = function() {
        return this._visibleMembers;
    };

    Game_Party.prototype.makeVisibleMembers = function() {
        var battleMembers  = this.battleMembers();
        var npcMembers     = this.npcMembers();
        var visibleMembers = [];
        for (var i = 0, n = this.maxBattleMembers() + 1; i < n; i++) {
            for (var j = 0, m = npcMembers.length; j < m; j++) {
                if (this._npcIndexes[j] === i) {
                    visibleMembers.push(npcMembers[j]);
                }
            }
            if (battleMembers.length > i && !paramHideNormalFollower) {
                visibleMembers.push(battleMembers);
            }
        }
        this._visibleMembers = visibleMembers;
    };

    //=============================================================================
    // Game_Followers
    //  NPCの最大数ぶんだけ余分にGame_Followerを作成します。
    //=============================================================================
    var _Game_Followers_initialize      = Game_Followers.prototype.initialize;
    Game_Followers.prototype.initialize = function() {
        _Game_Followers_initialize.apply(this, arguments);
        if (paramHideNormalFollower) {
            this._data = [];
        }
        this.initNpc();
    };

    Game_Followers.prototype.initNpc = function() {
        var memberLength = this._data.length > 0 ? this._data.length + 1 : 0;
        for (var i = 0; i < paramMaxNpcNumber; i++) {
            this._data.push(new Game_Follower(memberLength + i));
        }
    };

    //=============================================================================
    // Game_Follower
    //  NPC判定を追加定義します。
    //=============================================================================
    var _Game_Follower_actor      = Game_Follower.prototype.actor;
    Game_Follower.prototype.actor = function() {
        _Game_Follower_actor.apply(this, arguments);
        return $gameParty.visibleMembers()[this._memberIndex];
    };

    //=============================================================================
    // Game_Player
    //  リフレッシュまえに表示メンバーを更新します。
    //=============================================================================
    var _Game_Player_refresh      = Game_Player.prototype.refresh;
    Game_Player.prototype.refresh = function() {
        $gameParty.makeVisibleMembers();
        _Game_Player_refresh.apply(this, arguments);
    };

    //=============================================================================
    // DataManager
    //  プラグイン未適用のデータをロードした場合に必要なデータを初期化します。
    //=============================================================================
    var _DataManager_loadGame = DataManager.loadGame;
    DataManager.loadGame      = function(saveFileId) {
        var result = _DataManager_loadGame.apply(this, arguments);
        $gameParty.initNpcIfNeed();
        return result;
    };
})();

[/pre]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部