harem-ranch-life-dlc/js/plugins/SoR_DynamicMapModifier_MZ .js
2024-06-23 01:15:36 +07:00

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
})();