/*============================================================================= SameItemDisabled.js ---------------------------------------------------------------------------- (C)2023 Triacontane This software is released under the MIT License. http://opensource.org/licenses/mit-license.php ---------------------------------------------------------------------------- Version 1.3.4 2024/10/07 複数回行動のコストを考慮する設定のとき、MP消費率を計算に入れていなかった問題を修正 1.3.3 2024/06/09 行動選択してから実際に行動する前に行動不能になったとき、使用予定だったコストが解放されない問題を修正 1.3.2 2024/01/11 1.3.0の機能説明をヘルプに追加 1.3.1 2023/04/20 1.2.0で追加した併用対応にいくつか不具合があったので修正 1.3.0 2023/04/18 複数回行動できるアクターの場合、前に選択したスキルのコストを考慮して使用可能か判定する機能を追加 1.2.0 2023/04/17 CSVN_armsAsSpecialEffectItem.jsと併用できるよう専用のコードを追加 1.1.0 2023/04/17 テスト用コードが誤って混入していたので修正 1.0.0 2023/04/16 初版 ---------------------------------------------------------------------------- [Blog] : https://triacontane.blogspot.jp/ [Twitter]: https://twitter.com/triacontane/ [GitHub] : https://github.com/triacontane/ =============================================================================*/ /*: @target MZ @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/SameItemDisabled.js @plugindesc Same Item Prohibition Plugin @author Triacontane @license MIT License @help English Help Translator: munokura This is an unofficial English translation of the plugin help, created to support global RPG Maker users. Feedback is welcome to improve translation quality (see: https://github.com/munokura/triacontane-MZ-plugins ). Original plugin by Triacontane. Please check the latest official version at: https://triacontane.blogspot.com ----- SameItemDisabled.js This plugin prevents multiple players from using the same item. It cannot be used regardless of consumption settings. It can be used if there are spare items. In addition, for actors who can act multiple times, it also has a function that determines whether it can be used by taking into account the cost of previously selected skills. This plugin requires the base plugin "PluginCommonBase.js." "PluginCommonBase.js" is located in the following folder under the RPG Maker MZ installation folder: dlc/BasicResources/plugins/official Terms of Use: You may modify and redistribute this plugin without permission from the author, and there are no restrictions on its use (commercial, 18+, etc.). This plugin is now yours. @param multiActionCost @text Consider the cost of multiple actions @desc For actors who can act multiple times, the cost of previously selected skills is taken into account when determining whether they can be used. @type boolean @default false @param excludeNonConsumed @text Non-consumable items excluded @desc Non-consumable items can be used simultaneously. @type boolean @default false */ /*:ja @plugindesc 同一アイテム使用禁止プラグイン @target MZ @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/SameItemDisabled.js @base PluginCommonBase @orderAfter PluginCommonBase @orderAfter CSVN_armsAsSpecialEffectItem @author トリアコンタン @param multiActionCost @text 複数回行動のコストを考慮 @desc 複数回行動できるアクターの場合、前に選択したスキルのコストを考慮して使用可能か判定します。 @default false @type boolean @param excludeNonConsumed @text 非消耗アイテム除外 @desc 消耗しないアイテムは同時使用可能とします。 @default false @type boolean @help SameItemDisabled.js 複数人で同一のアイテムを使用できなくなります。 消耗の設定に拘わらず使用できません。 個数に余裕がある場合は使用できます。 また、複数回行動できるアクターの場合、前に選択したスキルの コストを考慮して使用可能か判定する機能もあります。 このプラグインの利用にはベースプラグイン『PluginCommonBase.js』が必要です。 『PluginCommonBase.js』は、RPGツクールMZのインストールフォルダ配下の 以下のフォルダに格納されています。 dlc/BasicResources/plugins/official 利用規約: 作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等) についても制限はありません。 このプラグインはもうあなたのものです。 */ (() => { 'use strict'; const script = document.currentScript; const param = PluginManagerEx.createParameter(script); const _Game_Party_initialize = Game_Party.prototype.initialize; Game_Party.prototype.initialize = function() { _Game_Party_initialize.apply(this, arguments); this.initActionStack(); }; Game_Party.prototype.initActionStack = function() { this._actionStack = []; }; Game_Party.prototype.pushAction = function(action) { if (!action) { return; } this._actionStack.push(action); }; Game_Party.prototype.popAction = function() { const action = this._actionStack.pop(); if (action?.subItem) { action.subItem = null; } return action; }; Game_Party.prototype.execAction = function(action) { this._actionStack = this._actionStack.filter(a => a !== action); }; Game_Party.prototype.clearActionByBattler = function(battler) { this._actionStack = this._actionStack.filter(action => action.subject() !== battler); }; Game_Party.prototype.findReserveItemCount = function(item) { return this._actionStack.filter(action => action.item() === item || action.subItem === item).length; }; Game_Party.prototype.findReserveSkillMpCost = function(battler) { return this.findActionStack(battler) .reduce((prev, action) => prev + battler.skillMpCost(action.item()), 0); }; Game_Party.prototype.findReserveSkillTpCost = function(battler) { return this.findActionStack(battler) .reduce((prev, action) => prev + battler.skillTpCost(action.item()), 0); }; Game_Party.prototype.findActionStack = function(battler) { return this._actionStack.filter(action => action.isSkill() && action.subject() === battler); }; const _Game_BattlerBase_canPaySkillCost = Game_BattlerBase.prototype.canPaySkillCost; Game_BattlerBase.prototype.canPaySkillCost = function(skill) { const result = _Game_BattlerBase_canPaySkillCost.apply(this, arguments); if (BattleManager.isInputting() && param.multiActionCost) { const party = $gameParty; return result && this._mp - party.findReserveSkillMpCost(this) >= this.skillMpCost(skill) && this._tp - party.findReserveSkillTpCost(this) >= this.skillTpCost(skill); } else { return result; } }; const _Game_Battler_clearActions = Game_Battler.prototype.clearActions; Game_Battler.prototype.clearActions = function() { _Game_Battler_clearActions.apply(this, arguments); $gameParty.clearActionByBattler(this); }; const _Game_Party_numItems = Game_Party.prototype.numItems; Game_Party.prototype.numItems = function(item) { const result = _Game_Party_numItems.apply(this, arguments); if (BattleManager.isInputting()) { if (param.excludeNonConsumed && !item.consumable) { return result; } else { return result - this.findReserveItemCount(item); } } else { return result; } }; // for CSVN_armsAsSpecialEffectItem.js start const _Scene_Battle_onItemOk = Scene_Battle.prototype.onItemOk; Scene_Battle.prototype.onItemOk = function() { const item = this._itemWindow.item(); if (DataManager.isWeapon(item) || DataManager.isArmor(item)) { const action = BattleManager.inputtingAction(); action.subItem = item; } _Scene_Battle_onItemOk.apply(this, arguments); }; const _Game_Party_canUse = Game_Party.prototype.canUse; Game_Party.prototype.canUse = function(item) { const result = _Game_Party_canUse.apply(this, arguments); if (BattleManager.isInputting()) { return result && this.canUseEquipItem(item); } else { return result; } }; Game_Party.prototype.canUseEquipItem = function(item) { if (param.excludeNonConsumed) { return true; } if (!DataManager.isArmor(item) && !DataManager.isWeapon(item)) { return true; } return this.numItems(item) > 0; }; // for CSVN_armsAsSpecialEffectItem.js end const _BattleManager_setup = BattleManager.setup; BattleManager.setup = function(troopId, canEscape, canLose) { _BattleManager_setup.apply(this, arguments); $gameParty.initActionStack(); }; const _BattleManager_selectNextCommand = BattleManager.selectNextCommand; BattleManager.selectNextCommand = function() { $gameParty.pushAction(this.inputtingAction()); _BattleManager_selectNextCommand.apply(this, arguments); }; const _BattleManager_selectPreviousCommand = BattleManager.selectPreviousCommand; BattleManager.selectPreviousCommand = function() { _BattleManager_selectPreviousCommand.apply(this, arguments); $gameParty.popAction(); }; const _BattleManager_startAction = BattleManager.startAction; BattleManager.startAction = function() { _BattleManager_startAction.apply(this, arguments); $gameParty.execAction(this._action); }; const _BattleManager_endBattle = BattleManager.endBattle; BattleManager.endBattle = function(result) { _BattleManager_endBattle.apply(this, arguments); $gameParty.initActionStack(); }; })();