458 lines
15 KiB
JavaScript
458 lines
15 KiB
JavaScript
//=============================================================================
|
|
// RPG Maker MZ - RegionSetting
|
|
//
|
|
// Copyright 2024 Panzer-IV. All rights reserved.
|
|
// This source code or any portion thereof must not be
|
|
// reproduced or used without licensed in any manner whatsoever.
|
|
//=============================================================================
|
|
/*:
|
|
* @target MZ
|
|
* @plugindesc リージョン設定プラグイン
|
|
* @author 四号戦車
|
|
* @base PluginCommonBase
|
|
* @base DebugSwitch
|
|
* @base TextResource
|
|
* @base PluginUtils
|
|
* @orderAfter PluginCommonBase
|
|
* @orderAfter DebugSwitch
|
|
* @orderAfter TextResource
|
|
* @orderAfter PluginUtils
|
|
*
|
|
* @param regions
|
|
* @text リージョン設定
|
|
* @desc リージョンと効果の指定です。
|
|
* @type struct<RegionSetting>[]
|
|
* @default []
|
|
*
|
|
* @param passageSetting
|
|
* @text 通行不可デフォルト設定
|
|
* @desc 通行不可リージョンが設定されていない
|
|
* タイルの通行設定
|
|
* @type select
|
|
* @default default_passage
|
|
* @option ツクールの設定に従う
|
|
* @value default_passage
|
|
* @option 全て通行可
|
|
* @value all_passible
|
|
* @option 全て通行不可
|
|
* @value all_not_passible
|
|
*
|
|
*
|
|
* @help RegionSetting.js
|
|
*
|
|
* Version: 0.0.3
|
|
*
|
|
* マップリージョンに特殊処理を持たせる設定プラグイン
|
|
*
|
|
*/
|
|
/*~struct~RegionSetting:
|
|
*
|
|
* @param name
|
|
* @text 設定名
|
|
* @desc 設定用の名前です。
|
|
* 入力時識別用にお使い下さい。
|
|
* @type string
|
|
* @default
|
|
*
|
|
* @param region
|
|
* @text リージョン番号
|
|
* @desc 指定リージョンの番号です。
|
|
* @type number
|
|
* @min 0
|
|
* @default 0
|
|
*
|
|
* @param effect
|
|
* @text 効果
|
|
* @desc 指定リージョンに付与する効果を指定します。
|
|
* @type select
|
|
* @default none
|
|
* @option なし
|
|
* @value none
|
|
* @option 通行不可
|
|
* @value blockPassible
|
|
* @option 左方向だけ移動不可
|
|
* @value onlyLeftBlock
|
|
* @option 上方向だけ移動不可
|
|
* @value onlyUpBlock
|
|
* @option 右方向だけ移動不可
|
|
* @value onlyRightBlock
|
|
* @option 下方向だけ移動不可
|
|
* @value onlyDownBlock
|
|
* @option 上下のみ移動可能
|
|
* @value onlyVirtical
|
|
* @option 左右のみ移動可能
|
|
* @value onlyHorizontal
|
|
* @option 左と上だけ移動不可
|
|
* @value onlyUpLeftBlock
|
|
* @option 上と右だけ移動不可
|
|
* @value onlyUpRightBlock
|
|
* @option 右と下だけ移動不可
|
|
* @value onlyDownRightBlock
|
|
* @option 下と左だけ移動不可
|
|
* @value onlyDownLeftBlock
|
|
* @option 強制通行
|
|
* @value forcePassible
|
|
* @option 通行不可(キャラクターの描画をマップより上に)
|
|
* @value blockPassibleWithOverlayTile
|
|
* @option 強制的にマップより優先表示(☆無視)
|
|
* @value overlayTile
|
|
*
|
|
* @param maskOnFarPlayer
|
|
* @text 近づくと消える壁設定
|
|
* @text ONにすると「近づくと消える壁」に出来ます。
|
|
* @type boolean
|
|
* @default false
|
|
*
|
|
*/
|
|
(() => {
|
|
"use strict";
|
|
|
|
//========================================================================
|
|
// プラグイン定義
|
|
//========================================================================
|
|
const pluginName = "RegionSetting";
|
|
const script = document.currentScript;
|
|
const param = PluginUtils.reparseParameter(script);
|
|
|
|
//========================================================================
|
|
// 定数定義
|
|
//========================================================================
|
|
const DIRECTION_UP = 8;
|
|
const DIRECTION_LEFT = 4;
|
|
const DIRECTION_RIGHT = 6;
|
|
const DIRECTION_DOWN = 2;
|
|
|
|
const checkDirection = (direction, ...blockdirections) => {
|
|
return !blockdirections.some(dir => dir === direction);
|
|
};
|
|
|
|
//========================================================================
|
|
// クラス定義 (Sprite_MapMask)
|
|
//========================================================================
|
|
class Sprite_MapMask extends Sprite {
|
|
constructor(mask) {
|
|
super(new Bitmap($gameMap.tileWidth(), $gameMap.tileHeight()));
|
|
|
|
this._mapMask = mask;
|
|
this.bitmap.fillAll('#000000');
|
|
}
|
|
|
|
get group() {
|
|
return this._mapMask?.group;
|
|
}
|
|
|
|
set maskVisible(value) {
|
|
if (!!this._mapMask) {
|
|
this._mapMask.visible = value;
|
|
}
|
|
}
|
|
|
|
update() {
|
|
super.update();
|
|
this.updatePosition();
|
|
this.updateOpacity();
|
|
}
|
|
|
|
updatePosition() {
|
|
if (!!this._mapMask) {
|
|
this.x = this._mapMask.screenX();
|
|
this.y = this._mapMask.screenY();
|
|
this.z = 6;
|
|
}
|
|
}
|
|
|
|
isNearThePlayer() {
|
|
if (!!this._mapMask) {
|
|
return this._mapMask.isNearThePlayer();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
updateOpacity() {
|
|
if (!!this._mapMask) {
|
|
if (this._mapMask.isVisible()) {
|
|
if (this.opacity < 255) {
|
|
this.opacity += 10;
|
|
if (this.opacity >= 255) {
|
|
this.opacity = 255;
|
|
}
|
|
}
|
|
} else {
|
|
if (this.opacity > 0) {
|
|
this.opacity -= 10;
|
|
if (this.opacity < 0) {
|
|
this.opacity = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
//========================================================================
|
|
// クラス定義 (Game_MapMask)
|
|
//========================================================================
|
|
class Game_MapMask {
|
|
constructor(mask) {
|
|
this._realX = mask.x;
|
|
this._realY = mask.y;
|
|
this._effect = mask.effect;
|
|
this._group = mask.group;
|
|
this._visible = true;
|
|
}
|
|
|
|
get x() {
|
|
return this._realX;
|
|
}
|
|
|
|
get y() {
|
|
return this._realY;
|
|
}
|
|
|
|
get group() {
|
|
return this._group;
|
|
}
|
|
|
|
set visible(value) {
|
|
this._visible = value;
|
|
}
|
|
|
|
screenX() {
|
|
const tw = $gameMap.tileWidth();
|
|
const scrolledX = $gameMap.adjustX(this._realX);
|
|
return Math.floor(scrolledX * tw);
|
|
}
|
|
|
|
screenY() {
|
|
const th = $gameMap.tileHeight();
|
|
const scrolledY = $gameMap.adjustY(this._realY);
|
|
return Math.floor(scrolledY * th);
|
|
}
|
|
|
|
isNearThePlayer() {
|
|
const sx = Math.abs($gameMap.deltaX(this._realX, $gamePlayer.x));
|
|
const sy = Math.abs($gameMap.deltaY(this._realY, $gamePlayer.y));
|
|
return sx + sy < 5;
|
|
}
|
|
|
|
show() {
|
|
this._visible = true;
|
|
}
|
|
|
|
hide() {
|
|
this._visible = false;
|
|
}
|
|
|
|
isVisible() {
|
|
return this._visible;
|
|
}
|
|
}
|
|
|
|
//========================================================================
|
|
// コアスクリプト変更部 (Game_Map)
|
|
//========================================================================
|
|
const _Game_Map_prototype_setup = Game_Map.prototype.setup;
|
|
Game_Map.prototype.setup = function(mapId) {
|
|
_Game_Map_prototype_setup.apply(this, arguments);
|
|
|
|
const width = $dataMap.width;
|
|
const height = $dataMap.height;
|
|
|
|
const masks = [];
|
|
for (let y = 1; y <= height; y++) {
|
|
for (let x = 1; x <= width; x++) {
|
|
const regionId = this.regionId(x, y);
|
|
const setting = param.regions.find(region => {
|
|
return region.region === regionId && region.maskOnFarPlayer;
|
|
});
|
|
|
|
if (!!setting) {
|
|
masks.push({
|
|
x: x,
|
|
y: y,
|
|
effect: setting.effect, regionId,
|
|
group: regionId,
|
|
visible: true,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
this._maskGroups = masks.map(mask => {
|
|
return mask.group;
|
|
}).filter((group, index, self) => {
|
|
return self.indexOf(group) === index;
|
|
});
|
|
this._mapMasks = masks;
|
|
};
|
|
|
|
Game_Map.prototype.mapMasks = function() {
|
|
return this._mapMasks;
|
|
};
|
|
|
|
Game_Map.prototype.mapMaskGroups = function() {
|
|
return this._maskGroups;
|
|
};
|
|
|
|
//========================================================================
|
|
// コアスクリプト変更部 (Spriteset_Map)
|
|
//========================================================================
|
|
const _Spriteset_Map_prototype_createCharacters = Spriteset_Map.prototype.createCharacters;
|
|
Spriteset_Map.prototype.createCharacters = function() {
|
|
_Spriteset_Map_prototype_createCharacters.apply(this, arguments);
|
|
|
|
this._mapMaskSprites = [];
|
|
|
|
for (const mask of $gameMap.mapMasks()) {
|
|
this._mapMaskSprites.push(new Sprite_MapMask(new Game_MapMask(mask)));
|
|
}
|
|
|
|
this._mapMaskSprites.forEach(sprite => {
|
|
this._tilemap.addChild(sprite);
|
|
});
|
|
};
|
|
|
|
const _Spriteset_Map_prototype_update = Spriteset_Map.prototype.update;
|
|
Spriteset_Map.prototype.update = function() {
|
|
if (!!this._mapMaskSprites) {
|
|
const maskGroups = $gameMap.mapMaskGroups();
|
|
maskGroups.forEach(group => {
|
|
const groups = this._mapMaskSprites.filter(maskSprite => {
|
|
return maskSprite.group === group;
|
|
});
|
|
|
|
const visible = groups.every(maskSprite => {
|
|
return !maskSprite.isNearThePlayer();
|
|
})
|
|
|
|
groups.forEach(maskSprite => {
|
|
maskSprite.maskVisible = visible;
|
|
});
|
|
});
|
|
}
|
|
_Spriteset_Map_prototype_update.apply(this, arguments);
|
|
};
|
|
|
|
//========================================================================
|
|
// コアスクリプト変更部 (Game_Map)
|
|
//========================================================================
|
|
const _Game_Map_prototype_isPassable = Game_Map.prototype.isPassable;
|
|
Game_Map.prototype.isPassable = function(x, y, d) {
|
|
const regionId = this.regionId(x, y);
|
|
const setting = param.regions.find(region => {
|
|
return region.region === regionId;
|
|
});
|
|
|
|
const passageSeeting = param.passageSetting;
|
|
const defaultPassible = () => {
|
|
switch (passageSeeting) {
|
|
case 'all_passible':
|
|
return true;
|
|
case 'all_not_passible':
|
|
return false;
|
|
case 'default_passage':
|
|
default:
|
|
return _Game_Map_prototype_isPassable.apply(this, arguments);
|
|
} // switch
|
|
};
|
|
|
|
if (!!setting) {
|
|
switch (setting.effect) {
|
|
case 'blockPassible':
|
|
case 'blockPassibleWithOverlayTile':
|
|
return false;
|
|
case 'forcePassible':
|
|
return true;
|
|
case 'onlyLeftBlock':
|
|
return checkDirection(d, DIRECTION_LEFT);
|
|
case 'onlyUpBlock':
|
|
return checkDirection(d, DIRECTION_UP);
|
|
case 'onlyRightBlock':
|
|
return checkDirection(d, DIRECTION_RIGHT);
|
|
case 'onlyDownBlock':
|
|
return checkDirection(d, DIRECTION_DOWN);
|
|
case 'onlyVirtical':
|
|
return checkDirection(d, DIRECTION_LEFT, DIRECTION_RIGHT);
|
|
case 'onlyHorizontal':
|
|
return checkDirection(d, DIRECTION_UP, DIRECTION_DOWN);
|
|
case 'onlyUpLeftBlock':
|
|
return checkDirection(d, DIRECTION_UP, DIRECTION_LEFT);
|
|
case 'onlyUpRightBlock':
|
|
return checkDirection(d, DIRECTION_UP, DIRECTION_RIGHT);
|
|
case 'onlyDownRightBlock':
|
|
return checkDirection(d, DIRECTION_DOWN, DIRECTION_RIGHT);
|
|
case 'onlyDownLeftBlock':
|
|
return checkDirection(d, DIRECTION_DOWN, DIRECTION_LEFT);
|
|
default:
|
|
return defaultPassible();
|
|
} // switch
|
|
} else {
|
|
return defaultPassible();
|
|
}
|
|
};
|
|
|
|
Game_Map.prototype.isOverlayTile = function(x, y) {
|
|
const regionId = this.regionId(x, y);
|
|
const setting = param.regions.find(region => {
|
|
return region.region === regionId;
|
|
});
|
|
return !!setting && [
|
|
'blockPassibleWithOverlayTile',
|
|
'overlayTile',
|
|
].some(effect => setting.effect === effect);
|
|
};
|
|
|
|
Game_Map.prototype.isBlockPassible = function(x, y) {
|
|
const regionId = this.regionId(x, y);
|
|
const setting = param.regions.find(region => {
|
|
return region.region === regionId;
|
|
});
|
|
return !!setting && setting.effect === 'blockPassible';
|
|
};
|
|
|
|
//========================================================================
|
|
// コアスクリプト変更部 (Game_Event)
|
|
//========================================================================
|
|
const _Game_Event_start = Game_Event.prototype.start;
|
|
Game_Event.prototype.start = function() {
|
|
if (this.isTriggerIn([0, 1])) {
|
|
// プレイヤーが侵入できない箇所にいるイベントはインタラクトもさせない
|
|
const x = $gamePlayer.x;
|
|
const y = $gamePlayer.y;
|
|
const d = $gamePlayer.direction();
|
|
|
|
if (!$gameMap.isPassable(x, y, d)) {
|
|
return;
|
|
}
|
|
} else if (this.isTriggerIn([2])) {
|
|
// イベント側からプレイヤーのいる箇所に侵入不可ならインタラクトさせない
|
|
const x = $gamePlayer.x;
|
|
const y = $gamePlayer.y;
|
|
const d = this.reverseDir(this.direction());
|
|
|
|
if (!$gameMap.isPassable(x, y, d)) {
|
|
return;
|
|
}
|
|
}
|
|
_Game_Event_start.apply(this, arguments);
|
|
};
|
|
|
|
//========================================================================
|
|
// コアスクリプト変更部 (Game_Event)
|
|
//========================================================================
|
|
const _Game_CharacterBase_screenZ = Game_CharacterBase.prototype.screenZ;
|
|
Game_CharacterBase.prototype.screenZ = function() {
|
|
const z = _Game_CharacterBase_screenZ.apply(this, arguments);
|
|
if ($gameMap.isOverlayTile(this.x, this.y)) {
|
|
return z + 3;
|
|
}
|
|
if ($gameMap.isBlockPassible(this.x, this.y - 1)) {
|
|
return z + 3;
|
|
}
|
|
return z;
|
|
};
|
|
|
|
//========================================================================
|
|
// プラグインコマンド
|
|
//========================================================================
|
|
})();
|