805 lines
30 KiB
JavaScript
805 lines
30 KiB
JavaScript
//=============================================================================
|
|
// SoR_DynamicMapModifier_MZ.js
|
|
// SoR License (C) 2020 蒼竜, REQUIRED User Registration on Dragon Cave
|
|
// http://dragonflare.blue/dcave/license.php
|
|
// ----------------------------------------------------------------------------
|
|
// Latest version v2.01 (2022/01/08)
|
|
//=============================================================================
|
|
/*:ja
|
|
@plugindesc <ゲーム内マップタイル動的置換> v2.01
|
|
@author 蒼竜
|
|
@target MZ
|
|
@url https://dragonflare.blue/dcave/
|
|
@help ゲーム内で,スイッチなどの条件に応じて
|
|
マップのタイルを動的に変更する機能を追加します。
|
|
|
|
通行設定等も変更後のタイルのものが適用されるため,「イベント」を
|
|
浪費することなしに、条件に応じて新しく出現する道も作成することができます。
|
|
また、他のマップのデータの一部を切り出して貼り付ける機能も持ちます。
|
|
(例: 進行状況に応じて、新しくマップ上に出現する建物)
|
|
マップのメモ欄にタグを記述しますが、具体的な数値設定等については
|
|
詳細な説明が必要なため、pdfヘルプに譲ります。
|
|
|
|
パターン1: 1タイルのみ指定書き換え
|
|
<TileReplace: x,y,z,tileID,condition>
|
|
|
|
パターン2: 複数タイル領域指定書き換え
|
|
<TileReplaceSet> ... </TileReplaceSet>
|
|
|
|
パターン3 (メイン): 他マップからのコピーによる指定領域書き換え
|
|
<TileReplaceMap> ... </TileReplaceMap>
|
|
*/
|
|
/*:
|
|
@plugindesc <Map Tile Replacement on Games> v2.01
|
|
@author Soryu
|
|
@target MZ
|
|
@url https://dragonflare.blue/dcave/index_e.php
|
|
@help This plugin introduces a function to modify tiles
|
|
dynamically in the current map depending on conditions
|
|
such as game variables.
|
|
|
|
With this map replacement, its passable settings are
|
|
also copied. When we want to add a bridge on the map as
|
|
players pass the specific level (to move on another level),
|
|
we usually put events of bridge sprite with conditional
|
|
event trigger on the map. But this plugin no longer requires
|
|
such event creation. Just overwrite the brdige tile temporary.
|
|
|
|
Additionally, we can copy and paste the specific area of
|
|
other maps. (Buildings can be appeared on bald land just
|
|
turning on the switch.)
|
|
|
|
Settings are given by note tags of target maps. Followings
|
|
are tags introduced by this plugin, but each parameter for
|
|
tags is complicated. You should read pdf documents for detail.
|
|
|
|
Pattern 1: Overwrite a one map tile.
|
|
<TileReplace: x,y,z,tileID,condition>
|
|
|
|
Pattern 2: Overwrite tiles in designated area.
|
|
<TileReplaceSet> ... </TileReplaceSet>
|
|
|
|
Pattern 3 (MAIN): Paste tiles temporary comes from other map data.
|
|
<TileReplaceMap> ... </TileReplaceMap>
|
|
*/
|
|
(function() {
|
|
const pluginName = "SoR_DynamicMapModifier_MZ";
|
|
const Param = PluginManager.parameters(pluginName);
|
|
const coeff_OVERMAPTILE = 1000000;
|
|
|
|
|
|
if(!DataManager.isEventTest()){
|
|
|
|
const SoR_DMM_DM_loadMapData = DataManager.loadMapData;
|
|
DataManager.loadMapData = function(mapId) {
|
|
SoR_DMM_DM_loadMapData.call(this, mapId);
|
|
if($gameTemp) $gameTemp.lastLoadedMapId = mapId;
|
|
}
|
|
|
|
const SoR_DMM_SSM_update = Spriteset_Map.prototype.update;
|
|
Spriteset_Map.prototype.update = function() {
|
|
SoR_DMM_SSM_update.call(this);
|
|
$gameMap.syncAppendMapData();
|
|
}
|
|
|
|
const SoR_DMM_SM_isReady = Scene_Map.prototype.isReady;
|
|
Scene_Map.prototype.isReady = function() {
|
|
const ret = this.isReady_SoRDMMAppend();
|
|
if(!ret) return false;
|
|
return SoR_DMM_SM_isReady.call(this); // <--- onMapLoaded (map real setup)
|
|
}
|
|
|
|
Scene_Map.prototype.isReady_SoRDMMAppend = function() {
|
|
if(this.isAppendMapDataQueued()){
|
|
if(this.isAppendMapDataReady()){
|
|
if(this.isAppendMapDataLoaded()){
|
|
if(!this._isAppendMapConstructed){
|
|
if($gameMap.canskip_MapDataReconstruct != true) $gameMap.setup_sync();
|
|
$gameMap._regularLoad = true;
|
|
this._isAppendMapConstructed = true;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Scene_Map.prototype.isAppendMapDataQueued = function() {
|
|
if(this._isAppendMapQueued==true) return true;
|
|
|
|
if (DataManager.isMapLoaded()) {
|
|
$gameMap.prepareMapInitialize();
|
|
$gameMap.createAlternateMaps();
|
|
this._isAppendMapQueued = true;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Scene_Map.prototype.isAppendMapDataReady = function() {
|
|
if($gameMap._tmp_MAPData && $gameMap._tmp_MAPData.length == 0) this._isAppendMapStandBy = true;
|
|
if(this._isAppendMapStandBy === true) return true;
|
|
|
|
$gameMap.syncAppendMapData();
|
|
for (let i in $gameMap._tmp_MAPData){
|
|
if(!$gameMap._tmp_MAPData[i].d) return false;
|
|
}
|
|
|
|
if(!$gameMap._appendMapData || $gamePlayer._transferring){
|
|
$gameMap._appendMapData = {};
|
|
$gameMap._MapDataReplacer = null;
|
|
$gameMap._modifiedDataMap = $dataMap.data.clone();
|
|
}
|
|
|
|
this._isAppendMapStandBy = true;
|
|
return true;
|
|
}
|
|
|
|
|
|
Scene_Map.prototype.isAppendMapDataLoaded = function() {
|
|
if($gameMap._tmp_MAPData && $gameMap._tmp_MAPData.length == 0) return true;
|
|
if(this._isAppendMapConstructed === true) return true;
|
|
const ret = collectReplaceMapTile();
|
|
if(!ret) return false;
|
|
|
|
if(ret.length==0 || $gameMap._MapDataReplacer != null){
|
|
return true;
|
|
}
|
|
else {
|
|
$gameMap._MapDataReplacer = ret;
|
|
$gameMap.createAppendMapData();
|
|
|
|
$gameMap._modifiedDataMap = $dataMap.data.clone();
|
|
$gameMap.createModifiedData();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
DataManager.loadMapTiles = function(name, src) {
|
|
const xhr = new XMLHttpRequest();
|
|
const url = "data/" + src;
|
|
window[name] = null;
|
|
xhr.open("GET", url);
|
|
xhr.overrideMimeType("application/json");
|
|
xhr.onload = () => this.onXhrMapLoad(xhr, name, src, url);
|
|
xhr.onerror = () => this.onXhrError(name, src, url);
|
|
xhr.send();
|
|
return xhr;
|
|
}
|
|
|
|
DataManager.onXhrMapLoad = function(xhr, name, src, url) {
|
|
if (xhr.status < 400) window[name] = JSON.parse(xhr.responseText);
|
|
}
|
|
|
|
const SoR_DMM_GM_data = Game_Map.prototype.data;
|
|
Game_Map.prototype.data = function() {
|
|
if(this._MapDataReplacer != null){
|
|
if(!this._modifiedDataMap){
|
|
this._modifiedDataMap = $dataMap.data.clone();
|
|
this.createModifiedData();
|
|
}
|
|
return this._modifiedDataMap;
|
|
}
|
|
|
|
return SoR_DMM_GM_data.call(this);
|
|
}
|
|
|
|
Game_Map.prototype.data_original = function() {
|
|
return $dataMap.data;
|
|
}
|
|
|
|
Game_Map.prototype.createModifiedData = function() {
|
|
for (let idx in this._appendMapData){
|
|
this._modifiedDataMap[idx] = this._appendMapData[idx]%coeff_OVERMAPTILE;
|
|
}
|
|
}
|
|
|
|
const SoR_DMM_GM_setup = Game_Map.prototype.setup;
|
|
Game_Map.prototype.setup = function(mapId) {
|
|
if(calledByFunction(new Error().stack) == "Game_Player.performTransfer"){
|
|
this.setup_sync();
|
|
return;
|
|
}
|
|
if(!this._regularLoad) SoR_DMM_GM_setup.call(this, mapId);
|
|
}
|
|
|
|
|
|
Game_Map.prototype.setup_sync = function() {
|
|
SoR_DMM_GM_setup.call(this, this._mapId);
|
|
this.canskip_MapDataReconstruct = true;
|
|
}
|
|
|
|
Game_Map.prototype.prepareMapInitialize = function() {
|
|
let mapid = $gameTemp.lastLoadedMapId;
|
|
this.canskip_MapDataReconstruct = (mapid == this._mapId);
|
|
this._mapId = mapid;
|
|
this._requireMapDataRefresh = false;
|
|
}
|
|
|
|
const SoR_DMM_SM_setup = Scene_Map.prototype.onMapLoaded;
|
|
Scene_Map.prototype.onMapLoaded = function() {
|
|
SoR_DMM_SM_setup.call(this);
|
|
$gameMap.CheckParallelTileRequired();
|
|
this._spriteset.refreshTilemap();
|
|
}
|
|
|
|
Game_Map.prototype.CheckParallelTileRequired = function() {
|
|
for (let i in this._tmp_MAPData){
|
|
obj = this._tmp_MAPData[i];
|
|
if(obj.tsid != this._tilesetId) SceneManager._scene._spriteset.makeParallelTilesets(obj.tilesetId);
|
|
}
|
|
}
|
|
|
|
Game_Map.prototype.createAlternateMaps = function() {
|
|
this._tmp_MAPData = {};
|
|
const arr = processReplaceMapIDs();
|
|
for(x of arr){
|
|
const filename = "Map%1.json".format(x.padZero(3));
|
|
const tmpname = "$TmpMap" + x;
|
|
this._tmp_MAPData[x] = DataManager.loadMapTiles(tmpname, filename);
|
|
}
|
|
}
|
|
|
|
Game_Map.prototype.syncAppendMapData = function() {
|
|
for (let i in this._tmp_MAPData){
|
|
const name = "$TmpMap" + i;
|
|
let obj = window[name];
|
|
if(obj!=null && !this._tmp_MAPData[i].d){
|
|
this._tmp_MAPData[i] = {d: obj.data, w: obj.width, h: obj.height, tsid: obj.tilesetId};
|
|
window[name] = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
const SoR_DMM_GP_reserveTransfer = Game_Player.prototype.reserveTransfer;
|
|
Game_Player.prototype.reserveTransfer = function(mapId, x, y, d, fadeType) {
|
|
SoR_DMM_GP_reserveTransfer.call(this,...arguments);
|
|
$gameMap._modifiedDataMap = null;
|
|
}
|
|
|
|
const SoR_DMM_GM_update = Game_Map.prototype.update;
|
|
Game_Map.prototype.update = function(sceneActive) {
|
|
SoR_DMM_GM_update.call(this, sceneActive);
|
|
this.createAppendMapData();
|
|
this.respondMapReload();
|
|
}
|
|
|
|
Game_Map.prototype.createAppendMapData = function() {
|
|
const ovwlayer = {};
|
|
|
|
if(this._MapDataReplacer && this._MapDataReplacer.length!=0){
|
|
const width = $gameMap.width();
|
|
const height = $gameMap.height();
|
|
const applyfilters = [];
|
|
|
|
for(let m of this._MapDataReplacer){
|
|
if(m.mapid && (!this._tmp_MAPData[m.mapid].w || !this._tmp_MAPData[m.mapid].h)) return false;
|
|
if(!SoR_Eval(m.cond)){
|
|
if(m.applied){
|
|
this._requireMapDataRefresh = true;
|
|
m.applied = false;
|
|
applyfilters.push(m);
|
|
}
|
|
}
|
|
else {
|
|
applyfilters.push(m);
|
|
if(!m.applied){
|
|
this._requireMapDataRefresh = true;
|
|
m.applied = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(this._requireMapDataRefresh){
|
|
for(let m of applyfilters){
|
|
for(const mfilt of m.filt){
|
|
const idx = (mfilt.at_X && mfilt.at_X>=0 &&mfilt.at_Y &&mfilt.at_Y>=0)? (mfilt.at_X + (mfilt.at_Y + mfilt.z * height)*width): (m.x + (m.y + mfilt.z * height)*width);
|
|
mfilt.tile.forEach(function(element, index){
|
|
const fw = mfilt.fwidth;
|
|
const gidx = index%fw;
|
|
const gidy = Math.floor(index/fw);
|
|
const key = idx+gidx+gidy*width;
|
|
|
|
//temporary %coeff_OVERMAPTILE;
|
|
if(m.applied) ovwlayer[key] = element%coeff_OVERMAPTILE;
|
|
else if(!(key in ovwlayer)) ovwlayer[key] = $dataMap.data[key]%coeff_OVERMAPTILE; //Restore the original tile if no append tiles are beneath here.
|
|
});
|
|
}
|
|
}
|
|
|
|
this._appendMapData = Object.assign({}, ovwlayer);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
Game_Map.prototype.respondMapReload = function() {
|
|
if(this._requireMapDataRefresh){
|
|
if(!this._modifiedDataMap) this._modifiedDataMap = $dataMap.data.clone();
|
|
this.createModifiedData();
|
|
|
|
const sm = SceneManager._scene;
|
|
if(sm instanceof Scene_Map){
|
|
SceneManager._scene._spriteset.refreshTilemap();
|
|
if(PluginManager._scripts.includes("SoR_MiniMapAndScene_MZ")) sm.MiniMapObj.callReconstructor();
|
|
}
|
|
|
|
this._requireMapDataRefresh = false;
|
|
}
|
|
}
|
|
|
|
Game_Map.prototype.tileId = function(x, y, z) {
|
|
const width = $dataMap.width;
|
|
const height = $dataMap.height;
|
|
//return $gameMap.data()[(z * height + y) * width + x]%coeff_OVERMAPTILE; //$dataMap.data[(z * height + y) * width + x] || 0;
|
|
return $gameMap.data()[(z * height + y) * width + x]%coeff_OVERMAPTILE;
|
|
}
|
|
|
|
Spriteset_Map.prototype.refreshTilemap = function() {
|
|
this._tilemap.setData($gameMap.width(), $gameMap.height(), $gameMap.data());
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
Spriteset_Map.prototype.makeParallelTilesets = function(tsetId) {
|
|
//this._tilemap;
|
|
const exTileSet = $dataTilesets[tsetId];
|
|
if (exTileSet) {
|
|
const bitmaps = [];
|
|
const tilesetNames = exTileSet.tilesetNames;
|
|
for (const name of tilesetNames) {
|
|
bitmaps.push(ImageManager.loadTileset(name));
|
|
}
|
|
this._tilemap.setparallelBitmaps(tsetId, bitmaps);
|
|
this._tilemap.exflags[tsetId] = exTileSet.flags;
|
|
}
|
|
}
|
|
|
|
const SoR_DMM_TM_initialize = Tilemap.prototype.initialize;
|
|
Tilemap.prototype.initialize = function() {
|
|
SoR_DMM_TM_initialize.call(this);
|
|
this._bitmaps_parallel = {};
|
|
this.exflags = {};
|
|
this._needsBitmapsUpdate_parallel = false;
|
|
}
|
|
|
|
const SoR_DMM_TM__updateBitmaps = Tilemap.prototype._updateBitmaps;
|
|
Tilemap.prototype._updateBitmaps = function() {
|
|
SoR_DMM_TM__updateBitmaps.call(this);
|
|
if (this._needsBitmapsUpdate_parallel && this.isReady()) {
|
|
this._lowerLayer.setparallelBitmaps(this._bitmaps_parallel);
|
|
this._needsBitmapsUpdate_parallel = false;
|
|
this._needsRepaint = true;
|
|
}
|
|
}
|
|
|
|
Tilemap.prototype.setparallelBitmaps = function(tsetId, bitmaps) {
|
|
// [Note] We wait for the images to finish loading. Creating textures
|
|
// from bitmaps that are not yet loaded here brings some maintenance
|
|
// difficulties. e.g. PIXI overwrites img.onload internally.
|
|
this._bitmaps_parallel[tsetId] = bitmaps;
|
|
const listener = this._updateBitmaps.bind(this);
|
|
for (const bitmap in this._bitmaps_parallel) {
|
|
if (!bitmap.isReady()) {
|
|
bitmap.addLoadListener(listener);
|
|
}
|
|
}
|
|
this._needsBitmapsUpdate_parallel = true;
|
|
this._updateBitmaps();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
const SoR_DMM_TML_initialize = Tilemap.Layer.prototype.initialize;
|
|
Tilemap.Layer.prototype.initialize = function() {
|
|
SoR_DMM_TML_initialize.call(this);
|
|
this._images_parallel = {};
|
|
}
|
|
|
|
Tilemap.Layer.prototype.setparallelBitmaps = function(bitmaps) {
|
|
for (const key in bitmaps) {
|
|
const bitmap = bitmaps[key];
|
|
this._images_parallel[key] = bitmaps.map(bitmap => bitmap.image || bitmap.canvas);
|
|
}
|
|
this._needsTexturesUpdate = true;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
/*
|
|
Tilemap.prototype._readMapData = function(x, y, z) {
|
|
if (this._mapData) {
|
|
const width = this._mapWidth;
|
|
const height = this._mapHeight;
|
|
if (this.horizontalWrap) x = x.mod(width);
|
|
if (this.verticalWrap) y = y.mod(height);
|
|
if (x >= 0 && x < width && y >= 0 && y < height) return this._mapDataSrc(x,y,z,width,height); //////////
|
|
else return 0;
|
|
}
|
|
else{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Tilemap.prototype._mapDataSrc = function(x, y, z, w, h){
|
|
const idx = x+ (y+z*h)*w;
|
|
if(idx in $gameMap._appendMapData){
|
|
return $gameMap._appendMapData[idx];
|
|
}
|
|
else return this._mapData[idx] || 0;
|
|
}
|
|
*/
|
|
//coeff_OVERMAPTILE
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
function collectReplaceMapTile(){
|
|
|
|
if($dataMap.note===undefined) return undefined;
|
|
const arr = [];
|
|
|
|
//mapswitch tag
|
|
const tag = /<(?:TileReplace):[ ]*(\d+),[ ]*(\d+),[ ]*(\d+),[ ]*(\d+),[ ]*(.*)>/i;
|
|
const tags = /<(?:TileReplaceSet)>/i;
|
|
const tags_e = /<(\/TileReplaceSet)>/i;
|
|
|
|
const tag1 = /(?:From):[ ]*(\d+),[ ]*(\d+)/i;
|
|
const tag2 = /(?:To):[ ]*(\d+),[ ]*(\d+)/i;
|
|
const tag22 = /(?:Rect):[ ]*(\d+),[ ]*(\d+)/i;
|
|
const tag3 = /(?:z):[ ]*(.*)/i;
|
|
const tag4 = /(?:tile):[ ]*(\d+)/i;
|
|
const tag5 = /(?:cond):[ ]*(.*)/i;
|
|
|
|
const tags2 = /<(?:TileReplaceMap)>/i;
|
|
const tags2_e = /<(\/TileReplaceMap)>/i;
|
|
const tag6 = /(?:mapID):[ ]*(\d+)/i;
|
|
const tag7 = /(?:at):[ ]*(\d+),[ ]*(\d+)/i;
|
|
const tag8 = /(?:Ignore0)/i;
|
|
|
|
|
|
const notes = $dataMap.note.split(/[\r\n]+/);
|
|
const Lnotes = notes.length;
|
|
for (let n = 0; n < Lnotes; n++) {
|
|
const line = notes[n];
|
|
if (line.match(tag)) {
|
|
//make 1x1 filter
|
|
let z = convParamRangeValue(RegExp.$3);
|
|
const switchtiles = {
|
|
x: parseInt(RegExp.$1),
|
|
y: parseInt(RegExp.$2),
|
|
filt: [],
|
|
cond: String(RegExp.$5),
|
|
applied: false
|
|
};
|
|
|
|
z.forEach((z, k) => {
|
|
switchtiles.filt.push({tile: [parseInt(RegExp.$4)], z: k, fwidth: 1})
|
|
});
|
|
|
|
arr.push(switchtiles);
|
|
}
|
|
//replace existing map tile
|
|
if (line.match(tags)) {
|
|
let x = -1, y = -1, z = -1;
|
|
let tile = -1;
|
|
let cond = "true";
|
|
let destx = -1, desty = -1;
|
|
let rectw = -1, recth = -1;
|
|
|
|
n++;
|
|
while(n < Lnotes){
|
|
const subline = notes[n];
|
|
if (subline.match(tag1)){x=parseInt(RegExp.$1); y=parseInt(RegExp.$2);}
|
|
else if (subline.match(tag2)){destx=parseInt(RegExp.$1); desty=parseInt(RegExp.$2);}
|
|
else if (subline.match(tag22)){rectw=parseInt(RegExp.$1); recth=parseInt(RegExp.$2);}
|
|
else if (subline.match(tag3)){z=convParamRangeValue(RegExp.$1);}
|
|
else if (subline.match(tag4)){tile=parseInt(RegExp.$1);}
|
|
else if (subline.match(tag5)){cond=String(RegExp.$1);}
|
|
else if (subline.match(tags_e)){//finish tags
|
|
if(x!=-1&& y!=-1 && z!=-1 && tile!=-1){
|
|
if(destx!=-1 && desty !=-1){
|
|
//process
|
|
const diffx = destx - x;
|
|
const diffy = desty - y;
|
|
|
|
const switchtiles = {
|
|
x: x,
|
|
y: y,
|
|
filt: [],
|
|
cond: cond,
|
|
applied: false
|
|
};
|
|
|
|
const xlen = Math.abs(diffx);
|
|
const ylen = Math.abs(diffy);
|
|
const fwidth = Math.abs(xlen)+1;
|
|
|
|
for(const k of z){
|
|
const filt = {tile: [], z: k, fwidth: fwidth};
|
|
|
|
const tilecands = [];
|
|
const tilelen = ylen==0? xlen+1 : ylen+1;
|
|
for(let i = 0; i<tilelen; i++){
|
|
const idi = diffx<0? -i : (diffx==0? 0 : i);
|
|
const idj = diffy<0? -i : (diffy==0? 0 : i);
|
|
const idx = idi+idj*fwidth;
|
|
tilecands.push(idx);
|
|
}
|
|
|
|
const minidx = tilecands.reduce((a,b)=>{return a<b?a:b;});
|
|
if(minidx<0){
|
|
switchtiles.x -= Math.abs(minidx)%fwidth;
|
|
switchtiles.y -= Math.abs(minidx)/fwidth;
|
|
}
|
|
for(const idx of tilecands){
|
|
const i = minidx<0? idx+Math.abs(minidx) : idx;
|
|
filt.tile[i] = tile;
|
|
}
|
|
|
|
switchtiles.filt.push(filt);
|
|
}
|
|
|
|
arr.push(switchtiles);
|
|
break;
|
|
}
|
|
else if(rectw!=-1 && recth !=-1){
|
|
//process
|
|
|
|
const switchtiles = {
|
|
x: x,
|
|
y: y,
|
|
filt: [],
|
|
cond: cond,
|
|
applied: false
|
|
};
|
|
|
|
for(const k of z){
|
|
const fwidth = rectw;
|
|
const filt = {tile: [], z: k, fwidth: rectw};
|
|
for(let j = 0; j<recth; j++){
|
|
for(let i = 0; i<rectw; i++){
|
|
filt.tile[j*fwidth+i] = tile;
|
|
}
|
|
}
|
|
switchtiles.filt.push(filt);
|
|
}
|
|
arr.push(switchtiles);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
n++;
|
|
}
|
|
}
|
|
else if (line.match(tags2)) {//replace map
|
|
|
|
let x = -1, y = -1, z = -1;
|
|
let tile = -1;
|
|
let cond = "true";
|
|
let destx = -1, desty = -1;
|
|
let rectw = -1, recth = -1;
|
|
let mapid = -1;
|
|
let atX = -1, atY = -1;
|
|
let zeroIgnore = false;
|
|
|
|
n++;
|
|
while(n < Lnotes){
|
|
const subline = notes[n];
|
|
if (subline.match(tag1)){x=parseInt(RegExp.$1); y=parseInt(RegExp.$2);}
|
|
else if (subline.match(tag2)){destx=parseInt(RegExp.$1); desty=parseInt(RegExp.$2);}
|
|
else if (subline.match(tag22)){rectw=parseInt(RegExp.$1); recth=parseInt(RegExp.$2);}
|
|
else if (subline.match(tag3)){z=convParamRangeValue(RegExp.$1);}
|
|
else if (subline.match(tag5)){cond=String(RegExp.$1);}
|
|
else if (subline.match(tag6)){mapid=parseInt(RegExp.$1);}
|
|
else if (subline.match(tag7)){atX=parseInt(RegExp.$1); atY=parseInt(RegExp.$2);}
|
|
else if (subline.match(tag8)){zeroIgnore = true;}
|
|
else if (subline.match(tags2_e)){//finish tags
|
|
if(x!=-1&& y!=-1 && z!=-1 && mapid!=-1){
|
|
if(destx!=-1 && desty !=-1){
|
|
//process
|
|
const diffx = destx - x;
|
|
const diffy = desty - y;
|
|
|
|
const dlen = diffx!=0? diffx:diffy;
|
|
const switchtiles = {
|
|
x: x, y: y,
|
|
filt: [],
|
|
cond: cond,
|
|
applied: false
|
|
};
|
|
|
|
const xlen = Math.abs(diffx);
|
|
const ylen = Math.abs(diffy);
|
|
const fwidth = Math.abs(xlen)+1;
|
|
const tmpm = $gameMap._tmp_MAPData[mapid]; // = {d: obj.data, w: obj.width, h: obj.height};
|
|
|
|
for(const k of z){
|
|
const filt = {tile: [], z: k, fwidth: fwidth};
|
|
|
|
const tilecands = [];
|
|
const tilelen = ylen==0? xlen+1 : ylen+1;
|
|
for(let i = 0; i<tilelen; i++){
|
|
const idi = diffx<0? -i : (diffx==0? 0 : i);
|
|
const idj = diffy<0? -i : (diffy==0? 0 : i);
|
|
const idx = idi+idj*fwidth;
|
|
tilecands.push(idx);
|
|
}
|
|
|
|
const minidx = tilecands.reduce((a,b)=>{return a<b?a:b;});
|
|
if(minidx<0){
|
|
switchtiles.x -= Math.abs(minidx)%fwidth;
|
|
switchtiles.y -= Math.abs(minidx)/fwidth;
|
|
}
|
|
for(const idx of tilecands){
|
|
const i = minidx<0? idx+Math.abs(minidx) : idx;
|
|
const idx_orig = i + x + (y * tmpm.w) + (k * tmpm.w * tmpm.h);
|
|
if(k>0 && zeroIgnore && tmpm.d[idx_orig]==0) continue;
|
|
filt.tile[i] = tmpm.d[idx_orig];
|
|
if(tmpm.tsid != $dataMap.tilesetId) filt.tile[i] += tmpm.tsid*coeff_OVERMAPTILE;
|
|
}
|
|
|
|
switchtiles.filt.push(filt);
|
|
}
|
|
|
|
arr.push(switchtiles);
|
|
break;
|
|
}
|
|
else if(rectw!=-1 && recth !=-1){
|
|
//process
|
|
let ts= z, te= z;
|
|
if(z==9) {ts=0; te = 5;}//all layers
|
|
const switchtiles = {
|
|
x: x, y: y,
|
|
filt: [],
|
|
cond: cond,
|
|
applied: false
|
|
};
|
|
|
|
const tmpm = $gameMap._tmp_MAPData[mapid]; // = {d: obj.data, w: obj.width, h: obj.height};
|
|
for(const k of z){
|
|
const fwidth = rectw;
|
|
const filt = {tile: [], z: k, fwidth: fwidth};
|
|
if(atX && atY){
|
|
filt.at_X = atX;
|
|
filt.at_Y = atY;
|
|
}
|
|
|
|
for(let j=0; j<recth; j++){
|
|
for(let i=0; i<rectw; i++){
|
|
const idx = (x+i) + ((y+j) * tmpm.w) + (k * tmpm.w * tmpm.h);
|
|
if(k>0 && zeroIgnore && tmpm.d[idx]==0) continue;
|
|
filt.tile[j*fwidth+i] = tmpm.d[idx];
|
|
if(tmpm.tsid != $dataMap.tilesetId) filt.tile[i] += tmpm.tsid*coeff_OVERMAPTILE;
|
|
}
|
|
}
|
|
|
|
switchtiles.filt.push(filt);
|
|
}
|
|
arr.push(switchtiles);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
n++;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return arr;
|
|
}
|
|
|
|
|
|
function processReplaceMapIDs(){
|
|
if($dataMap.note===undefined) return undefined;
|
|
const arr = [];
|
|
|
|
//mapswitch tag
|
|
const tags2 = /<(?:TileReplaceMap)>/i;
|
|
const tags2_e = /<(\/TileReplaceMap)>/i;
|
|
const tag6 = /(?:mapID):[ ]*(\d+)/i;
|
|
|
|
const notes = $dataMap.note.split(/[\r\n]+/);
|
|
const Lnotes = notes.length;
|
|
for (let n = 0; n < Lnotes; n++) {
|
|
const line = notes[n];
|
|
|
|
if (line.match(tags2)) {//replace map
|
|
let mapid = -1;
|
|
n++;
|
|
while(n < Lnotes){
|
|
const subline = notes[n];
|
|
if (subline.match(tag6)){mapid=parseInt(RegExp.$1);}
|
|
else if (subline.match(tags2_e)){
|
|
if(mapid!= -1) arr.push(mapid);
|
|
}
|
|
n++;
|
|
}
|
|
}
|
|
}
|
|
|
|
for(let i=0;i<arr.length;i++){
|
|
const v = arr[i];
|
|
let j = i+1;
|
|
while(j<arr.length){
|
|
if(v == arr[j]){ arr.splice(j,1);}
|
|
else j++;
|
|
}
|
|
}
|
|
|
|
return arr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
function convParamRangeValue(str){
|
|
if(str=="9") return [0,1,2,3,4,5];
|
|
|
|
let id_array = [];
|
|
const spl_str = str.split(',');
|
|
const regex = /(\d+)\s*-\s*(\d+)/;
|
|
if (!str) return id_array; //empty
|
|
|
|
const nspl = spl_str.length;
|
|
for (let i = 0; i < nspl; i++){
|
|
if (regex.test(spl_str[i]) == true){
|
|
const begin = Number(RegExp.$1);
|
|
const end = Number(RegExp.$2);
|
|
for (let j = begin; j <= end; j++) id_array.push(j); //ranged ID
|
|
}
|
|
else id_array.push(Number(spl_str[i])); //one ID
|
|
}
|
|
|
|
return id_array;
|
|
}
|
|
|
|
function SoR_Eval(ev) {
|
|
const sentence = "return (" + ev + ");";
|
|
|
|
if(typeof $gameTemp.SoRTmp_script === "undefined") $gameTemp.SoRTmp_script = new Map();
|
|
if(!$gameTemp.SoRTmp_script.has(sentence)){
|
|
$gameTemp.SoRTmp_script.set(sentence, new Function(sentence));
|
|
}
|
|
const res = $gameTemp.SoRTmp_script.get(sentence)();
|
|
return res;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
Game_Map.prototype.data_DiffSoR = function() {
|
|
if(!this._modifiedDataMap) return null;
|
|
const orig = $gameMap.data_original();
|
|
let nd = 0;
|
|
console.info("Difference in Replacement...");
|
|
for (let idx in this._modifiedDataMap){
|
|
if(this._modifiedDataMap[idx] != orig[idx]){
|
|
console.info(this._modifiedDataMap[idx],orig[idx]);
|
|
console.info("idx= " + idx + ", Modified: " + this._modifiedDataMap[idx] + " Original: " , orig[idx]);
|
|
nd++;
|
|
}
|
|
}
|
|
return nd;
|
|
}
|
|
|
|
|
|
function calledByFunction(stack){
|
|
const stacks = stack.split(/\n/);
|
|
const target = stacks[2];
|
|
|
|
const res = target.match(/at\s([^\s]+)/);
|
|
return res[1].trim()
|
|
}
|
|
|
|
}//evtest
|
|
})();
|
|
|
|
|
|
|