903 lines
31 KiB
JavaScript
903 lines
31 KiB
JavaScript
//=============================================================================
|
||
// NRP_OverpassTile.js
|
||
//=============================================================================
|
||
/*:
|
||
* @target MV MZ
|
||
* @plugindesc v1.021 Realize a high-performance overpass.
|
||
* @author Takeshi Sunagawa (original triacontane & Yoji Ojima)
|
||
* @orderAfter NRP_EventCollisionEX
|
||
* @orderAfter NRP_BushEX
|
||
* @url http://newrpg.seesaa.net/article/482040708.html
|
||
*
|
||
* @help You can represent overpasses such as bridges on the map.
|
||
*
|
||
* This is an enhanced version of
|
||
* the official RPG Maker MZ plugin "OverpassTile.js".
|
||
* It allows you to create overpasses with a higher degree of freedom
|
||
* by allowing you to place tiles on the overpass that prohibit passage.
|
||
*
|
||
* It can also be used as a hidden passage
|
||
* that can be slipped through on maps that do not use overpass.
|
||
*
|
||
* You can also switch the layer where the player or event exists
|
||
* by using the event's note field or plugin commands.
|
||
*
|
||
* OverpassTile.js" also exists in RPG Maker MV,
|
||
* but this plugin is based on the more advanced MZ version.
|
||
* On top of that, I have improved it
|
||
* so that it can be used in MV as well.
|
||
*
|
||
* ■Caution
|
||
* This plugin should be placed below the following plugins.
|
||
*
|
||
* - NRP_EventCollisionEX
|
||
* - NRP_BushEX
|
||
*
|
||
* ■Usage
|
||
* If you place a tile in the upper layer (layer 3-4 in MZ),
|
||
* it will be treated as an overpass.
|
||
* Then, as in "OverpassTile.js", specify the overpass
|
||
* and its entrance in the region and terrain tags.
|
||
*
|
||
* Initially, the character will be treated as being under the overpass.
|
||
* When the character passes through the entrance of the overpass,
|
||
* the character will move above the overpass.
|
||
*
|
||
* ■Note
|
||
* If you specify the following in the event's note field,
|
||
* it will appear above the overpass from the beginning.
|
||
*
|
||
* <OverpassHigher>
|
||
*
|
||
* ■Plugin Command (MZ)
|
||
* ◆ChangeHeight
|
||
* Specify the target character
|
||
* and change its vertical relationship to the overpass.
|
||
* Check the actual plugin command for details.
|
||
*
|
||
* ■Plugin Command (MV)
|
||
* ◆NRP.OverpassTile.Higher [Target] [Position (true/false)]
|
||
* Change the height at which the target is displayed as in the MZ version.
|
||
* ※If Position is omitted, it will be true.
|
||
* ※It does not matter if it is uppercase or lowercase.
|
||
*
|
||
* The following is an example.
|
||
*
|
||
* >NRP.OverpassTile.Higher 0
|
||
* Move this event to the upper layer.
|
||
* ※0 can be omitted.
|
||
*
|
||
* >NRP.OverpassTile.Higher 1 false
|
||
* Move the event with ID=1 to the lower level.
|
||
*
|
||
* >NRP.OverpassTile.Higher 1~10
|
||
* Move the events with ID=1 to 10 to the upper layer.
|
||
*
|
||
* >NRP.OverpassTile.Higher -1
|
||
* Move player (-1) to the upper level.
|
||
*
|
||
* >NRP.OverpassTile.Higher -1~-4
|
||
* Move the four party members to the upper level.
|
||
* ※-2 and below means formation walking friends.
|
||
*
|
||
* ■Acknowledgements
|
||
* This plugin is a modification of RPG Maker MZ's official OverpassTile.js
|
||
* (by Triacontane and Yoji Ojima).
|
||
*
|
||
* ■Reference: From OverpassTile.js
|
||
* Overpasses, such as bridges, can be represented on the map.
|
||
* This plugin improves functionality for RPG Maker MV's official "OverpassTile.js" plugin's MZ.
|
||
*
|
||
* Since you can specify not only regions but terrain tags,
|
||
* considerations are made for event launches and collision determination as well.
|
||
* The plugin does not make considerations for vehicles.
|
||
*
|
||
* Specifications for Determination of Passage
|
||
* -When at the entrance of a bridge
|
||
* →The player can always move towards the overpass.
|
||
* -When on an overpass
|
||
* →If on top of a bridge, the player can always move towards the entrance of the bridge and overpass.
|
||
* →If under a bridge, the player can never move toward the bridge's entrance.
|
||
* -If movement allowance was not determined from the above conditions
|
||
* →Follows the map's original passage settings.
|
||
*
|
||
* The plugin can take event launch determination and collision determination into consideration.
|
||
* -Events with different heights (over and under a bridge) will launch, without collision.
|
||
*
|
||
* @command ChangeHeight
|
||
* @desc Toggles whether the character will be displayed above or below the overpass.
|
||
*
|
||
* @arg Target
|
||
* @desc Specify the character (ID) whose position is to be changed. Multiple characters can be specified.
|
||
* @type combo
|
||
* @default 0 #this event
|
||
* @option 0 #this event
|
||
* @option -1 #player
|
||
* @option -1~-4 #party
|
||
* @option 1,2,3 #multiple
|
||
* @option 1~3 #range
|
||
* @option this._eventId + 1
|
||
*
|
||
* @arg Higher
|
||
* @desc Display above overpass.
|
||
* If off, it will be displayed below.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
*
|
||
* @param OverPathRegion
|
||
* @desc Region ID set for bridge or other overpass sections.
|
||
* @default 0
|
||
* @type number
|
||
*
|
||
* @param OverPathTerrainTag
|
||
* @desc Terrain tag set for bridge or other overpass sections.
|
||
* @default 0
|
||
* @type number
|
||
*
|
||
* @param GatewayRegion
|
||
* @desc Region ID set for overpass entrances, such as both ends of a bridge.
|
||
* @default 0
|
||
* @type number
|
||
*
|
||
* @param GatewayTerrainTag
|
||
* @desc Terrain tag set for overpass entrances, such as both ends of a bridge.
|
||
* @default 0
|
||
* @type number
|
||
*
|
||
* @param ConsiderLadder
|
||
* @desc If the character is on the overpass, ignore the ladder attribute below.
|
||
* @default true
|
||
* @type boolean
|
||
*/
|
||
|
||
/*:ja
|
||
* @target MV MZ
|
||
* @plugindesc v1.021 高機能な立体交差を実現します。
|
||
* @author 砂川赳 (original トリアコンタン & Yoji Ojima)
|
||
* @orderAfter NRP_EventCollisionEX
|
||
* @orderAfter NRP_BushEX
|
||
* @url http://newrpg.seesaa.net/article/482040708.html
|
||
*
|
||
* @help マップ上で橋などの立体交差を表現できます。
|
||
*
|
||
* ツクールMZ公式プラグイン『OverpassTile.js』の機能強化版です。
|
||
* 立体交差上に通行禁止のタイルを配置できるため、
|
||
* より自由度の高い立体交差を作成できます。
|
||
*
|
||
* 立体交差を使わないマップでも、
|
||
* すり抜け可能な隠し通路として利用することもできます。
|
||
*
|
||
* また、イベントのメモ欄やプラグインコマンドによって、
|
||
* プレイヤーやイベントが存在する層を切替できます。
|
||
*
|
||
* 『OverpassTile.js』はツクールMVにも存在しますが、
|
||
* 当プラグインはより高機能なMZ版に準拠しています。
|
||
* その上でMVでも使用できるように改良しました。
|
||
*
|
||
* ■注意点
|
||
* このプラグインは、以下のプラグインよりも下に配置してください。
|
||
*
|
||
* ・NRP_EventCollisionEX
|
||
* ・NRP_BushEX
|
||
*
|
||
* ■使用法
|
||
* 上層(MZにおけるレイヤー3~4)にタイルを配置すれば、
|
||
* 立体交差として扱われます。
|
||
* あとは『OverpassTile.js』と同じようにリージョンや地形タグで
|
||
* 立体交差とその入口を指定してください。
|
||
*
|
||
* 初期状態では、キャラクターは立体交差の下にいるものとして扱われます。
|
||
* 立体交差の入口を通過すると、キャラクターが立体交差の上に移動します。
|
||
*
|
||
* ■メモ欄
|
||
* イベントのメモ欄に以下を指定すれば、
|
||
* 最初から立体交差の上にいるものとして扱われます。
|
||
*
|
||
* <OverpassHigher>
|
||
*
|
||
* ■プラグインコマンド(MZ)
|
||
* ◆高さを変更
|
||
* 対象となるキャラクターを指定し、立体交差との上下関係を変更します。
|
||
* 詳細は実際のプラグインコマンドを確認してください。
|
||
*
|
||
* ■プラグインコマンド(MV)
|
||
* ◆NRP.OverpassTile.Higher [対象] [高さ(true/false)]
|
||
* MZ版と同じく対象を表示する高さを変更します。
|
||
* ※高さを省略するとtrueになります。
|
||
* ※大文字小文字は問いません。
|
||
*
|
||
* 以下は例です。
|
||
*
|
||
* >NRP.OverpassTile.Higher 0
|
||
* このイベントを上層に移動します。
|
||
* ※0は省略可能です。
|
||
*
|
||
* >NRP.OverpassTile.Higher 1 false
|
||
* ID=1のイベントを下層に移動します。
|
||
*
|
||
* >NRP.OverpassTile.Higher 1~10
|
||
* ID=1~10のイベントを上層に移動します。
|
||
*
|
||
* >NRP.OverpassTile.Higher -1
|
||
* プレイヤー(-1)を上層に移動します。
|
||
*
|
||
* >NRP.OverpassTile.Higher -1~-4
|
||
* パーティ4人を上層に移動します。
|
||
* ※-2以下は隊列歩行の仲間になります。
|
||
*
|
||
* ■謝辞
|
||
* このプラグインはRPGツクールMZ公式の
|
||
* OverpassTile.js(トリアコンタン様&Yoji Ojima様)を改修させて頂きました。
|
||
*
|
||
* ■参考:OverpassTile.jsの解説を引用
|
||
* マップ上で橋などの立体交差を表現できます。
|
||
* ツクールMV公式プラグイン「OverpassTile.js」のMZ向け機能強化版です。
|
||
*
|
||
* リージョンだけでなく地形タグも指定可能で、
|
||
* さらにイベントの起動や衝突判定に関する考慮がなされています。
|
||
* 乗り物の存在は考慮しません。
|
||
*
|
||
* 通行可能判定に関する仕様
|
||
* ・橋の入り口にいる場合
|
||
* →立体交差に対して必ず移動できます。
|
||
* ・立体交差にいる場合
|
||
* →橋の上にいる場合、立体交差と橋の入り口に対して必ず移動できます。
|
||
* →橋の下にいる場合、橋の入り口に対して必ず移動できません。
|
||
* ・上記の条件で移動可否を判定しなかった場合
|
||
* →マップの本来の通行設定に従います。
|
||
*
|
||
* イベントの起動判定、衝突判定を考慮できます。
|
||
* ・高さが異なる(橋の上と下にいる)イベントは起動、衝突しません。
|
||
*
|
||
* @command ChangeHeight
|
||
* @text 高さを変更
|
||
* @desc キャラクターがいる高さを変更します。つまり立体交差の上下いずれに表示されるかを切り替えます。
|
||
*
|
||
* @arg Target
|
||
* @text 対象
|
||
* @desc 高さを変更するキャラクター(ID)を指定します。
|
||
* 複数指定も可能です。
|
||
* @type combo
|
||
* @default 0 #このイベント
|
||
* @option 0 #このイベント
|
||
* @option -1 #プレイヤー
|
||
* @option -1~-4 #パーティ
|
||
* @option 1,2,3 #複数指定
|
||
* @option 1~3 #範囲指定
|
||
* @option this._eventId + 1 #イベントID+1
|
||
*
|
||
* @arg Higher
|
||
* @text 上に表示
|
||
* @desc 立体交差の上に表示します。
|
||
* オフだと下に表示します。
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
*
|
||
* @param OverPathRegion
|
||
* @text 立体交差リージョン
|
||
* @desc 橋などの立体交差部分に設定するリージョンIDです。
|
||
* @default 0
|
||
* @type number
|
||
*
|
||
* @param OverPathTerrainTag
|
||
* @text 立体交差地形タグ
|
||
* @desc 橋などの立体交差部分に設定する地形タグです。
|
||
* @default 0
|
||
* @type number
|
||
*
|
||
* @param GatewayRegion
|
||
* @text 立体交差入り口リージョン
|
||
* @desc 橋の両端など、立体交差の入り口部分に設定するリージョンIDです。
|
||
* @default 0
|
||
* @type number
|
||
*
|
||
* @param GatewayTerrainTag
|
||
* @text 立体交差入り口地形タグ
|
||
* @desc 橋の両端など、立体交差の入り口部分に設定するリージョンIDです。
|
||
* @default 0
|
||
* @type number
|
||
*
|
||
* @param ConsiderLadder
|
||
* @text ハシゴ属性に対応
|
||
* @desc ハシゴ属性を立体交差に対応させます。
|
||
* 立体交差上にいる場合、下のハシゴ属性を無視します。
|
||
* @default true
|
||
* @type boolean
|
||
*/
|
||
|
||
(function () {
|
||
"use strict";
|
||
|
||
function toBoolean(val, def) {
|
||
// 空白なら初期値を返す
|
||
if (val === "" || val === undefined) {
|
||
return def;
|
||
|
||
// 既にboolean型なら、そのまま返す
|
||
} else if (typeof val === "boolean") {
|
||
return val;
|
||
}
|
||
// 文字列ならboolean型に変換して返す
|
||
return val.toLowerCase() == "true";
|
||
}
|
||
function toNumber(str, def) {
|
||
return isNaN(str) ? def : +(str || def);
|
||
}
|
||
function setDefault(str, def) {
|
||
return str ? str : def;
|
||
}
|
||
|
||
const PLUGIN_NAME = "NRP_OverpassTile";
|
||
const parameters = PluginManager.parameters(PLUGIN_NAME);
|
||
const pOverPathRegion = toNumber(parameters["OverPathRegion"]);
|
||
const pOverPathTerrainTag = toNumber(parameters["OverPathTerrainTag"]);
|
||
const pGatewayRegion = toNumber(parameters["GatewayRegion"]);
|
||
const pGatewayTerrainTag = toNumber(parameters["GatewayTerrainTag"]);
|
||
const pConsiderLadder = toBoolean(parameters["ConsiderLadder"], true);
|
||
|
||
/**
|
||
* Game_CharacterBase
|
||
*/
|
||
const _Game_CharacterBase_isMapPassable = Game_CharacterBase.prototype.isMapPassable;
|
||
Game_CharacterBase.prototype.isMapPassable = function (x, y, d) {
|
||
const passable = this.isMapPassableOnOverPath(x, y, d);
|
||
if (passable !== undefined) {
|
||
return passable;
|
||
}
|
||
return _Game_CharacterBase_isMapPassable.apply(this, arguments)
|
||
};
|
||
|
||
const _Game_CharacterBase_isCollidedWithEvents = Game_CharacterBase.prototype.isCollidedWithEvents;
|
||
Game_CharacterBase.prototype.isCollidedWithEvents = function (x, y) {
|
||
return _Game_CharacterBase_isCollidedWithEvents.apply(this, arguments) &&
|
||
this.isCollidedWithSameHigherEvents(x, y);
|
||
};
|
||
|
||
Game_CharacterBase.prototype.isCollidedWithSameHigherEvents = function (x, y) {
|
||
const events = $gameMap.eventsXyNt(x, y);
|
||
return events.some(event => this.isSameHigher(event));
|
||
};
|
||
|
||
Game_CharacterBase.prototype.isSameHigher = function (target) {
|
||
return Math.abs(this.getHigherLevel() - target.getHigherLevel()) <= 1;
|
||
};
|
||
|
||
Game_CharacterBase.prototype.getHigherLevel = function () {
|
||
if (!this._higher) {
|
||
return this.isOnOverPath() ? -1 : 0;
|
||
} else {
|
||
return this.isOnOverPath() ? 2 : 1;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* ●立体交差の通行判定
|
||
*/
|
||
Game_CharacterBase.prototype.isMapPassableOnOverPath = function (x, y, d) {
|
||
const overPath = $gameMap.isOverPath(x, y);
|
||
const gateway = $gameMap.isGatewayOverPath(x, y);
|
||
const advancedX = $gameMap.roundXWithDirection(x, d);
|
||
const advancedY = $gameMap.roundYWithDirection(y, d);
|
||
const advancedOverPath = $gameMap.isOverPath(advancedX, advancedY);
|
||
const advancedGateway = $gameMap.isGatewayOverPath(advancedX, advancedY);
|
||
const d2 = this.reverseDir(d);
|
||
|
||
// 現在地が入口→立体交差上に移動(変更)
|
||
if (gateway && advancedOverPath) {
|
||
return undefined;
|
||
// return true;
|
||
|
||
// 現在地が立体交差
|
||
} else if (overPath) {
|
||
// 現在地が立体交差上
|
||
if (this._higher) {
|
||
// →立体交差上に移動(変更)
|
||
if (advancedOverPath) {
|
||
// 処理しない(通常の移動判定)
|
||
return undefined;
|
||
}
|
||
return advancedGateway;
|
||
|
||
// 現在地が立体交差下
|
||
} else {
|
||
// →入口に移動
|
||
if (advancedGateway) {
|
||
return false;
|
||
|
||
// →立体交差下に移動(追加)
|
||
} else if (advancedOverPath) {
|
||
// 下層(レイヤー3~4)の通行判定
|
||
// 上層は☆として扱うため無視
|
||
return isPassableLowerLayer(this, advancedX, advancedY, d2);
|
||
|
||
// →立体交差外に移動(追加)
|
||
} else {
|
||
// RegionBase.jsとの競合対策
|
||
if ($gameMap.setPassableSubject) {
|
||
$gameMap.setPassableSubject(this);
|
||
}
|
||
|
||
// 移動先の移動判定だけを参照
|
||
return isPassable(this, advancedX, advancedY, d2);
|
||
}
|
||
}
|
||
|
||
// 現在地が立体交差外→立体交差下に移動(追加)
|
||
} else if (advancedOverPath) {
|
||
// RegionBase.jsとの競合対策
|
||
if ($gameMap.setPassableSubject) {
|
||
$gameMap.setPassableSubject(this);
|
||
}
|
||
|
||
// 移動元の移動判定と下層(レイヤー3~4)の通行判定を参照
|
||
return isPassable(this, x, y, d)
|
||
&& isPassableLowerLayer(this, advancedX, advancedY, d2);
|
||
}
|
||
|
||
return undefined;
|
||
};
|
||
|
||
const _Game_CharacterBase_refreshBushDepth = Game_CharacterBase.prototype.refreshBushDepth;
|
||
Game_CharacterBase.prototype.refreshBushDepth = function () {
|
||
_Game_CharacterBase_refreshBushDepth.apply(this, arguments);
|
||
this.updateOverPath();
|
||
};
|
||
|
||
Game_CharacterBase.prototype.updateOverPath = function () {
|
||
if (this.isOnGateway()) {
|
||
this._higher = true;
|
||
} else if (!this.isOnOverPath()) {
|
||
this._higher = false;
|
||
}
|
||
};
|
||
|
||
Game_CharacterBase.prototype.isOnGateway = function () {
|
||
return $gameMap.isGatewayOverPath(this.x, this.y);
|
||
};
|
||
|
||
Game_CharacterBase.prototype.isOnOverPath = function () {
|
||
return $gameMap.isOverPath(this.x, this.y);
|
||
};
|
||
|
||
const _Game_CharacterBase_screenZ = Game_CharacterBase.prototype.screenZ;
|
||
Game_CharacterBase.prototype.screenZ = function () {
|
||
const z = _Game_CharacterBase_screenZ.apply(this, arguments);
|
||
|
||
// Z座標を『3+2.5 = 5.5』に変更
|
||
// 5:通常キャラの上、6:飛行船の影の中間
|
||
// ※元のOverpassTile.jsの仕様では6ですが、
|
||
// 飛行船の影より下でよいと思われるので調整しています。
|
||
return this.isHigherPriority() ? z + 2.5 : z;
|
||
// return this.isHigherPriority() ? z + 3 : z;
|
||
};
|
||
|
||
Game_CharacterBase.prototype.isHigherPriority = function () {
|
||
return this._higher;
|
||
};
|
||
|
||
Game_CharacterBase.prototype.updateOverPathOnLocate = function () {
|
||
this._higher = this.isOnOverPath() || this.isOnGateway();
|
||
};
|
||
|
||
/**
|
||
* Game_Character
|
||
*/
|
||
const _Game_Character_findDirectionTo = Game_Character.prototype.findDirectionTo;
|
||
Game_Character.prototype.findDirectionTo = function (goalX, goalY) {
|
||
let result = _Game_Character_findDirectionTo.apply(this, arguments);
|
||
if (result + this._prevFindDirectionTo === 10) {
|
||
result = 0;
|
||
}
|
||
this._prevFindDirectionTo = result;
|
||
return result;
|
||
};
|
||
|
||
const _Game_Player_moveByInput = Game_Player.prototype.moveByInput;
|
||
Game_Player.prototype.moveByInput = function () {
|
||
if (!$gameTemp.isDestinationValid()) {
|
||
this._prevFindDirectionTo = 0;
|
||
}
|
||
_Game_Player_moveByInput.apply(this, arguments);
|
||
};
|
||
|
||
/**
|
||
* Game_Event
|
||
*/
|
||
const _Game_Event_start = Game_Event.prototype.start;
|
||
Game_Event.prototype.start = function () {
|
||
if (this.isTriggerIn([0, 1, 2]) && !this.isSameHigher($gamePlayer)) {
|
||
return;
|
||
}
|
||
_Game_Event_start.apply(this, arguments);
|
||
};
|
||
|
||
const _Game_Event_isCollidedWithEvents = Game_Event.prototype.isCollidedWithEvents;
|
||
Game_Event.prototype.isCollidedWithEvents = function (x, y) {
|
||
return _Game_Event_isCollidedWithEvents.apply(this, arguments) &&
|
||
this.isCollidedWithSameHigherEvents(x, y);
|
||
};
|
||
|
||
const _Game_Event_isCollidedWithPlayerCharacters = Game_Event.prototype.isCollidedWithPlayerCharacters;
|
||
Game_Event.prototype.isCollidedWithPlayerCharacters = function (x, y) {
|
||
if (!this.isSameHigher($gamePlayer)) {
|
||
return false;
|
||
}
|
||
return _Game_Event_isCollidedWithPlayerCharacters.apply(this, arguments);
|
||
};
|
||
|
||
/**
|
||
* ●ページ設定開始(追加)
|
||
*/
|
||
const _Game_Event_setupPageSettings = Game_Event.prototype.setupPageSettings;
|
||
Game_Event.prototype.setupPageSettings = function () {
|
||
_Game_Event_setupPageSettings.apply(this, arguments);
|
||
|
||
// メモ欄から<OverpassHigher>を取得
|
||
let overpassHigher = this.event().meta.OverpassHigher;
|
||
if (overpassHigher === true) {
|
||
// 立体交差の上に配置
|
||
this._higher = true;
|
||
return;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Game_Followers
|
||
*/
|
||
Game_Followers.prototype.updateOverPathOnLocate = function () {
|
||
this._data.forEach(follower => {
|
||
follower.updateOverPathOnLocate();
|
||
})
|
||
};
|
||
|
||
/**
|
||
* Game_Map
|
||
*/
|
||
Game_Map.prototype.isRegionOrTerrainTag = function (x, y, regionId, terrainTag) {
|
||
if (regionId > 0 && this.regionId(x, y) === regionId) {
|
||
return true;
|
||
} else if (terrainTag > 0 && this.terrainTag(x, y) === terrainTag) {
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
};
|
||
|
||
Game_Map.prototype.isOverPath = function (x, y) {
|
||
return this.isRegionOrTerrainTag(x, y, pOverPathRegion, pOverPathTerrainTag);
|
||
};
|
||
|
||
Game_Map.prototype.isGatewayOverPath = function (x, y) {
|
||
return this.isRegionOrTerrainTag(x, y, pGatewayRegion, pGatewayTerrainTag);
|
||
};
|
||
|
||
/**
|
||
* 【独自】下層(レイヤー3~4)の通行判定
|
||
*/
|
||
Game_Map.prototype.isPassableLowerLayer = function (x, y, d) {
|
||
return this.checkPassageLowerLayer(x, y, (1 << (d / 2 - 1)) & 0x0f);
|
||
};
|
||
|
||
/**
|
||
* 【独自】下層(レイヤー3~4)の通行判定(小型船)
|
||
*/
|
||
Game_Map.prototype.isBoatPassableLowerLayer = function (x, y) {
|
||
return this.checkPassageLowerLayer(x, y, 0x0200);
|
||
};
|
||
|
||
/**
|
||
* 【独自】下層(レイヤー3~4)の通行判定(大型船)
|
||
*/
|
||
Game_Map.prototype.isShipPassableLowerLayer = function (x, y) {
|
||
return this.checkPassageLowerLayer(x, y, 0x0400);
|
||
};
|
||
|
||
/**
|
||
* 【独自】下層(レイヤー3~4)の通行判定
|
||
*/
|
||
Game_Map.prototype.checkPassageLowerLayer = function (x, y, bit) {
|
||
const flags = this.tilesetFlags();
|
||
const tiles = this.allTiles(x, y);
|
||
// for (const tile of tiles) {
|
||
for (let i = 2; i < tiles.length; i++) {
|
||
const tile = tiles[i];
|
||
|
||
const flag = flags[tile];
|
||
if ((flag & 0x10) !== 0) {
|
||
// [*] No effect on passage
|
||
continue;
|
||
}
|
||
if ((flag & bit) === 0) {
|
||
// [o] Passable
|
||
return true;
|
||
}
|
||
if ((flag & bit) === bit) {
|
||
// [x] Impassable
|
||
return false;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
const _Tilemap_isOverpassPosition = Tilemap.prototype._isOverpassPosition;
|
||
Tilemap.prototype._isOverpassPosition = function (mx, my) {
|
||
const result = _Tilemap_isOverpassPosition.apply(this, arguments);
|
||
return result || ($gameMap && $gameMap.isOverPath(mx, my));
|
||
};
|
||
|
||
//-------------------------------------------------
|
||
// 以下、プラグインコマンド
|
||
//-------------------------------------------------
|
||
|
||
/**
|
||
* ●プラグインコマンドのコンボの値を取得する。
|
||
*/
|
||
function getComboValue(value) {
|
||
if (value === undefined) {
|
||
return value;
|
||
}
|
||
// #以降は注釈扱いなので除去
|
||
// さらに前後の空白を除去する。
|
||
return value.split("#")[0].trim();
|
||
}
|
||
|
||
/**
|
||
* ●引数を元に対象(行動主体)の配列を取得する。
|
||
* ※bindによってinterpreterをthisに渡して用いる。
|
||
*/
|
||
function makeTargets(targetId) {
|
||
const targets = [];
|
||
|
||
// 無効なら処理しない。
|
||
if (targetId === undefined || targetId === null || targetId === "") {
|
||
return targets;
|
||
}
|
||
|
||
// カンマ区切りでループ
|
||
for (let id of targetId.split(",")) {
|
||
// 空白除去
|
||
id = id.trim();
|
||
// 1~5というように範囲指定の場合
|
||
// ※~が存在する。
|
||
if (id.indexOf("~") >= 0) {
|
||
const idRange = id.split("~");
|
||
const idRangeStart = eval(idRange[0]);
|
||
const idRangeEnd = eval(idRange[1]);
|
||
|
||
// IDの指定範囲で実行
|
||
// 開始のほうが終了より大きい場合は反対に実行
|
||
if (idRangeEnd < idRangeStart) {
|
||
for (let i = idRangeStart; i >= idRangeEnd; i--) {
|
||
const evalId = eval(i);
|
||
if (this.characterAndFollower(evalId)) {
|
||
targets.push(this.characterAndFollower(evalId));
|
||
}
|
||
}
|
||
} else {
|
||
for (let i = idRangeStart; i <= idRangeEnd; i++) {
|
||
const evalId = eval(i);
|
||
if (this.characterAndFollower(evalId)) {
|
||
targets.push(this.characterAndFollower(evalId));
|
||
}
|
||
}
|
||
}
|
||
|
||
// 通常時
|
||
} else {
|
||
const evalId = eval(id);
|
||
if (this.characterAndFollower(evalId)) {
|
||
targets.push(this.characterAndFollower(evalId));
|
||
}
|
||
}
|
||
}
|
||
return targets;
|
||
}
|
||
|
||
/**
|
||
* 【独自】キャラクター取得時、-2以下はフォロワーとして取得する。
|
||
*/
|
||
Game_Interpreter.prototype.characterAndFollower = function (param) {
|
||
if ($gameParty.inBattle()) {
|
||
return null;
|
||
// フォロワーを取得
|
||
} else if (param <= -2) {
|
||
// -2 -> 0, -3 -> 1というように変換
|
||
const n = Math.abs(param) - 2;
|
||
return $gamePlayer.followers().follower(n);
|
||
} else if (param < 0) {
|
||
return $gamePlayer;
|
||
} else if (this.isOnCurrentMap()) {
|
||
return $gameMap.event(param > 0 ? param : this._eventId);
|
||
} else {
|
||
return null;
|
||
}
|
||
};
|
||
|
||
//----------------------------------------
|
||
// MZ用プラグインコマンド
|
||
//----------------------------------------
|
||
|
||
if (PluginManager.registerCommand) {
|
||
/**
|
||
* ●高さの変更
|
||
*/
|
||
PluginManager.registerCommand(PLUGIN_NAME, "ChangeHeight", function (args) {
|
||
const targetId = setDefault(getComboValue(args.Target), "0");
|
||
const higher = toBoolean(args.Higher, true);
|
||
|
||
// 対象を生成
|
||
// ※bindによってthisをメソッドに渡す。
|
||
const targets = makeTargets.bind(this)(targetId);
|
||
// 対象が取得できなければ処理しない。
|
||
if (targets.length == 0) {
|
||
return;
|
||
}
|
||
|
||
// 速度変更
|
||
for (const target of targets) {
|
||
target._higher = higher;
|
||
}
|
||
});
|
||
}
|
||
|
||
//----------------------------------------
|
||
// MV用プラグインコマンド
|
||
//----------------------------------------
|
||
|
||
/**
|
||
* ●高さの変更
|
||
*/
|
||
const _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
|
||
Game_Interpreter.prototype.pluginCommand = function (command, args) {
|
||
_Game_Interpreter_pluginCommand.call(this, command, args);
|
||
|
||
// 小文字化してから判定
|
||
const lowerCommand = command.toLowerCase();
|
||
|
||
// 高さを変更
|
||
if (lowerCommand === "nrp.overpasstile.higher") {
|
||
const targetId = setDefault(args[0], "0");
|
||
const higher = toBoolean(args[1], true);
|
||
|
||
// 対象を生成
|
||
// ※bindによってthisをメソッドに渡す。
|
||
const targets = makeTargets.bind(this)(targetId);
|
||
// 対象が取得できなければ処理しない。
|
||
if (targets.length == 0) {
|
||
return;
|
||
}
|
||
|
||
// 速度変更
|
||
for (const target of targets) {
|
||
target._higher = higher;
|
||
}
|
||
}
|
||
};
|
||
|
||
//----------------------------------------
|
||
// ハシゴ処理
|
||
//----------------------------------------
|
||
|
||
if (pConsiderLadder) {
|
||
/**
|
||
* ●ハシゴ上にいるかどうか?
|
||
*/
|
||
Game_CharacterBase.prototype.isOnLadder = function () {
|
||
// キャラクターが上層にいる場合
|
||
if (this._higher) {
|
||
return $gameMap.isLadderHigher(this._x, this._y);
|
||
}
|
||
|
||
return $gameMap.isLadder(this._x, this._y);
|
||
};
|
||
|
||
/**
|
||
* 【独自】上層がハシゴかどうか?
|
||
*/
|
||
Game_Map.prototype.isLadderHigher = function (x, y) {
|
||
if (!this.isValid(x, y)) {
|
||
return false;
|
||
}
|
||
|
||
// 各タイルが保有するフラグ情報
|
||
const flags = this.tilesetFlags();
|
||
|
||
// 上層(3~4)だけを確認
|
||
for (let i = 0; i < 2; i++) {
|
||
const tileId = this.tileId(x, y, 3 - i);
|
||
// ハシゴ(0x20)ならばハシゴとして判定
|
||
if ((flags[tileId] & 0x20) !== 0) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
};
|
||
}
|
||
|
||
//----------------------------------------
|
||
// 乗物対応
|
||
//----------------------------------------
|
||
|
||
/**
|
||
* ●乗物のマップ通行判定
|
||
*/
|
||
const _Game_Vehicle_isMapPassable = Game_Vehicle.prototype.isMapPassable;
|
||
Game_Vehicle.prototype.isMapPassable = function (x, y, d) {
|
||
// 小型船、大型船
|
||
if (this.isBoat() || this.isShip()) {
|
||
// 立体交差の通行判定
|
||
const passable = this.isMapPassableOnOverPath(x, y, d);
|
||
if (passable !== undefined) {
|
||
return passable;
|
||
}
|
||
}
|
||
|
||
return _Game_Vehicle_isMapPassable.apply(this, arguments);
|
||
};
|
||
|
||
/**
|
||
* RegionBaseで定義されている関数をオーバライド
|
||
* ※RegionBase.jsとの競合対策
|
||
*/
|
||
Game_Vehicle.prototype.findCollisionData = function (x, y) {
|
||
// プレイヤーの情報を参照
|
||
return $gameMap.findArrayDataRegionAndTerrain(x, y, 'collisionForPlayer');
|
||
};
|
||
|
||
/**
|
||
* ●乗り物の乗降時の判定
|
||
* ※RegionBase.jsとの競合対策
|
||
*/
|
||
const _Game_Vehicle_isLandOk = Game_Vehicle.prototype.isLandOk;
|
||
Game_Vehicle.prototype.isLandOk = function (x, y, d) {
|
||
// RegionBaseの関数が有効な場合
|
||
if ($gameMap.setPassableSubject) {
|
||
// ロード直後、一度もsetPassableSubjectが呼ばれないまま、
|
||
// 乗降を実行するとエラーになるので対処
|
||
$gameMap.setPassableSubject(this);
|
||
}
|
||
return _Game_Vehicle_isLandOk.apply(this, arguments);
|
||
}
|
||
|
||
/**
|
||
* ●通行判定
|
||
*/
|
||
function isPassable(character, x, y, d) {
|
||
// 乗物の場合
|
||
if (character.constructor === Game_Vehicle) {
|
||
// 小型船
|
||
if (character.isBoat()) {
|
||
return $gameMap.isBoatPassable(x, y);
|
||
|
||
// 大型船
|
||
} else if (character.isShip()) {
|
||
return $gameMap.isShipPassable(x, y);
|
||
}
|
||
}
|
||
|
||
return $gameMap.isPassable(x, y, d);
|
||
}
|
||
|
||
/**
|
||
* ●通行判定
|
||
*/
|
||
function isPassableLowerLayer(character, x, y, d) {
|
||
// 乗物の場合
|
||
if (character.constructor === Game_Vehicle) {
|
||
// 小型船
|
||
if (character.isBoat()) {
|
||
return $gameMap.isBoatPassableLowerLayer(x, y);
|
||
|
||
// 大型船
|
||
} else if (character.isShip()) {
|
||
return $gameMap.isShipPassableLowerLayer(x, y);
|
||
}
|
||
}
|
||
|
||
return $gameMap.isPassableLowerLayer(x, y, d);
|
||
}
|
||
|
||
})();
|