//============================================================================= // RPG Maker MZ - Overpass Plugin //============================================================================= /*: * @target MZ * @plugindesc Overpass Plugin * @author triacontane(original Yoji Ojima) * @base PluginCommonBase * @orderAfter PluginCommonBase * @url * * @param overPathRegion * @text Overpass Region * @desc Region ID set for bridge or other overpass sections. * @default 0 * @type number * * @param overPathTerrainTag * @text Overpass Terrain Tag * @desc Terrain tag set for bridge or other overpass sections. * @default 0 * @type number * * @param gatewayRegion * @text Overpass Entrance Region * @desc Region ID set for overpass entrances, such as both ends of a bridge. * @default 0 * @type number * * @param gatewayTerrainTag * @text Overpass Entrance Terrain Tag * @desc Terrain tag set for overpass entrances, such as both ends of a bridge. * @default 0 * @type number * * @help 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. */ /*:ja * @target MZ * @plugindesc 立体交差を作成します。 * @author トリアコンタン(original Yoji Ojima) * @base PluginCommonBase * @orderAfter PluginCommonBase * @url * * @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 * * @help OverpassTile.js * * マップ上で橋などの立体交差を表現できます。 * ツクールMV公式プラグイン「OverpassTile.js」のMZ向け機能強化版です。 * * リージョンだけでなく地形タグも指定可能で、 * さらにイベントの起動や衝突判定に関する考慮がなされています。 * 乗り物の存在は考慮しません。 * * 通行可能判定に関する仕様 * ・橋の入り口にいる場合 *  →立体交差に対して必ず移動できます。 * ・立体交差にいる場合 *  →橋の上にいる場合、立体交差と橋の入り口に対して必ず移動できます。 *  →橋の下にいる場合、橋の入り口に対して必ず移動できません。 * ・上記の条件で移動可否を判定しなかった場合 *  →マップの本来の通行設定に従います。 * * イベントの起動判定、衝突判定を考慮できます。 * ・高さが異なる(橋の上と下にいる)イベントは起動、衝突しません。 */ (() => { 'use strict'; const script = document.currentScript; const param = PluginManagerEx.createParameter(script); /** * 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); if (gateway && advancedOverPath) { return true; } else if (overPath) { if (this._higher) { return advancedOverPath || advancedGateway; } else if (advancedGateway) { return false; } } 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); 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); }; /** * 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, param.overPathRegion, param.overPathTerrainTag); }; Game_Map.prototype.isGatewayOverPath = function(x, y) { return this.isRegionOrTerrainTag(x, y, param.gatewayRegion, param.gatewayTerrainTag); }; 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)); }; })();