11798 lines
No EOL
286 KiB
JavaScript
11798 lines
No EOL
286 KiB
JavaScript
//=============================================================================
|
||
// TRP_MapDecorator.js
|
||
//=============================================================================
|
||
|
||
// SETTING
|
||
// Plugin Command
|
||
// Start
|
||
// Mode / Update
|
||
// Undo/Redo
|
||
|
||
// process ZMap
|
||
// processCriff
|
||
// Supply Walls
|
||
// Supply Ceilings
|
||
// supply BackTiles
|
||
// Supply Shadows
|
||
// Room Select
|
||
|
||
|
||
// MODE: PaintFloor
|
||
// MODE: FloorVariationPalette
|
||
// MODE: ManualPaint
|
||
// MODE: ManualPaintPalette
|
||
|
||
// MODE: LocateObject
|
||
// Dot Shift Objects
|
||
// MODE: ManualLocate
|
||
// MODE: ObjectPalette
|
||
// MODE: ObjectSelect
|
||
// MODE: ObjectGrouping
|
||
|
||
|
||
// MODE: UserProcess
|
||
// User Process
|
||
|
||
|
||
// ParamEditor
|
||
// MapObject
|
||
// Util Funcs
|
||
// Restore Map
|
||
// Auto Tile Connection
|
||
// ColorPicker
|
||
// Palette
|
||
// TilesetEdit
|
||
// ParallaxSave
|
||
|
||
|
||
|
||
//=============================================================================
|
||
/*:
|
||
* @author Thirop
|
||
* @target MZ
|
||
* @plugindesc 自動装飾プラグイン<開発用>
|
||
* @base TRP_CORE
|
||
* @base TRP_MapDecorator_Template
|
||
* @orderAfter TRP_CORE
|
||
* @orderAfter TRP_MapObject
|
||
*
|
||
* @help
|
||
* 【導入】
|
||
* 以下のプラグインより下に配置
|
||
* ・TRP_CORE.js<必須>
|
||
* ・TRP_MapObject.js<オプション>
|
||
*
|
||
* 以下のプラグインより上に配置
|
||
* ・TRP_MapDecorator_Template.js<必須>
|
||
*
|
||
*
|
||
* 【更新履歴】
|
||
* 1.44 2023/09/04 修正:MapObject不使用時に再編集時のエラー修正
|
||
* 1.41 2023/06/08 修正:Windowsでモック保存ができない不具合修正。
|
||
* 修正:操作ガイドが正しく表示されていない不具合修正
|
||
* 1.36 2023/04/03 追加:置換パラメータ追加
|
||
* 1.35 2023/04/01 修正:オブジェクトの縦横比率変更ができない不具合
|
||
* 1.34 2023/04/01 修正:他タイルセット画像オブジェのプライオリティ設定
|
||
* 1.33 2023/03/25 追加:オブジェグループ、タイルセット画像登録
|
||
* 追加:遠景モック表示
|
||
* 1.32 2023/03/13 修正:アンドゥ機能のバグ/オブジェ手動配置時のエラー
|
||
* 1.31 2023/03/13 追加:複数回前までのバックアップ対応
|
||
* 追加:簡易アンドゥ/リドゥ対応
|
||
* 追加:装飾種類ロックパレット/手動ペイントパレット
|
||
* 修正:装飾種類ロック、水場ロック、チャンク消去のキー変更
|
||
* 追加:オブジェクトのドットシフト(要:TRP_MapObject)
|
||
* 追加:各モード用のカーソルアイコン設定
|
||
* 追加:パラメータ編集機能
|
||
* 1.21 2023/01/15 修正:zMap確認後にモードが戻れない不具合修正
|
||
* 1.20 2023/01/10 修正:水場ロック後の水場へのオブジェ抽選の不具合修正
|
||
* 1.19 2023/01/10 修正:オブジェ配置済みマップを再編集後にオブジェが消える不具合修正
|
||
* 1.15 2023/01/09 修正:オブジェドラッグ移動の不具合修正
|
||
* 1.14 2022/12/25 拡張:オブジェクトパレット
|
||
* 修正:「全処理の取り消し」
|
||
* 修正:手動配置時の座標ズレ、ほか細かな不具合
|
||
* 1.13 2022/12/19 修正:裏タイル補完時の影プロセスの不具合
|
||
* 1.12 2022/12/11 拡張:指定部屋の編集、置換プロセスの手動実行
|
||
* 1.11 2022/12/04 不具合修正:B-E天井タイル裏への水タイル塗布に関するバグ修正
|
||
* 1.10 2022/12/04 拡張:置換処理拡張
|
||
* 設定「autoCeilingSupplyWithEmpty」追加
|
||
* 不具合修正:バリエーション置換関連
|
||
* 1.09 2022/11/27 拡張:バリエーション置換
|
||
* 1.08 2022/11/27 修正:オブジェロック後に手動編集可能に
|
||
* 1.07 2022/11/14 拡張:オブジェクトパレット(要:TRP_CORE.js<ver1.07>)
|
||
* 1.06 2022/11/14 拡張:オブジェクトの手動配置
|
||
* 修正:崖フチへの重ね装飾タイル配置許容
|
||
* 1.05 2022/11/13 拡張:床装飾の手動調整モード追加
|
||
* 1.01 2022/11/06 保存コマンドのガイド表示
|
||
* 1.00 2022/11/05 初版
|
||
*
|
||
*
|
||
* @command start
|
||
* @text 開始
|
||
* @desc
|
||
*
|
||
* @arg templateMapId
|
||
* @text テンプレートマップID
|
||
* @desc 使用するテンプレートマップID。(テンプレートマップ自身から実行時はタイル種別を確認可)
|
||
* @type number
|
||
* @default 0
|
||
*
|
||
* @arg disableAutoSupply
|
||
* @text 壁・天井・崖の自動補完無効
|
||
* @desc ONにすると開始時の壁・天井・崖の自動補完を無効
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
*
|
||
*
|
||
*
|
||
* @param command
|
||
* @text コマンド名(MV)
|
||
* @desc MV形式プラグインコマンドのコマンド名
|
||
* @default decorator
|
||
* @type string
|
||
*
|
||
* @param roomSeparatorRegionId
|
||
* @text 部屋区切りリージョンID
|
||
* @desc 部屋区切りリージョンID
|
||
* @default 1
|
||
* @type number
|
||
*
|
||
* @param objForbiddenRegionId
|
||
* @text オブジェ配置禁止リージョンID
|
||
* @desc オブジェ配置禁止リージョンID
|
||
* @default 2
|
||
* @type number
|
||
*
|
||
*
|
||
* @param maxUndoSize
|
||
* @text アンドゥ保持サイズ(MB)
|
||
* @desc 簡易アンドゥ/リドゥに使用する内部ログデータのおおまかな保持サイズ(MB)。デフォルトは100MB
|
||
* @default 100
|
||
* @type number
|
||
*
|
||
* @param cursorIcons
|
||
* @text モードカーソル設定
|
||
* @desc 各モードのカーソルに表示するアイコンID。カンマつなぎで「床装飾」「手動ペイント」「オブジェ配置」「手動オブジェ配置」の順
|
||
* @default 217,246,129,142
|
||
* @type string
|
||
*
|
||
* @param palettePageNum
|
||
* @text ページ名表示数
|
||
* @desc ページ名の1画面内での表示数。デフォ値は20
|
||
* @default 20
|
||
* @type number
|
||
*
|
||
*
|
||
*
|
||
* @param pluginPath
|
||
* @text _プラグインパス
|
||
* @desc このプラグインのファイルパス。通常は未設定でOK
|
||
* @default
|
||
*
|
||
*
|
||
*
|
||
*/
|
||
//=============================================================================
|
||
|
||
|
||
|
||
var TRP_CORE = TRP_CORE || {};
|
||
function TRP_MapDecorator(){
|
||
this.initialize.apply(this, arguments);
|
||
};
|
||
|
||
TRP_MapDecorator.INFO_CHARACTER_NAME = 'DecorationInfo';
|
||
TRP_MapDecorator.INFO_CHARACTER_Z_NAME = 'DecorationZ';
|
||
TRP_MapDecorator.INFO_CHARACTER_TYPES = {
|
||
/* [characterIndex,direction,pattern]
|
||
===================================*/
|
||
//tile types
|
||
tileTypeBase:[0,4,0],
|
||
tileTypeAccessory:[0,4,1],
|
||
tileTypeWater:[0,4,2],
|
||
|
||
wall:[0,6,0],
|
||
criff:[0,6,1],
|
||
|
||
objPalette:[0,8,0],
|
||
|
||
|
||
//obj setting
|
||
baseObjEnabled:[1,4,0],
|
||
baseObjDisabled:[1,4,1],
|
||
bigObjEmptyTile:[1,4,2],
|
||
|
||
objLocateOnEdgeEnabled:[1,6,0],
|
||
objLocateOverEdgeEnabled:[1,6,1],
|
||
objUnderLocateEnabled:[1,6,2],
|
||
|
||
objRate:[1,8,0],
|
||
bigObjRate:[1,8,1],
|
||
|
||
|
||
//other settings
|
||
variationRate:[2,4,0],
|
||
return:[2,8,2],
|
||
|
||
|
||
//process settings
|
||
variation:[3,4,0],
|
||
variationOneSize:[3,4,1],
|
||
processGroup:[3,4,2],
|
||
supplyBack:[3,6,0],
|
||
condNot:[3,6,1],
|
||
noShape:[3,6,2],
|
||
noKinds:[3,8,1],
|
||
|
||
|
||
//system
|
||
mapObjectSave:[7,4,0],
|
||
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// remove Info Character
|
||
//=============================================================================
|
||
(function(){
|
||
'use strict';
|
||
|
||
var MapDecorator = TRP_MapDecorator;
|
||
|
||
var _Game_Map_setupEvents = Game_Map.prototype.setupEvents;
|
||
Game_Map.prototype.setupEvents = function() {
|
||
_Game_Map_setupEvents.call(this,...arguments);
|
||
|
||
var events = this._events;
|
||
for(var i=events.length-1; i>=0; i=(i-1)|0){
|
||
var event = events[i];
|
||
if(!event)continue;
|
||
|
||
var charaName = event._characterName;
|
||
if(!charaName){
|
||
var eventData = event.event();
|
||
var page = eventData.pages ? eventData.pages[0] : null;
|
||
var image = page ? page.image : null;
|
||
charaName = image ? image.characterName : null;
|
||
}
|
||
if(charaName===MapDecorator.INFO_CHARACTER_NAME
|
||
|| charaName===MapDecorator.INFO_CHARACTER_Z_NAME
|
||
){
|
||
event.erase()
|
||
events[i] = null;
|
||
}
|
||
}
|
||
};
|
||
|
||
})();
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// main scope
|
||
//=============================================================================
|
||
(function(){
|
||
'use strict';
|
||
|
||
if(!Utils.isNwjs() || !Utils.isOptionValid('test'))return;
|
||
var pluginName = 'TRP_MapDecorator';
|
||
|
||
|
||
var _Dev = TRP_CORE.DevFuncs;
|
||
var MapDecorator = TRP_MapDecorator;
|
||
var MapObject = TRP_CORE.MapObject||null;
|
||
|
||
var isMZ = Utils.RPGMAKER_NAME === "MZ";
|
||
var isMac = navigator.userAgent.contains('Macintosh');
|
||
var ctrlKey = isMac ? 'Cmd' : 'Ctrl';
|
||
|
||
var supplementDef = TRP_CORE.supplementDef;
|
||
var supplementDefNum = TRP_CORE.supplementDefNum;
|
||
|
||
|
||
var parameters = PluginManager.parameters(pluginName);
|
||
var palettePageNum = Number(parameters.palettePageNum)||20;
|
||
|
||
|
||
//=============================================================================
|
||
// SETTING
|
||
//=============================================================================
|
||
var SETTING = MapDecorator.SETTING = {
|
||
|
||
// <<エディタ設定>>
|
||
//===================================
|
||
//編集時のマップ表示範囲[0以上の数値]
|
||
//└2.0とすると2倍の範囲表示(拡大率50%)<unit:0.1>
|
||
mapDispRange:1.0,
|
||
|
||
//編集時のウィンドウ幅。0=リサイズなし<unit:100>
|
||
windowWidth:1400,
|
||
|
||
//編集時のウィンドウ高さ。0=リサイズなし<unit:100>
|
||
windowHeight:900,
|
||
|
||
|
||
// <<プロセス設定>>
|
||
//===================================
|
||
//床の上マスに壁を自動配置[true/false]
|
||
autoWallSupply:true,
|
||
|
||
//壁の上マスに天井を自動配置[true/false]
|
||
autoCeilingSupply:true,
|
||
|
||
//空マスに天井タイル敷き詰め[true/false]
|
||
autoCeilingSupplyWithEmpty:false,
|
||
|
||
//天井設置に失敗しているかチェック[true/false]
|
||
checkCeilingCorrect:true,
|
||
|
||
//影を自動補完(解析したZ値マップから計算)[true/false]
|
||
autoShadowSupply:true,
|
||
|
||
//1以上でビッグオブジェをできるだけ敷き詰めるように配置。処理が重いので徐々に大きくすること
|
||
maximizeObjRateTryNum:0,
|
||
|
||
//割合算出の振れ幅[0.0~1.0]<unit:0.1>
|
||
rateRange:0.3,
|
||
|
||
|
||
|
||
// <<マップ設定>>
|
||
//===================================
|
||
//壁なし(主に遠景を使うマップ)[true/false]
|
||
noWall:false,
|
||
|
||
//壁+崖の高さを揃える[true/false]
|
||
arrangeTotalHeight:true,
|
||
|
||
//空マスを天井とみなして接続[true/false]
|
||
isEmptySpaceCeiling:false,
|
||
|
||
//壁・がけに影を落とさない[true/false]
|
||
noShadowOnWall:true,
|
||
|
||
//崖フチのオブジェ配置禁止の辺の数[1~]
|
||
criffTopObjForbiddenSideNum:1,
|
||
|
||
|
||
|
||
// <<ベース床設定>
|
||
//===================================
|
||
//床装飾を塗るベース割当[0~1.0]
|
||
floorPaintRate:0.4,
|
||
|
||
//床装飾の1箇所の最小タイル数[1~]
|
||
floorPaintChankMin:2,
|
||
//床装飾の1箇所の最大タイル数[1~]
|
||
floorPaintChankMax:10,
|
||
|
||
//0以上で床装飾のパターン数を固定、-1で床の広さに応じて算出
|
||
floorPaintPatternNum:-1,
|
||
|
||
//1部屋内で使用する床装飾の種類数の設定
|
||
// └設定例:[0,0,30,100,200]
|
||
// └29マス以下:2種, 30マス以上:3種, 100マス以上:4種, 200マス以上:5種
|
||
floorPaintPatternsWithTiles:[0,0,30,100,200],
|
||
|
||
//オブジェクトの配置割合[0~1.0]<unit:0.1>
|
||
floorObjRate:0.2,
|
||
//大オブジェクトの配置割合[0~1.0]<unit:0.1>
|
||
floorBigObjRate:0.01,
|
||
|
||
|
||
|
||
// <<水場設定>>
|
||
//================================================
|
||
//水場の配置モード[-1:自動,0:無効,1:強制配置]
|
||
waterLocateMode:-1,
|
||
|
||
//部屋に水場の配置する確率[0~1.0]<unit:0.1>
|
||
waterLocateRate:0.4,
|
||
|
||
//床面積に対する水場のベース割合[0~1.0]<unit:0.1>
|
||
waterPaintRate:0.15,
|
||
|
||
//水場1かたまりのタイル数の最小[1~]
|
||
waterChankMin:8,
|
||
//水場1かたまりのタイル数の最大[1~]
|
||
waterChankMax:18,
|
||
|
||
//水場の装飾タイルを塗るベース割合[0~1.0]<unit:0.1>
|
||
waterAccPaintRate:0.2,
|
||
|
||
//水場の装飾タイルの1かたまりのタイル数の最小[1~]
|
||
waterPaintChankMin:2,
|
||
//水場の装飾タイルの1かたまりのタイル数の最大[1~]
|
||
waterPaintChankMax:6,
|
||
|
||
//水場のオブジェクトの配置割合[0~1.0]<unit:0.1>
|
||
waterObjRate:0.15,
|
||
//水場の大オブジェクトの配置割合[0~1.0]<unit:0.1>
|
||
waterBigObjRate:0.0125,
|
||
|
||
//水場のフチにオブジェ配置許可[true/false]
|
||
waterObjOnEdge:true,
|
||
|
||
//水場の壁への接続を無効化[true/false]
|
||
diasbleWaterConnect:false,
|
||
|
||
|
||
// <<その他タイル設定>>
|
||
//===================================
|
||
//崖フチ上部の裏にタイルを補填(MZデフォタイル用)[true/false]
|
||
supplyUpperCriffTopBack:true,
|
||
|
||
|
||
|
||
};
|
||
//=============================================================================
|
||
|
||
|
||
|
||
var DEFAULT_SETTING = MapDecorator.DEFAULT_SETTING = SETTING;
|
||
var CURRENT_SETTING = MapDecorator.CURRENT_SETTING = SETTING;
|
||
|
||
MapDecorator.overwriteSettings = function(setting,validKeys=null){
|
||
if(!setting)return;
|
||
var keys = Object.keys(setting);
|
||
for(const key of keys){
|
||
this.overwriteSetting(key,setting[key],validKeys);
|
||
}
|
||
};
|
||
MapDecorator.overwriteSetting = function(key,value,validKeys=null,dstSetting=SETTING){
|
||
if(validKeys && !validKeys.contains(key)){
|
||
_Dev.showTempAlert('設定「%1」はこのコマンドでは無効です'.format(key));
|
||
return;
|
||
}
|
||
if(dstSetting===SETTING && dstSetting[key]===undefined){
|
||
_Dev.showTempAlert('設定「%1」はスペルミスの可能性があります。'.format(key));
|
||
}
|
||
dstSetting[key] = value;
|
||
};
|
||
|
||
MapDecorator.tryOverwriteSettingsWithList = function(list,index=0,command,validKeys,dstSetting){
|
||
if(!list)return;
|
||
|
||
var length = list.length;
|
||
var params = [];
|
||
for(var i=index; i<length;){
|
||
var command = list[i];
|
||
if(command.code === 105){
|
||
//scroll text
|
||
while(list[++i].code === 405){
|
||
params.push(list[i].parameters[0]);
|
||
}
|
||
}else if(command.code === 355){
|
||
//script
|
||
while(list[++i].code === 655){
|
||
params.push(list[i].parameters[0]);
|
||
}
|
||
}else{
|
||
i++;
|
||
}
|
||
}
|
||
|
||
for(var param of params){
|
||
if(param.indexOf('//')===0)continue;
|
||
var commentIdx = param.indexOf('//');
|
||
if(commentIdx>=0){
|
||
param = param.substring(0,commentIdx);
|
||
}
|
||
if(param.indexOf(':')<0)continue;
|
||
|
||
param = param.trim();
|
||
if(!param)continue;
|
||
|
||
if(param[param.length-1]===','){
|
||
param = param.substring(0,param.length-1);
|
||
}
|
||
|
||
var elems = param.split(':');
|
||
var key = elems[0];
|
||
var value = elems[1];
|
||
if(key===undefined || value===undefined)continue;
|
||
|
||
key = key.trim();
|
||
value = value.trim();
|
||
if(!isNaN(value)){
|
||
value = Number(elems[1]);
|
||
}else if(value==='false'){
|
||
value = false;
|
||
}else if(value==='true'){
|
||
value = true;
|
||
}else if(value[0]==='['||value[0]==='{'){
|
||
value = JSON.parse(value);
|
||
}
|
||
this.overwriteSetting(key,value,validKeys,dstSetting);
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Plugin Command
|
||
//=============================================================================
|
||
if(isMZ){
|
||
['start'].forEach(command=>PluginManager.registerCommand(pluginName, command, function(args){
|
||
var argsArr = Object.values(args)
|
||
argsArr.unshift(command);
|
||
MapDecorator.pluginCommand(argsArr,this);
|
||
}));
|
||
}
|
||
|
||
var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
|
||
Game_Interpreter.prototype.pluginCommand = function(command,args){
|
||
if(command===parameters.command){
|
||
MapDecorator.pluginCommand(args,this);
|
||
}else{
|
||
_Game_Interpreter_pluginCommand.call(this,...arguments);
|
||
}
|
||
};
|
||
|
||
MapDecorator.pluginCommand = function(args,interpreter){
|
||
var name = args[0];
|
||
var command = "processCommand"+name[0].toUpperCase()+name.substring(1)
|
||
this[command](args,interpreter);
|
||
};
|
||
|
||
MapDecorator.processCommandStart = function(args,interpreter){
|
||
var idx = 1;
|
||
var templateMapId = Number(args[idx++]);
|
||
var disableAutoSupply = TRP_CORE.supplementDefBool(false,args[idx++]);
|
||
if(!templateMapId || !$dataMapInfos[templateMapId]){
|
||
SoundManager.playBuzzer();
|
||
window.prompt('テンプレートマップIDが無効です。\ntemplateMapId:'+templateMapId);
|
||
return;
|
||
}
|
||
|
||
|
||
if(interpreter){
|
||
this.tryOverwriteSettingsWithList(interpreter._list,interpreter._index,'start');
|
||
}
|
||
DEFAULT_SETTING = MapDecorator.DEFAULT_SETTING = JsonEx.makeDeepCopy(SETTING);
|
||
CURRENT_SETTING = MapDecorator.CURRENT_SETTING = JsonEx.makeDeepCopy(SETTING);
|
||
|
||
|
||
MapDecorator.start(templateMapId,disableAutoSupply);
|
||
};
|
||
|
||
|
||
//=============================================================================
|
||
// env variables
|
||
//=============================================================================
|
||
var allInfo = null;
|
||
var info = null;
|
||
|
||
var ENV_VARS = {};
|
||
var data;
|
||
var width;
|
||
var height;
|
||
var zLayerSize;
|
||
var zRegion;
|
||
var zAcc;
|
||
var zObj1;
|
||
var zObj2;
|
||
var zShadow;
|
||
var zRegion;
|
||
|
||
var proc = null;
|
||
var undoLog = [];
|
||
var redoLog = [];
|
||
var originalData = null;
|
||
|
||
var baseTileIds = null;
|
||
var allFloorLevelTileIds = null;
|
||
var criffTopIds = null;
|
||
var ceilingBaseIds = null;
|
||
var criffWallBaseIds = null;
|
||
var allWallIds = null;
|
||
var allCeilingIds = null;
|
||
var allObjects = null;
|
||
|
||
var tileW = 48;
|
||
var tileH = 48;
|
||
function setupEnvVariables(dataMap,allInfo){
|
||
data = dataMap.data;
|
||
width = dataMap.width;
|
||
height = dataMap.height;
|
||
zLayerSize = width*height;
|
||
zAcc = 1*zLayerSize;
|
||
zObj1 = 2*zLayerSize;
|
||
zObj2 = 3*zLayerSize;
|
||
zShadow = 4*zLayerSize;
|
||
zRegion = 5*zLayerSize;
|
||
ENV_VARS = {
|
||
data,width,height,zLayerSize,zAcc,zObj1,zObj2,zShadow,zRegion
|
||
};
|
||
|
||
tileW = $gameMap.tileWidth();
|
||
tileH = $gameMap.tileHeight();
|
||
|
||
|
||
//allInfo cache
|
||
ceilingBaseIds = [];
|
||
allCeilingIds = [];
|
||
criffWallBaseIds = [];
|
||
baseTileIds = [];
|
||
allFloorLevelTileIds = [];
|
||
criffTopIds = [];
|
||
allWallIds = [];
|
||
allObjects = [];
|
||
for(const info of allInfo){
|
||
TRP_CORE.uniquePush(baseTileIds,info.floorBaseId);
|
||
TRP_CORE.uniquePush(allFloorLevelTileIds,info.floorBaseId);
|
||
|
||
if(info.floorVariationIds){
|
||
TRP_CORE.uniquePushArray(allFloorLevelTileIds,info.floorVariationIds);
|
||
}
|
||
if(info.dummyFloorVariationIds){
|
||
TRP_CORE.uniquePushArray(allFloorLevelTileIds,info.dummyFloorVariationIds);
|
||
}
|
||
if(info.waterBaseId){
|
||
TRP_CORE.uniquePush(allFloorLevelTileIds,info.waterBaseId);
|
||
}
|
||
if(info.waterAccIds){
|
||
TRP_CORE.uniquePushArray(allFloorLevelTileIds,info.waterAccIds);
|
||
}
|
||
|
||
if(info.criffTopBaseId){
|
||
criffTopIds.push(info.criffTopBaseId);
|
||
TRP_CORE.uniquePush(allFloorLevelTileIds,info.criffTopBaseId);
|
||
}
|
||
if(info.criffTopSubIds){
|
||
TRP_CORE.uniquePushArray(criffTopIds,info.criffTopSubIds);
|
||
}
|
||
|
||
if(info.ceilingBaseId){
|
||
TRP_CORE.uniquePush(ceilingBaseIds,info.ceilingBaseId);
|
||
TRP_CORE.uniquePush(allCeilingIds,info.ceilingBaseId);
|
||
}
|
||
if(info.criffWallBaseId){
|
||
TRP_CORE.uniquePush(criffWallBaseIds,info.criffWallBaseId);
|
||
}
|
||
if(info.wallTileIds){
|
||
TRP_CORE.uniquePushArray(allWallIds,info.wallTileIds);
|
||
}
|
||
|
||
if(info.allObjIds){
|
||
TRP_CORE.uniquePushArray(allObjects,info.allObjIds);
|
||
}
|
||
}
|
||
TRP_CORE.removeArray(allObjects,MapDecorator.paletteObjects);
|
||
};
|
||
|
||
var INFO_SETTINGS = {};
|
||
MapDecorator.changeBaseInfo = function(target){
|
||
info = target;
|
||
|
||
if(!INFO_SETTINGS[info.floorBaseId]){
|
||
var setting = JsonEx.makeDeepCopy(CURRENT_SETTING);
|
||
INFO_SETTINGS[info.floorBaseId] = setting;
|
||
|
||
SETTING = INFO_SETTINGS[info.floorBaseId];
|
||
this.overwriteSettings(info.setting);
|
||
}else{
|
||
SETTING = INFO_SETTINGS[info.floorBaseId];
|
||
}
|
||
MapDecorator.SETTING = SETTING;
|
||
};
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Start
|
||
//=============================================================================
|
||
MapDecorator._mode = null;
|
||
MapDecorator._lastModes = [];
|
||
MapDecorator._playerMoveByInput = null;
|
||
MapDecorator._sceneUpDate = null;
|
||
MapDecorator._keyDownListener = null;
|
||
MapDecorator._keyUpListener = null;
|
||
MapDecorator._mouseDownListener = null;
|
||
MapDecorator._mouseUpListener = null;
|
||
MapDecorator._pasteListener = null;
|
||
MapDecorator.allInfo = null;
|
||
MapDecorator.start = function(templateMapId,disableAutoSupply=false){
|
||
this.setupScreen();
|
||
|
||
if(MapObject){
|
||
if(!MapObject.isOverlayEnabled()){
|
||
_Dev.showText('mapObjOverlayAlert',[
|
||
'MapObjectのオーバーレイ表示が無効です。',
|
||
'関連オブジェクトを正しく配置・保存できません。'
|
||
],'rgb(255,100,100)');
|
||
}
|
||
MapObject.disableSpritesheet();
|
||
}
|
||
|
||
var help = [ctrlKey+'+S:マップ保存'];
|
||
if(MapObject){
|
||
help.push(ctrlKey+'Shift+S:遠景モックで保存');
|
||
}
|
||
help.push(
|
||
'Esc:メニュー呼び出し',
|
||
'Space:パラメータ設定',
|
||
(isMac?'Opt':'Alt')+'+ドラッグ:スクロール',
|
||
);
|
||
_Dev.showText('decoratorBase',help);
|
||
|
||
|
||
/* player setting
|
||
===================================*/
|
||
$gamePlayer._transparent = true;
|
||
if($gamePlayer._followers){
|
||
$gamePlayer._followers.update();
|
||
}
|
||
SceneManager._scene._spriteset.update();
|
||
|
||
this._playerMoveByInput = $gamePlayer.moveByInput;
|
||
$gamePlayer.moveByInput = (()=>{});
|
||
if($gamePlayer._followers){
|
||
$gamePlayer._followers.update();
|
||
}
|
||
|
||
|
||
SceneManager._scene._spriteset.update();
|
||
|
||
|
||
/* scene setting
|
||
===================================*/
|
||
this._sceneUpDate = SceneManager._scene.update;
|
||
SceneManager._scene.update = ()=>{
|
||
this.update();
|
||
if(SceneManager._scene.updateTrpMousePosition){
|
||
SceneManager._scene.updateTrpMousePosition();
|
||
}
|
||
};
|
||
|
||
|
||
/* register listners
|
||
===================================*/
|
||
this._keyDownListener = this.onKeyDown.bind(this);
|
||
this._keyUpListener = (event=>{
|
||
this.disableLastStateOverwritable();
|
||
|
||
if(event.key==='Alt'){
|
||
this.onKeyAlt = false;
|
||
TRP_CORE.changeMouseCursor(this.CURSOR_BITMAP[this._mode]);
|
||
}else if(event.key==='Meta'){
|
||
this.onKeyMeta = false;
|
||
}else if(event.key==='Control'){
|
||
this.onKeyControl = false;
|
||
if(this.showingObjOutline){
|
||
this.removeObjectsOutline();
|
||
}
|
||
}
|
||
});
|
||
this._mouseDownListener = this.onMouseDown.bind(this);
|
||
this._mouseUpListener = this.onMouseUp.bind(this);
|
||
this._pasteListener = this.onPaste.bind(this);
|
||
document.addEventListener('keydown',this._keyDownListener);
|
||
document.addEventListener('keyup',this._keyUpListener);
|
||
document.addEventListener('mousedown',this._mouseDownListener);
|
||
document.addEventListener('mouseup',this._mouseUpListener);
|
||
document.addEventListener('paste',this._pasteListener);
|
||
|
||
|
||
/* disable interpreter command
|
||
===================================*/
|
||
Game_Interpreter.prototype.command105 = function(){
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
/* prepare variables
|
||
===================================*/
|
||
allInfo = this.analyzeTemplate(templateMapId);
|
||
this.allInfo = allInfo;
|
||
this.setupProcessWindowCommands();
|
||
|
||
setupEnvVariables($dataMap,allInfo);
|
||
this._clearSceneFade();
|
||
|
||
this.executeInitProcess();
|
||
|
||
|
||
/* start room select
|
||
===================================*/
|
||
this.setMode('paintFloor');
|
||
this.saveState('開始');
|
||
|
||
|
||
//check ceiling correct -> tonner error idxes
|
||
if(SETTING.checkCeilingCorrect){
|
||
this.checkCeilingCorrect();
|
||
}
|
||
};
|
||
MapDecorator.executeInitProcess = function(disableAutoSupply){
|
||
this.initProc();
|
||
this.analyzeAll();
|
||
if(MapObject){
|
||
this.analyzeMapObjects();
|
||
}
|
||
|
||
/* supply tiles
|
||
===================================*/
|
||
this.executeBeforeProcess(disableAutoSupply);
|
||
this.analyzeTileObjects();
|
||
};
|
||
|
||
|
||
MapDecorator.setupScreen = function(){
|
||
var mapDispRange = Number(SETTING.mapDispRange)||1.0
|
||
var windowW = Number(SETTING.windowWidth);
|
||
var windowH = Number(SETTING.windowHeight);
|
||
if(!windowW || windowW<=0){
|
||
windowW = Graphics.width;
|
||
}
|
||
if(!windowH || windowH<=0){
|
||
windowH = Graphics.height;
|
||
}
|
||
|
||
|
||
SETTING.mapDispRange = mapDispRange;
|
||
SETTING.windowWidth = windowW;
|
||
SETTING.windowHeight = windowH;
|
||
|
||
if(windowW!==Graphics.width || windowH!==Graphics.height){
|
||
_Dev.resizeWindow(windowW,windowH);
|
||
}
|
||
|
||
|
||
var rate = SETTING.mapDispRange;
|
||
var zoom = 1/rate;
|
||
var sprset = SceneManager._scene._spriteset;
|
||
var tilemap = sprset._tilemap;
|
||
|
||
var width = rate*Graphics.width;
|
||
var height = rate*Graphics.height;
|
||
|
||
tilemap._width = width+tilemap._margin*2;
|
||
tilemap._height = height+tilemap._margin*2;
|
||
var tileCols = Math.ceil(tilemap._width / tilemap._tileWidth) + 1;
|
||
var tileRows = Math.ceil(tilemap._height / tilemap._tileHeight) + 1;
|
||
var layerWidth = tilemap._layerWidth = tileCols * tilemap._tileWidth;
|
||
var layerHeight = tilemap._layerHeight = tileRows * tilemap._tileHeight;
|
||
tilemap._needsRepaint = true;
|
||
|
||
var container = new TRP_CORE.TRP_Container();
|
||
container.addChild(SceneManager._scene._spriteset);
|
||
container.scale.set(zoom,zoom);
|
||
SceneManager._scene.addChild(container);
|
||
|
||
|
||
if(MapObject){
|
||
$dataTrpMapObjects.forEach(obj=>{obj.setupMargin()})
|
||
}
|
||
};
|
||
|
||
|
||
|
||
MapDecorator.analyzeAll = function(){
|
||
proc.idxBaseInfoIdxMap = TRP_CORE.packValues([],0,zLayerSize);
|
||
this.analyzeRooms();
|
||
this.analyzeFloorZMap();
|
||
this.analyzeWallIdxes();
|
||
this.analyzeCeilingIdxes();
|
||
};
|
||
|
||
MapDecorator.proc = null;
|
||
MapDecorator.initProc = function(){
|
||
// _Dev.showText('roomInfo','《対象の部屋ID:--》');
|
||
originalData = data.concat();
|
||
|
||
proc = MapDecorator.proc = {};
|
||
|
||
proc.allRoomIdxes = [];
|
||
proc.roomIdxMapForUserProc = [];
|
||
proc.allBaseIdxes = [];
|
||
proc.idxBaseInfoIdxMap = [];
|
||
proc.wallIdxMap = [];
|
||
proc.wallIdxes = [];
|
||
proc.ceilingIdxes = [];
|
||
proc.zMap = [];
|
||
proc.floorLevelZMap = [];
|
||
proc.minZ = 0;
|
||
proc.maxZ = 0;
|
||
|
||
proc.waterIdxes = [];
|
||
proc.waterAccIdxes = [];
|
||
proc.passIdxes = [];
|
||
proc.criffIdxes = [];
|
||
proc.criffTopIdxes = [];
|
||
proc.criffWallIdxes = [];
|
||
|
||
proc.floorSuppliedIdxes = [];
|
||
|
||
proc.oncePaintFloor = false;
|
||
proc.lockedFloorPaintRoomIds = [];
|
||
proc.lastFloorPaintInfoArr = [];
|
||
proc.lockedFloorVariations = [];
|
||
proc.lastFloorVariations = [];
|
||
proc.noAccIdxes = [];
|
||
proc.noConnectMap = {};
|
||
proc.connectFloorIdxes = [];
|
||
proc.autoConnectRequestIdxes = [];
|
||
|
||
proc.lockedWaterRoomIds = [];
|
||
proc.lastWaterInfoArr = [];
|
||
|
||
proc.locateObj = false;
|
||
proc.lockedObjRoomIds = [];
|
||
proc.lastObjInfoArr = [];
|
||
proc.leftObjIdxesArr = [];
|
||
proc.objForbiddenIdxes = [];
|
||
}
|
||
|
||
|
||
MapDecorator.end = function(){
|
||
this.setMode(null);
|
||
_Dev.showText('roomInfo',null);
|
||
_Dev.showText('mapDec',null);
|
||
|
||
$gamePlayer._transparent = false;
|
||
$gamePlayer.moveByInput = this._playerMoveByInput;
|
||
this._playerMoveByInput = null;
|
||
|
||
SceneManager._scene.update = this._sceneUpDate;
|
||
this._sceneUpDate = null;
|
||
|
||
document.removeEventListener('keydown',this._keyDownListener);
|
||
document.removeEventListener('keyup',this._keyUpListener);
|
||
document.removeEventListener('mousedown',this._mouseDownListener);
|
||
document.removeEventListener('mouseup',this._mouseUpListener);
|
||
document.removeEventListener('paste',this._pasteListener);
|
||
this._keyDownListener = null;
|
||
this._keyUpListener = null;
|
||
this._mouseDownListener = null;
|
||
this._mouseUpListener = null;
|
||
this._pasteListener = null;
|
||
};
|
||
|
||
|
||
MapDecorator._clearSceneFade = function(){
|
||
var scene = SceneManager._scene;
|
||
scene._fadeDuration = 0;
|
||
scene._fadeOpacity = 0;
|
||
if(scene.updateColorFilter){
|
||
scene.updateColorFilter();
|
||
}
|
||
};
|
||
|
||
MapDecorator.setupProcessWindowCommands = function(){
|
||
var groups = [];
|
||
for(var i=1; i<MapDecorator.procGroupId; i=(i+1)|0){
|
||
groups.push(['group:'+i,'グループ:'+i]);
|
||
}
|
||
groups.push(['afterSupply','自動']);
|
||
|
||
|
||
var commands = [];
|
||
for(const group of groups){
|
||
commands.push({
|
||
name:'置換プロセス:'+group[1],
|
||
type:'script',
|
||
param:"TRP_MapDecorator.startUserProcessMode('%1',true)".format(group[0])
|
||
,key:'',
|
||
closeWindow:true,
|
||
});
|
||
commands.push({
|
||
name:'└抽選モード',
|
||
type:'script',
|
||
param:"TRP_MapDecorator.startUserProcessMode('%1')".format(group[0])
|
||
,key:'',
|
||
closeWindow:true,
|
||
});
|
||
}
|
||
|
||
_Dev.registerToolCommands({
|
||
key:'',
|
||
id:'decorator:processList',
|
||
name:'プロセスリスト',
|
||
commands,
|
||
});
|
||
};
|
||
|
||
|
||
MapDecorator.executeBeforeProcess = function(disableAutoSupply){
|
||
if(!disableAutoSupply){
|
||
this.processMapCriff();
|
||
|
||
if(SETTING.autoWallSupply){
|
||
this.supplyWalls();
|
||
}
|
||
if(SETTING.autoCeilingSupply){
|
||
this.supplyCeilings();
|
||
}
|
||
if(SETTING.autoShadowSupply){
|
||
this.supplyShadows();
|
||
}
|
||
if(this.processUserProcessList('afterSupply',null,true)){
|
||
_Dev.showTempAlert([
|
||
'《自動ユーザープロセスを実行しました!》',
|
||
'「Esc→手動プロセス実行→前処理の取り消し」で取消'
|
||
]);
|
||
}
|
||
}
|
||
|
||
originalData = data.concat();
|
||
this.requestRefreshTilemap();
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Mode / Update
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE = {};
|
||
MapDecorator.setMode = function(mode,modeData=null){
|
||
if(this._mode === mode)return;
|
||
Input.clear();
|
||
|
||
var lastMode = this._mode;
|
||
if(lastMode){
|
||
this.endMode();
|
||
}
|
||
|
||
this.modeData = modeData;
|
||
this.modeUICache = {};
|
||
this.tryReleaseTonnerSprite();
|
||
this.clearShowingPalette();
|
||
this.cantShowMenu = false;
|
||
this.cantScroll = false;
|
||
|
||
this.showParamEditor(mode);
|
||
TRP_CORE.changeMouseCursor(this.CURSOR_BITMAP[mode]);
|
||
|
||
if(mode==='paintFloor'||mode==='locateObject'){
|
||
this._lastModes.length = 0;
|
||
}
|
||
if(![null,'zMap','zMapError','wallIdx','mapObjectCollision','objectPalette','userProcess','roomSelect',
|
||
'objctSelect','objectGrouping',
|
||
'playerMove','tilesetEdit'].contains(lastMode))
|
||
{
|
||
this._lastModes.push(lastMode);
|
||
}
|
||
if(['objectGrouping','objectSelect','playerMove','tilesetEdit'].contains(mode)){
|
||
this.cantShowMenu = true;
|
||
}
|
||
|
||
this._mode = mode;
|
||
|
||
//refreshGuideText
|
||
var refreshGuide = 'refreshGuide'+TRP_CORE.capitalize(mode);
|
||
if(this[refreshGuide]){
|
||
this[refreshGuide]();
|
||
}else{
|
||
var guide = MapDecorator.MODE_GUIDE[mode]||null;
|
||
_Dev.showText('modeGuide',guide);
|
||
}
|
||
|
||
var setModeFunc = 'setMode'+TRP_CORE.capitalize(mode);
|
||
if(this[setModeFunc]){
|
||
this[setModeFunc]();
|
||
}
|
||
};
|
||
|
||
|
||
MapDecorator.endMode = function(){
|
||
if(!this._mode)return;
|
||
var endHandler = 'endMode'+TRP_CORE.capitalize(this._mode);
|
||
if(this[endHandler]){
|
||
this[endHandler]();
|
||
}
|
||
|
||
if(this.showingObjOutline){
|
||
this.removeObjectsOutline();
|
||
}
|
||
this._mode = null;
|
||
this.hideParamEditor();
|
||
};
|
||
|
||
MapDecorator.restoreMode = function(noSaveState=false){
|
||
var mode = this._lastModes.pop();
|
||
if(!mode)return;
|
||
|
||
this.endMode();
|
||
this.setMode(mode);
|
||
|
||
if(!noSaveState){
|
||
this.saveState('モード終了');
|
||
}
|
||
};
|
||
|
||
MapDecorator.CURSOR_BITMAP = {};
|
||
(()=>{
|
||
var iconIds = parameters.cursorIcons ? parameters.cursorIcons.split(',') : [217,246,129,142];
|
||
if(!iconIds)return;
|
||
|
||
var iconSet = ImageManager.loadSystem('IconSet');
|
||
var w = 24;
|
||
var h = 24;
|
||
|
||
iconSet.addLoadListener(()=>{
|
||
for(var i=0; i<4; i=(i+1)|0){
|
||
var iconId = Number(iconIds[i]);
|
||
if(!iconId)continue;
|
||
|
||
var mode;
|
||
if(i===0)mode = 'paintFloor';
|
||
else if(i===1)mode = 'manualPaint';
|
||
else if(i===2)mode = 'locateObject';
|
||
else mode = 'manualLocate';
|
||
|
||
|
||
var bitmap = new Bitmap(w,h);
|
||
var pw = ImageManager.iconWidth;
|
||
var ph = ImageManager.iconHeight;
|
||
var sx = (iconId % 16) * pw;
|
||
var sy = Math.floor(iconId / 16) * ph;
|
||
|
||
var tw = w-4;
|
||
var th = h-4;
|
||
var tx = w-tw;
|
||
var ty = h-th;
|
||
TRP_CORE.bltImage(bitmap,iconSet,sx,sy,pw,ph,tx,ty,tw,th);
|
||
|
||
var ctx = bitmap._context;
|
||
ctx.save();
|
||
ctx.beginPath();
|
||
ctx.moveTo(0,0);
|
||
ctx.lineTo(w/2,0);
|
||
ctx.lineTo(0,h/2);
|
||
ctx.lineTo(0,0);
|
||
ctx.closePath();
|
||
ctx.strokeStyle = 'white';
|
||
ctx.lineWidth = 2;
|
||
ctx.fillStyle = 'rgb(50,50,50)';
|
||
ctx.fill();
|
||
ctx.stroke();
|
||
ctx.restore();
|
||
|
||
bitmap._canvas.toBlob(function(mode,blob){
|
||
var url = URL.createObjectURL(blob);;
|
||
MapDecorator.CURSOR_BITMAP[mode] = 'url("'+url+'"),auto';
|
||
// URL.revokeObjectURL(url)
|
||
}.bind(this,mode), 'image/png');
|
||
}
|
||
});
|
||
})();
|
||
|
||
MapDecorator.onPaste = function(e){
|
||
if(this.paramEditor && this.paramEditor.active){
|
||
this.onPasteParamEditor(e);
|
||
}
|
||
};
|
||
|
||
|
||
MapDecorator.onKeyControl = false;
|
||
MapDecorator.onKeyMeta = false;
|
||
MapDecorator.onKeyAlt = false;
|
||
MapDecorator.onKeyDown = function(event){
|
||
if(event.key==='Alt'){
|
||
this.onKeyAlt = true;
|
||
TRP_CORE.changeMouseCursor('move');
|
||
}else if(event.key==='Meta'){
|
||
this.onKeyMeta = true;
|
||
}else if(event.key==='Control'){
|
||
this.onKeyControl = true;
|
||
}
|
||
if(!event.ctrlKey){
|
||
this.onKeyControl = false;
|
||
}
|
||
|
||
if(this.onKeyMeta && event.key==='1'){
|
||
this.devTest();
|
||
}
|
||
|
||
|
||
if(_Dev.showingToolsWindow)return false;
|
||
if(this._pickingColor){
|
||
return this.onKeyDownPickingColor(event);
|
||
}
|
||
|
||
var exUIActive = false;
|
||
if(this.showingPalette){
|
||
exUIActive = true;
|
||
this.onKeyDownPalette(event);
|
||
}
|
||
if(this.paramEditor && this.paramEditor.active){
|
||
this.onKeyDownParamEditor(event);
|
||
return;
|
||
}
|
||
|
||
if(this.onKeyAlt)return;
|
||
|
||
if(!exUIActive){
|
||
if(MapObject && !this.showingObjOutline){
|
||
if(event.key==='Control' && !$dataTrpMapObjects.some(obj=>obj&&obj._devOutlineFilter)){
|
||
this.setObjectsOutline();
|
||
}
|
||
}
|
||
|
||
if(event.code === 'Space'){
|
||
//paramEditor
|
||
this.tryActivateParamEditor();
|
||
}else if(event.metaKey || event.ctrlKey){
|
||
if(event.key === 't'){
|
||
if(MapObject){
|
||
this.tryAnalyzeOtherTilesetObjects();
|
||
}
|
||
return true;
|
||
}else if(event.key.toLowerCase() === 's'){
|
||
if(this.isSaveEnabled()){
|
||
this.processSave(event.shiftKey);
|
||
}else{
|
||
SoundManager.playBuzzer();
|
||
}
|
||
return true;
|
||
}else if(event.key.toLowerCase() === 'z'){
|
||
if(event.shiftKey){
|
||
this.tryRedo();
|
||
}else{
|
||
this.tryUndo();
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
var command = this._mode ? 'onKeyDown'+TRP_CORE.capitalize(this._mode) : null;
|
||
if(command && this[command]){
|
||
this[command](event);
|
||
return true;
|
||
}
|
||
};
|
||
|
||
MapDecorator.isSaveEnabled = function(){
|
||
if(this.showingPalette)return false;
|
||
|
||
|
||
switch(this._mode){
|
||
case 'roomSelect':
|
||
case 'zMap':
|
||
case 'zMapError':
|
||
case 'objectSelect':
|
||
case 'objectGrouping':
|
||
return false;
|
||
default:
|
||
return true;
|
||
}
|
||
};
|
||
|
||
|
||
MapDecorator.processSave = function(parallaxSave=false){
|
||
if(parallaxSave && !TRP_CORE.isMapMockEnabled()){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
|
||
//save mapObject
|
||
if(MapObject){
|
||
var noLink = parallaxSave;
|
||
this.saveMapObjectData(noLink);
|
||
}
|
||
if(parallaxSave){
|
||
this.saveAsParallaxMock();
|
||
}else{
|
||
_Dev.saveMapFile();
|
||
}
|
||
};
|
||
MapDecorator.restoreFromBackup = function(){
|
||
_Dev.restoreFromBackup(()=>{
|
||
this.reloadMapData(true);
|
||
});
|
||
}
|
||
|
||
|
||
MapDecorator.roomIdxOfTouchInput = function(){
|
||
var tx = TouchInput.x;
|
||
var ty = TouchInput.y;
|
||
var dx = Math.floor($gameMap._displayX*tileW + tx*SETTING.mapDispRange);
|
||
var dy = Math.floor($gameMap._displayY*tileH + ty*SETTING.mapDispRange);
|
||
var x = Math.floor(dx/tileW);
|
||
var y = Math.floor(dy/tileH);
|
||
var idx = x+y*width;
|
||
return idxOfRoom(idx);
|
||
};
|
||
|
||
|
||
MapDecorator.mouseScrolling = null;
|
||
MapDecorator.onMouseDown = function(event){
|
||
if(_Dev.showingToolsWindow)return;
|
||
if(this._pickingColor)return;
|
||
if(this.paramEditor && this.paramEditor.active)return;
|
||
|
||
|
||
var tx = Graphics.pageToCanvasX(event.pageX);
|
||
var ty = Graphics.pageToCanvasY(event.pageY);
|
||
|
||
if(this.onKeyAlt){
|
||
//scrolling
|
||
this.mouseScrolling = {tx,ty,spdX:0,spdY:0,spdXArr:[],spdYArr:[]};
|
||
return;
|
||
}
|
||
|
||
|
||
var dx = Math.floor($gameMap._displayX*tileW + tx*SETTING.mapDispRange);
|
||
var dy = Math.floor($gameMap._displayY*tileH + ty*SETTING.mapDispRange);
|
||
var x = Math.floor(dx/tileW);
|
||
var y = Math.floor(dy/tileH);
|
||
dx -= x*tileW;
|
||
dy -= y*tileH;
|
||
|
||
var idx = x+y*width;
|
||
var roomId = idxOfRoom(idx);
|
||
|
||
var name = null;
|
||
if(event.button===0)name = 'Left';
|
||
else if(event.button===1)name = 'Middle';
|
||
else if(event.button===2)name = 'Right';
|
||
|
||
var command = this._mode ? ('onMouseDown'+name+TRP_CORE.capitalize(this._mode)) : null;
|
||
if(!command || !this[command])return;
|
||
this[command](event,roomId,x,y,tx,ty,dx,dy);
|
||
};
|
||
MapDecorator.onMouseUp = function(event){
|
||
var tx = Graphics.pageToCanvasX(event.pageX);
|
||
var ty = Graphics.pageToCanvasY(event.pageY);
|
||
|
||
if(event.button!==0)return;
|
||
|
||
if(this.modeData && this.modeData.onDraggingLocateObj){
|
||
this.modeData.onDraggingLocateObj = null;
|
||
if(this.draggingGrid){
|
||
this.draggingGrid.visible = false;
|
||
}
|
||
}
|
||
this.disableLastStateOverwritable();
|
||
|
||
if(this.showingPalette){
|
||
this.onMouseUpLeftShowingPalette(event,tx,ty);
|
||
}
|
||
|
||
|
||
var command = this._mode ? ('onMouseUp'+TRP_CORE.capitalize(this._mode)) : null;
|
||
if(!command || !this[command])return;
|
||
|
||
var dx = Math.floor($gameMap._displayX*tileW + tx*SETTING.mapDispRange);
|
||
var dy = Math.floor($gameMap._displayY*tileH + ty*SETTING.mapDispRange);
|
||
var x = Math.floor(dx/tileW);
|
||
var y = Math.floor(dy/tileH);
|
||
dx -= x*tileW;
|
||
dy -= y*tileH;
|
||
|
||
var idx = x+y*width;
|
||
var roomId = idxOfRoom(idx);
|
||
this[command](event,roomId,x,y,tx,ty,dx,dy);
|
||
};
|
||
|
||
MapDecorator.tryCallOnMousePress = function(){
|
||
var tx = TouchInput.x;
|
||
var ty = TouchInput.y;
|
||
|
||
if(this.showingPalette){
|
||
this.onMousePressPalette(tx,ty);
|
||
return;
|
||
}
|
||
|
||
|
||
var command = this._mode ? 'onMousePress'+TRP_CORE.capitalize(this._mode) : null;
|
||
if(!command || !this[command])return;
|
||
|
||
var dx = Math.floor($gameMap._displayX*tileW + tx*SETTING.mapDispRange);
|
||
var dy = Math.floor($gameMap._displayY*tileH + ty*SETTING.mapDispRange);
|
||
var x = Math.floor(dx/tileW);
|
||
var y = Math.floor(dy/tileH);
|
||
dx -= x*tileW;
|
||
dy -= y*tileH;
|
||
|
||
// var x = Math.floor($gameMap._displayX+tx/48*SETTING.mapDispRange);
|
||
// var y = Math.floor($gameMap._displayY+ty/48*SETTING.mapDispRange);
|
||
var idx = x+y*width;
|
||
var roomId = idxOfRoom(idx);
|
||
|
||
this[command](null,roomId,x,y,tx,ty,dx,dy);
|
||
}
|
||
|
||
|
||
MapDecorator.updateList = [];
|
||
MapDecorator.update = function(){
|
||
_Dev.updateTexts();
|
||
|
||
if(this._pickingColor){
|
||
this.updateColorPicker();
|
||
return;
|
||
}
|
||
if(this.paramEditor && this.paramEditor.active){
|
||
this.paramEditor.update();
|
||
if(TouchInput.isCancelled()
|
||
|| (TouchInput.isTriggered() && this.paramEditor.notTouching)
|
||
){
|
||
this.tryDeactivateParamEditor();
|
||
}
|
||
return;
|
||
}
|
||
if(this.draggingGrid && this.draggingGrid.visible){
|
||
this.updateDraggingGrid();
|
||
}
|
||
if(this.mouseScrolling){
|
||
this.updateMouseScrolling();
|
||
}
|
||
|
||
this.updateWheel();
|
||
|
||
/* update input
|
||
===================================*/
|
||
if(Input._latestButton){
|
||
var updateInput = this._mode ? "updateInput"+TRP_CORE.capitalize(this._mode) : null;
|
||
if(updateInput && this[updateInput] && this[updateInput]()){
|
||
//mode input
|
||
}else if(Input.isTriggered('cancel')){
|
||
if(!this.cantShowMenu){
|
||
this.showMenu();
|
||
}
|
||
}else if(this.updateScroll()){
|
||
//scrolled
|
||
}
|
||
}
|
||
|
||
|
||
/* update main
|
||
===================================*/
|
||
var command = 'update'+TRP_CORE.capitalize(this._mode);
|
||
if(this[command])this[command]();
|
||
|
||
|
||
/* mouse press
|
||
===================================*/
|
||
if(TouchInput.isPressed() && !this.mouseScrolling){
|
||
this.tryCallOnMousePress();
|
||
}
|
||
|
||
|
||
/* main mode update
|
||
===================================*/
|
||
var command = this._mode ? "update"+TRP_CORE.capitalize(this._mode) : null;
|
||
if(command && this[command]){
|
||
this[command]();
|
||
}
|
||
|
||
/* extra registered update objects
|
||
===================================*/
|
||
for(var i=MapDecorator.updateList.length-1; i>=0; i=(i-1)|0){
|
||
MapDecorator.updateList[i].update();
|
||
}
|
||
|
||
|
||
/* update trpMapObjects
|
||
===================================*/
|
||
if(MapObject){
|
||
SceneManager._scene._spriteset.updateTrpMapObjects();
|
||
$dataTrpMapObjects.forEach(obj=>{
|
||
if(obj.sprite)obj.sprite.update();
|
||
});
|
||
}
|
||
};
|
||
|
||
|
||
MapDecorator.wheelThreshold = 4;
|
||
MapDecorator.updateWheel = function(){
|
||
var value = TouchInput.wheelY;
|
||
if(!value)return;
|
||
|
||
var command = 'onWheelValueChange'+TRP_CORE.capitalize(this._mode);
|
||
if(this.showingPalette){
|
||
this.onWheelValueChangePalette(value);
|
||
}else if(this[command]){
|
||
this[command](value);
|
||
}
|
||
|
||
|
||
var idx = Math.floor(value/this.wheelThreshold);
|
||
if(idx){
|
||
var command = 'onWheelIdxChange'+TRP_CORE.capitalize(this._mode);
|
||
if(this.showingPalette){
|
||
// this.onWheelIdxChangePalette(idx);
|
||
}else if(this[command]){
|
||
this[command](idx);
|
||
}
|
||
}
|
||
};
|
||
|
||
/* menu
|
||
===================================*/
|
||
MapDecorator.cantShowMenu = false;
|
||
MapDecorator.showMenu = function(){
|
||
_Dev.showToolsWindowWithId('decorator:main');
|
||
SoundManager.playCancel();
|
||
};
|
||
|
||
(()=>{
|
||
//register main menu
|
||
var commands = [];
|
||
|
||
/* category:display analyze values
|
||
===================================*/
|
||
commands.push({
|
||
name:'解析値の表示',
|
||
type:'window',
|
||
param:'decorator:show'
|
||
,key:'',
|
||
closeWindow:true,
|
||
});
|
||
var analyzeCommands = [{
|
||
name:'Z値マップの表示',
|
||
type:'script',
|
||
param:'TRP_MapDecorator.showZMap();'
|
||
,key:'',
|
||
closeWindow:true,
|
||
|
||
},{
|
||
name:'壁IndexMapの表示',
|
||
type:'script',
|
||
param:'TRP_MapDecorator.showWallIdxMap();'
|
||
,key:'',
|
||
closeWindow:true,
|
||
}];
|
||
if(MapObject){
|
||
analyzeCommands.push({
|
||
name:'スプライトオブジェ衝突判定',
|
||
type:'script',
|
||
param:'TRP_MapDecorator.showMapObjectCollisions();'
|
||
,key:'',
|
||
closeWindow:true,
|
||
});
|
||
}
|
||
_Dev.registerToolCommands({
|
||
key:'',
|
||
id:'decorator:show',
|
||
name:'メインメニュー',
|
||
commands:analyzeCommands
|
||
});
|
||
|
||
|
||
commands.push({
|
||
name:'移動テスト',
|
||
type:'script',
|
||
param:'TRP_MapDecorator.setMode("playerMove");'
|
||
,key:'',
|
||
closeWindow:true,
|
||
});
|
||
|
||
|
||
//selectRoomTarget
|
||
commands.push({
|
||
name:'編集対象の部屋を指定',
|
||
type:'script',
|
||
param:'TRP_MapDecorator.startRoomSelect()'
|
||
,key:'',
|
||
closeWindow:true,
|
||
});
|
||
|
||
|
||
|
||
/* category:manual process
|
||
===================================*/
|
||
commands.push({
|
||
name:'手動プロセス実行',
|
||
type:'window',
|
||
param:'decorator:manual'
|
||
,key:'',
|
||
closeWindow:true,
|
||
});
|
||
_Dev.registerToolCommands({
|
||
key:'',
|
||
id:'decorator:manual',
|
||
name:'手動プロセス実行',
|
||
commands:[{
|
||
name:'全処理の取り消し',
|
||
type:'script',
|
||
param:'TRP_MapDecorator.reloadMapData(true);'
|
||
,key:'',
|
||
closeWindow:false,
|
||
},{
|
||
name:'崖の自動処理',
|
||
type:'script',
|
||
param:`
|
||
TRP_MapDecorator.processMapCriff();
|
||
TRP_MapDecorator.requestRefreshTilemap();
|
||
TRP_MapDecorator.saveState('崖の自動処理');
|
||
`
|
||
,key:'',
|
||
closeWindow:false,
|
||
},{
|
||
name:'壁の自動補完',
|
||
type:'script',
|
||
param:`
|
||
TRP_MapDecorator.supplyWalls();
|
||
TRP_MapDecorator.requestRefreshTilemap();
|
||
TRP_MapDecorator.saveState('壁の自動補完');
|
||
`
|
||
,key:'',
|
||
closeWindow:false,
|
||
},{
|
||
name:'天井の自動補完',
|
||
type:'script',
|
||
param:`
|
||
TRP_MapDecorator.supplyCeilings();
|
||
TRP_MapDecorator.requestRefreshTilemap();
|
||
TRP_MapDecorator.saveState('天井の自動補完');
|
||
`
|
||
,key:'',
|
||
closeWindow:false,
|
||
},{
|
||
name:'影の自動補完/+Shift->クリア',
|
||
type:'script',
|
||
param:`
|
||
TRP_MapDecorator.clearShadows();
|
||
if(!Input.isPressed("shift")){
|
||
TRP_MapDecorator.supplyShadows();
|
||
}
|
||
TRP_MapDecorator.saveState('影の処理');
|
||
`
|
||
,key:'',
|
||
closeWindow:false,
|
||
}]
|
||
});
|
||
|
||
|
||
/* category:processList
|
||
===================================*/
|
||
commands.push({
|
||
name:'置換プロセスの手動実行',
|
||
type:'window',
|
||
param:'decorator:processList'
|
||
,key:'',
|
||
closeWindow:true,
|
||
});
|
||
|
||
commands.push({
|
||
name:'バックアップから復元',
|
||
type:'script',
|
||
param:'TRP_MapDecorator.restoreFromBackup();'
|
||
,key:'',
|
||
closeWindow:true,
|
||
});
|
||
|
||
|
||
_Dev.registerToolCommands({
|
||
key:'',
|
||
id:'decorator:main',
|
||
name:'メインメニュー',
|
||
commands:commands,
|
||
});
|
||
})();
|
||
|
||
|
||
MapDecorator.reloadMapData = function(noInitProc=false){
|
||
var filePath = TRP_CORE.mapFilePath();
|
||
var mapData = JSON.parse(_Dev.readFile(filePath));
|
||
|
||
data.length = 0;
|
||
data.push(...(mapData.data));
|
||
originalData = data.concat();
|
||
|
||
SceneManager._scene._spriteset._tilemap._mapData = data;
|
||
this.requestRefreshTilemap();
|
||
|
||
if(!noInitProc){
|
||
this.executeInitProcess();
|
||
|
||
// this.initProc();
|
||
// this.analyzeAll();
|
||
// if(MapObject){
|
||
// this.analyzeMapObjects();
|
||
// }
|
||
|
||
this._restoreMapObjects();
|
||
this.restoreMap(true);
|
||
}
|
||
|
||
SoundManager.playLoad();
|
||
|
||
this.saveState('マップの再読み込み');
|
||
};
|
||
|
||
|
||
|
||
|
||
/* scroll
|
||
===================================*/
|
||
MapDecorator.updateScroll = function(){
|
||
if(this.cantScroll)return;
|
||
if(this.onKeyAlt)return;
|
||
|
||
var shift = Input.isPressed('shift');
|
||
if(Input.isPressed('left')){
|
||
processKeyScroll(-1,0,shift);
|
||
}else if(Input.isPressed('right')){
|
||
processKeyScroll(1,0,shift);
|
||
}else if(Input.isPressed('down')){
|
||
processKeyScroll(0,1,shift);
|
||
}else if(Input.isPressed('up')){
|
||
processKeyScroll(0,-1,shift);
|
||
}
|
||
};
|
||
|
||
function processKeyScroll(dx,dy,shift){
|
||
var speed = 16;
|
||
var shiftRate = 2;
|
||
dx *= shift ? speed*shiftRate : speed;
|
||
dy *= shift ? speed*shiftRate : speed;
|
||
processScroll(dx,dy);
|
||
}
|
||
|
||
function processScroll(dx,dy){
|
||
$gameMap._displayX += dx/tileW;
|
||
$gameMap._displayY += dy/tileH;
|
||
|
||
var dispW = Graphics.width*SETTING.mapDispRange/tileW;
|
||
var dispH = Graphics.height*SETTING.mapDispRange/tileH;
|
||
var mx = width-dispW;
|
||
var my = height-dispH;
|
||
if(mx<0)mx=0;
|
||
if(my<0)my=0;
|
||
$gameMap._displayX = $gameMap._displayX.clamp(0,mx);
|
||
$gameMap._displayY = $gameMap._displayY.clamp(0,my);
|
||
|
||
SceneManager._scene._spriteset.updateTilemap();
|
||
};
|
||
|
||
MapDecorator.tryEndMouseScrolling = function(){
|
||
if(!this.mouseScrolling)return;
|
||
this.mouseScrolling = null;
|
||
};
|
||
|
||
MapDecorator.updateMouseScrolling = function(){
|
||
var reduceRate = 0.7;
|
||
var spdNum = 5;
|
||
|
||
var scrolling = this.mouseScrolling;
|
||
var spdXArr = scrolling.spdXArr;
|
||
var spdYArr = scrolling.spdYArr;
|
||
|
||
var dx,dy;
|
||
if(TouchInput.isPressed()){
|
||
var tx = TouchInput.x;
|
||
var ty = TouchInput.y;
|
||
|
||
dx = scrolling.tx-tx;
|
||
dy = scrolling.ty-ty;
|
||
spdXArr.push(dx);
|
||
spdYArr.push(dy);
|
||
if(spdXArr.length>=spdNum)spdXArr.shift();
|
||
if(spdYArr.length>=spdNum)spdYArr.shift();
|
||
|
||
scrolling.tx = tx;
|
||
scrolling.ty = ty;
|
||
}else{
|
||
if(!scrolling.spdX && !scrolling.spdY){
|
||
var spdX = 0;
|
||
var spdY = 0;
|
||
for(var i=spdXArr.length-1; i>=0; i=(i-1)|0){
|
||
spdX += spdXArr[i];
|
||
spdY += spdYArr[i];
|
||
}
|
||
scrolling.spdX = spdX;
|
||
scrolling.spdY = spdY;
|
||
}
|
||
dx = scrolling.spdX = scrolling.spdX*reduceRate;
|
||
dy = scrolling.spdY = scrolling.spdY*reduceRate;
|
||
|
||
if(Math.abs(dx)<0.1 && Math.abs(dy)<0.1){
|
||
this.mouseScrolling = null;
|
||
}
|
||
}
|
||
|
||
processScroll(dx,dy);
|
||
};
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Undo/Redo
|
||
//=============================================================================
|
||
var maxUndoSize = supplementDefNum(10,parameters.maxUndoSize)*1000*1000;
|
||
var undoLogSize = 0;
|
||
MapDecorator.saveState = function(name,overwritable=false,forceOverwritable=false){
|
||
var procStr = JSON.stringify(proc);
|
||
var size = procStr.length;
|
||
|
||
var editorState = {
|
||
mode:this._mode,
|
||
lastModes:this._lastModes,
|
||
modeData:this.modeData?JSON.stringify(this.modeData):null,
|
||
};
|
||
|
||
var lastLog = TRP_CORE.last(undoLog);
|
||
if(overwritable && lastLog && lastLog.overwritable && lastLog.name===name){
|
||
undoLogSize -= lastLog.size;
|
||
undoLog.pop();
|
||
}else{
|
||
this.disableLastStateOverwritable();
|
||
}
|
||
|
||
undoLog.push({
|
||
forceOverwritable,
|
||
overwritable,
|
||
name,
|
||
procStr,
|
||
size,
|
||
originalData,
|
||
editorState,
|
||
});
|
||
redoLog.length = 0;
|
||
|
||
undoLogSize += size;
|
||
|
||
//truncate undoLogs
|
||
while(undoLogSize>maxUndoSize && undoLog.length>1){
|
||
var state = undoLog.shift();
|
||
undoLogSize -= state.size;
|
||
}
|
||
|
||
|
||
if(_Dev.inDev){
|
||
// console.log('logSize:%1/%2<%3%>'.format(
|
||
// undoLogSize,maxUndoSize,Math.ceil(undoLogSize/maxUndoSize*100)
|
||
// ));
|
||
}
|
||
};
|
||
MapDecorator.disableLastStateOverwritable = function(name=null){
|
||
var lastLog = TRP_CORE.last(undoLog);
|
||
if(!lastLog)return;
|
||
|
||
if(name){
|
||
if(lastLog.name !== name)return;
|
||
}else if(lastLog.forceOverwritable){
|
||
return;
|
||
}
|
||
|
||
lastLog.forceOverwritable = false;
|
||
lastLog.overwritable = false;
|
||
};
|
||
|
||
MapDecorator.tryUndo = function(){
|
||
this.disableLastStateOverwritable();
|
||
if(undoLog.length<=1){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
var state = undoLog.pop();
|
||
redoLog.unshift(state);
|
||
undoLogSize -= state.size;
|
||
|
||
var name = '<< '+state.name;
|
||
_Dev.showTempText('undo',name);
|
||
SoundManager.playCursor();
|
||
|
||
//restore last
|
||
this._restoreState(state);
|
||
};
|
||
|
||
MapDecorator.tryRedo = function(){
|
||
this.disableLastStateOverwritable();
|
||
var state = redoLog.shift();
|
||
if(!state){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
undoLog.push(state);
|
||
undoLogSize += state.size;
|
||
|
||
var name = '>> '+state.name;
|
||
_Dev.showTempText('undo',name);
|
||
SoundManager.playCursor();
|
||
|
||
//restore new
|
||
this._restoreState();
|
||
};
|
||
|
||
MapDecorator._restoreState = function(){
|
||
var state = TRP_CORE.last(undoLog);
|
||
|
||
proc = JSON.parse(state.procStr);
|
||
originalData = state.originalData;
|
||
|
||
var editorState = state.editorState;
|
||
if(this._mode!==editorState.mode){
|
||
this.setMode(editorState.mode);
|
||
}
|
||
this._lastModes = editorState.lastModes.concat();
|
||
this.modeData = editorState.modeData ? JSON.parse(editorState.modeData) : null;
|
||
|
||
|
||
if(MapObject){
|
||
this._restoreMapObjects();
|
||
}
|
||
|
||
this.restoreMap(true);
|
||
if(MapObject){
|
||
MapObject.refreshCollisions();
|
||
}
|
||
|
||
var onStateChange = 'onStateChange'+TRP_CORE.capitalize(this._mode);
|
||
if(this[onStateChange])this[onStateChange]();
|
||
};
|
||
|
||
MapDecorator._restoreMapObjects = function(){
|
||
var objects = [];
|
||
|
||
//restore MapObjects
|
||
for(const objInfoArr of proc.lastObjInfoArr){
|
||
if(!objInfoArr)continue;
|
||
for(const objInfo of objInfoArr){
|
||
objInfo[1] = this._tryRestoreMapObject(objInfo[1],true);
|
||
|
||
if(objInfo[1] instanceof MapObject){
|
||
objects.push(objInfo[1]);
|
||
}
|
||
}
|
||
}
|
||
|
||
if(this.modeData){
|
||
if(this.modeData.lastLocateMapObj){
|
||
this.modeData.lastLocateMapObj = this._tryRestoreMapObject(this.modeData.lastLocateMapObj);
|
||
}
|
||
if(this.modeData.manualLocateObj){
|
||
this.modeData.manualLocateObj = this._tryRestoreMapObject(this.modeData.manualLocateObj);
|
||
}
|
||
}
|
||
|
||
//cache notUsed
|
||
if(MapObject){
|
||
for(const obj of $dataTrpMapObjects){
|
||
if(!objects.contains(obj)){
|
||
MapObject.cache(obj);
|
||
}
|
||
}
|
||
$dataTrpMapObjects = objects;
|
||
}
|
||
};
|
||
|
||
MapDecorator._tryRestoreMapObject = function(srcData,addFlag=false){
|
||
if(!srcData
|
||
|| Array.isArray(srcData)
|
||
|| typeof srcData!=='object'
|
||
|| srcData instanceof MapObject
|
||
){
|
||
return srcData;
|
||
}
|
||
|
||
var target = null;
|
||
for(var i=$dataTrpMapObjects.length-1; i>=0; i=(i-1)|0){
|
||
var obj = $dataTrpMapObjects[i];
|
||
if(obj._uid === srcData._uid){
|
||
target = obj;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(!target){
|
||
target = MapObject.object();
|
||
|
||
if(addFlag){
|
||
MapObject.tryAdd(target,true);
|
||
}
|
||
}
|
||
|
||
var dx = srcData.x-target.x;
|
||
var dy = srcData.y-target.y;
|
||
|
||
MapObject.copy(srcData,target,true);
|
||
if(!target.bitmap){
|
||
target.loadBitmap();
|
||
}
|
||
target.tryRefreshSpriteState();
|
||
|
||
if(target.sprite){
|
||
target.sprite.x += dx;
|
||
target.sprite.y += dy;
|
||
}
|
||
|
||
return target;
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// process ZMap
|
||
//=============================================================================
|
||
MapDecorator.analyzeFloorZMap = function(){
|
||
|
||
/* analyze proc.zMap prior by eventSetting
|
||
===================================*/
|
||
var procSuccess = this.analyzeZMapByEventSettings();
|
||
if(!procSuccess)return;
|
||
|
||
|
||
/* analyze left tiles
|
||
===================================*/
|
||
var validIdxes = [];
|
||
for(const idxes of proc.allRoomIdxes){
|
||
validIdxes = validIdxes.concat(idxes);
|
||
}
|
||
|
||
var floorBaseIdxes = [];
|
||
validIdxes = validIdxes.filter(idx=>{
|
||
var tileId = data[idx];
|
||
if(!tileId)return false;
|
||
if(baseTileIds.contains(baseTileId(tileId))){
|
||
floorBaseIdxes.push(idx);
|
||
return false;
|
||
}
|
||
|
||
if(Tilemap.isWallSideTile(tileId))return false;
|
||
if(this.isWallTile(tileId,idx))return false;
|
||
if(this.isCeilingTile(tileId))return false;
|
||
return true;
|
||
});
|
||
|
||
for(var pi=0; pi<2; pi=(pi+1)|0){
|
||
var idxes = pi===0 ? floorBaseIdxes : validIdxes;
|
||
for(const idx of idxes){
|
||
if(proc.zMap[idx]!==undefined)continue;
|
||
proc.zMap[idx] = 0;
|
||
|
||
var x = idx%width;
|
||
var y = Math.floor(idx/width);
|
||
this.processZMap(x,y)
|
||
}
|
||
}
|
||
|
||
|
||
/* analyze proc.minZ
|
||
===================================*/
|
||
var length = proc.zMap.length;
|
||
proc.minZ = Number.MAX_SAFE_INTEGER;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
var z = proc.zMap[i];
|
||
if(z!==undefined){
|
||
if(z<proc.minZ){
|
||
proc.minZ = z;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* adjust proc.minZ to zero
|
||
===================================*/
|
||
proc.maxZ = 0;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
var z = proc.zMap[i];
|
||
if(z!==undefined){
|
||
proc.zMap[i] -= proc.minZ;
|
||
proc.maxZ = Math.max(proc.maxZ,proc.zMap[i]);
|
||
if(SETTING.writeZ_Region){
|
||
data[zRegion+i] = (proc.zMap[i]+1)*10;
|
||
}
|
||
}
|
||
}
|
||
proc.minZ = 0;
|
||
proc.floorLevelZMap = proc.zMap.concat();
|
||
};
|
||
|
||
|
||
MapDecorator.analyzeZMapByEventSettings = function(){
|
||
var events = $dataMap.events;
|
||
var eventIdxes = [];
|
||
for(const event of events){
|
||
if(!event)continue;
|
||
|
||
var image = event.pages[0].image;
|
||
if(image.characterName !== MapDecorator.INFO_CHARACTER_Z_NAME)continue;
|
||
|
||
var col = 3*(image.characterIndex%4)+image.pattern;
|
||
var row = 4*Math.floor(image.characterIndex/4)+(image.direction/2-1);
|
||
var eventZ = col+row*12;
|
||
if(eventZ>=36){
|
||
eventZ -= 35;
|
||
eventZ *= -1;
|
||
}
|
||
var eIdx = event.x+event.y*width;
|
||
eventIdxes.push(eIdx);
|
||
|
||
proc.zMap[eIdx] = eventZ;
|
||
}
|
||
|
||
for(const idx of eventIdxes){
|
||
var ex = idx%width;
|
||
var ey = Math.floor(idx/width);
|
||
this.processZMap(ex,ey);
|
||
}
|
||
return true;
|
||
};
|
||
|
||
MapDecorator.processZMap = function(sx,sy){
|
||
var sIdx = sx+sy*width;
|
||
var sTileId = baseTileId(data[sIdx]);
|
||
if(!sTileId)return;
|
||
|
||
var sz = proc.zMap[sIdx];
|
||
var next = [sIdx];
|
||
var current = [];
|
||
|
||
while(next.length){
|
||
var temp = current;
|
||
temp.length = 0;
|
||
current = next;
|
||
next = temp;
|
||
|
||
if(current.length>1){
|
||
//sort by z
|
||
current.sort((idxA,idxB)=>{
|
||
return (proc.zMap[idxA]||0) - (proc.zMap[idxB]||0);
|
||
});
|
||
}
|
||
|
||
|
||
for(const idx of current){
|
||
var baseZ = proc.zMap[idx];
|
||
var tileId = baseTileId(data[idx]);
|
||
var x = idx%width;
|
||
var y = Math.floor(idx/width);
|
||
|
||
/* set same floor z
|
||
===================================*/
|
||
var criffBeginIdxes = [];
|
||
this.analyzeNeighbors(x,y,(nx,ny,ox,oy,positions,checkedIdxes)=>{
|
||
var nIdx = nx+ny*width;
|
||
if(idx===nIdx)return true;
|
||
|
||
var nId = baseTileId(data[nIdx]);
|
||
if(!this.isSameNeighborZTiles(nId,tileId)){
|
||
//save criffBeginIdxes
|
||
if(criffWallBaseIds.contains(nId)){
|
||
if(proc.zMap[nIdx]!==undefined)return false;
|
||
|
||
if(nx!==ox){
|
||
if(checkedIdxes){
|
||
TRP_CORE.remove(checkedIdxes,nIdx);
|
||
}
|
||
}else{
|
||
var zSign = ny>oy ? -1 : 1;
|
||
TRP_CORE.uniquePush(
|
||
criffBeginIdxes,
|
||
zSign * nIdx
|
||
);
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
//same floor tile > neighbor ok
|
||
proc.zMap[nIdx] = baseZ;
|
||
return true;
|
||
});
|
||
|
||
/* process criff
|
||
===================================*/
|
||
for(const criffIdx of criffBeginIdxes){
|
||
var zSign = criffIdx > 0 ? 1 : -1;
|
||
var nIdx = Math.abs(criffIdx);
|
||
|
||
|
||
//criff start
|
||
var z = baseZ+zSign*0.5;
|
||
proc.zMap[nIdx] = z;
|
||
for(;;){
|
||
nIdx -= zSign*width;
|
||
if(nIdx<0 || nIdx>=zLayerSize)break;
|
||
|
||
var nId = baseTileId(data[nIdx]);
|
||
if(!nId)break;
|
||
|
||
if(criffWallBaseIds.contains(nId)){
|
||
//criff continue
|
||
}else{
|
||
//found higher or lower floor
|
||
if(proc.zMap[nIdx]===undefined){
|
||
next.push(nIdx);
|
||
proc.zMap[nIdx] = z+0.5*zSign;
|
||
}
|
||
break;
|
||
}
|
||
|
||
z += zSign;
|
||
proc.zMap[nIdx] = z;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
/* helper
|
||
===================================*/
|
||
MapDecorator.isSameNeighborZTiles = function(tileId1,tileId2){
|
||
if(tileId1===tileId2)return true;
|
||
|
||
//both baseTile (different baseFloor)
|
||
if(baseTileIds.contains(tileId1) && baseTileIds.contains(tileId2))return true;
|
||
|
||
return false;
|
||
};
|
||
|
||
|
||
|
||
/* proc.zMap mode
|
||
===================================*/
|
||
MapDecorator._tonnerSprite = null;
|
||
MapDecorator.showZMap = function(errorMode){
|
||
this.setMode(errorMode ? 'zMapError' : 'zMap');
|
||
};
|
||
|
||
MapDecorator.setModeZMapError = function(){
|
||
this.setModeZMapCommon();
|
||
};
|
||
MapDecorator.setModeZMap = function(){
|
||
this.setModeZMapCommon();
|
||
};
|
||
|
||
MapDecorator.setModeZMapCommon = function(){
|
||
var positions = [];
|
||
var colorMin = 'rgb(0,255,0)';
|
||
|
||
//color setting [min,max];
|
||
var base = 50;
|
||
var red = [base,255];
|
||
var green = [base,base];
|
||
var blue = [255,base];
|
||
var alpha = 0.8;
|
||
|
||
var colorZMin = proc.minZ;
|
||
var colorZMax = proc.maxZ;
|
||
var texts = [];
|
||
var colors = [];
|
||
|
||
for(var i=proc.zMap.length-1; i>=0; i=(i-1)|0){
|
||
var z = proc.zMap[i];
|
||
var text = z;
|
||
var color;
|
||
if(z===undefined)continue;
|
||
if(z===Number.MAX_SAFE_INTEGER){
|
||
text = '∞';
|
||
color = 'rgba(0,0,0,0)';
|
||
}else{
|
||
var r = red[0] + z/colorZMax * (red[1]-red[0]);
|
||
var g = green[0] + z/colorZMax * (green[1]-green[0]);
|
||
var b = blue[0] + z/colorZMax * (blue[1]-blue[0]);
|
||
color = 'rgb(%1,%2,%3,%4)'.format(r,g,b,alpha);
|
||
}
|
||
|
||
positions.push(i);
|
||
texts.push(text);
|
||
colors.push(color);
|
||
}
|
||
this.tonnerTiles(positions,texts,colors);
|
||
};
|
||
|
||
MapDecorator.tonnerTiles = function(positions,texts,color,tonnerTiles,drawText){
|
||
var sprite = _Dev.tonnerTiles(positions,false,color,texts,tonnerTiles,drawText);
|
||
if(!sprite){
|
||
this.tryReleaseTonnerSprite();
|
||
return;
|
||
}
|
||
|
||
MapDecorator._tonnerSprite = sprite;
|
||
TRP_CORE.uniquePush(this.updateList,sprite);
|
||
sprite.update()
|
||
}
|
||
|
||
MapDecorator.MODE_GUIDE.zMap = [
|
||
'【Zマップ確認モード】',
|
||
'左クリック:確認モード終了'
|
||
];
|
||
MapDecorator.MODE_GUIDE.zMapError = [
|
||
'【Zマップエラー】',
|
||
'Z値が衝突しないようにイベント設定・崖の高さを調整してください。'
|
||
];
|
||
|
||
MapDecorator.restoreModeByMouse = function(){
|
||
this.restoreMode();
|
||
SoundManager.playCancel();
|
||
}
|
||
MapDecorator.updateInputToCheckRestoreMode = function(){
|
||
if(Input.isTriggered('ok')){
|
||
this.restoreMode();
|
||
SoundManager.playCancel();
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
MapDecorator.tryReleaseTonnerSprite = function(){
|
||
var sprite = this._tonnerSprite;
|
||
if(sprite){
|
||
if(sprite.parent){
|
||
sprite.parent.removeChild(sprite);
|
||
}
|
||
TRP_CORE.remove(this.updateList,sprite);
|
||
}
|
||
this._tonnerSprite = null;
|
||
};
|
||
|
||
MapDecorator.onMouseDownRightZMap = MapDecorator.restoreModeByMouse;
|
||
MapDecorator.updateInputZMap = MapDecorator.updateInputToCheckRestoreMode;
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// processCriff
|
||
//=============================================================================
|
||
MapDecorator.processMapCriff = function(){
|
||
var length = allInfo.length;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
this.changeBaseInfo(allInfo[i]);
|
||
if(!info.criffTopBaseId)continue;
|
||
|
||
this.processMapCriffWithInfo(info);
|
||
}
|
||
|
||
this.requestRefreshTilemap();
|
||
};
|
||
|
||
MapDecorator.processMapCriffWithInfo = function(info){
|
||
var newData = data.concat();
|
||
|
||
for(var idx=0; idx<zLayerSize; idx=(idx+1)|0){
|
||
var tileId = baseTileId(data[idx]);
|
||
if(!tileId)continue;
|
||
|
||
var z = proc.zMap[idx];
|
||
if(info.criffTopAllIds.contains(tileId)){
|
||
this.processCriffTop(newData,idx,tileId,z);
|
||
}else if(tileId===info.criffWallBaseId && !proc.wallIdxes.contains(idx)){
|
||
this.processCriffWall(newData,idx,tileId,z);
|
||
}
|
||
}
|
||
|
||
this.replaceCriffTopTiles(newData);
|
||
|
||
/* apply data
|
||
===================================*/
|
||
data.length = 0;
|
||
Array.prototype.push.apply(data,newData);
|
||
newData = null;
|
||
};
|
||
|
||
MapDecorator.processCriffTop = function(newData,idx,tileId,z){
|
||
var nf = TRP_CORE.packValues([],0,10);
|
||
nf[5] = 1;
|
||
|
||
var noSupplyBack = this.analyzeCriffTopNeighborFlags(nf,idx,tileId,z);
|
||
tileId = connectAutoTile(tileId,nf);
|
||
|
||
if(!noSupplyBack && SETTING.supplyUpperCriffTopBack && !nf[8]){
|
||
/* supply upper criff top back
|
||
===================================*/
|
||
newData[zAcc+idx] = tileId;
|
||
this.supplyBackTile(idx,newData,true);
|
||
}else{
|
||
newData[idx] = tileId;
|
||
}
|
||
|
||
|
||
if(Tilemap.getAutotileShape(tileId)){
|
||
proc.criffIdxes.push(idx);
|
||
proc.criffTopIdxes.push(idx);
|
||
|
||
if(
|
||
(nf[2]?0:1)+(nf[4]?0:1)+(nf[6]?0:1)+(nf[8]?0:1)>=SETTING.criffTopObjForbiddenSideNum && SETTING.criffTopObjForbiddenSideNum>0
|
||
){
|
||
proc.objForbiddenIdxes.push(idx);
|
||
}
|
||
}
|
||
};
|
||
|
||
MapDecorator.analyzeCriffTopNeighborFlags = function(nf,idx,tileId,z){
|
||
//return needs supplyBack
|
||
var noSupplyBack = false;
|
||
for(var ni=1; ni<=9; ni=(ni+1)|0){
|
||
//check flag set
|
||
if(nf[ni])continue;
|
||
if(ni===5){
|
||
nf[ni] = 1;
|
||
continue;
|
||
}
|
||
|
||
var neighbor = idxForNeighborDir(idx,ni);
|
||
if(neighbor<0){
|
||
//outside -> connect
|
||
nf[ni] = 1;
|
||
continue;
|
||
}
|
||
|
||
var neighborId = baseTileId(data[neighbor]);
|
||
var neighborZ = !neighborId ? Number.MAX_SAFE_INTEGER : proc.zMap[neighbor];
|
||
|
||
var y = Math.floor(idx/width)
|
||
if(!neighborId){
|
||
if(SETTING.noWall){
|
||
nf[ni] = 0;
|
||
noSupplyBack = true;
|
||
continue;
|
||
}
|
||
|
||
if(ni!==2&&ni!==8){
|
||
//side
|
||
var h = 0;
|
||
for(var dy=0; ; dy=(dy+1)|0){
|
||
if(y+dy>=height)break;
|
||
|
||
var tidx = neighbor+dy*width;
|
||
if(data[tidx]){
|
||
neighborZ = dy + proc.zMap[tidx]-1;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if(criffWallBaseIds.contains(neighborId) || proc.wallIdxes.contains(neighborId)){
|
||
nf[ni] = neighborZ>z ? 1 : 0;
|
||
continue;
|
||
}
|
||
if(tileId==neighborId){
|
||
nf[ni] = 1;
|
||
}else{
|
||
nf[ni] = neighborZ>=z ? 1 : 0;
|
||
}
|
||
}
|
||
return noSupplyBack;
|
||
}
|
||
|
||
MapDecorator.processCriffWall = function(newData,idx,tileId,z){
|
||
proc.criffIdxes.push(idx);
|
||
proc.criffWallIdxes.push(idx);
|
||
proc.objForbiddenIdxes.push(idx);
|
||
|
||
|
||
//auto shape
|
||
var s = 0;
|
||
for(var di=0; di<4; di=(di+1)|0){
|
||
var dir = (di+1)*2;
|
||
var nIdx = idxForNeighborDir(idx,dir);
|
||
|
||
var nId = data[nIdx];
|
||
var nz = proc.zMap[nIdx];
|
||
|
||
var connect = false;
|
||
if(!nId){
|
||
if(nIdx<0){
|
||
connect = true;
|
||
}else if(dir===2 && z<1){
|
||
//wall bottom
|
||
connect = false;
|
||
}else{
|
||
connect = true;
|
||
}
|
||
}else if(dir===4 || dir===6){
|
||
//side
|
||
connect = nz>=z;
|
||
}else if(dir===2 && nz>z+1 && z===0.5){
|
||
//z=0.5 & lower criff top
|
||
connect = false;
|
||
}else if(!Tilemap.isAutotile(nId)){
|
||
connect = false;
|
||
}else{
|
||
nId -= Tilemap.getAutotileShape(nId);
|
||
if(nz>z){
|
||
//check left or right
|
||
if(nIdx%width>0&&nz-1<proc.zMap[nIdx-1]){
|
||
//left is lower > maybe bottom
|
||
connect = false;
|
||
}else if(nIdx%width<width-1&&nz-1<proc.zMap[nIdx+1]){
|
||
//right is lower > maybe bottom
|
||
connect = false;
|
||
}else{
|
||
connect = true;
|
||
}
|
||
}else {
|
||
connect = nId===info.criffWallBaseId
|
||
}
|
||
}
|
||
if(!connect){
|
||
var powIdx = DIR_SHAPE_POW[dir];
|
||
s += Math.pow(2,powIdx);
|
||
}
|
||
}
|
||
newData[idx] = tileId+s;
|
||
};
|
||
|
||
var DIR_SHAPE_POW = [0,0,3,0,0,0,2,0,1];
|
||
|
||
MapDecorator.replaceCriffTopTiles = function(newData){
|
||
for(var idx=0; idx<zLayerSize; idx=(idx+1)|0){
|
||
for(var z=0; z<2; z=(z+1)|0){
|
||
var zIdx = z*zLayerSize+idx;
|
||
var tileId = baseTileId(newData[zIdx]);
|
||
if(info.criffTopAllIds.contains(tileId)){
|
||
var shape = newData[zIdx]-tileId;
|
||
if(shape===0){
|
||
newData[zIdx] = info.floorBaseId;
|
||
}else{
|
||
newData[zIdx] = info.criffTopBaseId+shape;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Supply Walls
|
||
//=============================================================================
|
||
MapDecorator.analyzeWallIdxes = function(){
|
||
/* <proc.wallIdxMap>
|
||
* -1:empty
|
||
* 0~:wall
|
||
* max:floor
|
||
===================================*/
|
||
for(var i=0; i<zLayerSize; i=(i+1)|0){
|
||
if(proc.wallIdxMap[i]!==undefined)continue;
|
||
proc.wallIdxMap[i] = -1;
|
||
|
||
var x = i%width;
|
||
var y = Math.floor(i/width);
|
||
|
||
if(y>=height-1){
|
||
//map bottom
|
||
continue;
|
||
}
|
||
|
||
var tileId = data[i];
|
||
|
||
var lowerIdx = i+width;
|
||
var lowerId = lowerIdx<zLayerSize ? data[lowerIdx] : 0;
|
||
var lowerFloorZ = proc.zMap[i+width]||0;
|
||
var upperIdx = i-width;
|
||
var upperId = upperIdx>=0 ? data[upperIdx] : 0;
|
||
|
||
if(tileId){
|
||
if(this.isWallTile(tileId,i)){
|
||
//already wall set
|
||
// -> will process from top
|
||
|
||
if(this.isWallTile(upperId,upperIdx))continue;
|
||
|
||
//supply proc.wallIdxes
|
||
var dy = 0;
|
||
for(; i+dy*width<zLayerSize; dy=(dy+1)|0){
|
||
var cIdx = i+dy*width;
|
||
var cTile = data[cIdx];
|
||
if(dy>0 && !this.isWallTile(cTile,cIdx))break;
|
||
|
||
proc.wallIdxMap[cIdx] = dy;
|
||
proc.wallIdxes.push(cIdx);
|
||
proc.zMap[cIdx] = lowerFloorZ+dy+0.5;
|
||
}
|
||
|
||
//set proc.zMap from bottom
|
||
var wallH = dy;
|
||
lowerFloorZ = proc.zMap[i+wallH*width]||0;
|
||
for(var dy=0; dy<wallH; dy=(dy+1)|0){
|
||
proc.zMap[i+dy*width] = lowerFloorZ + (wallH-dy-0.5);
|
||
}
|
||
}else if(this.isCeilingTile(tileId)){
|
||
//ceiling
|
||
proc.wallIdxMap[i] = -1;
|
||
}else{
|
||
//floor
|
||
proc.wallIdxMap[i] = Number.MAX_SAFE_INTEGER;
|
||
}
|
||
continue;
|
||
}
|
||
|
||
//check needs supplyWalls
|
||
if(!SETTING.autoWallSupply)continue;
|
||
|
||
//check lower ground
|
||
if(!this.isGroundTile(lowerId,lowerIdx))continue;
|
||
|
||
var roomId = proc.roomIdxMapForUserProc[lowerIdx];
|
||
var baseSetting = this.baseFloorInfoWithTile(tileId);
|
||
if(!baseSetting.wallTileIds){
|
||
baseSetting = allInfo[0];
|
||
}
|
||
if(!baseSetting.wallTileIds || !baseSetting.wallTileIds.length){
|
||
continue;
|
||
}
|
||
var wallH = baseSetting.wallTileIds ? baseSetting.wallTileIds.length : 0;
|
||
|
||
//arrange total height
|
||
if(SETTING.arrangeTotalHeight){
|
||
wallH = proc.maxZ+wallH-lowerFloorZ;
|
||
}
|
||
|
||
|
||
|
||
//set idx to wall top ceiling
|
||
var idx = i-wallH*width;
|
||
|
||
|
||
//set idx to wall top
|
||
idx += width;
|
||
for(var dy=0; dy<wallH; dy=(dy+1)|0,idx+=width){
|
||
if(idx<0)continue;
|
||
if(proc.wallIdxMap[idx]>-1)continue;
|
||
|
||
var tileId = data[idx];
|
||
if(tileId)continue;
|
||
|
||
proc.wallIdxMap[idx] = dy;
|
||
proc.wallIdxes.push(idx);
|
||
proc.zMap[idx] = lowerFloorZ+(wallH-dy-0.5);
|
||
if(roomId>=0 && proc.roomIdxMapForUserProc[idx]<0){
|
||
proc.roomIdxMapForUserProc[idx] = roomId;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
MapDecorator.isWallTile = function(tileId,idxForCheckNonRegisterWall=-1){
|
||
if(SETTING.noWall)return false;
|
||
|
||
if(idxForCheckNonRegisterWall>=0){
|
||
//check nonRegisterWall
|
||
if(!Tilemap.isWallSideTile(tileId))return false;
|
||
return this.checkWallTopCeilingOrEmpty(idxForCheckNonRegisterWall-width);
|
||
}else{
|
||
if(allWallIds.contains(baseTileId(tileId)))return true;
|
||
return false;
|
||
}
|
||
};
|
||
|
||
MapDecorator.checkWallTopCeilingOrEmpty = function(idx){
|
||
if(idx<0)return true;
|
||
var tileId = data[idx];
|
||
if(!tileId)return true;
|
||
if(this.isCeilingTile(tileId))return true;
|
||
|
||
if(Tilemap.isWallSideTile(tileId)){
|
||
return this.checkWallTopCeilingOrEmpty(idx-width);
|
||
}else{
|
||
return false;
|
||
}
|
||
};
|
||
|
||
MapDecorator.isCeilingTile = function(tileId){
|
||
if(!tileId && SETTING.autoCeilingSupplyWithEmpty){
|
||
return true;
|
||
}
|
||
return allCeilingIds.contains(baseTileId(tileId));
|
||
};
|
||
MapDecorator.isGroundTile = function(tileId,idx){
|
||
return tileId && !this.isWallTile(tileId,idx) && !this.isCeilingTile(tileId);
|
||
};
|
||
MapDecorator.baseFloorInfoWithTile = function(tileId,allowFailure=false){
|
||
tileId = baseTileId(tileId);
|
||
|
||
for(const info of allInfo){
|
||
if(info.floorBaseId===tileId)return info;
|
||
if(info.ceilingBaseId===tileId)return info;
|
||
if(info.wallTileIds && info.wallTileIds.contains(tileId))return info;
|
||
if(info.waterBaseId===tileId)return info;
|
||
if(info.waterAccIds && info.waterAccIds.contains(tileId))return info;
|
||
if(info.floorVariationIds && info.floorVariationIds.contains(tileId))return info;
|
||
if(info.accSettings[tileId])return info;
|
||
}
|
||
return allowFailure ? null : allInfo[0];
|
||
};
|
||
|
||
|
||
|
||
|
||
/* wallIdx mode
|
||
===================================*/
|
||
MapDecorator.showWallIdxMap = function(){
|
||
this.setMode('wallIdx');
|
||
};
|
||
MapDecorator.setModeWallIdx = function(){
|
||
var positions = [];
|
||
var autoRemove = false;
|
||
var color = 'rgba(0,0,255,0.2)';
|
||
var texts = [];
|
||
for(var i=zLayerSize-1; i>=0; i=(i-1)|0){
|
||
var wallIdx = proc.wallIdxMap[i];
|
||
if(wallIdx===Number.MAX_SAFE_INTEGER)continue;
|
||
|
||
positions.push(i);
|
||
texts.push(wallIdx);
|
||
}
|
||
|
||
this.tonnerTiles(positions,texts,color);
|
||
};
|
||
MapDecorator.MODE_GUIDE.wallIdx = [
|
||
'【壁IndexMap確認モード】',
|
||
'左クリック:確認モード終了'
|
||
];
|
||
|
||
|
||
MapDecorator.onMouseDownLeftWallIdx = MapDecorator.restoreModeByMouse;
|
||
MapDecorator.updateInputWallIdx = MapDecorator.updateInputToCheckRestoreMode;
|
||
|
||
|
||
|
||
|
||
/* supplyWalls
|
||
===================================*/
|
||
MapDecorator.supplyWalls = function(){
|
||
var floorWallIdx = Number.MAX_SAFE_INTEGER;
|
||
for(var idx=0; idx<zLayerSize; idx=(idx+1)|0){
|
||
if(invalidIdxes && invalidIdxes.contains(idx))continue;
|
||
|
||
//proc from floor top
|
||
if(proc.wallIdxMap[idx]!==floorWallIdx)continue;
|
||
|
||
//check upper wall
|
||
var upperIdx = idx-width;
|
||
var wallIdx = proc.wallIdxMap[upperIdx];
|
||
if(upperIdx<0)continue;
|
||
if(wallIdx===-1)continue;
|
||
if(wallIdx===floorWallIdx)continue;
|
||
|
||
|
||
//prepare wallTileIds
|
||
var tileId = data[idx];
|
||
var baseInfo = this.baseFloorInfoWithTile(tileId);
|
||
if(!baseInfo.wallTileIds)baseInfo = allInfo[0];
|
||
if(!baseInfo.wallTileIds)continue;
|
||
|
||
var wallTileIds = baseInfo.wallTileIds;
|
||
var baseInfoIdx = allInfo.indexOf(baseInfo);
|
||
var defWallH = wallTileIds.length;
|
||
|
||
//supply wallTiles
|
||
var cIdx = upperIdx;
|
||
var wallH = wallIdx+1;
|
||
for(; cIdx>=0; cIdx=(cIdx-width)|0){
|
||
var cTileId = data[cIdx];
|
||
if(cTileId)continue;
|
||
|
||
var wallIdx = proc.wallIdxMap[cIdx];
|
||
if(wallIdx===-1)break;
|
||
if(wallIdx===floorWallIdx)break;
|
||
|
||
//adjust wallIdx
|
||
if(wallIdx===wallH-1){
|
||
wallIdx = defWallH-1;
|
||
}else{
|
||
wallIdx = wallIdx.clamp(0,defWallH-2);
|
||
}
|
||
|
||
//supply wall tile
|
||
cTileId = data[cIdx] = wallTileIds[wallIdx];
|
||
|
||
//cache baseInfoIdx
|
||
proc.idxBaseInfoIdxMap[cIdx] = baseInfoIdx;
|
||
}
|
||
}
|
||
|
||
this.connectWallTiles();
|
||
};
|
||
|
||
MapDecorator.connectWallTiles = function(){
|
||
for(var wi=0; wi<proc.wallIdxes.length; wi=(wi+1)|0){
|
||
this.connectWallTile(proc.wallIdxes[wi]);
|
||
}
|
||
};
|
||
|
||
|
||
var FLOOR_WALL_IDX = Number.MAX_SAFE_INTEGER
|
||
MapDecorator.connectWallTile = function(idx){
|
||
//original loc
|
||
if(originalData[idx])return;
|
||
|
||
var tileId = baseTileId(data[idx]);
|
||
if(!Tilemap.isAutotile(tileId))return;
|
||
|
||
var wallIdx = proc.wallIdxMap[idx];
|
||
var z = proc.zMap[idx];
|
||
|
||
data[idx] = this._connectWallTile(idx,tileId,wallIdx,z);
|
||
};
|
||
|
||
MapDecorator._connectWallTile = function(idx,tileId,wallIdx,z){
|
||
var x = idx%width;
|
||
var y = Math.floor(idx/width);
|
||
|
||
/* analyze Left/Right close
|
||
===================================*/
|
||
var leftClose = 0;
|
||
var rightClose = 0;
|
||
|
||
if(x>0 && !(invalidIdxes&&!invalidIdxes.contains(idx-1))){
|
||
var neighborWallIdx = proc.wallIdxMap[idx-1];
|
||
var neighborZ = proc.zMap[idx-1];
|
||
if(neighborWallIdx<Number.MAX_SAFE_INTEGER){
|
||
if(wallIdx<neighborWallIdx){
|
||
leftClose = 1;
|
||
}
|
||
}else{
|
||
if(z>neighborZ){
|
||
leftClose = 1;
|
||
}
|
||
}
|
||
// if(tileId !== baseTileId(data[idx-1])){
|
||
// //diffrent kind wall
|
||
// // leftClose = 1;
|
||
// }
|
||
}
|
||
|
||
if(x<width-1 && !(invalidIdxes&&!invalidIdxes.contains(idx+1))){
|
||
var neighborWallIdx = proc.wallIdxMap[idx+1];
|
||
var neighborZ = proc.zMap[idx+1];
|
||
if(neighborWallIdx<Number.MAX_SAFE_INTEGER){
|
||
if(wallIdx<neighborWallIdx){
|
||
rightClose = 1;
|
||
}
|
||
}else{
|
||
if(z>neighborZ){
|
||
rightClose = 1;
|
||
}
|
||
}
|
||
// if(tileId !== baseTileId(data[idx+1])){
|
||
// //diffrent kind wall
|
||
// // rightClose = 1;
|
||
// }
|
||
}
|
||
|
||
/* analyze Top/Bottom close
|
||
===================================*/
|
||
var topClose = 0;
|
||
var bottomClose = 0;
|
||
|
||
if(wallIdx===0){
|
||
topClose = 1;
|
||
}
|
||
|
||
var lowerIdx = idx+width;
|
||
var lowerWallIdx = proc.wallIdxMap[lowerIdx];
|
||
if(lowerWallIdx===FLOOR_WALL_IDX){
|
||
bottomClose = 1;
|
||
}
|
||
|
||
|
||
/* adjust shape
|
||
===================================*/
|
||
var s = 0;
|
||
if(leftClose)s += 1<<0;
|
||
if(topClose)s += 1<<1;
|
||
if(rightClose)s += 1<<2;
|
||
if(bottomClose)s += 1<<3;
|
||
|
||
return tileId+s;
|
||
}
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Supply Ceilings
|
||
//=============================================================================
|
||
MapDecorator.analyzeCeilingIdxes = function(){
|
||
//make ceilingIdxes
|
||
for(var idx=0; idx<zLayerSize; idx=(idx+1)|0){
|
||
//check is floor or wall
|
||
var wallIdx = proc.wallIdxMap[idx];
|
||
var tileId = data[idx];
|
||
if(wallIdx<0){
|
||
//empty
|
||
if(this.isCeilingTile(tileId)){
|
||
TRP_CORE.uniquePush(proc.ceilingIdxes,idx);
|
||
proc.zMap[idx] = Number.MAX_SAFE_INTEGER;
|
||
}
|
||
continue;
|
||
}
|
||
|
||
if(!SETTING.autoCeilingSupply)continue;
|
||
|
||
var roomId = proc.roomIdxMapForUserProc[idx];
|
||
|
||
|
||
//auto supply
|
||
for(var ni=1; ni<10; ni=(ni+1)|0){
|
||
if(ni===5)continue;
|
||
|
||
var nIdx = idxForNeighborDir(idx,ni);
|
||
var nWallIdx = proc.wallIdxMap[nIdx];
|
||
|
||
//check neighbor empty > ceiling
|
||
if(nWallIdx === -1){
|
||
var firstPush = TRP_CORE.uniquePush(proc.ceilingIdxes,nIdx);
|
||
proc.zMap[nIdx] = Number.MAX_SAFE_INTEGER;
|
||
|
||
if(roomId>=0 && proc.roomIdxMapForUserProc[nIdx]<0){
|
||
proc.roomIdxMapForUserProc[nIdx] = roomId;
|
||
}
|
||
|
||
//cache baseInfoIdx
|
||
var forceOverWrite = ni===2||ni===4||ni===6||ni===8;
|
||
if(forceOverWrite || !firstPush){
|
||
var baseInfo = this.baseFloorInfoWithTile(tileId);
|
||
if(!baseInfo.ceilingBaseId)baseInfo = allInfo[0];
|
||
|
||
var baseInfoIdx = allInfo.indexOf(baseInfo);
|
||
proc.idxBaseInfoIdxMap[nIdx] = baseInfoIdx;
|
||
}
|
||
}
|
||
};
|
||
}
|
||
proc.ceilingIdxes.sort((a,b)=>a-b);
|
||
};
|
||
|
||
MapDecorator.supplyCeilings = function(){
|
||
var nf = TRP_CORE.packValues([],0,10);
|
||
nf[5] = 1;
|
||
|
||
for(const idx of proc.ceilingIdxes){
|
||
if(invalidIdxes && invalidIdxes.contains(idx))continue;
|
||
|
||
//check already set
|
||
if(originalData[idx])continue;
|
||
|
||
//supply tile id
|
||
var tileId = baseTileId(data[idx]);
|
||
if(!tileId){
|
||
var baseInfoIdx = proc.idxBaseInfoIdxMap[idx];
|
||
var baseInfo = allInfo[baseInfoIdx||0];
|
||
tileId = baseInfo.ceilingBaseId;
|
||
if(!tileId)continue;
|
||
|
||
data[idx] = tileId;
|
||
}
|
||
|
||
//check neighbor connection
|
||
for(var ni=1; ni<10; ni=(ni+1)|0){
|
||
if(ni===5)continue;
|
||
|
||
var nIdx = idxForNeighborDir(idx,ni);
|
||
if(proc.ceilingIdxes.contains(nIdx)){
|
||
nf[ni] = 1;
|
||
}else{
|
||
if(SETTING.isEmptySpaceCeiling){
|
||
if(nIdx<0 || proc.wallIdxMap[nIdx]<0 || (invalidIdxes&&invalidIdxes.contains(nIdx))){
|
||
nf[ni] = 1;
|
||
}else{
|
||
nf[ni] = 0;
|
||
}
|
||
}else{
|
||
nf[ni] = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
//auto connect
|
||
data[idx] = connectAutoTile(tileId,nf)
|
||
}
|
||
};
|
||
|
||
MapDecorator.checkCeilingCorrect = function(){
|
||
var failureIdxes = [];
|
||
var texts = [];
|
||
for(const idx of proc.wallIdxes){
|
||
var upperIdx = idx-width;
|
||
if(upperIdx<0)continue;
|
||
|
||
if(proc.wallIdxes.contains(upperIdx))continue;
|
||
if(proc.ceilingIdxes.contains(upperIdx))continue;
|
||
|
||
var x = upperIdx%width;
|
||
var y = Math.floor(upperIdx/width);
|
||
var alert = '天井設置に失敗<x:%1,y:%2>'.format(x,y);
|
||
_Dev.showText(null,alert,'red');
|
||
|
||
failureIdxes.push(upperIdx);
|
||
texts.push('x');
|
||
}
|
||
|
||
if(failureIdxes.length){
|
||
var color = 'rgba(255,0,0,0.8)';
|
||
this.tonnerTiles(failureIdxes,texts,color);
|
||
|
||
$gamePlayer.locate(x,y);
|
||
SceneManager._scene._spriteset.update();
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// supply BackTiles
|
||
//=============================================================================
|
||
MapDecorator.supplyBackTile = function(idx,dstData=data){
|
||
var baseIdx = proc.idxBaseInfoIdxMap[idx];
|
||
var info = allInfo[baseIdx]||allInfo[0];
|
||
|
||
//search supply sample directions
|
||
var maxZ = proc.minZ-1;
|
||
var bestDirs = [];
|
||
var z = proc.zMap[idx];
|
||
|
||
for(var dir=2; dir<=8; dir=(dir+2)|0){
|
||
var nz = this.zForSupplyBackTile(idx,z,dir,info);
|
||
if(nz>maxZ){
|
||
maxZ = nz;
|
||
bestDirs.length = 0;
|
||
bestDirs.push(dir);
|
||
}else if(nz===maxZ){
|
||
bestDirs.push(dir);
|
||
}
|
||
}
|
||
maxZ = Math.max(maxZ,proc.minZ);
|
||
|
||
//prior side dirs
|
||
if(TRP_CORE.remove(bestDirs,2))bestDirs.push(2);
|
||
if(TRP_CORE.remove(bestDirs,8))bestDirs.push(8);
|
||
|
||
this.supplyBackTilesWithDirs(idx,bestDirs,maxZ,info,dstData);
|
||
};
|
||
|
||
MapDecorator.zForSupplyBackTile = function(idx,z,dir,info){
|
||
var nIdx = idxForNeighborDir(idx,dir);
|
||
|
||
//check in map
|
||
if(nIdx<0)return Number.MIN_SAFE_INTEGER;
|
||
|
||
//check not ceiling
|
||
var nz = proc.zMap[nIdx];
|
||
if(nz===Number.MAX_SAFE_INTEGER){
|
||
return Number.MIN_SAFE_INTEGER;
|
||
}
|
||
|
||
//check z lower
|
||
if(nz>=z){
|
||
return Number.MIN_SAFE_INTEGER;
|
||
}
|
||
|
||
//check not sequencial wall
|
||
if(dir===2 && proc.ceilingIdxes.contains(idx) && proc.wallIdxes.contains(nIdx)){
|
||
//ceiling ~ wall -> sequencial
|
||
return Number.MIN_SAFE_INTEGER;
|
||
}
|
||
if(proc.wallIdxes.contains(idx)){
|
||
if((dir===2 && proc.wallIdxMap[idx]+1===proc.wallIdxMap[nIdx])
|
||
|| (dir===8 && proc.wallIdxMap[nIdx]+1===proc.wallIdxMap[idx])
|
||
){
|
||
return Number.MIN_SAFE_INTEGER;
|
||
}
|
||
}
|
||
return nz;
|
||
};
|
||
|
||
|
||
MapDecorator.supplyBackTilesWithDirs = function(idx,bestDirs,z,info,dstData){
|
||
var bestTileId = -1;
|
||
var isCriffTop = false;
|
||
for(const dir of bestDirs){
|
||
var nIdx = idxForNeighborDir(idx,dir);
|
||
var tileId = data[nIdx];
|
||
if(proc.wallIdxes.contains(nIdx) ||
|
||
(proc.criffWallIdxes&&proc.criffWallIdxes.contains(nIdx))
|
||
){
|
||
//supply wallTile
|
||
if(proc.wallIdxes.contains(nIdx)){
|
||
tileId = info.wallTileIds ? info.wallTileIds[0] : tielId;
|
||
}
|
||
if(Tilemap.isAutotile(tileId)){
|
||
var wallIdx = proc.wallIdxMap[nIdx];
|
||
var supplyWall = true;
|
||
if(dir===2){
|
||
wallIdx -= 1;
|
||
}else if(dir===8){
|
||
if(nIdx%width>0&&z-1<proc.zMap[nIdx-1]){
|
||
//bottom -> supply left floor
|
||
tileId = baseTileId(data[nIdx-1]);
|
||
supplyWall = false;
|
||
}else if(nIdx%width<width-1&&z-1<proc.zMap[nIdx+1]){
|
||
tileId = baseTileId(data[nIdx+1]);
|
||
supplyWall = false;
|
||
}else{
|
||
wallIdx += 1;
|
||
}
|
||
}
|
||
if(supplyWall){
|
||
tileId = this._connectWallTile(idx,baseTileId(tileId),wallIdx,z);
|
||
}
|
||
}
|
||
|
||
dstData[idx] = tileId;
|
||
return;
|
||
}else{
|
||
/* try supply criffTop tile
|
||
===================================*/
|
||
if(proc.criffTopIdxes.contains(nIdx)){
|
||
var nf = TRP_CORE.packValues([],0,10);
|
||
nf[5] = 1;
|
||
for(var di=bestDirs.length-1; di>=0; di=(di-1)|0){
|
||
nf[bestDirs[di]] = 1;
|
||
}
|
||
|
||
var noSupplyBack = this.analyzeCriffTopNeighborFlags(nf,idx,baseTileId(tileId),z);
|
||
tileId = connectAutoTile(baseTileId(tileId),nf);
|
||
|
||
//apply backTile
|
||
bestTileId = tileId
|
||
isCriffTop = true;
|
||
break;
|
||
}else if(tileId){
|
||
bestTileId = bestTileId>=0 ? bestTileId : (baseTileId(tileId)||-1)
|
||
}
|
||
}
|
||
}
|
||
|
||
//supply normal floor
|
||
if(bestTileId<0){
|
||
bestTileId = info.floorBaseId;
|
||
}
|
||
|
||
//apply backTile
|
||
dstData[idx] = bestTileId;
|
||
|
||
|
||
//register idxes
|
||
TRP_CORE.uniquePush(proc.floorSuppliedIdxes,idx);
|
||
proc.floorLevelZMap[idx] = z;
|
||
if(!isCriffTop && !proc.wallIdxes.contains(idx) && !proc.criffWallIdxes.contains(idx)){
|
||
var roomId = idxOfRoom(nIdx);
|
||
if(roomId>=0){
|
||
TRP_CORE.uniquePush(proc.allRoomIdxes[roomId],idx);
|
||
TRP_CORE.uniquePush(proc.allBaseIdxes[roomId],idx);
|
||
proc.roomIdxMapForUserProc[idx] = roomId;
|
||
}
|
||
}
|
||
|
||
//supply shadow
|
||
this.supplyShadow(idx,dstData);
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Supply Shadows
|
||
//=============================================================================
|
||
MapDecorator.supplyShadows = function(){
|
||
for(var idx=0; idx<zLayerSize; idx=(idx+1)|0){
|
||
if(invalidIdxes && invalidIdxes.contains(idx))continue;
|
||
this.supplyShadow(idx);
|
||
}
|
||
this.requestRefreshTilemap();
|
||
};
|
||
MapDecorator.supplyShadow = function(idx,dstData=data){
|
||
var wallIdx = proc.wallIdxMap[idx];
|
||
if(wallIdx<0 && !proc.floorSuppliedIdxes.contains(idx)){
|
||
//ceiling or empty -> noShadow
|
||
dstData[idx+zShadow] = 0;
|
||
return
|
||
}
|
||
|
||
//skip wall shadow setting
|
||
if(SETTING.noShadowOnWall){
|
||
if(wallIdx>=0 && wallIdx!==Number.MAX_SAFE_INTEGER){
|
||
return
|
||
}else if(proc.criffWallIdxes.contains(idx)){
|
||
return
|
||
}
|
||
}
|
||
|
||
|
||
/* compare zValue to left & leftUp tile
|
||
===================================*/
|
||
var z = proc.floorLevelZMap[idx];
|
||
if(proc.floorLevelZMap[idx] !== proc.zMap[idx]){
|
||
// if(!data[idx+zAcc] &&!data[idx+zObj1]&!data[idx+zObj2]){
|
||
// //accLayer is not upperTile -> original z
|
||
// z = proc.zMap[idx];
|
||
if((data[idx+zAcc]&&data[idx+zAcc]<1024)
|
||
|| (data[idx+zObj1]&&data[idx+zObj1]<1024)
|
||
|| (data[idx+zObj2]&&data[idx+zObj2]<1024)
|
||
){
|
||
//exists higher tile -> usefloorLevel
|
||
}else{
|
||
//accLayer is not upperTile -> original z
|
||
z = proc.zMap[idx];
|
||
}
|
||
}
|
||
|
||
|
||
|
||
var leftZ = proc.zMap[idx-1];
|
||
var leftUpZ = proc.zMap[idx-1-width];
|
||
if(idx%width===0){
|
||
if(SETTING.autoCeilingSupply){
|
||
leftZ = Number.MAX_SAFE_INTEGER;
|
||
leftUpZ = Number.MAX_SAFE_INTEGER;
|
||
}else{
|
||
return;
|
||
}
|
||
}else if(idx-width-1<0){
|
||
leftUpZ = Number.MAX_SAFE_INTEGER;
|
||
}
|
||
|
||
if(z<leftZ && z<leftUpZ){
|
||
dstData[idx+zShadow] = 5;
|
||
}
|
||
}
|
||
|
||
MapDecorator.clearShadows = function(){
|
||
for(var i=0; i<zLayerSize; i=(i+1)|0){
|
||
data[i+zShadow] = originalData[i+zShadow] = 0;
|
||
}
|
||
|
||
this.requestRefreshTilemap();
|
||
};
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Room Select
|
||
//=============================================================================
|
||
MapDecorator.analyzeRooms = function(){
|
||
var checked = [];
|
||
var separatorRegionId = Number(parameters.roomSeparatorRegionId)||-1;
|
||
var objForbiddenRegionId = Number(parameters.objForbiddenRegionId)||-1;
|
||
|
||
TRP_CORE.packValues(proc.roomIdxMapForUserProc,-1,zLayerSize);
|
||
|
||
for(var idx=0; idx<zLayerSize; idx=(idx+1)|0){
|
||
if(checked.contains(idx))continue;
|
||
if(isEmptyTile(idx))continue;
|
||
if(invalidIdxes && invalidIdxes.contains(idx))continue;
|
||
|
||
var roomIdxes = [];
|
||
var roomId = proc.allRoomIdxes.length;
|
||
proc.allRoomIdxes.push(roomIdxes);
|
||
|
||
|
||
var x = idx%width;
|
||
var y = Math.floor(idx/width);
|
||
analyzeNeighbors(x,y,(nx,ny)=>{
|
||
var nIdx = nx+ny*width;
|
||
if(checked.contains(nIdx))return false;
|
||
if(invalidIdxes && invalidIdxes.contains(idx))return false;
|
||
|
||
checked.push(nIdx);
|
||
if(isEmptyTile(nIdx))return false;
|
||
|
||
roomIdxes.push(nIdx);
|
||
proc.roomIdxMapForUserProc[nIdx] = roomId;
|
||
|
||
|
||
var regionId = data[nIdx+zRegion];
|
||
if(regionId===separatorRegionId){
|
||
return false;
|
||
}else if(regionId===objForbiddenRegionId){
|
||
TRP_CORE.uniquePush(proc.objForbiddenIdxes,nIdx);
|
||
}
|
||
|
||
return true;
|
||
});
|
||
}
|
||
|
||
/* baseIdxes
|
||
===================================*/
|
||
proc.allBaseIdxes = [];
|
||
for(const roomIdxes of proc.allRoomIdxes){
|
||
var roomBaseIdxes = [];
|
||
proc.allBaseIdxes.push(roomBaseIdxes);
|
||
for(var btIdx=baseTileIds.length-1; btIdx>=0; btIdx=(btIdx-1)|0){
|
||
roomBaseIdxes.push([]);
|
||
}
|
||
|
||
for(const idx of roomIdxes){
|
||
var tileId = baseTileId(data[idx]);
|
||
if(!tileId)continue;
|
||
|
||
var baseIdx = baseTileIds.indexOf(tileId);
|
||
if(baseIdx>=0){
|
||
roomBaseIdxes[baseIdx].push(idx);
|
||
continue;
|
||
}
|
||
for(var baseIdx=allInfo.length-1; baseIdx>=0; baseIdx=(baseIdx-1)|0){
|
||
var tempInfo = allInfo[baseIdx];
|
||
if(tempInfo.criffTopAllIds.contains(tileId)){
|
||
roomBaseIdxes[baseIdx].push(idx);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
if(proc.allRoomIdxes.length===0){
|
||
_Dev.throwError('部屋が検出できませんでした。');
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: roomSelect
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.roomSelect = [
|
||
'【編集対象の部屋を選択】',
|
||
'左クリ:部屋を選択',
|
||
'右クリ/Esc:キャンセル',
|
||
'※完成マップに部屋を追加する際に使用',
|
||
'※部屋を完全に境界リージョンIDで囲っておくこと!!',
|
||
];
|
||
|
||
|
||
MapDecorator.startRoomSelect = function(){
|
||
if(proc.allRoomIdxes.length<=1){
|
||
SoundManager.playBuzzer();
|
||
confirm('部屋が1つしかないか、すでに編集対象の部屋を指定済みです。')
|
||
return;
|
||
}
|
||
this.setMode('roomSelect');
|
||
};
|
||
|
||
|
||
var invalidIdxes = null;
|
||
MapDecorator.onMouseDownLeftRoomSelect = function(event,roomId,x,y,tx,ty){
|
||
if(roomId<0){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
|
||
//search invalidIdxes by regionId
|
||
var separatorRegionId = Number(parameters.roomSeparatorRegionId)||-1;
|
||
var idxes = proc.allRoomIdxes[roomId];
|
||
for(var i=idxes.length-1; i>=0; i=(i-1)|0){
|
||
var idx = idxes[i];
|
||
var sx = idx%width;
|
||
var sy = Math.floor(idx/width);
|
||
analyzeNeighbors(sx,sy,(nx,ny,ox,oy)=>{
|
||
var nIdx = nx+ny*width;
|
||
if(idx!==nIdx && idxes.contains(nIdx))return false;
|
||
|
||
var oRegionId = data[ox+oy*width+zRegion];
|
||
if(oRegionId===separatorRegionId){
|
||
//origin:separator -> only allow neighbor:sepearator
|
||
if(data[nIdx+zRegion]!==separatorRegionId){
|
||
return false;
|
||
}
|
||
}
|
||
idxes.push(nIdx);
|
||
return true;
|
||
});
|
||
}
|
||
|
||
invalidIdxes = [];
|
||
for(var i=0; i<zLayerSize; i=(i+1)|0){
|
||
if(!idxes.contains(i)){
|
||
invalidIdxes.push(i);
|
||
}
|
||
}
|
||
|
||
SoundManager.playOk();
|
||
this.restoreMode();
|
||
this.initProc();
|
||
|
||
|
||
if(confirm('自動補完をやり直しますか?')){
|
||
this.reloadMapData(true);
|
||
// this.analyzeAll();
|
||
// this.executeBeforeProcess();
|
||
}
|
||
|
||
this.saveState('編集対象の部屋を指定')
|
||
};
|
||
|
||
MapDecorator.onMouseDownRightRoomSelect = function(event,roomId,x,y,tx,ty){
|
||
SoundManager.playCancel();
|
||
this.restoreMode();
|
||
};
|
||
MapDecorator.updateInputRoomSelect = function(){
|
||
if(Input.isTriggered('cancel')){
|
||
SoundManager.playCancel();
|
||
this.restoreMode();
|
||
return true;
|
||
}else{
|
||
return false;
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: paintFloor
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.paintFloor = [
|
||
'【床装飾ペイントモード】',
|
||
'左クリ:再抽選',
|
||
'右クリ@部屋:確定!',
|
||
'Vキー@部屋:装飾種類をロック',
|
||
'Wキー@部屋:水場ロック',
|
||
'Ctrl+右クリ:装飾種類パレット',
|
||
];
|
||
|
||
MapDecorator.onKeyDownPaintFloor = function(event){
|
||
if(event.key==='v'){
|
||
var i = this.roomIdxOfTouchInput();
|
||
|
||
//pattern lock
|
||
if(i<0){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
if(proc.lockedFloorVariations[i]){
|
||
proc.lockedFloorVariations[i] = null;
|
||
|
||
var text = '装飾種類をロック解除';
|
||
showInfoText(text);
|
||
this.saveState(text);
|
||
SoundManager.playCancel();
|
||
}else{
|
||
proc.lockedFloorVariations[i] = proc.lastFloorVariations[i];
|
||
|
||
var text = '装飾種類をロック';
|
||
showInfoText(text+'!');
|
||
this.saveState(text);
|
||
SoundManager.playOk();
|
||
}
|
||
}else if(event.key==='w'){
|
||
var i = this.roomIdxOfTouchInput();
|
||
//water lock
|
||
if(i<0){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
if(proc.lockedFloorPaintRoomIds.contains(i)){
|
||
this.tryShowObjectPalette();
|
||
}else if(proc.lockedWaterRoomIds.contains(i)){
|
||
TRP_CORE.remove(proc.lockedWaterRoomIds,i);
|
||
|
||
var text = '水場ロック解除';
|
||
showInfoText(text);
|
||
this.saveState(text);
|
||
SoundManager.playCancel();
|
||
}else{
|
||
proc.lockedWaterRoomIds.push(i);
|
||
|
||
var text = '水場ロック!';
|
||
showInfoText(text);
|
||
this.saveState(text);
|
||
SoundManager.playOk();
|
||
}
|
||
}
|
||
};
|
||
MapDecorator.onMouseDownLeftPaintFloor = function(event,i,x,y,tx,ty,dx,dy){
|
||
if(this.onKeyControl){
|
||
if(this.tryStartManualLocateMode(event,i,x,y,tx,ty,dx,dy)){
|
||
//manual loc
|
||
}else{
|
||
this.tryStartManualPaintMode(event,i,x,y,tx,ty);
|
||
}
|
||
}else if(Input.isPressed('shift')){
|
||
// //pattern lock
|
||
// if(i<0){
|
||
// SoundManager.playBuzzer();
|
||
// return;
|
||
// }
|
||
// if(proc.lockedFloorVariations[i]){
|
||
// proc.lockedFloorVariations[i] = null;
|
||
|
||
// var text = '装飾種類をロック解除';
|
||
// showInfoText(text);
|
||
// this.saveState(text);
|
||
// SoundManager.playCancel();
|
||
// }else{
|
||
// proc.lockedFloorVariations[i] = proc.lastFloorVariations[i];
|
||
|
||
// var text = '装飾種類をロック';
|
||
// showInfoText(text+'!');
|
||
// this.saveState(text);
|
||
// SoundManager.playOk();
|
||
// }
|
||
}else{
|
||
//repaint
|
||
this.paintFloors();
|
||
|
||
this.saveState('床装飾の抽選');
|
||
SoundManager.playCursor();
|
||
}
|
||
};
|
||
MapDecorator.onMouseDownMiddlePaintFloor = function(event,i,x,y,tx,ty){
|
||
};
|
||
MapDecorator.onMouseDownRightPaintFloor = function(event,i,x,y,tx,ty,dx,dy){
|
||
if(i<0){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
if(this.onKeyControl){
|
||
this.startFloorVariationPaletteMode(event,i,x,y,tx,ty,dx,dy);
|
||
|
||
// //water lock
|
||
// if(i<0){
|
||
// SoundManager.playBuzzer();
|
||
// return;
|
||
// }
|
||
|
||
// if(proc.lockedFloorPaintRoomIds.contains(i)){
|
||
// this.tryShowObjectPalette();
|
||
// }else if(proc.lockedWaterRoomIds.contains(i)){
|
||
// TRP_CORE.remove(proc.lockedWaterRoomIds,i);
|
||
|
||
// var text = '水場ロック解除';
|
||
// showInfoText(text);
|
||
// this.saveState(text);
|
||
// SoundManager.playCancel();
|
||
// }else{
|
||
// proc.lockedWaterRoomIds.push(i);
|
||
|
||
// var text = '水場ロック!';
|
||
// showInfoText(text);
|
||
// this.saveState(text);
|
||
// SoundManager.playOk();
|
||
// }
|
||
}else if(Input.isPressed('shift')){
|
||
this.tryUnlockRoomState(i);
|
||
}else if(proc.lockedFloorPaintRoomIds.contains(i)){
|
||
SoundManager.playBuzzer();
|
||
// this.tryUnlockRoomState(i);
|
||
}else{
|
||
//paint lock
|
||
TRP_CORE.uniquePush(proc.lockedFloorPaintRoomIds,i);
|
||
TRP_CORE.uniquePush(proc.lockedWaterRoomIds,i);
|
||
|
||
this.setMode('locateObject');
|
||
|
||
var text = '装飾ロック!';
|
||
showInfoText(text);
|
||
this.saveState(text);
|
||
SoundManager.playOk();
|
||
}
|
||
};
|
||
MapDecorator.tryUnlockRoomState = function(i){
|
||
if(proc.lockedObjRoomIds.contains(i)){
|
||
TRP_CORE.remove(proc.lockedObjRoomIds,i);
|
||
this.clearLastObjects(i);
|
||
|
||
this.setMode('locateObject')
|
||
this.restoreMap();
|
||
|
||
var text = 'オブジェロック解除';
|
||
showInfoText(text);
|
||
this.saveState(text);
|
||
SoundManager.playCancel();
|
||
|
||
}else if(proc.lockedFloorPaintRoomIds.contains(i)){
|
||
TRP_CORE.remove(proc.lockedFloorPaintRoomIds,i);
|
||
TRP_CORE.remove(proc.lockedWaterRoomIds,i);
|
||
proc.lastFloorPaintInfoArr[i] = null;
|
||
proc.lastWaterInfoArr[i] = null;
|
||
this.clearLastObjects(i);
|
||
SoundManager.playCancel();
|
||
|
||
this.setMode('paintFloor');
|
||
this.restoreMap();
|
||
|
||
var text = '装飾ロック解除';
|
||
showInfoText(text);
|
||
this.saveState(text);
|
||
}else{
|
||
SoundManager.playBuzzer();
|
||
}
|
||
}
|
||
|
||
|
||
MapDecorator.paintFloors = function(){
|
||
//clear not locked paint info
|
||
var length = proc.allRoomIdxes.length;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
if(!proc.lockedFloorPaintRoomIds.contains(i)){
|
||
proc.lastFloorPaintInfoArr[i] = [];
|
||
proc.autoConnectRequestIdxes[i] = [];
|
||
}
|
||
|
||
if(!proc.lockedWaterRoomIds.contains(i)){
|
||
proc.lastWaterInfoArr[i] = [];
|
||
proc.waterAccIdxes[i] = [];
|
||
}
|
||
};
|
||
|
||
//restore map
|
||
if(proc.oncePaintFloor){
|
||
this.restoreMap();
|
||
}
|
||
|
||
//paint floors
|
||
proc.waterIdxes = [];
|
||
proc.oncePaintFloor = true;
|
||
|
||
|
||
var length = proc.allRoomIdxes.length;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
if(proc.lockedFloorPaintRoomIds.contains(i))continue;
|
||
|
||
var validIdxes = proc.allRoomIdxes[i];
|
||
if(proc.criffIdxes){
|
||
validIdxes = validIdxes.concat();
|
||
TRP_CORE.removeArray(validIdxes,proc.criffIdxes);
|
||
}
|
||
TRP_CORE.removeArray(validIdxes,proc.noAccIdxes);
|
||
|
||
for(const baseInfo of allInfo){
|
||
this.changeBaseInfo(baseInfo);
|
||
this.paintFloorWithRoom(validIdxes,i);
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
MapDecorator.paintFloorWithRoom = function(validIdxes,roomId){
|
||
/* analyze manual water locate
|
||
===================================*/
|
||
var waterInfo = proc.lastWaterInfoArr[roomId];
|
||
var manualWaterLocate = this.analyzeManualWaterLocate(validIdxes,roomId);
|
||
|
||
|
||
/* analyze floorIdxes
|
||
===================================*/
|
||
var targetIds = [info.floorBaseId];
|
||
var floorIdxes = validIdxes.filter(idx=>{
|
||
var tileId = data[idx];
|
||
if(!tileId)return false;
|
||
|
||
tileId = baseTileId(tileId)
|
||
return targetIds.contains(tileId);
|
||
});
|
||
|
||
|
||
/* draw paint WaterTiles
|
||
===================================*/
|
||
if(!manualWaterLocate){
|
||
this._paintWaterFloors(validIdxes,roomId,floorIdxes);
|
||
}
|
||
|
||
|
||
/* draw floor paint variations
|
||
===================================*/
|
||
this._paintFloors(validIdxes,roomId,floorIdxes);
|
||
|
||
|
||
/* adjust autotile shape
|
||
===================================*/
|
||
for(var i=floorIdxes.length-1; i>=0; i=(i-1)|0){
|
||
var idx = floorIdxes[i];
|
||
var tileId = baseTileId(data[idx]);
|
||
if(tileId && !info.criffTopAllIds.contains(tileId)){
|
||
data[idx] = connectAutoTileWithIdx(idx);
|
||
}
|
||
|
||
idx += zAcc;
|
||
data[idx] = connectAutoTileWithIdx(idx);
|
||
}
|
||
|
||
for(const idx of proc.autoConnectRequestIdxes[roomId]){
|
||
data[idx] = connectAutoTileWithIdx(idx);
|
||
}
|
||
|
||
|
||
/* save paint cache
|
||
===================================*/
|
||
var paintInfo = proc.lastFloorPaintInfoArr[roomId];
|
||
for(const idx of validIdxes){
|
||
paintInfo.push(idx);
|
||
paintInfo.push(data[idx]);
|
||
paintInfo.push(data[idx+zAcc]);
|
||
}
|
||
|
||
this.requestRefreshTilemap();
|
||
};
|
||
|
||
MapDecorator.requestRefreshTilemap = function(){
|
||
SceneManager._scene._spriteset._tilemap._needsRepaint = true;
|
||
};
|
||
|
||
|
||
MapDecorator.analyzeManualWaterLocate = function(validIdxes,roomId){
|
||
var waterInfo = proc.lastWaterInfoArr[roomId];
|
||
var hasManualLocate = false;
|
||
if(waterInfo.length){
|
||
waterInfo = null;
|
||
}
|
||
for(const idx of validIdxes){
|
||
var tileId = baseTileId(data[idx]);
|
||
if(tileId === info.waterBaseId){
|
||
hasManualLocate = true;
|
||
|
||
if(!waterInfo){
|
||
break;
|
||
}
|
||
waterInfo.push(idx);
|
||
waterInfo.push(data[idx]);
|
||
waterInfo.push(data[idx+zAcc]);
|
||
}
|
||
}
|
||
return hasManualLocate;
|
||
};
|
||
|
||
MapDecorator._paintWaterFloors = function(validIdxes,roomId,floorIdxes){
|
||
if(!info.waterBaseId)return;
|
||
|
||
var waterInfo = proc.lastWaterInfoArr[roomId];
|
||
|
||
|
||
/* try locate
|
||
===================================*/
|
||
var waterLocate = false;
|
||
if(proc.lockedFloorVariations[roomId]
|
||
&& proc.lockedFloorVariations[roomId][info.floorBaseId]
|
||
&& proc.lockedFloorVariations[roomId][info.floorBaseId].contains(MapDecorator.VARIATION_FLAG_WATER)
|
||
){
|
||
waterLocate = true;
|
||
}else if(SETTING.waterLocateMode<0){
|
||
waterLocate = Math.random()<=SETTING.waterLocateRate;
|
||
}else{
|
||
waterLocate = SETTING.waterLocateMode>0;
|
||
}
|
||
|
||
if(proc.lockedWaterRoomIds.contains(roomId)){
|
||
//locate on restoreMap
|
||
}else if(waterLocate){
|
||
//paint water base
|
||
var variationIds = [info.waterBaseId];
|
||
|
||
var waterPaintRate = SETTING.waterPaintRate;
|
||
waterPaintRate *= TRP_CORE.randomRateWithRange(SETTING.rateRange);
|
||
waterPaintRate = waterPaintRate.clamp(0,1);
|
||
|
||
var paintNum = Math.ceil(floorIdxes.length*waterPaintRate);
|
||
var chankMin = SETTING.waterChankMin;
|
||
var chankMax = SETTING.waterChankMax;
|
||
|
||
var validWaterIdxes = validIdxes.concat();
|
||
TRP_CORE.removeArray(validWaterIdxes,proc.passIdxes);
|
||
var waterIdxes = this.paintChank(variationIds,paintNum,chankMin,chankMax,validWaterIdxes);
|
||
proc.waterIdxes = proc.waterIdxes.concat(waterIdxes);
|
||
|
||
//paint water accessory
|
||
variationIds = info.waterAccIds;
|
||
if(variationIds && variationIds.length){
|
||
var waterAccPaintRate = SETTING.waterAccPaintRate;
|
||
waterAccPaintRate *= TRP_CORE.randomRateWithRange(SETTING.rateRange);
|
||
waterAccPaintRate = waterAccPaintRate.clamp(0,1);
|
||
|
||
paintNum = Math.ceil(waterIdxes.length*waterAccPaintRate);
|
||
chankMin = SETTING.waterPaintChankMin;
|
||
chankMax = SETTING.waterPaintChankMax;
|
||
var waterAccIdxes = this.paintChank(variationIds,paintNum,chankMin,chankMax,waterIdxes,info.waterBaseId);
|
||
if(waterAccIdxes){
|
||
proc.waterAccIdxes[roomId] = proc.waterAccIdxes[roomId].concat(waterAccIdxes);
|
||
}
|
||
}
|
||
|
||
//supply B-ceiling to water
|
||
var bCeilingWaters = [];
|
||
for(const idx of waterIdxes){
|
||
for(var d=0; d<3; d=(d+1)|0){
|
||
var dir = d===0 ? width : (d===1 ? -1 : 1);
|
||
if(proc.ceilingIdxes.contains(idx+dir)){
|
||
if(allFloorLevelTileIds.contains(baseTileId(data[idx+dir])) && data[idx+dir+zObj1]){
|
||
data[idx+dir] = info.waterBaseId;
|
||
bCeilingWaters.push(idx+dir);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
waterIdxes = waterIdxes.concat(bCeilingWaters);
|
||
bCeilingWaters = null;
|
||
|
||
|
||
/* adjust autotile shape
|
||
===================================*/
|
||
TRP_CORE.removeArray(floorIdxes,waterIdxes);
|
||
for(var i=waterIdxes.length-1; i>=0; i=(i-1)|0){
|
||
var idx = waterIdxes[i];
|
||
var connectEmpty = 2;
|
||
data[idx] = connectAutoTileWithIdx(idx,connectEmpty);
|
||
data[idx+zAcc] = connectAutoTileWithIdx(idx+zAcc);
|
||
|
||
waterInfo.push(idx);
|
||
waterInfo.push(data[idx]);
|
||
waterInfo.push(data[idx+zAcc]);
|
||
}
|
||
}
|
||
};
|
||
|
||
MapDecorator._paintFloors = function(validIdxes,roomId,floorIdxes){
|
||
var baseId = info.floorBaseId;
|
||
|
||
var paintRate = SETTING.floorPaintRate;
|
||
paintRate *= TRP_CORE.randomRateWithRange(SETTING.rateRange);
|
||
paintRate = paintRate.clamp(0,1);
|
||
|
||
|
||
var variationIds;
|
||
floorIdxes = floorIdxes.concat();
|
||
TRP_CORE.removeArray(floorIdxes,proc.waterIdxes);
|
||
|
||
var paintNum = Math.ceil(floorIdxes.length*paintRate);
|
||
var chankMin = SETTING.floorPaintChankMin;
|
||
var chankMax = SETTING.floorPaintChankMax;
|
||
|
||
//calc variationNum
|
||
var variationNum;
|
||
if(SETTING.floorPaintPatternNum>=0){
|
||
variationNum = SETTING.floorPaintPatternNum;
|
||
}else{
|
||
variationNum = 1;
|
||
for(var pi=2;; pi=(pi+1)|0){
|
||
var threshold = SETTING.floorPaintPatternsWithTiles[pi-1];
|
||
if(threshold===undefined)break;
|
||
|
||
if(floorIdxes.length >= threshold){
|
||
variationNum = pi;
|
||
}else{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
var candidates = info.floorVariationIds.concat();
|
||
|
||
//apply locked variations
|
||
var isLocked = proc.lockedFloorVariations[roomId]&&proc.lockedFloorVariations[roomId][info.floorBaseId];
|
||
if(isLocked){
|
||
variationIds = proc.lockedFloorVariations[roomId][info.floorBaseId];
|
||
|
||
//process flags
|
||
if(variationIds.contains(MapDecorator.VARIATION_FLAG_WATER)
|
||
|| variationIds.contains(MapDecorator.VARIATION_FLAG_SUPPLY)
|
||
){
|
||
variationIds = variationIds.concat();
|
||
}
|
||
|
||
TRP_CORE.remove(variationIds,MapDecorator.VARIATION_FLAG_WATER);
|
||
if(TRP_CORE.remove(variationIds,MapDecorator.VARIATION_FLAG_SUPPLY)){
|
||
variationNum -= variationIds.length;
|
||
TRP_CORE.removeArray(candidates,variationIds);
|
||
}else{
|
||
variationNum = 0;
|
||
}
|
||
}else{
|
||
variationIds = [];
|
||
}
|
||
|
||
|
||
var drawen = false;
|
||
for(var i=0; i<variationNum && candidates.length; i=(i+1)|0){
|
||
drawen = true;
|
||
TRP_CORE.uniquePush(variationIds,TRP_CORE.randomShift(candidates));
|
||
}
|
||
|
||
//add floor fix variation tiles
|
||
if(drawen){
|
||
if(info.floorFixVariationIds && info.floorFixVariationIds.length){
|
||
//adjust draw rate
|
||
var chankAve = Math.ceil((chankMin+chankMax)/2);
|
||
var srcVariationIds = variationIds.concat();
|
||
for(var i=chankAve-1-1; i>=0; i=(i-1)|0){
|
||
variationIds = variationIds.concat(srcVariationIds);
|
||
}
|
||
variationIds = variationIds.concat(info.floorFixVariationIds);
|
||
}
|
||
proc.lastFloorVariations[roomId] = proc.lastFloorVariations[roomId]||{};
|
||
proc.lastFloorVariations[roomId][info.floorBaseId] = variationIds;
|
||
}
|
||
|
||
|
||
//paint
|
||
var paintedIdxes;
|
||
if(variationIds.length>0){
|
||
paintedIdxes = this.paintChank(variationIds,paintNum,chankMin,chankMax,floorIdxes);
|
||
}else{
|
||
paintedIdxes = [];
|
||
}
|
||
return paintedIdxes;
|
||
}
|
||
|
||
|
||
/* helper
|
||
===================================*/
|
||
MapDecorator.isAccLayerTile = function(tileId){
|
||
var kind = Tilemap.getAutotileKind(tileId);
|
||
if(Tilemap.isTileA1(tileId)){
|
||
return kind>=1&&kind<=3;
|
||
}else{
|
||
return Math.floor(kind/4)%2===1;
|
||
}
|
||
};
|
||
MapDecorator.paintChank = function(variationIds, paintNum,chankMin,chankMax,idxPool,targetBaseId=info.floorBaseId){
|
||
if(!Array.isArray(variationIds)){
|
||
_Dev.throwError('invalid variationIds',variationIds);
|
||
}
|
||
|
||
var painted = [];//result
|
||
var current = [];
|
||
var next = [];
|
||
var checked = [];
|
||
var dirs = [width,width-1,-1,-1-width,-width,-width+1,1,1+width];
|
||
var paintTileId;
|
||
var noOverwrap = true;
|
||
|
||
idxPool = idxPool.concat();
|
||
for(var pi=0/*<paintIdx>*/; paintNum>=chankMin; pi=(pi+1)|0){
|
||
if(idxPool.length===0)break;
|
||
|
||
var idx = TRP_CORE.randomShift(idxPool);
|
||
if(noOverwrap){
|
||
if(baseTileId(data[idx])!==targetBaseId || baseTileId(data[idx+zAcc]))continue;
|
||
}else{
|
||
if(baseTileId(data[idx])!==targetBaseId && baseTileId(data[idx+zAcc]))continue;
|
||
}
|
||
|
||
|
||
//draw paintTileId
|
||
TRP_CORE.shuffle(variationIds);
|
||
|
||
var isAccesory = false;
|
||
for(var vi=variationIds.length-1; vi>=0; vi=(vi-1)|0){
|
||
paintTileId = variationIds[vi];
|
||
|
||
if(Tilemap.isAutotile(paintTileId)){
|
||
var isAccesory = this.isAccLayerTile(paintTileId);
|
||
|
||
if(noOverwrap){
|
||
break;
|
||
}else if(isAccesory){
|
||
if(!data[idx+zAcc]){
|
||
break;
|
||
}
|
||
}else{
|
||
if(baseTileId(data[idx])===targetBaseId)break;
|
||
}
|
||
}else{
|
||
//simple fix-variation tile
|
||
if(baseTileId(data[idx])!==targetBaseId)continue;
|
||
if(noOverwrap && data[idx+zAcc])continue;
|
||
break;
|
||
}
|
||
}
|
||
|
||
painted.push(idx);
|
||
|
||
//paint if simple fix variation tile
|
||
if(!Tilemap.isAutotile(paintTileId)){
|
||
data[idx] = paintTileId;
|
||
paintNum -= 1;
|
||
continue;
|
||
}
|
||
|
||
if(isAccesory){
|
||
data[idx+zAcc] = paintTileId;
|
||
}else{
|
||
data[idx] = paintTileId;
|
||
}
|
||
|
||
|
||
checked.length = 0;
|
||
current.length = 0;
|
||
next.length = 0;
|
||
next.push(idx);
|
||
|
||
|
||
//draw chank
|
||
var num = chankMin+Math.randomInt(chankMax-chankMin+1);
|
||
num = num.clamp(0,paintNum);
|
||
|
||
while(next.length && num>0){
|
||
var temp = TRP_CORE.prepareArray(current);
|
||
current = next;
|
||
next = temp;
|
||
|
||
for(const idx of current){
|
||
var di0 = 2*Math.randomInt(4);
|
||
var baseDi = -1;
|
||
for(var di=0; di<8; di=(di+1)|0){
|
||
var dirIdx = (di0+di)%8;
|
||
|
||
if(baseDi<0){
|
||
if(dirIdx%2===1){
|
||
//opposite
|
||
continue
|
||
}
|
||
}else{
|
||
if(dirIdx > baseDi+2){
|
||
break;
|
||
}
|
||
}
|
||
|
||
var dir = dirs[dirIdx];
|
||
var neighbor = idx+dir;
|
||
|
||
if(checked.contains(neighbor))continue;
|
||
checked.push(neighbor);
|
||
if(!idxPool.contains(neighbor))continue;
|
||
|
||
//check already paint with same type tile
|
||
if(noOverwrap){
|
||
if(baseTileId(data[neighbor])!==targetBaseId || baseTileId(data[neighbor+zAcc]))continue;
|
||
if(isAccesory){
|
||
data[neighbor+zAcc] = paintTileId;
|
||
}else{
|
||
data[neighbor] = paintTileId;
|
||
}
|
||
}else if(!isAccesory){
|
||
if(baseTileId(data[neighbor])!==targetBaseId)continue;
|
||
data[neighbor] = paintTileId;
|
||
}else{//isAccc
|
||
if(data[neighbor+zAcc])continue;
|
||
data[neighbor+zAcc] = paintTileId;
|
||
}
|
||
|
||
baseDi = di;
|
||
next.push(neighbor);
|
||
painted.push(neighbor);
|
||
num -= 1;
|
||
paintNum -= 1;
|
||
|
||
if(num<=0)break;
|
||
}
|
||
if(num<=0)break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return painted;
|
||
};
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: FloorVariationPalette
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.floorVariationPalette = [
|
||
'【床装飾種類パレットモード】',
|
||
'左クリ:装飾種類のロック/解除',
|
||
'右クリ:戻る',
|
||
];
|
||
MapDecorator.FLOOR_VARIATION_PALETTE_EMPTY_NUM = 5;
|
||
MapDecorator.FLOOR_VARIATION_PALETTE_SIZE = 48;
|
||
MapDecorator.FLOOR_VARIATION_PALETTE_MARGIN = 12;
|
||
|
||
MapDecorator.startFloorVariationPaletteMode = function(event,i,x,y,tx,ty,dx,dy){
|
||
if(i<0){
|
||
SoundManager.playBuzzer();
|
||
_Dev.showTempAlert('装飾種類をロックする部屋の上で実行!')
|
||
return;
|
||
}
|
||
|
||
this.setMode('floorVariationPalette',{
|
||
type:'floorVariationPalette',
|
||
roomId:i,
|
||
tx,ty,
|
||
});
|
||
SoundManager.playOk();
|
||
};
|
||
|
||
MapDecorator.setModeFloorVariationPalette = function(){
|
||
var roomId = this.modeData.roomId;
|
||
proc.lockedFloorVariations[roomId] = proc.lockedFloorVariations[roomId]||{};
|
||
|
||
var objectsArr = [];
|
||
var currentIdsArr = [];
|
||
var pageNames = [];
|
||
var idx = 0;
|
||
for(const _info of allInfo){
|
||
var objects = _info.floorVariationIds||null;
|
||
if(_info.dummyFloorVariationIds&&_info.dummyFloorVariationIds.length){
|
||
objects = objects.concat(_info.dummyFloorVariationIds);
|
||
}
|
||
pageNames.push('ベース床:%1<tileId=%2>'.format(idx++,_info.floorBaseId))
|
||
|
||
//supply variation button
|
||
var buttons = [
|
||
MapDecorator.VARIATION_FLAG_NO_SUPPLY,
|
||
MapDecorator.VARIATION_FLAG_WATER,
|
||
];
|
||
objects = buttons.concat(objects);
|
||
objectsArr.push(objects);
|
||
|
||
var currentIds = proc.lockedFloorVariations[roomId][_info.floorBaseId];
|
||
currentIdsArr.push(currentIds||null);
|
||
}
|
||
|
||
//palette setting
|
||
var size = MapDecorator.FLOOR_VARIATION_PALETTE_SIZE;
|
||
var m = MapDecorator.FLOOR_VARIATION_PALETTE_MARGIN;
|
||
var x0Num = MapDecorator.FLOOR_VARIATION_PALETTE_EMPTY_NUM;
|
||
|
||
//show palette
|
||
var pageIdx = 0;
|
||
this.showPalette(objectsArr,pageNames,pageIdx,size,m,x0Num,null,currentIdsArr);
|
||
};
|
||
|
||
MapDecorator.updateInputFloorVariationPalette = function(){
|
||
return true;
|
||
}
|
||
MapDecorator.onMouseDownLeftFloorVariationPalette = function(event,i,x,y,tx,ty){
|
||
this.onMouseDownLeftPaletteCommon(event,i,x,y,tx,ty);
|
||
};
|
||
|
||
MapDecorator.VARIATION_FLAG_SUPPLY = -1000;
|
||
MapDecorator.VARIATION_FLAG_NO_SUPPLY = -1001;
|
||
MapDecorator.VARIATION_FLAG_WATER = -1002;
|
||
MapDecorator.onMouseDownRightFloorVariationPalette = function(event,i,x,y,tx,ty){
|
||
var palette = this.showingPalette;
|
||
var objectsArr = palette.objectsArr;
|
||
var selectedArr = palette.selected;
|
||
|
||
var modeData = this.modeData;
|
||
var roomId = modeData.roomId;
|
||
proc.lockedFloorVariations[roomId] = proc.lockedFloorVariations[roomId]||{};
|
||
|
||
for(var i=0; i<objectsArr.length; i=(i+1)|0){
|
||
var floorBaseId = allInfo[i].floorBaseId;
|
||
var objects = objectsArr[i];
|
||
var selected = selectedArr[i];
|
||
var noSupply = TRP_CORE.remove(selected,0);
|
||
var variationIds = selected.map(idx=>{
|
||
if(idx===1)return MapDecorator.VARIATION_FLAG_WATER;
|
||
return objects[idx];
|
||
});
|
||
if(!noSupply){
|
||
variationIds.unshift(MapDecorator.VARIATION_FLAG_SUPPLY);
|
||
}
|
||
if(variationIds.length===0){
|
||
variationIds = null;
|
||
}
|
||
proc.lockedFloorVariations[roomId][floorBaseId] = variationIds;
|
||
}
|
||
|
||
this.restoreMode();
|
||
|
||
showInfoText('装飾種類ロックを変更!',modeData.tx,modeData.ty);
|
||
SoundManager.playOk();
|
||
};
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: ManualPaint
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.manualPaint = [
|
||
'【手動ペイントモード】',
|
||
'左クリ:塗り/消去',
|
||
'右クリ:終了',
|
||
'Ctrl+左クリ:タイル選択(スポイト)',
|
||
'Shift+右クリ:チャンク消去',
|
||
'Ctrl+右クリ:パレット表示',
|
||
];
|
||
|
||
MapDecorator.initManualPaintData = function(){
|
||
var modeData = this.modeData = {};
|
||
modeData.type = 'manualPaint';
|
||
modeData.paintTileId = 0;
|
||
modeData.paintAccLayer = false;
|
||
modeData.paintWater = false;
|
||
modeData.lastPaintIdx = -1;
|
||
modeData.paintErasing = false;
|
||
}
|
||
MapDecorator.tryStartManualPaintMode = function(event,roomId,x,y,tx,ty){
|
||
var paintTileId = 0;
|
||
var paintAccLayer = false;
|
||
var obj = null;
|
||
var idx = x+y*width;
|
||
for(var z=1; z>=0; z=(z-1)|0){
|
||
var tileId = baseTileId(data[z*zLayerSize+idx]);
|
||
if(!tileId)continue;
|
||
if(baseTileIds.contains(tileId))continue;
|
||
if(this.isWallTile(tileId))continue;
|
||
if(this.isCeilingTile(tileId))continue;
|
||
|
||
if(z<=1){
|
||
paintTileId = tileId;
|
||
paintAccLayer = z===1;
|
||
}
|
||
break;
|
||
}
|
||
if(!paintTileId){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
this.startManualPaintModeWithTileId(paintTileId);
|
||
var modeData = this.modeData;
|
||
modeData.paintAccLayer = paintAccLayer;
|
||
modeData.lastPaintIdx = idx;
|
||
modeData.paintWater = modeData.paintWater || (proc.waterIdxes&&proc.waterIdxes.contains(idx));
|
||
|
||
SoundManager.playCursor();
|
||
};
|
||
MapDecorator.startManualPaintModeWithTileId = function(tileId){
|
||
this.setMode('manualPaint');
|
||
|
||
this.initManualPaintData();
|
||
var modeData = this.modeData;
|
||
modeData.paintTileId = tileId;
|
||
modeData.paintWater = Tilemap.isWaterTile(tileId)||Tilemap.isTileA1(tileId);
|
||
modeData.paintAccLayer = this.isAccLayerTile(tileId);
|
||
|
||
this.saveState('手動ペイント開始');
|
||
};
|
||
|
||
|
||
MapDecorator.onMousePressManualPaint = function(event,roomId,x,y,tx,ty){
|
||
if(!this.modeData)return;
|
||
if(!this.modeData.paintTileId)return;
|
||
if(roomId<0)return;
|
||
|
||
if(this.onKeyControl){
|
||
}else if(Input.isPressed('shift')){
|
||
}else{
|
||
this.processManualPaint(...arguments);
|
||
}
|
||
};
|
||
MapDecorator.onMouseDownLeftManualPaint = function(event,roomId,x,y,tx,ty){
|
||
if(roomId<0)return;
|
||
|
||
if(this.onKeyControl){
|
||
this.tryStartManualPaintMode(event,roomId,x,y,tx,ty);
|
||
}else{
|
||
this.processManualPaint(event,roomId,x,y,tx,ty);
|
||
}
|
||
};
|
||
MapDecorator.onMouseDownRightManualPaint = function(event,roomId,x,y,tx,ty){
|
||
if(Input.isPressed('shift')){
|
||
this.processManualPaintChankDelete(event,roomId,x,y,tx,ty);
|
||
}else if(this.onKeyControl){
|
||
this.startManualPaintPaletteMode();
|
||
}else{
|
||
SoundManager.playCancel();
|
||
this.restoreMode();
|
||
}
|
||
};
|
||
|
||
MapDecorator.processManualPaint = function(event,roomId,x,y,tx,ty){
|
||
if(!this.modeData)return;
|
||
|
||
var idx = x+y*width;
|
||
if(this.modeData.lastPaintIdx===idx)return;
|
||
var startPainting = this.modeData.lastPaintIdx<0;
|
||
this.modeData.lastPaintIdx = idx;
|
||
|
||
var isAccLayer = this.modeData.paintAccLayer;
|
||
var isWater = this.modeData.paintWater;
|
||
var targetWater = Tilemap.isWaterTile(data[idx]) || (proc.waterIdxes&&proc.waterIdxes.contains(idx))
|
||
|
||
var tileId = this.modeData.paintTileId;
|
||
var baseInfoIdx = proc.idxBaseInfoIdxMap[idx]||0;
|
||
var baseInfo = allInfo[baseInfoIdx];
|
||
|
||
|
||
/* check target tile or idx valid
|
||
===================================*/
|
||
var failure = false;
|
||
if(proc.wallIdxes.contains(idx)){
|
||
failure = true;
|
||
}else if(isWater!==targetWater && tileId!==baseInfo.waterBaseId){
|
||
failure = true;
|
||
}else if(isAccLayer&&proc.criffTopIdxes.contains(idx)){
|
||
//acc && criffTop
|
||
if(criffTopIds.contains(baseTileId(data[zAcc+idx]))){
|
||
//accLayer:criff -> fail
|
||
failure = true;
|
||
}else{
|
||
//accLayer:free -> ok
|
||
}
|
||
}else if(proc.criffTopIdxes.contains(idx)||proc.criffIdxes.contains(idx)){
|
||
failure = true;
|
||
}
|
||
if(failure){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
|
||
/* write tileId
|
||
===================================*/
|
||
var zIdx = isAccLayer ? zAcc : 0;
|
||
var paintId = tileId;
|
||
if(baseTileId(data[idx+zIdx])===tileId){
|
||
//erase
|
||
if(startPainting){
|
||
this.modeData.paintErasing = true;
|
||
}else if(!this.modeData.paintErasing){
|
||
return;
|
||
}
|
||
paintId = 0;
|
||
|
||
if(isWater && tileId===baseInfo.waterBaseId){
|
||
isWater = false;
|
||
}
|
||
}else{
|
||
if(startPainting){
|
||
this.modeData.paintErasing = false;
|
||
}else if(this.modeData.paintErasing){
|
||
return;
|
||
}
|
||
}
|
||
|
||
var idxes = [idx];
|
||
var waterWrite = isWater!==targetWater;
|
||
this.paintTilesWithIdxes(idxes,isAccLayer,roomId,paintId,isWater,waterWrite)
|
||
|
||
this.saveState('手動ペイント:塗り',true);
|
||
SoundManager.playCursor();
|
||
};
|
||
|
||
MapDecorator.processManualPaintChankDelete = function(event,roomId,x,y,tx,ty){
|
||
var idx = x+y*width;
|
||
var isAccLayer = this.modeData.paintAccLayer;
|
||
|
||
this.modeData.lastPaintIdx = idx;
|
||
this.modeData.paintErasing = true;
|
||
|
||
|
||
/* write tileId
|
||
===================================*/
|
||
var zIdx = isAccLayer ? zAcc : 0;
|
||
var tileId = this.modeData.paintTileId;
|
||
if(!tileId || baseTileId(data[idx+zIdx])!==tileId){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
|
||
//search chank idxes
|
||
var idxes = this.analyzeNeighbors(x,y,(nx,ny,ox,oy)=>{
|
||
if(nx===x&&ny===y)return true;
|
||
|
||
if(proc.zMap[ox+oy*width]!==proc.zMap[nx+ny*width])return false;
|
||
if(idxOfRoom(nx+ny*width)!==roomId)return false;
|
||
|
||
var nIdx = (isAccLayer?zAcc:0)+nx+ny*width;
|
||
var nTileId = data[nIdx];
|
||
if(baseTileId(nTileId)!==tileId)return false;
|
||
|
||
return true;
|
||
},true);
|
||
|
||
if(idxes.length===1){
|
||
var idxes = this.analyzeNeighbors(x,y,(nx,ny,ox,oy)=>{
|
||
if(nx===x&&ny===y)return true;
|
||
|
||
if(proc.zMap[ox+oy*width]!==proc.zMap[nx+ny*width])return false;
|
||
if(idxOfRoom(nx+ny*width)!==roomId)return false;
|
||
|
||
var nIdx = (isAccLayer?zAcc:0)+nx+ny*width;
|
||
var nTileId = data[nIdx];
|
||
if(baseTileId(nTileId)!==tileId)return false;
|
||
|
||
return true;
|
||
},true);
|
||
}
|
||
|
||
|
||
var baseInfoIdx = proc.idxBaseInfoIdxMap[idx]||0;
|
||
var baseInfo = allInfo[baseInfoIdx];
|
||
var isWater = this.modeData.paintWater;
|
||
var waterWrite = this.modeData.paintTileId===baseInfo.waterBaseId;
|
||
if(waterWrite){
|
||
isWater = false;
|
||
}
|
||
|
||
this.paintTilesWithIdxes(idxes,isAccLayer,roomId,0,isWater,waterWrite);
|
||
SoundManager.playCursor();
|
||
|
||
this.saveState('手動ペイント:消し');
|
||
};
|
||
|
||
MapDecorator.updateManualPaint = function(){
|
||
if(!this.modeData)return;
|
||
if(!TouchInput.isPressed() && !TouchInput.isTriggered()){
|
||
this.modeData.lastPaintIdx = -1;
|
||
}
|
||
};
|
||
|
||
MapDecorator.paintTilesWithIdxes = function(idxes,isAccLayer,roomId,tileId,isWater=false,waterWrite=false){
|
||
var zIdx = isAccLayer ? zAcc : 0;
|
||
|
||
/* water write
|
||
===================================*/
|
||
proc.lastFloorPaintInfoArr[roomId] = proc.lastFloorPaintInfoArr[roomId]||[];
|
||
proc.lastWaterInfoArr[roomId] = proc.lastWaterInfoArr[roomId]||[]
|
||
var paintInfo = proc.lastFloorPaintInfoArr[roomId];
|
||
var waterInfo = proc.lastWaterInfoArr[roomId];
|
||
var srcInfo = isWater ? paintInfo : waterInfo;
|
||
if(waterWrite){
|
||
//clear all tile
|
||
for(const idx of idxes){
|
||
data[idx] = 0;
|
||
data[idx+zAcc] = 0;
|
||
}
|
||
//clear paint info
|
||
for(var i=0; i<srcInfo.length; i=(i+3)|0){
|
||
if(idxes.contains(srcInfo[i])){
|
||
srcInfo.splice(i,3);
|
||
i -= 3;
|
||
}
|
||
}
|
||
|
||
//remove waterIdxes
|
||
if(!isWater){
|
||
if(proc.waterIdxes){
|
||
TRP_CORE.removeArray(proc.waterIdxes,idxes);
|
||
}
|
||
if(proc.waterAccIdxes){
|
||
TRP_CORE.removeArray(proc.waterAccIdxes,idxes);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/* write data
|
||
===================================*/
|
||
for(const idx of idxes){
|
||
var paintId = tileId;
|
||
var baseInfoIdx = proc.idxBaseInfoIdxMap[idx]||0;
|
||
var baseInfo = allInfo[baseInfoIdx];
|
||
|
||
if(zIdx===0 && !tileId){
|
||
//clear tile
|
||
paintId = isWater ? (baseInfo.waterBaseId||allInfo[0].waterBaseId) : baseInfo.floorBaseId;
|
||
}
|
||
data[idx+zIdx] = paintId;
|
||
|
||
if(isWater){
|
||
TRP_CORE.uniquePush(proc.waterIdxes,idx);
|
||
if(baseInfo.waterBaseId!==paintId){
|
||
TRP_CORE.uniquePush(proc.waterAccIdxes,idx);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/* around tiles
|
||
===================================*/
|
||
//search neighbors
|
||
var changedIdxes = idxes.concat();
|
||
var dirs8 = [-1+width,width,1+width,-1,1,-1-width,-width,1-width];
|
||
for(const idx of idxes){
|
||
for(var dir=1; dir<=9; dir=(dir+1)|0){
|
||
if(dir===5)continue;
|
||
|
||
var dIdx = idxForNeighborDir(idx,dir);
|
||
if(dIdx<0)continue;
|
||
if(changedIdxes.contains(dIdx))continue;
|
||
|
||
var nId = baseTileId(data[dIdx]);
|
||
var nIdAcc = baseTileId(data[dIdx+zAcc]);
|
||
if(!nId && !nIdAcc)continue;
|
||
|
||
if(!criffTopIds.contains(nId)&&(Tilemap.isTileA3(nId)||Tilemap.isTileA4(nId)))continue;
|
||
if(!criffTopIds.contains(nIdAcc)&&(Tilemap.isTileA3(nIdAcc)||Tilemap.isTileA4(nIdAcc)))continue;
|
||
|
||
changedIdxes.push(dIdx);
|
||
}
|
||
}
|
||
|
||
//auto connect
|
||
for(const idx of changedIdxes){
|
||
for(var z=0; z<2; z=(z+1)|0){
|
||
var tIdx = idx+z*zLayerSize;
|
||
var tileId = baseTileId(data[tIdx]);
|
||
if(tileId && Tilemap.isAutotile(tileId) && !criffTopIds.contains(tileId)){
|
||
data[tIdx] = connectAutoTileWithIdx(tIdx);
|
||
}
|
||
}
|
||
|
||
|
||
//once delete paint Info
|
||
for(var type=0; type<2; type=(type+1)|0){
|
||
var info = type===0 ? waterInfo : paintInfo;
|
||
for(var i=0; i<info.length; i=(i+3)|0){
|
||
if(info[i]===idx){
|
||
info.splice(i,3);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
//add to info
|
||
var water = Tilemap.isWaterTile(data[idx]) || (proc.waterIdxes&&proc.waterIdxes.contains(idx))
|
||
var info = water ? waterInfo : paintInfo
|
||
info.push(idx);
|
||
info.push(data[idx]);
|
||
info.push(data[idx+zAcc]);
|
||
}
|
||
|
||
|
||
this.requestRefreshTilemap();
|
||
};
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: ManualPaintPalette
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.manualPaintPalette = [
|
||
'【手動ペイントパレットモード】',
|
||
'左クリ:タイルの選択',
|
||
'右クリ:戻る',
|
||
];
|
||
|
||
MapDecorator.startManualPaintPaletteMode = function(event,i,x,y,tx,ty,dx,dy){
|
||
this.setMode('manualPaintPalette');
|
||
SoundManager.playOk();
|
||
};
|
||
MapDecorator.setModeManualPaintPalette = function(){
|
||
var objectsArr = [];
|
||
var pageNames = [];
|
||
var idx = 0;
|
||
for(const _info of allInfo){
|
||
var objects = [];
|
||
objectsArr.push(objects);
|
||
pageNames.push('ベース床:%1<tileId=%2>'.format(idx++,_info.floorBaseId))
|
||
|
||
if(_info.floorVariationIds){
|
||
objects.push(..._info.floorVariationIds);
|
||
}
|
||
if(_info.waterBaseId){
|
||
objects.push(_info.waterBaseId);
|
||
}
|
||
if(_info.waterAccIds && _info.waterAccIds.length){
|
||
for(const tileId of _info.waterAccIds){
|
||
objects.push([_info.waterBaseId,tileId]);
|
||
}
|
||
}
|
||
}
|
||
|
||
//palette setting
|
||
var size = MapDecorator.FLOOR_VARIATION_PALETTE_SIZE;
|
||
var m = MapDecorator.FLOOR_VARIATION_PALETTE_MARGIN;
|
||
var x0Num = MapDecorator.FLOOR_VARIATION_PALETTE_EMPTY_NUM;
|
||
|
||
//show palette
|
||
var pageIdx = 0;
|
||
this.showPalette(objectsArr,pageNames,pageIdx,size,m,x0Num,obj=>{
|
||
if(Array.isArray(obj)){
|
||
obj = TRP_CORE.last(obj);
|
||
}
|
||
this.startManualPaintModeWithTileId(obj);
|
||
SoundManager.playCursor();
|
||
});
|
||
};
|
||
|
||
MapDecorator.updateInputManualPaintPalette = function(){
|
||
return true;
|
||
}
|
||
MapDecorator.onMouseDownLeftManualPaintPalette = function(event,i,x,y,tx,ty){
|
||
this.onMouseDownLeftPaletteCommon(event,i,x,y,tx,ty);
|
||
};
|
||
MapDecorator.onMouseDownRightManualPaintPalette = function(event,i,x,y,tx,ty){
|
||
SoundManager.playCancel();
|
||
this.restoreMode();
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: LocateObject
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.locateObject = [
|
||
'【オブジェクト配置モード】',
|
||
'左クリ:再配置',
|
||
'右クリ@部屋:確定!',
|
||
'Shift+右クリ@部屋:ロック解除',
|
||
'Ctrl+左クリ:オブジェ手動調整<スポイト>',
|
||
'Ctrl+右クリ:オブジェクトパレット',
|
||
];
|
||
if(MapObject){
|
||
MapDecorator.MODE_GUIDE.locateObject.push(
|
||
'Shift+左クリ:ドットシフト'
|
||
);
|
||
}
|
||
MapDecorator.onMouseDownLeftLocateObject = function(event,i,x,y,tx,ty,dx,dy){
|
||
if(this.onKeyControl){
|
||
if(this.tryStartManualLocateMode(event,i,x,y,tx,ty,dx,dy)){
|
||
return;
|
||
}
|
||
// if(proc.lastObjInfoArr && proc.lastObjInfoArr[i]){
|
||
// SoundManager.playBuzzer();
|
||
// }else{
|
||
this.tryStartManualPaintMode(event,i,x,y,tx,ty);
|
||
// }
|
||
}else if(Input.isPressed('shift')){
|
||
this.tryDotShiftObjects(i);
|
||
}else{
|
||
//relocate
|
||
this.locateObjects();
|
||
SoundManager.playCursor();
|
||
this.saveState('オブジェクトの抽選');
|
||
}
|
||
};
|
||
MapDecorator.onMouseDownMiddleLocateObject = function(event,i,x,y,tx,ty){
|
||
};
|
||
MapDecorator.onMouseDownRightLocateObject = function(event,i,x,y,tx,ty){
|
||
if(i<0){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
if(Input.isPressed('shift')){
|
||
//try back to paintFloor
|
||
this.tryUnlockRoomState(i);
|
||
}else if(this.onKeyControl){
|
||
this.tryShowObjectPalette();
|
||
}else if(proc.lockedObjRoomIds.contains(i)){
|
||
SoundManager.playBuzzer();
|
||
}else if(!proc.lockedFloorPaintRoomIds.contains(i)){
|
||
//not lock floor paint yet
|
||
SoundManager.playBuzzer();
|
||
}else{
|
||
//object lock
|
||
TRP_CORE.uniquePush(proc.lockedObjRoomIds,i);
|
||
TRP_CORE.uniquePush(proc.lockedFloorPaintRoomIds,i);
|
||
TRP_CORE.uniquePush(proc.lockedWaterRoomIds,i);
|
||
proc.leftObjIdxesArr[i] = null;
|
||
this.setMode('paintFloor');
|
||
|
||
|
||
var text = 'オブジェロック!';
|
||
showInfoText(text);
|
||
this.saveState(text);
|
||
SoundManager.playOk();
|
||
}
|
||
};
|
||
|
||
MapDecorator.locateObjects = function(){
|
||
//restore map
|
||
var length = proc.allRoomIdxes.length;
|
||
if(proc.locateObj){
|
||
this.restoreMap();
|
||
}else{
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
if(!proc.lockedObjRoomIds.contains(i)){
|
||
proc.lastObjInfoArr[i] = [];
|
||
}
|
||
}
|
||
}
|
||
proc.locateObj = true;
|
||
|
||
|
||
//locate objects
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
if(proc.lockedObjRoomIds.contains(i))continue;
|
||
if(!proc.lockedFloorPaintRoomIds.contains(i))continue;
|
||
|
||
var validIdxes = proc.allRoomIdxes[i];
|
||
var roomId = i;
|
||
|
||
validIdxes = validIdxes.concat();
|
||
|
||
TRP_CORE.removeArray(validIdxes,proc.objForbiddenIdxes);
|
||
TRP_CORE.removeArray(validIdxes,proc.passIdxes);
|
||
proc.leftObjIdxesArr[i] = {};
|
||
|
||
var baseIdx = 0;
|
||
var roomBaseIdxes = proc.allBaseIdxes[i];
|
||
for(const baseInfo of allInfo){
|
||
this.changeBaseInfo(baseInfo);
|
||
|
||
var baseIdxes = roomBaseIdxes[baseIdx++].concat();
|
||
TRP_CORE.removeArray(baseIdxes,proc.objForbiddenIdxes);
|
||
TRP_CORE.removeArray(baseIdxes,proc.passIdxes);
|
||
proc.leftObjIdxesArr[i][info.floorBaseId] = {};
|
||
|
||
this.locateObjectsWithRoom(validIdxes,roomId,baseIdxes);
|
||
}
|
||
}
|
||
};
|
||
|
||
MapDecorator.locateObjectsWithRoom = function(validIdxes,roomId,baseIdxes){
|
||
var types = ['base'];
|
||
|
||
/* prepare accIdxes
|
||
===================================*/
|
||
var accIds = info.separateLocateObjAccIds;
|
||
var accIdxes = {};
|
||
for(const accId of accIds){
|
||
accIdxes[accId] = this.prepareAccIdxesForLocateObject(baseIdxes,accId);
|
||
types.push(accId);
|
||
}
|
||
|
||
|
||
/* prepare waterIdxes
|
||
===================================*/
|
||
var waterInfoArr = proc.lastWaterInfoArr[roomId];
|
||
var waterIdxes = null;
|
||
if(waterInfoArr){
|
||
waterIdxes = prepareWaterIdxesForLocateObject(baseIdxes,waterInfoArr,proc.waterAccIdxes[roomId]);
|
||
types.push('water');
|
||
}
|
||
|
||
|
||
/* locate objects
|
||
===================================*/
|
||
var targetIdxes,rate,objIds,floorBaseId,bigObjIds,bigRate;
|
||
var objInfo = [];
|
||
var maxObjInfo = objInfo;
|
||
var typeLen = types.length;
|
||
for(var typeIdx=0; typeIdx<typeLen; typeIdx=(typeIdx+1)|0){
|
||
var type = types[typeIdx];
|
||
if(type==='base'){
|
||
//floor
|
||
targetIdxes = baseIdxes;
|
||
rate = SETTING.floorObjRate;
|
||
bigRate = SETTING.floorBigObjRate;
|
||
objIds = info.objIds;
|
||
bigObjIds = info.bigObjIds;
|
||
floorBaseId = info.floorBaseId;
|
||
}else if(type==='water'){
|
||
//water
|
||
targetIdxes = waterIdxes;
|
||
if(!targetIdxes || targetIdxes.length===0)continue;
|
||
|
||
rate = SETTING.waterObjRate;
|
||
bigRate = SETTING.waterBigRate;
|
||
objIds = info.waterObjIds;
|
||
bigObjIds = info.waterBigObjIds;
|
||
floorBaseId = info.waterBaseId;
|
||
}else{
|
||
//accessory
|
||
floorBaseId = Number(type);
|
||
targetIdxes = accIdxes[floorBaseId];
|
||
|
||
var accInfo = info.accSettings[floorBaseId];
|
||
rate = SETTING.floorObjRate * accInfo.objRate;
|
||
bigRate = SETTING.floorBigObjRate * accInfo.bigObjRate;
|
||
objIds = accInfo.objIds;
|
||
bigObjIds = accInfo.bigObjIds;
|
||
}
|
||
|
||
|
||
var maximizeTryNum = SETTING.maximizeObjRateTryNum||1;
|
||
var doMaximize = SETTING.maximizeObjRateTryNum >= 1;
|
||
var srcTargetIdxes = targetIdxes;
|
||
var minLeftTargetIdxesNum = Number.MAX_SAFE_INTEGER;
|
||
var srcObjInfo = objInfo;
|
||
var srcBigObjIds = bigObjIds;
|
||
|
||
var floorLen = targetIdxes.length;
|
||
|
||
if(!doMaximize){
|
||
rate *= TRP_CORE.randomRateWithRange(0.3);
|
||
bigRate *= TRP_CORE.randomRateWithRange(0.3);
|
||
}
|
||
var objNum = TRP_CORE.randomRound(rate*floorLen);
|
||
|
||
var bigObjNum = TRP_CORE.randomRound(bigRate*floorLen);
|
||
|
||
if(!objIds || objIds.length===0)objNum = 0;
|
||
if(!bigObjIds || bigObjIds.length===0)bigObjNum = 0;
|
||
|
||
|
||
/* for loop try maximize packRate
|
||
===================================*/
|
||
for(var tryIdx=maximizeTryNum-1; tryIdx>=0; tryIdx=(tryIdx-1)|0){
|
||
objInfo = srcObjInfo.concat();
|
||
targetIdxes = srcTargetIdxes.concat();
|
||
TRP_CORE.shuffle(targetIdxes);
|
||
|
||
|
||
/* locate obj
|
||
===================================*/
|
||
var idx;
|
||
for(var i=objNum-1; i>=0; i=(i-1)|0){
|
||
var tileIds = TRP_CORE.random(objIds);
|
||
var tileId = tileIds[0];
|
||
idx = -1;
|
||
if(Tilemap.isTileA5(tileId)){
|
||
for(const tempIdx of targetIdxes){
|
||
if(data[tempIdx]!==floorBaseId && data[tempIdx+zAcc]!==floorBaseId){
|
||
idx = tempIdx;
|
||
break;
|
||
}
|
||
}
|
||
}else{
|
||
idx = TRP_CORE.random(targetIdxes);
|
||
}
|
||
if(idx>=0 && idx!==null){
|
||
if(!Array.isArray(tileIds)){
|
||
tileIds = tileIds.copy();
|
||
}
|
||
TRP_CORE.remove(targetIdxes,idx);
|
||
objInfo.push([idx,tileIds]);
|
||
}
|
||
}
|
||
|
||
|
||
/* locate bigObj
|
||
===================================*/
|
||
var locateInfo = [];
|
||
if(doMaximize){
|
||
bigObjIds = srcBigObjIds.concat();
|
||
TRP_CORE.shuffle(bigObjIds);
|
||
}
|
||
|
||
var locateSuccess = false;
|
||
for(var i=bigObjNum-1; i>=0;i-=1){
|
||
var bigObjInfo;
|
||
if(doMaximize){
|
||
if(locateSuccess || bigObjIds.length===0){
|
||
bigObjIds = srcBigObjIds.concat();
|
||
TRP_CORE.shuffle(bigObjIds);
|
||
}else{
|
||
if(i<bigObjNum-1){
|
||
i += 1;
|
||
}
|
||
}
|
||
bigObjInfo = bigObjIds.pop();
|
||
}else{
|
||
bigObjInfo = TRP_CORE.random(bigObjIds);
|
||
}
|
||
var bigObj = bigObjInfo[0];
|
||
var onFloorFlags = bigObjInfo[1];
|
||
var bigMapObject = !Array.isArray(bigObj) ? bigObj.copy() : null;
|
||
|
||
var w = onFloorFlags.length;
|
||
var h = onFloorFlags[0].length;
|
||
|
||
locateSuccess = false;
|
||
for(var ti=0; ti<targetIdxes.length; ti=(ti+1)|0){
|
||
locateInfo.length = 0;
|
||
|
||
/* check bigObj locatable
|
||
===================================*/
|
||
var baseIdx = targetIdxes[ti];
|
||
var locateFailed = false;
|
||
var floorZ = Number.MAX_SAFE_INTEGER;
|
||
for(var dx=0; dx<w; dx=(dx+1)|0){
|
||
for(var dy=0; dy<h; dy=(dy+1)|0){
|
||
var idx = baseIdx+dx-dy*width;
|
||
var tileIds = bigMapObject ? null : bigObj[dx][h-1-dy];
|
||
var onFloor = onFloorFlags[dx][h-1-dy];
|
||
|
||
if(!bigMapObject && !tileIds)continue;
|
||
|
||
if(onFloor){
|
||
//check is floor
|
||
if(!targetIdxes.contains(idx)){
|
||
locateFailed = true;
|
||
break;
|
||
}
|
||
//check all floor z same
|
||
if(floorZ===Number.MAX_SAFE_INTEGER){
|
||
floorZ = proc.zMap[idx];
|
||
}else if(floorZ !== proc.zMap[idx]){
|
||
locateFailed = true;
|
||
break;
|
||
}
|
||
}
|
||
locateInfo.push(idx);
|
||
locateInfo.push(tileIds);
|
||
locateInfo.push(onFloor);
|
||
}
|
||
if(locateFailed)break;
|
||
}
|
||
if(locateFailed)continue;
|
||
|
||
//add objInfo to locate
|
||
objInfo.push([baseIdx-(h-1)*width,bigMapObject||bigObj]);
|
||
|
||
//remove target idxes
|
||
var baseY = Math.floor(baseIdx/width);
|
||
for(var li=0; li<locateInfo.length; li=(li+3)|0){
|
||
var idx = locateInfo[li];
|
||
var tileIds = locateInfo[li+1];
|
||
var onFloor = locateInfo[li+2];
|
||
|
||
if(onFloor){
|
||
TRP_CORE.remove(targetIdxes,idx);
|
||
}
|
||
}
|
||
|
||
locateSuccess = true;
|
||
i -= (locateInfo.length/3);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* calc packRate
|
||
===================================*/
|
||
var leftNum = targetIdxes.length;
|
||
if(leftNum<minLeftTargetIdxesNum){
|
||
minLeftTargetIdxesNum = leftNum;
|
||
maxObjInfo = objInfo;
|
||
|
||
//save leftIdxes
|
||
proc.leftObjIdxesArr[roomId][info.floorBaseId][type] = targetIdxes;
|
||
}
|
||
}
|
||
objInfo = maxObjInfo;
|
||
}
|
||
|
||
|
||
//sort by "y"
|
||
proc.lastObjInfoArr[roomId] = proc.lastObjInfoArr[roomId].concat(
|
||
objInfo.sort((a,b)=>{
|
||
return a[0]-b[0];
|
||
})
|
||
);
|
||
|
||
//apply add objects
|
||
addObjTilesWithObjInfoArr(objInfo);
|
||
this.requestRefreshTilemap();
|
||
|
||
if(MapObject){
|
||
MapObject.refreshCollisions();
|
||
}
|
||
};
|
||
|
||
MapDecorator.prepareAccIdxesForLocateObject = function(validIdxes,accId){
|
||
var idxes = [];
|
||
for(var i=validIdxes.length-1; i>=0; i=(i-1)|0){
|
||
var idx = validIdxes[i];
|
||
if(baseTileId(data[idx])===accId
|
||
|| baseTileId([data[idx+zAcc]])===accId
|
||
){
|
||
idxes.unshift(idx);
|
||
validIdxes.splice(i,1);
|
||
}
|
||
}
|
||
return idxes;
|
||
};
|
||
|
||
function prepareWaterIdxesForLocateObject(validIdxes,waterInfoArr,waterAccIdxes){
|
||
var length = waterInfoArr.length;
|
||
var tempIdxes = [];
|
||
for(var i=0; i<length; i=(i+3)|0){
|
||
tempIdxes.push(waterInfoArr[i])
|
||
}
|
||
TRP_CORE.removeArray(validIdxes,tempIdxes);
|
||
|
||
|
||
//filter linkNum=4
|
||
var dirs = [-width,-1,1,width];
|
||
var waterIdxes = [];
|
||
for(var i=tempIdxes.length-1; i>=0; i=(i-1)|0){
|
||
var idx = tempIdxes[i];
|
||
waterIdxes.push(idx);
|
||
|
||
if(SETTING.waterObjOnEdge){
|
||
for(const dir of dirs){
|
||
if(!tempIdxes.contains(idx+dir)){
|
||
waterIdxes.pop();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
TRP_CORE.removeArray(waterIdxes,waterAccIdxes);
|
||
|
||
return waterIdxes;
|
||
};
|
||
|
||
function addObjTilesWithObjInfoArr(objInfoArr){
|
||
var infoLen = objInfoArr.length;
|
||
for(var i=0; i<infoLen; i=(i+1)|0){
|
||
var objInfo = objInfoArr[i];
|
||
var idx = objInfo[0];
|
||
var obj = objInfo[1];
|
||
var exData = objInfo.length>2 ? objInfo.slice(2) : null;
|
||
|
||
if(Array.isArray(obj[0])){
|
||
//bigObj
|
||
var cols = obj.length;
|
||
for(var dx=0; dx<cols; dx=(dx+1)|0){
|
||
var col = obj[dx];
|
||
var rows = col.length;
|
||
for(var dy=0; dy<rows; dy=(dy+1)|0){
|
||
var tileIds = col[dy];
|
||
if(!tileIds)continue;
|
||
|
||
addObjTiles(data,idx+dx+dy*width,tileIds,exData);
|
||
}
|
||
}
|
||
}else{
|
||
var tileIds = obj;
|
||
addObjTiles(data,idx,tileIds,exData);
|
||
}
|
||
}
|
||
}
|
||
|
||
function addObjTiles(data,idx,tileIds,exData=null){
|
||
if(!Array.isArray(tileIds)){
|
||
//trpMapObject
|
||
if(MapObject && tileIds instanceof MapObject){
|
||
addMapObject(tileIds,idx,exData);
|
||
}
|
||
return;
|
||
}
|
||
|
||
for(const tileId of tileIds){
|
||
addObjTile(data,idx,tileId);
|
||
}
|
||
};
|
||
function addMapObject(mapObj,idx,exData=null){
|
||
if(MapObject.tryAdd(mapObj,true)){
|
||
var x = idx%width + 0.5;
|
||
var y = Math.floor(idx/width) + 1;
|
||
|
||
if(mapObj.tileId){
|
||
x += (mapObj.tileW-1)/2;
|
||
y += (mapObj.tileH-1);
|
||
}
|
||
mapObj.x = x*tileW;
|
||
mapObj.y = y*tileH;
|
||
if(exData){
|
||
mapObj.x += exData[0];
|
||
mapObj.y += exData[1];
|
||
}
|
||
}
|
||
};
|
||
|
||
function addObjTile(data,idx,tileId){
|
||
if(isTileAnyA(tileId)){
|
||
return addObjTileA(data,idx,tileId);
|
||
}
|
||
if(data[idx+zObj2]){
|
||
if(data[idx+zObj1]){
|
||
if(data[idx+zAcc]){
|
||
return false;
|
||
}
|
||
data[idx+zAcc] = data[idx+zObj1];
|
||
}
|
||
data[idx+zObj1] = data[idx+zObj2];
|
||
}
|
||
data[idx+zObj2] = tileId;
|
||
|
||
return true;
|
||
};
|
||
function addObjTileA(data,idx,tileId){
|
||
data[idx+zObj2] = 0;
|
||
data[idx+zObj1] = 0;
|
||
data[idx+zAcc] = 0;
|
||
data[idx] = tileId;
|
||
|
||
return true;
|
||
};
|
||
function isTileAnyA(tileId){
|
||
return Tilemap.isTileA1(tileId)||Tilemap.isTileA2(tileId)||Tilemap.isTileA3(tileId)||Tilemap.isTileA4(tileId)||Tilemap.isTileA5(tileId);
|
||
};
|
||
|
||
function unshiftObjTileA(data,idx,tileId){
|
||
if(data[idx]){
|
||
if(data[idx+zAcc]){
|
||
if(data[idx+zObj1]){
|
||
if(data[idx+zObj2]){
|
||
return false;
|
||
}
|
||
data[idx+zObj2] = data[idx+zObj1];
|
||
}
|
||
data[idx+zObj1] = data[idx+zAcc];
|
||
}
|
||
data[idx+zAcc] = data[idx];
|
||
}
|
||
data[idx] = tileId;
|
||
};
|
||
|
||
function shiftDir(idx,dir){
|
||
if(idx<0)return idx;
|
||
|
||
if(dir===5)return idx;
|
||
if(dir===1)return shiftDir(shiftDir(2,idx),4);
|
||
if(dir===3)return shiftDir(shiftDir(2,idx),6);
|
||
if(dir===7)return shiftDir(shiftDir(8,idx),4);
|
||
if(dir===9)return shiftDir(shiftDir(8,idx),6);
|
||
|
||
var x = idx%width;
|
||
var y = Math.floor(idx/width);
|
||
|
||
var nIdx = idx;
|
||
if(dir===2){
|
||
if(y>=height-1)return -1;
|
||
nIdx += width;
|
||
}else if(dir===8){
|
||
if(y<=0)return -1;
|
||
nIdx-=width;
|
||
}else if(dir===4){
|
||
if(x<=0)return -1;
|
||
nIdx-=1;
|
||
}else{
|
||
if(x>=width-1)return -1;
|
||
nIdx+=1;
|
||
}
|
||
return nIdx;
|
||
};
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Dot Shift Objects
|
||
//=============================================================================
|
||
MapDecorator.tryDotShiftObjects = function(roomId){
|
||
if(!MapObject)return;
|
||
|
||
var objInfoArr = proc.lastObjInfoArr[roomId];
|
||
var idxesMap = proc.leftObjIdxesArr[roomId];
|
||
if(!objInfoArr || !idxesMap){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
var zMap = proc.floorLevelZMap.concat();
|
||
var usedIdxes = [];
|
||
for(const objInfo of objInfoArr){
|
||
this._tryDotShiftObject(objInfo,zMap,idxesMap,usedIdxes);
|
||
}
|
||
|
||
SoundManager.playCursor();
|
||
this.restoreMap(true);
|
||
|
||
this.saveState('ドットシフト');
|
||
};
|
||
MapDecorator._tryDotShiftObject = function(objInfo,zMap,idxesMap,usedIdxes){
|
||
var idx = objInfo[0];
|
||
var obj = objInfo[1];
|
||
if(objInfo[2]||objInfo[3]){
|
||
if(objInfo[2]<=-tileW/4 || objInfo[2]>=tileW/4)return;
|
||
if(objInfo[3]<=-tileH/4 || objInfo[3]>=tileH/4)return;
|
||
}
|
||
|
||
var infoIdx = proc.idxBaseInfoIdxMap[idx];
|
||
var _info = allInfo[infoIdx];
|
||
|
||
var typeResult = this._objectLocateType(obj,_info);
|
||
if(!typeResult)return;
|
||
var type = typeResult.type;
|
||
var onFloorFlags = typeResult.onFloorFlags||null;
|
||
|
||
var idxes = idxesMap[_info.floorBaseId][type];
|
||
if(!idxes)return;
|
||
|
||
|
||
//check 4 dirs
|
||
var dirs4 = [];
|
||
for(const dir of MapDecorator.DIRS4){
|
||
var nIdx = shiftDir(idx,dir);
|
||
if(nIdx<0)continue;
|
||
|
||
if(!this._canShiftObject(idx,nIdx,obj,onFloorFlags,zMap,idxes,usedIdxes))continue;
|
||
dirs4.push(dir);
|
||
}
|
||
|
||
//check 8 dirs
|
||
var DIRS = MapDecorator.DIRS4.concat();
|
||
while(DIRS.length){
|
||
var dir = TRP_CORE.randomShift(DIRS);
|
||
var dirLeft = this.DIR_LEFT_90[dir];
|
||
if(!dirs4.contains(dir) || !dirs4.contains(dirLeft))continue;
|
||
|
||
var nIdx = shiftDir(idx,dir);
|
||
if(nIdx<0)continue;
|
||
|
||
if(!this._canShiftObject(idx,nIdx,obj,onFloorFlags,zMap,idxes,usedIdxes))continue;
|
||
|
||
this._execDotShiftObject(objInfo,obj,onFloorFlags,dir,idxes,usedIdxes);
|
||
this._execDotShiftObject(objInfo,obj,onFloorFlags,dirLeft,idxes,usedIdxes);
|
||
return;
|
||
};
|
||
|
||
while(dirs4.length){
|
||
var dir = TRP_CORE.randomShift(dirs4);
|
||
this._execDotShiftObject(objInfo,obj,onFloorFlags,dir,idxes,usedIdxes);
|
||
return;
|
||
}
|
||
};
|
||
MapDecorator._execDotShiftObject = function(objInfo,obj,onFloorFlags,dir,idxes,usedIdxes){
|
||
if(!(obj instanceof MapObject)){
|
||
var template = this.mapObjectTemplateWithTileObject(obj,true);
|
||
if(!template)return;
|
||
obj = objInfo[1] = template.copy();
|
||
}
|
||
|
||
objInfo[2] = objInfo[2]||0;
|
||
objInfo[3] = objInfo[3]||0;
|
||
|
||
var infoIdx = (dir===4||dir===6) ? 2 : 3;
|
||
var delta0 = objInfo[infoIdx]||0;
|
||
objInfo[infoIdx] = 0;
|
||
|
||
var tileSize = (dir===2||dir===8) ? tileH : tileH;
|
||
var value = Math.randomInt(tileSize/4);
|
||
|
||
if(dir===2)objInfo[infoIdx] += value;
|
||
else if(dir===8)objInfo[infoIdx] -= value;
|
||
else if(dir===4)objInfo[infoIdx] -= value;
|
||
else if(dir===6)objInfo[infoIdx] += value;
|
||
|
||
|
||
if(MapObject && obj instanceof MapObject){
|
||
if(infoIdx===2)obj.x += objInfo[infoIdx]-delta0;
|
||
else obj.y += objInfo[infoIdx]-delta0;
|
||
|
||
obj._lastDispX = Number.MAX_SAFE_INTEGER;
|
||
obj._lastDispY = Number.MAX_SAFE_INTEGER;
|
||
obj.setupMargin();
|
||
}
|
||
|
||
|
||
//reserve idxes
|
||
var idx = objInfo[0];
|
||
var nIdx = shiftDir(idx,dir);
|
||
if(onFloorFlags){
|
||
var w = onFloorFlags.length;
|
||
var h = onFloorFlags[0].length;
|
||
for(var dx=0; dx<w; dx=(dx+1)|0){
|
||
for(var dy=0; dy<h; dy=(dy+1)|0){
|
||
var onFloor = onFloorFlags[dx][h-1-dy];
|
||
if(!onFloor)continue;
|
||
|
||
var tIdx = nIdx+dx-dy*width;
|
||
usedIdxes.push(tIdx);
|
||
}
|
||
}
|
||
}else{
|
||
usedIdxes.push(nIdx);
|
||
}
|
||
};
|
||
|
||
MapDecorator.DIRS4 = [2,4,6,8];
|
||
MapDecorator.DIR_LEFT_90 = [0,0, 4,0, 8,0, 2,0, 6];
|
||
|
||
MapDecorator._objectLocateType = function(obj,_info){
|
||
var types = ['base','water',..._info.separateLocateObjAccIds];
|
||
var objIds,bigObjIds,floorBaseId;
|
||
var isMapObj = MapObject && obj instanceof MapObject;
|
||
for(const type of types){
|
||
if(type==='base'){
|
||
//floor
|
||
objIds = _info.objIds;
|
||
bigObjIds = _info.bigObjIds;
|
||
floorBaseId = _info.floorBaseId;
|
||
}else if(type==='water'){
|
||
//water
|
||
objIds = _info.waterObjIds;
|
||
bigObjIds = _info.waterBigObjIds;
|
||
floorBaseId = _info.waterBaseId;
|
||
}else{
|
||
//accessory
|
||
floorBaseId = Number(type);
|
||
var accInfo = _info.accSettings[floorBaseId];
|
||
objIds = accInfo.objIds;
|
||
bigObjIds = accInfo.bigObjIds;
|
||
}
|
||
|
||
if(floorBaseId===obj)return {type};
|
||
if(objIds){
|
||
if(isMapObj){
|
||
if(objIds.some(target=>(target instanceof MapObject)&&target.tag===obj.tag)){
|
||
return {type};
|
||
}
|
||
}else{
|
||
if(TRP_CORE.containsEqual(objIds,obj)){
|
||
return {type};
|
||
}
|
||
}
|
||
}
|
||
if(bigObjIds){
|
||
var bigObjIdsData = bigObjIds.map(bo=>bo[0]);
|
||
if(isMapObj){
|
||
if(bigObjIdsData.some(target=>(target instanceof MapObject)&&target.tag===obj.tag)){
|
||
return {type,onFloorFlags};
|
||
}
|
||
}else{
|
||
var idx = TRP_CORE.indexOfEqual(bigObjIdsData,obj)
|
||
if(idx>=0){
|
||
var onFloorFlags = bigObjIds[idx][1];
|
||
return {type,onFloorFlags};
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if(isMapObj){
|
||
//retry with tileIds array data
|
||
if(obj.tileId){
|
||
var tileIds = obj.tileIds(true);
|
||
if(tileIds.length===1 && tileIds[0].length===1){
|
||
tileIds = tileIds[0][0];
|
||
}
|
||
return this._objectLocateType(tileIds,_info);
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
|
||
MapDecorator._canShiftObject = function(idx,nIdx,obj,onFloorFlags,zMap,idxes,usedIdxes){
|
||
if(onFloorFlags){
|
||
//check bigObj
|
||
var w = onFloorFlags.length;
|
||
var h = onFloorFlags[0].length;
|
||
|
||
var objIdxes = [];
|
||
for(var dx=0; dx<w; dx=(dx+1)|0){
|
||
for(var dy=0; dy<h; dy=(dy+1)|0){
|
||
var onFloor = onFloorFlags[dx][h-1-dy];
|
||
if(onFloor){
|
||
var tIdx = idx+dx+dy*width;
|
||
objIdxes.push(tIdx);
|
||
}
|
||
}
|
||
}
|
||
for(var dx=0; dx<w; dx=(dx+1)|0){
|
||
for(var dy=0; dy<h; dy=(dy+1)|0){
|
||
var onFloor = onFloorFlags[dx][h-1-dy];
|
||
if(!onFloor)continue;
|
||
|
||
var tIdx = nIdx+dx+dy*width;
|
||
if(objIdxes.contains(tIdx))continue;
|
||
|
||
if(!idxes.contains(tIdx))return false;
|
||
if(usedIdxes.contains(tIdx))return false;
|
||
if(zMap[idx] !== zMap[tIdx])return false;
|
||
}
|
||
}
|
||
}else{
|
||
if(!idxes.contains(nIdx))return false;
|
||
if(usedIdxes.contains(tIdx))return false;
|
||
if(zMap[idx] !== zMap[nIdx])return false;
|
||
}
|
||
return true;
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: ManualLocate
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.manualLocate = [
|
||
'【手動オブジェ配置モード】',
|
||
'左クリ:配置/削除',
|
||
'右クリ:終了',
|
||
'Ctrl+左クリ:オブジェ選択(スポイト)',
|
||
];
|
||
if(MapObject){
|
||
MapDecorator.MODE_GUIDE.manualLocate.push(
|
||
'Vキー:オブジェクト範囲選択',
|
||
);
|
||
}
|
||
|
||
MapDecorator.setModeManualLocate = function(){
|
||
this.tryInitManualLocateData();
|
||
}
|
||
MapDecorator.endModeManualLocate = function(){
|
||
_Dev.showText('dotLocate',null);
|
||
_Dev.showText('adjustMapObj',null);
|
||
|
||
this.releaseLastLocateMapObj();
|
||
};
|
||
|
||
MapDecorator.tryInitManualLocateData = function(){
|
||
if(this.modeData && this.modeData.type==='manualLocate'){
|
||
if(this.modeData.onDraggingLocateObj)return;
|
||
return;
|
||
}
|
||
|
||
var modeData = this.modeData = {};
|
||
modeData.type = 'manualLocate';
|
||
modeData.manualLocateObj = null;
|
||
modeData.onDraggingLocateObj = null;
|
||
this.releaseLastLocateMapObj();
|
||
};
|
||
|
||
MapDecorator.releaseLastLocateMapObj = function(){
|
||
var modeData = this.modeData;
|
||
if(!modeData || !modeData.lastLocateMapObj)return;
|
||
|
||
modeData.lastLocateMapObj = null;
|
||
};
|
||
|
||
MapDecorator.tryConvertMapObjectToMapData = function(obj){
|
||
if(obj.aX || obj.aY || obj.blendMode || obj.opacity!==255
|
||
|| obj.scaleX!==1 || obj.scaleY!==1 || obj.rotation
|
||
|| obj.mirror || obj.anchorX!==0.5 || obj.anchorY!==1
|
||
|| !obj.tileId
|
||
|| obj._animations
|
||
|| obj.commonIds
|
||
|| MapDecorator.mapObjectOriginalTemplateTags.contains(obj.tag)
|
||
|| (obj.x-obj.tileW*tileW/2)%tileW!==0
|
||
|| obj.y%tileH!==0
|
||
){
|
||
//obj
|
||
}else{
|
||
//obj -> tile
|
||
var tileIds = obj.tileIds(true);
|
||
if(tileIds){
|
||
var infoArr = null;
|
||
var targetObjInfo = null;
|
||
for(const roomObjInfo of proc.lastObjInfoArr){
|
||
if(!roomObjInfo)continue;
|
||
for(const objInfo of roomObjInfo){
|
||
if(obj===objInfo[1]){
|
||
targetObjInfo = objInfo;
|
||
infoArr = roomObjInfo;
|
||
break;
|
||
}
|
||
}
|
||
if(infoArr)break;
|
||
}
|
||
if(!infoArr)return false;
|
||
|
||
var w = obj.tileW;
|
||
var h = obj.tileH;
|
||
var x = Math.floor((obj.x-w/2)/tileW);
|
||
var y = Math.floor((obj.y-h)/tileH);
|
||
if(!this._tryReplaceTilesWithLocation(tileIds,x,y,w,h))return false;
|
||
|
||
MapObject.remove(obj);
|
||
TRP_CORE.remove(infoArr,targetObjInfo);
|
||
|
||
return true;
|
||
|
||
|
||
// objInfo[1] = tileIds;
|
||
// tileIds = null;
|
||
// if(!noRestoreMap){
|
||
// this.restoreMap(true);
|
||
// }
|
||
// return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
MapDecorator.tryStartManualLocateMode = function(event,roomId,x,y,tx,ty,dx,dy){
|
||
var idx = x+y*width;
|
||
var objInfo = this.searchObjInfo(idx,roomId,dx,dy);
|
||
_Dev.showText('dotLocate',null);
|
||
|
||
if(!objInfo){
|
||
return false;
|
||
}
|
||
|
||
if(this._mode==='manualLocate'){
|
||
if(this.modeData.lastLocateMapObj!==objInfo){
|
||
this.releaseLastLocateMapObj();
|
||
}
|
||
if(!objInfo){
|
||
this.modeData.manualLocateObj = null;
|
||
}
|
||
}
|
||
this.startManualLocateMode(objInfo);
|
||
return true;
|
||
};
|
||
|
||
MapDecorator.startManualLocateMode = function(obj=null){
|
||
var dragging = this.modeData ? this.modeData.onDraggingLocateObj : null;
|
||
this.setMode('manualLocate');
|
||
|
||
this.tryInitManualLocateData();
|
||
this.modeData.onDraggingLocateObj = this.modeData.onDraggingLocateObj||dragging||null;
|
||
if(!Array.isArray(obj)){
|
||
if(this.modeData.lastLocateMapObj!==obj){
|
||
this.modeData.lastLocateMapObj = obj;
|
||
}
|
||
this.refreshAdjustMapObjectHelp(obj);
|
||
|
||
obj = obj.copy();
|
||
_Dev.showText('dotLocate','Shift+左クリ:ドット単位で配置(ドラッグで移動)');
|
||
}
|
||
this.modeData.manualLocateObj = obj;
|
||
|
||
|
||
var name;
|
||
if(this.modeData.onDraggingLocateObj){
|
||
name = '手動オブジェ配置:配置&移動';
|
||
}else{
|
||
name = '手動オブジェ配置:開始';
|
||
}
|
||
|
||
this.disableLastStateOverwritable(name);
|
||
this.saveState(name,true,true);
|
||
|
||
SoundManager.playCursor();
|
||
return true;
|
||
};
|
||
MapDecorator.searchObjInfo = function(idx,roomId,dx,dy){
|
||
return this._searchObjInfo(idx,roomId,dx,dy);
|
||
};
|
||
|
||
MapDecorator.checkObjectInfoTouch = function(objInfo,x,y,x1,y1,completion){
|
||
var objIdx = objInfo[0];
|
||
var obj = objInfo[1];
|
||
|
||
//check obj touch the idx
|
||
var ox,oy,w,h,ax,ay;
|
||
if(Array.isArray(obj)){
|
||
ox = (objIdx%width)*tileW;
|
||
oy = Math.floor(objIdx/width)*tileH;
|
||
if(objInfo[2])ox += objInfo[2];
|
||
if(objInfo[3])oy += objInfo[3];
|
||
|
||
if(Array.isArray(obj[0])){
|
||
//bigObj
|
||
w = obj.length;
|
||
h = obj[0].length;
|
||
}else{
|
||
w = 1;
|
||
h = 1;
|
||
}
|
||
w *= tileW;
|
||
h *= tileH;
|
||
ax = ox+w/2;
|
||
ay = oy+h;
|
||
}else{
|
||
//mapObject
|
||
if(!obj.sprite)return false;
|
||
|
||
var sprite = obj.sprite;
|
||
w = sprite.width*sprite.scale.x;
|
||
h = sprite.height*sprite.scale.y;
|
||
if(w<0)w*=-1;
|
||
if(h<0)h*=-1;
|
||
|
||
ox = sprite.x - sprite.anchor.x*w + $gameMap._displayX*tileW;
|
||
oy = sprite.y - sprite.anchor.y*h + $gameMap._displayY*tileH;
|
||
ax = ox + w*sprite.anchor.x;
|
||
ay = oy + h*sprite.anchor.y;
|
||
|
||
|
||
// if(sprite.rotation){
|
||
// var dx = x -(sprite.x+$gameMap._displayX*tileW);
|
||
// var dy = y -(sprite.y+$gameMap._displayY*tileH);
|
||
// var theta = -sprite.rotation;
|
||
// x = (sprite.x+$gameMap._displayX*tileW) + dx*Math.cos(theta)-dy*Math.sin(theta);
|
||
// y = (sprite.y+$gameMap._displayX*tileH) + dx*Math.sin(theta)+dy*Math.cos(theta);
|
||
// }
|
||
|
||
// var bitmap = new Bitmap(w,h);
|
||
// var sprite = new Sprite(bitmap);
|
||
// bitmap.fillAll('rgba(255,0,0,0.5)');
|
||
// sprite.x = ox - $gameMap._displayX*tileW;
|
||
// sprite.y = oy - $gameMap._displayY*tileH;
|
||
// SceneManager._scene.addChild(sprite);
|
||
}
|
||
|
||
if(x1===undefined){
|
||
if(x<ox || x>ox+w)return false;
|
||
if(y<oy || y>oy+h)return false;
|
||
}else{
|
||
if(x1<ox || x>ox+w)return false;
|
||
if(y1<oy || y>oy+h)return false;
|
||
}
|
||
|
||
if(completion){
|
||
completion(ax,ay);
|
||
}
|
||
|
||
|
||
return true;
|
||
};
|
||
|
||
MapDecorator._searchObjInfo = function(idx,roomId,dx=0,dy=0,eraseTarget=null){
|
||
var objInfoArr = proc.lastObjInfoArr[roomId];
|
||
if(!objInfoArr)return null;
|
||
|
||
var x = (idx%width)*tileW + dx;
|
||
var y = Math.floor(idx/width)*tileH + dy;
|
||
var isTargetArray = eraseTarget && Array.isArray(eraseTarget);
|
||
|
||
var bestTargetInfo = null;
|
||
var bestDist = Number.MAX_SAFE_INTEGER;
|
||
var bestAx,bestAy;
|
||
for(const objInfo of objInfoArr){
|
||
var objIdx = objInfo[0];
|
||
var obj = objInfo[1];
|
||
|
||
if(eraseTarget){
|
||
if(eraseTarget===obj){
|
||
//sameObj
|
||
}else if(!isTargetArray&&eraseTarget.equalsMapObjectImage(obj)){
|
||
//sameMapObjImage
|
||
}else if(isTargetArray&&Array.isArray(obj)&&eraseTarget.equals(obj)){
|
||
//equals
|
||
}else{
|
||
//not match to targetObj
|
||
continue;
|
||
}
|
||
}
|
||
|
||
this.checkObjectInfoTouch(objInfo,x,y,undefined,undefined,(ax,ay)=>{
|
||
var dist = Math.abs(ax-x)+Math.abs(ay-y);
|
||
if(dist<bestDist){
|
||
bestDist = dist;
|
||
bestTargetInfo = objInfo;
|
||
bestAx = ax;
|
||
bestAy = ay;
|
||
}
|
||
});
|
||
}
|
||
|
||
if(!bestTargetInfo)return null;
|
||
|
||
var obj = bestTargetInfo[1];
|
||
if(eraseTarget){
|
||
TRP_CORE.remove(objInfoArr,bestTargetInfo);
|
||
if(!isTargetArray){
|
||
MapObject.remove(obj);
|
||
}
|
||
|
||
if(MapObject && obj instanceof MapObject){
|
||
if(this.modeData.manualLocateObj===obj){
|
||
this.modeData.manualLocateObj = null;
|
||
}
|
||
}
|
||
if(this.modeData.lastLocateMapObj===obj){
|
||
this.modeData.lastLocateMapObj = null;
|
||
}
|
||
|
||
}else{
|
||
/* register to draggingObj
|
||
===================================*/
|
||
if(MapObject && !(obj instanceof MapObject)){
|
||
var template = MapDecorator.mapObjectTemplateWithTileObject(obj,true);
|
||
if(template){
|
||
obj = template.copy();
|
||
bestTargetInfo[1] = obj;
|
||
obj.x = bestAx;
|
||
obj.y = bestAy;
|
||
MapObject.tryAdd(obj);
|
||
|
||
SceneManager._scene._spriteset.updateTrpMapObjects();
|
||
this.restoreMap(true);
|
||
}
|
||
}
|
||
|
||
if(MapObject && obj instanceof MapObject && obj.sprite){
|
||
var objInfoArr = null;
|
||
var tx = x-tileW/2;
|
||
var ty = y-tileH;
|
||
var idx;
|
||
var targetObj = null;
|
||
var objInfo = this.objInfoOfObj(obj);
|
||
if(objInfo){
|
||
targetObj = objInfo;
|
||
idx = objInfo[0];
|
||
for(const roomObjInfo of proc.lastObjInfoArr){
|
||
if(!roomObjInfo)continue;
|
||
if(roomObjInfo.contains(objInfo)){
|
||
objInfoArr = roomObjInfo;
|
||
break;
|
||
}
|
||
}
|
||
dx = objInfo[2]||0;
|
||
dy = objInfo[3]||0;
|
||
}
|
||
if(objInfoArr){
|
||
var sprite = obj.sprite;
|
||
var x = idx%width;
|
||
var y = Math.floor(idx/width);
|
||
var w = obj.tileId ? obj.tileW : 1;
|
||
var h = obj.tileId ? obj.tileH : 1;
|
||
x += Math.floor((w-1)/2);
|
||
y += h-1;
|
||
|
||
this.tryInitManualLocateData();
|
||
|
||
this.startObjectDragging({
|
||
onLocate:false,
|
||
obj,
|
||
objInfoArr,
|
||
data:targetObj,
|
||
tx,
|
||
ty,
|
||
dx,
|
||
dy,
|
||
x,
|
||
y,
|
||
count:6,
|
||
});
|
||
}
|
||
}
|
||
}
|
||
return obj;
|
||
};
|
||
|
||
MapDecorator.startObjectDragging = function(dragging){
|
||
this.modeData.onDraggingLocateObj = dragging;
|
||
|
||
|
||
if(!this.draggingGrid){
|
||
var col = Math.ceil(Graphics.width/SETTING.mapDispRange / tileW);
|
||
var row = Math.ceil(Graphics.height/SETTING.mapDispRange / tileH);
|
||
this.draggingGrid = this.tileGridGraphic(col,row,0xff0000,0.5);
|
||
}
|
||
SceneManager._scene.addChild(this.draggingGrid);
|
||
};
|
||
|
||
MapDecorator.tileGridGraphic = function(col,row,color=0x000000,alpha=0.8){
|
||
var grid = new PIXI.Graphics();
|
||
grid.beginFill(color,alpha);
|
||
var lineW = 1;
|
||
for(var c=0; c<col+1; c=(c+1)|0){
|
||
grid.drawRect(c*tileW,0,lineW,row*tileH);
|
||
}
|
||
for(var r=0; r<row+1; r=(r+1)|0){
|
||
grid.drawRect(0,r*tileH,col*tileW,lineW);
|
||
}
|
||
return grid;
|
||
};
|
||
MapDecorator.updateDraggingGrid = function(){
|
||
var grid = this.draggingGrid;
|
||
if(!grid)return;
|
||
|
||
grid.x = -(($gameMap._displayX*tileW/SETTING.mapDispRange)%tileW)
|
||
grid.y = -(($gameMap._displayY*tileH/SETTING.mapDispRange)%tileH)
|
||
};
|
||
|
||
|
||
|
||
/* manualLocate main proc
|
||
===================================*/
|
||
MapDecorator.onMouseDownLeftManualLocate = function(event,roomId,x,y,tx,ty,dx,dy){
|
||
if(!this.modeData)return;
|
||
|
||
this.modeData.onDraggingLocateObj = null;
|
||
if(this.draggingGrid){
|
||
this.draggingGrid.visible = false;
|
||
}
|
||
|
||
if(roomId<0){
|
||
roomId = proc.roomIdxMapForUserProc[x+y*width];
|
||
}
|
||
if(roomId<0 || roomId===undefined)return;
|
||
|
||
if(this.onKeyControl){
|
||
if(!this.tryStartManualLocateMode(event,roomId,x,y,tx,ty,dx,dy)){
|
||
SoundManager.playBuzzer();
|
||
}
|
||
}else{
|
||
var dotLoc = (MapObject&&Input.isPressed('shift'));
|
||
this.processManualLocate(event,roomId,x,y,dx,dy,dotLoc);
|
||
}
|
||
};
|
||
MapDecorator.onMouseDownRightManualLocate = function(event,roomId,x,y,tx,ty,dx,dy){
|
||
if(Input.isPressed('shift')){
|
||
}else if(this.onKeyControl){
|
||
MapDecorator.tryShowObjectPalette();
|
||
}else{
|
||
SoundManager.playCancel();
|
||
this.restoreMode();
|
||
}
|
||
};
|
||
MapDecorator.processManualLocate = function(event,roomId,x,y,dx,dy,dotLoc=false){
|
||
var obj = this.modeData.manualLocateObj;
|
||
this.releaseLastLocateMapObj();
|
||
|
||
_Dev.showText('adjustMapObj',null);
|
||
|
||
if(!obj){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
if(!MapObject /*|| !(obj instanceof MapObject)*/){
|
||
dotLoc = false;
|
||
}
|
||
if(dotLoc&&!(obj instanceof MapObject)){
|
||
var template = this.mapObjectTemplateWithTileObject(obj);
|
||
if(template){
|
||
obj = template.copy();
|
||
}else{
|
||
dotLoc = false;
|
||
}
|
||
}
|
||
|
||
|
||
var idx = x+y*width;
|
||
var roomId = idxOfRoom(idx);
|
||
if(!proc.lastObjInfoArr[roomId]){
|
||
proc.lastObjInfoArr[roomId] = [];
|
||
}
|
||
var objInfoArr = proc.lastObjInfoArr[roomId];
|
||
|
||
|
||
//try erase
|
||
var eraseTarget = obj;
|
||
var eraseTarget2 = null;
|
||
if(MapObject&&!(obj instanceof MapObject)){
|
||
//auto converted mapObjct
|
||
eraseTarget2 = MapDecorator._convertedMapObjMap[JSON.stringify(obj)]||null;
|
||
}
|
||
|
||
var erased = false;
|
||
if(!dotLoc && this._searchObjInfo(idx,roomId,dx,dy,eraseTarget)){
|
||
//erase success
|
||
erased = true;
|
||
}else if(!dotLoc && eraseTarget2 && this._searchObjInfo(idx,roomId,dx,dy,eraseTarget2)){
|
||
//erase success
|
||
erased = true;
|
||
}else{
|
||
//add obj
|
||
if(!dotLoc){
|
||
dx = 0;
|
||
dy = 0;
|
||
}else{
|
||
dx -= tileW/2;
|
||
dy -= tileH;
|
||
}
|
||
if(!this.tryManualLocateObject(idx,obj,roomId,objInfoArr,dx,dy)){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
}
|
||
SoundManager.playCursor();
|
||
|
||
|
||
//restoreMap to apply edit
|
||
var lockedObjRoomIds = proc.lockedObjRoomIds;
|
||
proc.lockedObjRoomIds = TRP_CORE.packSequence([],proc.allRoomIdxes.length);
|
||
this.restoreMap();
|
||
proc.lockedObjRoomIds = lockedObjRoomIds;
|
||
|
||
if(erased){
|
||
this.saveState('手動オブジェ配置:消去');
|
||
}else{
|
||
//saveState on tryManualLocateobject()
|
||
}
|
||
};
|
||
|
||
MapDecorator._mapObjTransformCopy = null;
|
||
MapDecorator.onKeyDownManualLocate = function(event){
|
||
var modeData = this.modeData;
|
||
if(!modeData || modeData.type!=='manualLocate')return;
|
||
if(modeData.onDraggingLocateObj)return;
|
||
|
||
if(!MapObject)return;
|
||
|
||
if(event.key==='v'){
|
||
this.startObjectSelectMode();
|
||
SoundManager.playCursor();
|
||
return true;
|
||
}
|
||
|
||
var obj = modeData.lastLocateMapObj;
|
||
if(obj){
|
||
if(event.key==='Backspace'){
|
||
//delete obj
|
||
for(const objInfoArr of proc.lastObjInfoArr){
|
||
for(const data of objInfoArr){
|
||
if(data.contains(obj)){
|
||
TRP_CORE.remove(objInfoArr,data);
|
||
MapObject.remove(obj);
|
||
this.releaseLastLocateMapObj();
|
||
SoundManager.playCursor();
|
||
|
||
this.saveState('手動オブジェ配置:消去');
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}else if(!isNaN(event.key)){
|
||
var rate = Number(event.key)*0.1||1.0;
|
||
obj.opacity = Math.ceil(255*rate);
|
||
this.saveState('オブジェ編集:不透明度',true);
|
||
}else if(event.key==='m'){
|
||
obj.mirror = !obj.mirror;
|
||
this.saveState('オブジェ編集:反転');
|
||
}else if(event.key==='r'){
|
||
obj.scaleX = obj.scaleY = 1;
|
||
obj.rotation = 0;
|
||
obj.mirror = false;
|
||
obj.tint = 0xffffff;
|
||
|
||
var tx = Math.round((obj.x-obj.tileW*tileW/2)/tileW);
|
||
var ty = Math.round(obj.y/tileH)-obj.tileH;
|
||
obj.x = tx*tileW+obj.tileW*tileW/2;
|
||
obj.y = (ty+obj.tileH)*tileH;
|
||
obj._lastDispX = obj._lastDispY = Number.MAX_SAFE_INTEGER;
|
||
var objInfo = this.objInfoOfObj(obj);
|
||
if(objInfo){
|
||
objInfo[0] = tx+ty*width;
|
||
}
|
||
this.saveState('オブジェ編集:リセット/マス中央');
|
||
}else if(event.key==='t'){
|
||
this.startPickColor(color=>{
|
||
obj.tint = Number(color.replace('#','0x'));
|
||
if(obj.sprite){
|
||
obj.sprite.tint = obj.tint;
|
||
}
|
||
this.saveState('オブジェ編集:色味(ティント)',true);
|
||
});
|
||
// }else if(event.key==='b'){
|
||
// var blend = obj.blendMode+1;
|
||
// if(blend>=5){
|
||
// blend = 0;
|
||
// }
|
||
// obj.setBlendMode(blend);
|
||
// _Dev.showTempText('mapObjBlend','ブレンド > %1'.format(
|
||
// blend===0 ? '通常' : (blend===1 ? '加算' : (blend===2 ? '乗算' : 'オーバーレイ'))
|
||
// ));
|
||
}else if(event.key==='e'||event.key==='E'){
|
||
//priority
|
||
obj.priority += event.shiftKey ? 0.1 : 1;
|
||
obj.priority = Math.round(obj.priority*10)/10;
|
||
if(!event.shiftKey && obj.priority>2){
|
||
obj.priority = 0;
|
||
}
|
||
this.saveState('オブジェ編集:プライオリティ変更',true);
|
||
}else if(event.key==='c'){
|
||
// MapDecorator._mapObjTransformCopy = [
|
||
// obj.scaleX,obj.scaleY,obj.rotation,obj.opacity,obj.mirror,obj.tint
|
||
// ];
|
||
MapDecorator.modeData.manualLocateObj = obj.copy();
|
||
SoundManager.playOk();
|
||
this.saveState('オブジェ編集:コピー');
|
||
// }else if(event.key==='v'){
|
||
// if(MapDecorator._mapObjTransformCopy){
|
||
// var info = MapDecorator._mapObjTransformCopy
|
||
// var idx = 0;
|
||
// obj.scaleX = info[idx++];
|
||
// obj.scaleY = info[idx++];
|
||
// obj.rotation = info[idx++];
|
||
// obj.opacity = info[idx++];
|
||
// obj.mirror = info[idx++];
|
||
// obj.tint = info[idx++];
|
||
// SoundManager.playOk();
|
||
// }else{
|
||
// SoundManager.playBuzzer();
|
||
// }
|
||
}else{
|
||
return;
|
||
}
|
||
|
||
this.refreshAdjustMapObjectHelp(obj);
|
||
obj.tryRefreshSpriteState();
|
||
SoundManager.playCursor();
|
||
}
|
||
};
|
||
MapDecorator.onStateChangeManualLocate = function(){
|
||
var obj = this.modeData.lastLocateMapObj;
|
||
if(obj){
|
||
obj = this.modeData.lastLocateMapObj = this._tryRestoreMapObject(obj);
|
||
}
|
||
};
|
||
|
||
MapDecorator.onMousePressManualLocate = function(event,roomId,x,y,tx,ty,dx,dy){
|
||
if(!this.modeData)return;
|
||
if(!this.modeData.onDraggingLocateObj)return;
|
||
|
||
var dragging = this.modeData.onDraggingLocateObj;
|
||
if(this.modeData.lastLocateMapObj!==dragging.obj)return;
|
||
|
||
dragging.count -= 1;
|
||
if(dragging.count>0){
|
||
return;
|
||
}
|
||
if(this.draggingGrid){
|
||
this.draggingGrid.visible = true;
|
||
}
|
||
|
||
//adjust pos to anchor
|
||
dx -= tileW/2;
|
||
dy -= tileH;
|
||
|
||
var offsetX = (x*tileW+dx) - dragging.tx;
|
||
var offsetY = (y*tileH+dy) - dragging.ty;
|
||
if(!offsetX && !offsetY){
|
||
return;
|
||
}
|
||
|
||
//calc real x,y,dx,dy
|
||
dx = dragging.x*tileW + dragging.dx + offsetX;
|
||
dy = dragging.y*tileH + dragging.dy + offsetY;
|
||
x = Math.floor(dx/tileW);
|
||
y = Math.floor(dy/tileH);
|
||
dx -= x*tileW;
|
||
dy -= y*tileH;
|
||
|
||
var rIdx = x+width*y;
|
||
if(rIdx<0)return;
|
||
|
||
// roomId = idxOfRoom(rIdx);
|
||
roomId = proc.roomIdxMapForUserProc[rIdx];
|
||
if(roomId<0 || roomId===undefined){
|
||
return;
|
||
}
|
||
// this.tonnerTiles([rIdx]);
|
||
|
||
dragging.tx += offsetX;
|
||
dragging.ty += offsetY;
|
||
|
||
var idx = x+y*width;
|
||
if(idx<0)return;
|
||
|
||
var objInfoArr = proc.lastObjInfoArr[roomId];
|
||
this.tryManualLocateObject(idx,dragging.obj,roomId,objInfoArr,dx,dy,dragging);
|
||
|
||
var stateName = '手動オブジェ配置:配置&移動';
|
||
this.saveState(stateName,true);
|
||
};
|
||
|
||
MapDecorator.updateInputManualLocate = function(){
|
||
if(!this.modeData)return false;
|
||
|
||
var obj = this.modeData.lastLocateMapObj;
|
||
if(!obj)return false;
|
||
|
||
if(Input.isPressed('shift')){
|
||
var stateName = null;
|
||
if(Input.isTriggered('left')||Input.isLongPressed('left')){
|
||
obj.rotation -= 5*Math.PI/180;
|
||
stateName = '角度';
|
||
}else if(Input.isTriggered('right')||Input.isLongPressed('right')){
|
||
obj.rotation += 5*Math.PI/180;
|
||
stateName = '角度';
|
||
}else if(Input.isTriggered('up')||Input.isLongPressed('up')){
|
||
obj.scaleX += 0.05;
|
||
obj.scaleY += 0.05;
|
||
stateName = '拡大率';
|
||
}else if(Input.isTriggered('down')||Input.isLongPressed('down')){
|
||
obj.scaleX -= 0.05;
|
||
obj.scaleY -= 0.05;
|
||
stateName = '拡大率';
|
||
}else if(
|
||
Input.isPressed('left') || Input.isPressed('right')
|
||
|| Input.isPressed('up') || Input.isPressed('down')
|
||
){
|
||
return true;
|
||
}else{
|
||
return false;
|
||
}
|
||
}else if(this.onKeyAlt){
|
||
if(Input.isTriggered('left')||Input.isLongPressed('left')){
|
||
obj.scaleX -= 0.05;
|
||
stateName = '拡大率<X>';
|
||
}else if(Input.isTriggered('right')||Input.isLongPressed('right')){
|
||
obj.scaleX += 0.05;
|
||
stateName = '拡大率<X>';
|
||
}else if(Input.isTriggered('up')||Input.isLongPressed('up')){
|
||
obj.scaleY += 0.05;
|
||
stateName = '拡大率<Y>';
|
||
}else if(Input.isTriggered('down')||Input.isLongPressed('down')){
|
||
obj.scaleY -= 0.05;
|
||
stateName = '拡大率<Y>';
|
||
}else if(
|
||
Input.isPressed('left') || Input.isPressed('right')
|
||
|| Input.isPressed('up') || Input.isPressed('down')
|
||
){
|
||
return true;
|
||
}else{
|
||
return false;
|
||
}
|
||
}else{
|
||
if(Input.isTriggered('pagedown')||Input.isLongPressed('pagedown')){
|
||
obj.opacity += 5;
|
||
stateName = '不透明度';
|
||
}else if(Input.isTriggered('pageup')||Input.isLongPressed('pageup')){
|
||
obj.opacity -= 5;
|
||
stateName = '不透明度';
|
||
}else{
|
||
return false;
|
||
}
|
||
obj.opacity = obj.opacity.clamp(0,255);
|
||
}
|
||
|
||
this.saveState(stateName,true);
|
||
obj.tryRefreshSpriteState();
|
||
this.refreshAdjustMapObjectHelp(obj);
|
||
|
||
if(Input._pressedTime===0 || Input._pressedTime%4===0){
|
||
SoundManager.playCursor();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
/* processManualLocateObj
|
||
===================================*/
|
||
MapDecorator.tryManualLocateObject = function(idx,obj,roomId,objInfoArr,dx=0,dy=0,dragging=null){
|
||
if(roomId<0)return false;
|
||
|
||
var roomBaseIdxes = proc.allBaseIdxes[roomId];
|
||
var baseIdx = proc.idxBaseInfoIdxMap[idx];
|
||
if(baseIdx<0){
|
||
return false;
|
||
}
|
||
|
||
var validIdxes = roomBaseIdxes[baseIdx++].concat();
|
||
TRP_CORE.removeArray(validIdxes,proc.objForbiddenIdxes);
|
||
TRP_CORE.removeArray(validIdxes,proc.passIdxes);
|
||
|
||
var w = 1;
|
||
var h = 1;
|
||
var tx,ty;
|
||
var isMapObj = false;
|
||
var needsSort = true;
|
||
if(Array.isArray(obj)){
|
||
if(Array.isArray(obj[0])){
|
||
//bigObj
|
||
w = obj.length;
|
||
h = obj[0].length;
|
||
}
|
||
tx = idx%width-Math.floor((w-1)/2);
|
||
ty = Math.floor(idx/width)-(h-1);
|
||
}else{
|
||
//MapObject
|
||
isMapObj;
|
||
if(obj.tileId){
|
||
w = obj.tileW;
|
||
h = obj.tileH;
|
||
}
|
||
tx = idx%width-(w-1)/2;
|
||
ty = Math.floor(idx/width)-(h-1);
|
||
|
||
if(!dragging){
|
||
obj = obj.copy();
|
||
}
|
||
}
|
||
|
||
//check target pos valid
|
||
if(tx<0||tx>=width)return false;
|
||
if(ty<0||ty>=height)return false;
|
||
var targetIdx = tx+ty*width;
|
||
|
||
|
||
var targetObj = [targetIdx,obj];
|
||
if(dx||dy){
|
||
targetObj.push(dx,dy);
|
||
}
|
||
if(!Array.isArray(obj)){
|
||
if(!dragging){
|
||
this.startObjectDragging({
|
||
onLocate:true,
|
||
obj,
|
||
objInfoArr,
|
||
data:targetObj,
|
||
tx:idx%width*tileW+dx,
|
||
ty:Math.floor(idx/width)*tileH+dy,
|
||
x:idx%width,
|
||
y:Math.floor(idx/width),
|
||
dx,dy,
|
||
count:10,
|
||
});
|
||
}else{
|
||
//dragging obj
|
||
TRP_CORE.remove(dragging.objInfoArr,dragging.data);
|
||
needsSort = dragging.dy!==dy || dragging.y!==Math.floor(idx/width);
|
||
if(obj.sprite){
|
||
var deltaX = (dx-dragging.dx)+tileW*(idx%width-dragging.x);
|
||
var deltaY = (dy-dragging.dy)+tileH*(Math.floor(idx/width)-dragging.y);
|
||
obj.x += deltaX;
|
||
obj.y += deltaY;
|
||
obj._lastDispX = Number.MAX_SAFE_INTEGER;
|
||
obj._lastDispY = Number.MAX_SAFE_INTEGER;
|
||
obj.setupMargin();
|
||
}
|
||
dragging.objInfoArr = objInfoArr;
|
||
dragging.data = targetObj;
|
||
dragging.dx = dx;
|
||
dragging.dy = dy;
|
||
dragging.x = idx%width;
|
||
dragging.y = Math.floor(idx/width);
|
||
}
|
||
|
||
this.modeData.lastLocateMapObj = obj;
|
||
this.refreshAdjustMapObjectHelp(obj);
|
||
}
|
||
|
||
objInfoArr.push(targetObj);
|
||
|
||
if(needsSort){
|
||
objInfoArr.sort((a,b)=>{
|
||
if(a[0]-b[0]>0)return true;
|
||
if(a[0]===b[0]){
|
||
if(a[3]){
|
||
if(b[3]){
|
||
return a[3]-b[3]>=0;
|
||
}else{
|
||
return true;
|
||
}
|
||
}else if(b[3]){
|
||
return false;
|
||
}else{
|
||
return true;
|
||
}
|
||
}else{
|
||
return false;
|
||
}
|
||
});
|
||
}
|
||
return true;
|
||
};
|
||
|
||
MapDecorator.HELP_ADJUST_MAP_OBJ = [
|
||
'Shift+左右キー:回転<%rotate>',
|
||
'Shift+上下キー:拡大率<%scale>',
|
||
'Alt/Opt+上下左右キー:XY方向拡大率<%xyScale>',
|
||
'M:反転<%mirror>',
|
||
'Q/W/0~9:不透明度<%opacity>',
|
||
'T:色味<%tint>',
|
||
// 'B:ブレンドモード',
|
||
'(Shift+)E:プライオリティ<%priority>',
|
||
'R:変形リセット',
|
||
'C:コピー',
|
||
'Backspace:削除',
|
||
|
||
'(※衝突判定は変形が反映されないので注意)'
|
||
];
|
||
MapDecorator.refreshAdjustMapObjectHelp = function(obj){
|
||
var guide = MapDecorator.HELP_ADJUST_MAP_OBJ.concat();
|
||
var params = {
|
||
rotate:Math.floor(obj.rotation*180/Math.PI),
|
||
scale:Math.floor(obj.scaleX*100)+'%',
|
||
xyScale:(obj.scaleY/obj.scaleX||0).toFixed(2),
|
||
mirror:obj.mirror,
|
||
tint:'%1,%2,%3'.format(obj.tint%255,Math.floor(obj.tint/255)%255,Math.floor(obj.tint/255/255)),
|
||
priority:obj.priority
|
||
}
|
||
for(var i=guide.length-1; i>=0; i=(i-1)|0){
|
||
guide[i] = guide[i]
|
||
.replace('%rotate',params.rotate)
|
||
.replace('%opacity',params.opacity)
|
||
.replace('%scale',params.scale)
|
||
.replace('%xyScale',params.xyScale)
|
||
.replace('%mirror',params.mirror)
|
||
.replace('%tint',params.tint)
|
||
.replace('%priority',params.priority)
|
||
}
|
||
_Dev.showText('adjustMapObj',guide);
|
||
};
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: ObjectPalette
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.objectPalette = [
|
||
'【オブジェパレット】',
|
||
'左クリ:オブジェ選択',
|
||
'右クリ:キャンセル',
|
||
|
||
'Ctrl+A:全タイルセット画像',
|
||
];
|
||
if(MapObject){
|
||
MapDecorator.MODE_GUIDE.objectPalette.push(
|
||
'Ctrl+G:グループオブジェ',
|
||
);
|
||
}
|
||
|
||
MapDecorator.OBJECT_PALETTE_EMPTY_NUM = 2;
|
||
MapDecorator.OBJECT_PALETTE_SIZE = 96;
|
||
MapDecorator.OBJECT_PALETTE_MARGIN = 8;
|
||
MapDecorator.tryShowObjectPalette = function(){
|
||
this.setMode('objectPalette');
|
||
SoundManager.playOk();
|
||
};
|
||
|
||
MapDecorator.lastObjPaletteCategory = 'main';
|
||
MapDecorator.setModeObjectPalette = function(){
|
||
var modeData = this.modeData = {};
|
||
modeData.main = this.objectPaletteMain();
|
||
|
||
if(MapObject){
|
||
modeData.all = this.objectPaletteAll();
|
||
modeData.group = this.objectPaletteGroup();
|
||
}
|
||
|
||
var category = MapDecorator.lastObjPaletteCategory;
|
||
this.showObjectPalette(category);
|
||
};
|
||
MapDecorator.endModeObjectPalette = function(){
|
||
_Dev.showText('objPaletteEx',null);
|
||
};
|
||
|
||
MapDecorator.lastObjPaletteIdxes = {};
|
||
MapDecorator.showObjectPalette = function(category='main'){
|
||
var modeData = this.modeData;
|
||
var palette = modeData[category];
|
||
if(!palette){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
MapDecorator.lastObjPaletteCategory = category;
|
||
|
||
var pageIdx = MapDecorator.lastObjPaletteIdxes[category]||0;
|
||
var completion = obj=>{
|
||
var palette = this.showingPalette;
|
||
if(palette){
|
||
MapDecorator.lastObjPaletteIdxes[category] = palette.pageIdx;
|
||
}
|
||
this.startManualLocateMode(obj);
|
||
};
|
||
|
||
var help = null;
|
||
if(category==='group'){
|
||
help = ['右クリック:オブジェ編集']
|
||
}else if(category==='main'){
|
||
help = ['B~Eキー:タイルセット切替'];
|
||
}else{
|
||
help = [' '];
|
||
}
|
||
_Dev.showText('objPaletteEx',help);
|
||
|
||
var keySearchEnable = category!=='main';
|
||
this.showPalette(palette.objectsArr,palette.pageNames,pageIdx,palette.size,palette.m,palette.x0Num,completion,null,keySearchEnable);
|
||
};
|
||
|
||
MapDecorator.objectPaletteMain = function(){
|
||
var size = MapDecorator.OBJECT_PALETTE_SIZE;
|
||
var m = MapDecorator.OBJECT_PALETTE_MARGIN;
|
||
var x0Num = MapDecorator.OBJECT_PALETTE_EMPTY_NUM;
|
||
var pageNames = [];
|
||
var objectsArr = [];
|
||
|
||
//palette
|
||
var objects = MapDecorator.paletteObjects;
|
||
if(objects.length){
|
||
objectsArr.push(objects);
|
||
pageNames.push('パレット登録');
|
||
}
|
||
|
||
//allObject
|
||
objectsArr.push(allObjects);
|
||
pageNames.push('テンプレ全オブジェ');
|
||
|
||
//tileset
|
||
var tileNames = $gameMap.tileset().tilesetNames;
|
||
var tilesetData = [];
|
||
for(var i=5; i<tileNames.length; i=(i+1)|0){
|
||
var tileName = tileNames[i];
|
||
if(!tileName)continue;
|
||
tilesetData.push('tileset:'+i+':'+tileName);
|
||
pageNames.push(tileName);
|
||
}
|
||
if(tilesetData.length){
|
||
objectsArr.push(...tilesetData);
|
||
}
|
||
return {
|
||
objectsArr,pageNames,size,m,x0Num
|
||
};
|
||
};
|
||
|
||
MapDecorator.ALL_TILESET_FILES = null;
|
||
MapDecorator.objectPaletteAll = function(){
|
||
var size = MapDecorator.OBJECT_PALETTE_SIZE;
|
||
var m = MapDecorator.OBJECT_PALETTE_MARGIN;
|
||
var x0Num = MapDecorator.OBJECT_PALETTE_EMPTY_NUM;
|
||
var pageNames = [];
|
||
var objectsArr = [];
|
||
|
||
if(!MapDecorator.ALL_TILESET_FILES){
|
||
MapDecorator.ALL_TILESET_FILES = [];
|
||
var files = _Dev.readdirSync('img/tilesets/');
|
||
for(const file of files){
|
||
if(!file || !/\.png$/.test(file))continue;
|
||
if(/_A[1-5]/.test(file))continue;
|
||
MapDecorator.ALL_TILESET_FILES.push(file);
|
||
}
|
||
}
|
||
|
||
var tilesetData = [];
|
||
for(const image of MapDecorator.ALL_TILESET_FILES){
|
||
var tileName = image.replace('.png','');
|
||
tilesetData.push('tileset:-1:'+tileName)
|
||
pageNames.push(tileName);
|
||
}
|
||
|
||
if(tilesetData.length){
|
||
objectsArr.push(...tilesetData);
|
||
}
|
||
return {
|
||
objectsArr,pageNames,size,m,x0Num
|
||
};
|
||
};
|
||
|
||
MapDecorator.objectPaletteGroup = function(){
|
||
var size = MapDecorator.OBJECT_PALETTE_SIZE;
|
||
var m = MapDecorator.OBJECT_PALETTE_MARGIN;
|
||
var x0Num = MapDecorator.OBJECT_PALETTE_EMPTY_NUM;
|
||
var pageNames = [];
|
||
var objectsArr = [];
|
||
|
||
var categories = $dataTrpMapObjectGroups.data;
|
||
var keys = Object.keys(categories);
|
||
if(keys.length===0)return null;
|
||
|
||
keys.sort();
|
||
|
||
//palette
|
||
for(const key of keys){
|
||
var categoryData = categories[key];
|
||
var objects = [];
|
||
for(var gi=0; gi<categoryData.length; gi=(gi+1)|0){
|
||
// objects.push('G::'+key+'::'+gi);
|
||
|
||
var data = categoryData[gi];
|
||
if(!data)continue;
|
||
|
||
var obj = MapObject.objectFromGroupData(data);
|
||
obj.cachable = true;
|
||
objects.push(obj);
|
||
}
|
||
|
||
if(objects.length===0)continue;
|
||
objectsArr.push(objects);
|
||
pageNames.push(key+' (%1)'.format(categoryData.length));
|
||
}
|
||
|
||
return {
|
||
objectsArr,pageNames,size,m,x0Num
|
||
};
|
||
};
|
||
|
||
|
||
MapDecorator.updateInputObjectPalette = function(){
|
||
return true;
|
||
}
|
||
MapDecorator.onMouseDownLeftObjectPalette = function(event,i,x,y,tx,ty){
|
||
this.onMouseDownLeftPaletteCommon(event,i,x,y,tx,ty);
|
||
};
|
||
MapDecorator.onMouseDownRightObjectPalette = function(event,i,x,y,tx,ty){
|
||
var selected = false;
|
||
if(MapDecorator.lastObjPaletteCategory==='group'){
|
||
this.onMouseDownLeftPaletteCommon(event,i,x,y,tx,ty,(obj,idx)=>{
|
||
if(!obj)return;
|
||
selected = true;
|
||
|
||
var palette = this.showingPalette;
|
||
TRP_CORE.uniquePush(palette.selected[palette.pageIdx],idx)
|
||
this.refreshPaletteBackSprite();
|
||
|
||
palette.editingObj = obj;
|
||
obj.cachable = false;
|
||
_Dev.showToolsWindowWithId('decorator:objGroup',()=>{
|
||
if(palette.selected){
|
||
TRP_CORE.remove(palette.selected[palette.pageIdx],idx);
|
||
this.refreshPaletteBackSprite();
|
||
}
|
||
|
||
TouchInput.clear();
|
||
palette.editingObj = null;
|
||
|
||
});
|
||
SoundManager.playCancel();
|
||
});
|
||
}
|
||
|
||
if(!selected){
|
||
SoundManager.playCancel();
|
||
this.restoreMode();
|
||
}
|
||
};
|
||
|
||
MapDecorator.onSelectEditMapObjectGroup = function(){
|
||
var palette = this.showingPalette;
|
||
if(!palette || !palette.editingObj)return;
|
||
var obj = palette.editingObj;
|
||
|
||
this.setMode('objectGrouping',{
|
||
editObject:obj,
|
||
});
|
||
}
|
||
|
||
MapDecorator.onSelectDeleteMapObjectGroup = function(){
|
||
var palette = this.showingPalette;
|
||
if(!palette || !palette.editingObj)return;
|
||
var obj = palette.editingObj;
|
||
|
||
if(!confirm('本当に画像とデータを削除しますか?\n(マップに配置済みのオブジェクトは表示されなくなります。)'))return;
|
||
|
||
var category = obj.characterName.replace('G::','');
|
||
var dataIdx = obj.characterIndex;
|
||
|
||
var categories = $dataTrpMapObjectGroups.data[category];
|
||
if(!categories)return;
|
||
|
||
//save groupData
|
||
categories[dataIdx] = null;
|
||
_Dev.saveFile($dataTrpMapObjectGroups,MapObject.GROUP_DATA_PATH);
|
||
|
||
//save image
|
||
var fileName = category+'_'+dataIdx.padZero(4)+'.png';
|
||
var filePath = MapObject.IMAGE_DIR+fileName;
|
||
_Dev.removeFile(filePath);
|
||
|
||
SoundManager.playSave();
|
||
|
||
//refresh ui
|
||
var idx = palette.objectsArr[palette.pageIdx].indexOf(obj);
|
||
TRP_CORE.remove(palette.objectsArr[palette.pageIdx],obj);
|
||
|
||
TRP_CORE.remove(palette.selected[palette.pageIdx],idx);
|
||
|
||
this.refreshPaletteObjects();
|
||
};
|
||
|
||
//register main menu
|
||
_Dev.registerToolCommands({
|
||
key:'',
|
||
id:'decorator:objGroup',
|
||
name:'グループデータ編集',
|
||
commands:[{
|
||
name:'衝突判定の編集',
|
||
type:'script',
|
||
param:'TRP_MapDecorator.onSelectEditMapObjectGroup()'
|
||
,key:'',
|
||
closeWindow:true,
|
||
},{
|
||
name:'画像&データ削除',
|
||
type:'script',
|
||
param:'TRP_MapDecorator.onSelectDeleteMapObjectGroup()'
|
||
,key:'',
|
||
closeWindow:true,
|
||
}],
|
||
});
|
||
|
||
MapDecorator.onKeyDownObjectPalette = function(event){
|
||
var modeData = this.modeData;
|
||
if(!modeData)return;
|
||
|
||
if(event.ctrlKey && event.key==='g'){
|
||
if(MapObject && $dataTrpMapObjectGroups){
|
||
if(MapDecorator.lastObjPaletteCategory==='group'){
|
||
this.showObjectPalette('main')
|
||
}else{
|
||
this.showObjectPalette('group')
|
||
}
|
||
}
|
||
}else if(event.ctrlKey && event.key==='a'){
|
||
if(MapDecorator.lastObjPaletteCategory==='all'){
|
||
this.showObjectPalette('main')
|
||
}else{
|
||
this.showObjectPalette('all')
|
||
}
|
||
}else if(MapDecorator.lastObjPaletteCategory==='main'){
|
||
if(event.key==='b'){
|
||
this.trySwitchPalettePageForTilesetNumber(5);
|
||
}else if(event.key==='c'){
|
||
this.trySwitchPalettePageForTilesetNumber(6);
|
||
}else if(event.key==='d'){
|
||
this.trySwitchPalettePageForTilesetNumber(7);
|
||
}else if(event.key==='e'){
|
||
this.trySwitchPalettePageForTilesetNumber(8);
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: ObjectSelect
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.objectSelect = [
|
||
'【オブジェクト選択モード】',
|
||
'左ドラッグ:オブジェクトをグループ選択',
|
||
'左クリック:オブジェクト選択/解除',
|
||
'Esc/右クリック:モード終了',
|
||
];
|
||
MapDecorator.startObjectSelectMode = function(){
|
||
this.setMode('objectSelect');
|
||
};
|
||
|
||
MapDecorator.setModeObjectSelect = function(){
|
||
if(!this.modeData){
|
||
this.modeData = {
|
||
type:'objectSelect',
|
||
touching:null,
|
||
selected:[],
|
||
};
|
||
}
|
||
};
|
||
MapDecorator.endModeObjectSelect = function(){
|
||
if(!this.modeData)return;
|
||
if(this.modeUICache.selectGraphic){
|
||
var graphic = this.modeUICache.selectGraphic;
|
||
if(graphic.parent){
|
||
graphic.parent.removeChild(graphic);
|
||
}
|
||
}
|
||
this.removeObjectsOutline();
|
||
|
||
_Dev.showText('objectSelected',null);
|
||
};
|
||
|
||
MapDecorator.onMouseDownRightObjectSelect = function(){
|
||
SoundManager.playCancel();
|
||
this.restoreMode();
|
||
};
|
||
MapDecorator.onKeyDownObjectSelect = function(event){
|
||
if(!this.modeData)return;
|
||
|
||
if(event.key==='Escape'){
|
||
SoundManager.playCancel();
|
||
this.restoreMode();
|
||
Input.clear();
|
||
}else if(event.key==='g'){
|
||
this.tryGroupingObjects();
|
||
}else if(event.key==='Backspace'){
|
||
if(!this.modeData.selected.length){
|
||
SoundManager.playBuzzer();
|
||
}else{
|
||
//removeObjects
|
||
this.deleteMapObjects(this.modeData.selected);
|
||
|
||
this.saveState('オブジェ消去');
|
||
SoundManager.playCursor();
|
||
this.restoreMode(true);
|
||
Input.clear();
|
||
}
|
||
}
|
||
};
|
||
MapDecorator.deleteMapObjects = function(objects){
|
||
//removeObjects
|
||
for(const objInfo of objects){
|
||
for(const objInfoArr of proc.lastObjInfoArr){
|
||
if(!objInfoArr)continue;
|
||
if(TRP_CORE.remove(objInfoArr,objInfo)){
|
||
MapObject.remove(objInfo[1]);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//leftClick -> start select
|
||
MapDecorator.onMouseDownLeftObjectSelect = function(event,roomId,x,y,tx,ty,dx,dy){
|
||
if(!this.modeData)return;
|
||
|
||
if(this.onKeyControl){
|
||
if(this.tryStartManualLocateMode(event,roomId,x,y,tx,ty,dx,dy)){
|
||
SoundManager.playCursor();
|
||
}else{
|
||
SoundManager.playBuzzer();
|
||
}
|
||
return;
|
||
}
|
||
|
||
this.modeData.touching = {
|
||
dragging:false,
|
||
shift:Input.isPressed('shift'),
|
||
dragging:false,
|
||
tx0:tx,
|
||
ty0:ty,
|
||
tx1:tx,
|
||
ty1:ty,
|
||
};
|
||
};
|
||
|
||
|
||
//press
|
||
MapDecorator.onMousePressObjectSelect = function(event,roomId,x,y,tx,ty){
|
||
if(!this.modeData)return;
|
||
|
||
var modeData = this.modeData;
|
||
var touching = modeData.touching;
|
||
if(!touching)return;
|
||
|
||
var modeUICache = this.modeUICache;
|
||
var tx0 = touching.tx0;
|
||
var ty0 = touching.ty0;
|
||
var tx1 = touching.tx1 = tx;
|
||
var ty1 = touching.ty1 = ty;
|
||
|
||
touching.dragging = touching.dragging||(Math.abs(tx1-tx0)+Math.abs(ty1-ty0)>=3);
|
||
|
||
if(touching.dragging){
|
||
if(!modeUICache.selectGraphic){
|
||
modeUICache.selectGraphic = new PIXI.Graphics();
|
||
modeUICache.selectGraphic.z = 999;
|
||
}
|
||
SceneManager._scene._spriteset._tilemap.addChild(modeUICache.selectGraphic);
|
||
|
||
var graphic = modeUICache.selectGraphic;
|
||
graphic.clear();
|
||
graphic.beginFill(0x5555ff,0.5)
|
||
.drawRect(tx0,ty0,tx-tx0,ty-ty0);
|
||
}
|
||
}
|
||
|
||
//keyUp -> execSelect
|
||
MapDecorator.onMouseUpObjectSelect = function(){
|
||
var modeData = this.modeData;
|
||
if(!modeData)return;
|
||
|
||
var modeUICache = this.modeUICache;
|
||
if(modeUICache.selectGraphic){
|
||
if(modeUICache.selectGraphic.parent){
|
||
modeUICache.selectGraphic.parent.removeChild(modeUICache.selectGraphic);
|
||
}
|
||
}
|
||
|
||
var touching = modeData.touching;
|
||
if(!touching)return;
|
||
|
||
|
||
var tx0 = Math.min(touching.tx0,touching.tx1);
|
||
var tx1 = Math.max(touching.tx0,touching.tx1);
|
||
var ty0 = Math.min(touching.ty0,touching.ty1);
|
||
var ty1 = Math.max(touching.ty0,touching.ty1);
|
||
var x0 = $gameMap._displayX*tileW+tx0/SETTING.mapDispRange;
|
||
var y0 = $gameMap._displayY*tileH+ty0/SETTING.mapDispRange;
|
||
|
||
var x1,y1;
|
||
var drag = touching.dragging;
|
||
if(drag){
|
||
x1 = $gameMap._displayX*tileW+tx1/SETTING.mapDispRange;
|
||
y1 = $gameMap._displayY*tileH+ty1/SETTING.mapDispRange;
|
||
}
|
||
|
||
var newSelected = [];
|
||
var converted = false;
|
||
var bestTargetInfo = null;
|
||
var bestDist = Number.MAX_SAFE_INTEGER;
|
||
for(const objInfoArr of proc.lastObjInfoArr){
|
||
if(!objInfoArr)continue;
|
||
for(const objInfo of objInfoArr){
|
||
if(Array.isArray(objInfo[1])){
|
||
var obj = this._convertTileIdsArrToMapObject(objInfo[1],objInfo[0]);
|
||
if(!obj)continue;
|
||
|
||
MapObject.tryAdd(obj);
|
||
SceneManager._scene._spriteset.updateTrpMapObjects();
|
||
converted = true;
|
||
objInfo[1] = obj;
|
||
}
|
||
if(this.checkObjectInfoTouch(objInfo,x0,y0,x1,y1,drag ? null : (ax,ay)=>{
|
||
//click -> searchBestDist obj
|
||
var dist = Math.abs(ax-x0)+Math.abs(ay-y0);
|
||
if(dist<bestDist){
|
||
bestDist = dist;
|
||
bestTargetInfo = objInfo;
|
||
}
|
||
})){
|
||
if(drag){
|
||
newSelected.push(objInfo);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
var selected = this.modeData.selected;
|
||
if(drag && !touching.shift){
|
||
//once reset selected
|
||
this.removeObjectsOutline()
|
||
selected.length = 0;
|
||
}
|
||
|
||
if(!drag){
|
||
var target = bestTargetInfo;
|
||
if(!target)return;
|
||
|
||
if(selected.contains(target)){
|
||
TRP_CORE.remove(selected,target);
|
||
}else{
|
||
selected.push(target);
|
||
}
|
||
}else{
|
||
selected.push(...newSelected);
|
||
}
|
||
|
||
if(converted){
|
||
this.restoreMap(true);
|
||
}
|
||
this.removeObjectsOutline();
|
||
|
||
for(const objInfo of selected){
|
||
objInfo[1].setOutlineFilter(0x0000ff,2);
|
||
}
|
||
|
||
if(newSelected.length || bestTargetInfo){
|
||
SoundManager.playCursor();
|
||
}
|
||
|
||
if(selected.length){
|
||
_Dev.showText('objectSelected',[
|
||
'Gキー:グループ化',
|
||
'Backspace:削除',
|
||
]);
|
||
}
|
||
this.saveState('オブジェ選択');
|
||
};
|
||
|
||
MapDecorator._convertTileIdsArrToMapObject = function(tileIds,idx=0,refreshMap=false){
|
||
if(!tileIds)return null;
|
||
|
||
var template = this.mapObjectTemplateWithTileObject(tileIds,true);
|
||
if(!template)return null;
|
||
|
||
var obj = template.copy();
|
||
var x = idx%width;
|
||
var y = Math.floor(idx/width);
|
||
obj.x = (x+obj.tileW/2)*tileW;
|
||
obj.y = (y+obj.tileH)*tileH;
|
||
|
||
if(refreshMap){
|
||
SceneManager._scene._spriteset.updateTrpMapObjects();
|
||
this.restoreMap(true);
|
||
}
|
||
return obj;
|
||
};
|
||
|
||
|
||
/* grouping
|
||
===================================*/
|
||
MapDecorator.tryGroupingObjects = function(){
|
||
var modeData = this.modeData;
|
||
if(!modeData || !modeData.selected)return;
|
||
|
||
var selected = modeData.selected;
|
||
if(selected.length===0){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
for(const objInfo of selected){
|
||
if(!objInfo[1].sprite){
|
||
SoundManager.playBuzzer();
|
||
_Dev.showText('すべてのオブジェクトが画面上に入っている必要があります!');
|
||
return;
|
||
}
|
||
}
|
||
|
||
this.removeObjectsOutline();
|
||
this.setMode('objectGrouping',{
|
||
selected,
|
||
});
|
||
};
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: ObjectGrouping
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.objectGrouping = [
|
||
'【オブジェクトグループ登録】',
|
||
'Sキー:グループ登録&画像保存',
|
||
'Tキー:タイルセット画像に登録',
|
||
'└※衝突判定は保存されません',
|
||
'右クリック:キャンセル',
|
||
];
|
||
MapDecorator.HELP_OBJ_GROUPING_PARAMS = [
|
||
'左クリック/ドラッグ:衝突判定切り替え',
|
||
'Shift+左クリック:水平方向の中心変更',
|
||
'E:プライオリティ変更<%priority>',
|
||
'B:ブレンドモード変更<%blend>',
|
||
];
|
||
MapDecorator.refreshObjectGroupParamsGuide = function(){
|
||
var modeData = this.modeData;
|
||
if(!modeData)return;
|
||
|
||
var guide = MapDecorator.HELP_OBJ_GROUPING_PARAMS.concat();
|
||
for(var i=guide.length-1; i>=0; i=(i-1)|0){
|
||
guide[i] = guide[i]
|
||
.replace('%priority',modeData.priority)
|
||
.replace('%blend',modeData.blendMode)
|
||
}
|
||
_Dev.showText('objGroupingParams',guide);
|
||
};
|
||
|
||
MapDecorator.endModeObjectGrouping = function(){
|
||
var screen = this.modeUICache.screen;
|
||
if(screen && screen.parent){
|
||
screen.parent.removeChild(screen);
|
||
}
|
||
var screen = this.modeUICache.topScreen;
|
||
if(screen && screen.parent){
|
||
screen.parent.removeChild(screen);
|
||
}
|
||
_Dev.showText('objGroupingParams',null);
|
||
};
|
||
|
||
MapDecorator.objectRect = function(s,obj){
|
||
var ax = s.anchor.x;
|
||
var ay = s.anchor.y;
|
||
var ox = obj.x+obj.aX;
|
||
var oy = obj.y+obj.aY;
|
||
var ox0 = -ax*s.scale.x*s.width;
|
||
var ox1 = (1-ax)*s.scale.x*s.width;
|
||
var oy0 = -ay*s.scale.y*s.height;
|
||
var oy1 = (1-ay)*s.scale.y*s.height;
|
||
|
||
if(s.rotation){
|
||
var cos = Math.cos(s.rotation);
|
||
var sin = Math.sin(s.rotation);
|
||
|
||
var arr = [[ox0,oy0],[ox0,oy1],[ox1,oy0],[ox1,oy1]];
|
||
ox0 = oy0 = Number.MAX_SAFE_INTEGER;
|
||
ox1 = oy1 = Number.MIN_SAFE_INTEGER;
|
||
for(const pos of arr){
|
||
var x = cos*pos[0] - sin*pos[1];
|
||
var y = sin*pos[0] + cos*pos[1];
|
||
if(x<ox0)ox0 = x;
|
||
if(x>ox1)ox1 = x;
|
||
if(y<oy0)oy0 = y;
|
||
if(y>oy1)oy1 = y;
|
||
}
|
||
}
|
||
return [ox+ox0,oy+oy0,ox+ox1,oy+oy1];
|
||
};
|
||
|
||
MapDecorator.setModeObjectGrouping = function(){
|
||
if(!this.modeData)return false;
|
||
|
||
var selected = this.modeData.selected;
|
||
var editObj = this.modeData.editObject;
|
||
|
||
|
||
/* confirmScreen
|
||
===================================*/
|
||
var screen = new PIXI.Graphics();
|
||
SceneManager._scene.addChild(screen);
|
||
_Dev.prepareDebugTextContainer();
|
||
|
||
|
||
/* calc rects
|
||
===================================*/
|
||
var objects = [];
|
||
var priority = 2;
|
||
var blendMode = 0;
|
||
var collisions = null;
|
||
|
||
var originalX,originalY,dx,dy,cx;
|
||
var sprite,bitmap;
|
||
// var mockMap = null;
|
||
// var mock = null;
|
||
if(selected){
|
||
|
||
/* analyze objects
|
||
===================================*/
|
||
var x0,x1,y0,y1;
|
||
x0 = y0 = Number.MAX_SAFE_INTEGER;
|
||
x1 = y1 = Number.MIN_SAFE_INTEGER;
|
||
|
||
// var mock = {tileId:0,w:0,h:0,x0:0,y0:0};
|
||
for(const objInfo of selected){
|
||
var obj = objInfo[1];
|
||
objects.push(obj);
|
||
|
||
var s = obj.sprite;
|
||
var rect = MapDecorator.objectRect(s,obj);
|
||
x0 = Math.min(x0,rect[0]);
|
||
y0 = Math.min(y0,rect[1]);
|
||
x1 = Math.max(x1,rect[2]);
|
||
y1 = Math.max(y1,rect[3]);
|
||
|
||
if(obj.priority===1){
|
||
priority = 1;
|
||
}else if(priority!==1){
|
||
priority = Math.min(priority,obj.priority);
|
||
}
|
||
if(obj.blendMode){
|
||
blendMode = obj.blendMode;
|
||
}
|
||
|
||
//search mock
|
||
// if(obj.tileId>0){
|
||
// if(obj.tileW*obj.tileH>mock.w*mock.h){
|
||
// mock.tileId = obj.tileId;
|
||
// mock.w = obj.tileW;
|
||
// mock.h = obj.tileH;
|
||
|
||
// mock.x0 = obj.x-s.width*s.scale.x*s.anchor.x;
|
||
// mock.y0 = obj.y-s.height*s.scale.y*s.anchor.y;
|
||
// }
|
||
// }
|
||
}
|
||
originalX = x0;
|
||
originalY = y0;
|
||
|
||
/* move objects
|
||
===================================*/
|
||
dx = -x0;
|
||
dy = -y0;
|
||
x0 += dx;
|
||
x1 += dx;
|
||
y0 += dy;
|
||
y1 += dy;
|
||
|
||
var w = Math.ceil(x1-x0);
|
||
var h = Math.ceil(y1-y0);
|
||
sprite = new Sprite();
|
||
var orgParents = [];
|
||
for(const obj of objects){
|
||
obj.sprite.x = obj.x+obj.aX+dx;
|
||
obj.sprite.y = obj.y+obj.aY+dy;
|
||
orgParents.push(obj.sprite.parent);
|
||
sprite.addChild(obj.sprite);
|
||
|
||
obj.removeOutlineFilter();
|
||
}
|
||
sprite.children.sort((a,b)=>{
|
||
if(a.z!==b.z)return a.z-b.z;
|
||
if(a.y!==b.y)return a.y-b.y;
|
||
return (a.spriteId - b.spriteId)||0;
|
||
});
|
||
|
||
|
||
/* trim empty pixel
|
||
===================================*/
|
||
var bitmap = TRP_CORE.snap(sprite,w,h);
|
||
var data = bitmap.context.getImageData(0,0,w,h).data;
|
||
var trimX0 = w;
|
||
var trimY0 = h;
|
||
var trimX1 = 0;
|
||
var trimY1 = 0;
|
||
for(var i=0; i<data.length; i=(i+4)|0){
|
||
var x = (i/4)%w;
|
||
var y = Math.floor((i/4)/w);
|
||
if(data[i+3]){
|
||
if(x<trimX0)trimX0 = x;
|
||
if(x>trimX1)trimX1 = x;
|
||
if(y<trimY0)trimY0 = y;
|
||
if(y>trimY1)trimY1 = y;
|
||
}
|
||
}
|
||
|
||
dx -= trimX0;
|
||
dy -= trimY0;
|
||
w = trimX1-trimX0;
|
||
h = trimY1-trimY0;
|
||
originalX += trimX0;
|
||
originalY += trimY0;
|
||
|
||
// mock.x0 += dx;
|
||
// mock.y0 += dy;
|
||
// if(mock.tileId){
|
||
// mockMap = {};
|
||
// var tilesetNumber = 5+Math.floor(mock.tileId/256);
|
||
// mock.tileId = mock.tileId%256;
|
||
// var tilesetName = $gameMap.tileset().tilesetNames[tilesetNumber];
|
||
// MapObject.registerObjectGroupTilesetImage(tilesetName);
|
||
// var tilesetImageId = $dataTrpMapObjectGroups.tilesetImageIds.indexOf(tilesetName);
|
||
// mockMap[tilesetImageId] = mock;
|
||
// }
|
||
|
||
w = Math.ceil(w/2)*2;
|
||
h = Math.ceil(h/2)*2;
|
||
cx = Math.floor(w/2);
|
||
|
||
var trimmedBitmap = new Bitmap(w,h);
|
||
// trimmedBitmap.fillAll('rgba(0,255,0,0.5)');
|
||
trimmedBitmap.blt(bitmap,trimX0,trimY0,w,h,0,0);
|
||
|
||
bitmap = trimmedBitmap;
|
||
|
||
sprite = new Sprite(bitmap);
|
||
|
||
/* restoreObjects
|
||
===================================*/
|
||
for(const obj of objects){
|
||
obj.sprite.x = obj.x+obj.aX-$gameMap._displayX*tileW;
|
||
obj.sprite.y = obj.y+obj.aY-$gameMap._displayY*tileH;
|
||
orgParents.shift().addChild(obj.sprite);
|
||
}
|
||
}else{
|
||
priority = editObj.priority;
|
||
blendMode = editObj.blendMode;
|
||
|
||
editObj.setupSprite(null);
|
||
sprite = editObj.sprite;
|
||
bitmap = sprite.bitmap;
|
||
|
||
originalX = originalY = 0;
|
||
dx = dy = 0;
|
||
w = bitmap.width;
|
||
h = bitmap.height;
|
||
|
||
cx = editObj.anchorX*editObj.spriteW;
|
||
|
||
if(editObj._collisions){
|
||
collisions = TRP_CORE.packValues([],0,(width*4)*(height*4));
|
||
var rowIdx = 0;
|
||
for(const row of editObj._collisions){
|
||
var colIdx = 0;
|
||
for(const flag of row){
|
||
collisions[rowIdx*width*4 + (colIdx++)] = flag;
|
||
}
|
||
rowIdx++;
|
||
}
|
||
}
|
||
|
||
// var category = editObj.characterName.replace('G::','');
|
||
// var groupData = $dataTrpMapObjectGroups.data[category][editObj.characterIndex];
|
||
// mockMap = groupData[MapObject.GROUP_OBJ_IDXES.indexOf(mock)];
|
||
// mock = MapObject.activeMockDataOfMockMap(mockMap);
|
||
// if(mock){
|
||
// mock.x0 += cx;
|
||
// }
|
||
}
|
||
|
||
|
||
|
||
sprite.anchor.set(0.5,0.5);
|
||
sprite.x = Graphics.width/2;
|
||
sprite.y = Graphics.height/2;
|
||
screen.addChild(sprite);
|
||
|
||
this.modeData.cx = cx;
|
||
this.modeData.originalX = originalX;
|
||
this.modeData.originalY = originalY;
|
||
this.modeData.w = w;
|
||
this.modeData.h = h;
|
||
this.modeData.dx = dx;
|
||
this.modeData.dy = dy;
|
||
this.modeData.collisions = collisions;
|
||
this.modeData.objects = objects.map(obj=>obj.copy());
|
||
this.modeData.priority = priority;
|
||
this.modeData.blendMode = blendMode;
|
||
// this.modeData.mockMap = mockMap
|
||
// this.modeData.mock = (mock&&mock.tileId) ? mock : null;
|
||
|
||
this.modeUICache.bitmap = bitmap;
|
||
this.modeUICache.sprite = sprite;
|
||
this.modeUICache.screen = screen;
|
||
this.modeUICache.groupSprite = sprite;
|
||
this.modeUICache.groupBitmap = bitmap;
|
||
this.modeUICache.topScreen = new PIXI.Graphics();
|
||
|
||
this.refreshObjectGroupParamsGuide();
|
||
this._refreshObjectGroupingScreen();
|
||
|
||
SoundManager.playCursor();
|
||
};
|
||
MapDecorator.quitObjectGroupingMode = function(){
|
||
var modeData = this.modeData;
|
||
if(!modeData)return;
|
||
|
||
if(modeData.selected){
|
||
for(const objInfo of modeData.selected){
|
||
objInfo[1].setOutlineFilter(0x0000ff,2);
|
||
}
|
||
this.setMode('objectSelect',{
|
||
type:'objectSelect',
|
||
touching:null,
|
||
selected:modeData.selected,
|
||
});
|
||
}else{
|
||
this.setMode('manualLocate');
|
||
}
|
||
};
|
||
MapDecorator.onMouseDownRightObjectGrouping = function(){
|
||
this.quitObjectGroupingMode();
|
||
SoundManager.playCancel();
|
||
};
|
||
|
||
MapDecorator.onMouseDownLeftObjectGrouping = function(event,roomId,x,y,tx,ty,dx,dy){
|
||
var modeData = this.modeData;
|
||
if(!modeData)return;
|
||
|
||
modeData.lastEditCollisionIdx = -1;
|
||
modeData.lastEditCollisionFlag = false;
|
||
|
||
|
||
if(Input.isPressed('shift')){
|
||
//change anchor x
|
||
var {w,h} = modeData;
|
||
var x0 = Graphics.width/2-w/2;
|
||
var y0 = Graphics.height/2-h/2;
|
||
|
||
if(tx<x0 || tx>x0+w){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
modeData.cx = tx-x0;
|
||
SoundManager.playCursor();
|
||
|
||
modeData.lastEditCollisionIdx = -1;
|
||
modeData.collisions = null;
|
||
modeData.collisionRects = null;
|
||
|
||
SoundManager.playCursor();
|
||
this._refreshObjectGroupingScreen();
|
||
}else{
|
||
var idx = this.objectGroupingTouchCollisionPosition(tx,ty);
|
||
if(idx<0)return;
|
||
|
||
var c0 = idx%(width*4);
|
||
var r0 = Math.floor(idx/(width*4));
|
||
var flag = !modeData.collisions[idx];
|
||
this.modeData.collisionEdit = {
|
||
flag,
|
||
c0:c0,
|
||
r0:r0,
|
||
c1:c0,
|
||
r1:r0,
|
||
lastIdx:idx,
|
||
collisions0:modeData.collisions.concat(),
|
||
};
|
||
if(modeData.priority!==1){
|
||
modeData.priority = 1;
|
||
this.refreshObjectGroupParamsGuide();
|
||
}
|
||
|
||
modeData.collisions[idx] = flag;
|
||
SoundManager.playCursor();
|
||
this._refreshObjectGroupingScreen();
|
||
}
|
||
};
|
||
|
||
MapDecorator.onMousePressObjectGrouping = function(event,roomId,x,y,tx,ty,dx,dy){
|
||
var modeData = this.modeData;
|
||
if(!modeData)return;
|
||
if(Input.isPressed('shift'))return;
|
||
if(this.onKeyControl||this.onKeyAlt||this.onKeyMeta)return;
|
||
|
||
/* edit collisions
|
||
===================================*/
|
||
var editData = modeData.collisionEdit;
|
||
if(editData){
|
||
var idx = this.objectGroupingTouchCollisionPosition(tx,ty);
|
||
if(idx<0)return;
|
||
if(editData.lastIdx===idx)return;
|
||
editData.lastIdx = idx;
|
||
|
||
var tc = idx%(width*4);
|
||
var tr = Math.floor(idx/(width*4));
|
||
var c0 = Math.min(tc,editData.c0);
|
||
var c1 = Math.max(tc,editData.c0);
|
||
var r0 = Math.min(tr,editData.r0);
|
||
var r1 = Math.max(tr,editData.r0);
|
||
|
||
//reset collisions
|
||
var collisions = modeData.collisions;
|
||
collisions.length = 0;
|
||
collisions.push(...(editData.collisions0));
|
||
|
||
//switch collisions
|
||
var flag = editData.flag;
|
||
for(var c=c0; c<=c1; c=(c+1)|0){
|
||
for(var r=r0; r<=r1; r=(r+1)|0){
|
||
var i = c+r*width*4;
|
||
collisions[i] = flag;
|
||
}
|
||
}
|
||
|
||
SoundManager.playCursor();
|
||
this._refreshObjectGroupingScreen();
|
||
}
|
||
};
|
||
MapDecorator.onMouseUpObjectGrouping = function(event){
|
||
if(this.modeData){
|
||
this.modeData.collisionEdit = null;
|
||
}
|
||
};
|
||
|
||
MapDecorator.objectGroupingTouchCollisionPosition = function(tx,ty){
|
||
var modeData = this.modeData;
|
||
if(!modeData)return -1;
|
||
|
||
var rects = modeData.collisionRects;
|
||
for(var i=rects.length-1; i>=0; i=(i-1)|0){
|
||
var rect = rects[i];
|
||
if(tx<rect[0])continue;
|
||
if(tx>=rect[0]+rect[2])continue;
|
||
if(ty<rect[1])continue;
|
||
if(ty>=rect[1]+rect[3])continue;
|
||
var collisionX = tx-modeData.collisionX0;
|
||
var collisionY = ty-modeData.collisionY0;
|
||
var col = Math.floor(collisionX/(tileW/4));
|
||
var row = Math.floor(collisionY/(tileH/4));
|
||
var idx = col+row*width*4;
|
||
return idx;
|
||
};
|
||
return -1;
|
||
};
|
||
|
||
|
||
MapDecorator.onKeyDownObjectGrouping = function(event){
|
||
var refreshParams = false;
|
||
if(event.key==='Escape'){
|
||
this.quitObjectGroupingMode();
|
||
SoundManager.playCancel();
|
||
}else if(event.key === 't'){
|
||
this.startTilesetEdit(this.modeUICache.bitmap);
|
||
SoundManager.playCursor();
|
||
}else if(event.key==='s'){
|
||
this.saveObjectGroup();
|
||
}else if(event.key==='e'){
|
||
//changePriority
|
||
this.modeData.priority += 1;
|
||
if(this.modeData.priority>2){
|
||
this.modeData.priority = 0;
|
||
}
|
||
this._refreshObjectGroupingScreen();
|
||
refreshParams = true;
|
||
}else if(event.key==='b'){
|
||
this.modeData.blendMode += 1;
|
||
if(this.modeData.blendMode>4){
|
||
this.modeData.blendMode = 0;
|
||
}
|
||
TRP_CORE.setBlendMode(this.modeUICache.sprite,this.modeData.blendMode);
|
||
refreshParams = true;
|
||
}
|
||
if(refreshParams){
|
||
this.refreshObjectGroupParamsGuide();
|
||
SoundManager.playCursor();
|
||
}
|
||
};
|
||
|
||
MapDecorator._refreshObjectGroupingScreen = function(){
|
||
var modeData = this.modeData;
|
||
if(!modeData)return;
|
||
|
||
var screen = this.modeUICache.screen;
|
||
var topScreen = this.modeUICache.topScreen;
|
||
SceneManager._scene.addChild(topScreen);
|
||
|
||
topScreen.clear();
|
||
screen.clear();
|
||
screen.beginFill(0x000000,0.8)
|
||
.drawRect(0,0,Graphics.width,Graphics.height);
|
||
|
||
var {w,h} = modeData;
|
||
var uw = tileW/4;
|
||
var uh = tileH/4;
|
||
|
||
var x0 = Graphics.width/2-w/2;
|
||
var y0 = Graphics.height/2-h/2;
|
||
var y1 = Graphics.height/2+h/2;
|
||
|
||
var cx = x0 + modeData.cx;
|
||
|
||
var x = cx-Math.ceil((cx-x0)/uw)*uw;
|
||
var y = y1-Math.ceil(h/uh)*uh;
|
||
modeData.collisionX0 = x;
|
||
modeData.collisionY0 = y;
|
||
|
||
|
||
//anchor line
|
||
topScreen.beginFill(0x0000ff)
|
||
.drawRect(cx,0,1,Graphics.height);
|
||
|
||
|
||
//calc collisions
|
||
var collisions = modeData.collisions;
|
||
if(!collisions){
|
||
var cacheMapObjects = $dataTrpMapObjects;
|
||
var objects = $dataTrpMapObjects = modeData.objects;
|
||
var dx = modeData.dx + modeData.cx%uw;
|
||
var dy = modeData.dy + y1%uh;
|
||
for(const obj of objects){
|
||
obj.x += dx;
|
||
obj.y += dy;
|
||
}
|
||
|
||
collisions = MapObject.collisionsMap();
|
||
modeData.collisions = collisions;
|
||
|
||
//restore collisions
|
||
$dataTrpMapObjects = cacheMapObjects;
|
||
for(const obj of objects){
|
||
obj.x -= dx;
|
||
obj.y -= dy;
|
||
}
|
||
}
|
||
|
||
|
||
//draw back
|
||
var col = 0;
|
||
var collisionRects = modeData.collisionRects = [];
|
||
for(var tx=x; tx<x0+w; tx+=uw){
|
||
var tw = uw;
|
||
var row = 0;
|
||
for(var ty=y; ty<y0+h; ty+=uh){
|
||
var th = uh;
|
||
var colorIdx = (row+col)%2;
|
||
screen.beginFill(colorIdx===0 ? 0xdcdcdc : 0xffffff)
|
||
.drawRect(tx,ty,tw,th);
|
||
|
||
collisionRects.push([tx,ty,tw,th]);
|
||
row++;
|
||
}
|
||
col++;
|
||
}
|
||
modeData.collisionRow = row;
|
||
modeData.collisionCol = col;
|
||
|
||
|
||
//draw lines
|
||
var c = 0;
|
||
for(var tx=x; tx<=x0+w; tx+=uw){
|
||
if(c%4===0){
|
||
topScreen.beginFill(0x000000)
|
||
.drawRect(tx,y,1,row*uh);
|
||
}
|
||
c++;
|
||
}
|
||
var r = 0;
|
||
for(var ty=y; ty<=y0+h; ty+=uh){
|
||
if((row-r)%4===0){
|
||
topScreen.beginFill(0x000000)
|
||
.drawRect(x,ty,col*uh,1);
|
||
}
|
||
r++;
|
||
}
|
||
|
||
|
||
//draw collisions
|
||
var length = collisions.length;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
if(!collisions[i])continue;
|
||
var c = i%(4*width);
|
||
var r = Math.floor(i/(4*width));
|
||
if(modeData.priority===1){
|
||
topScreen.beginFill(0xff0000,0.6)
|
||
.drawRect(x+c*uw,y+r*uh,uw-1,uh-1);
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
/* saveObjectGroup
|
||
===================================*/
|
||
MapDecorator.saveObjectGroup = function(){
|
||
var modeData = this.modeData;
|
||
if(!modeData)return;
|
||
|
||
var sprite = this.modeUICache.sprite;
|
||
var bitmap = this.modeUICache.bitmap;
|
||
|
||
var dataIdx = -1;
|
||
var category,categoryData;
|
||
if(modeData.selected){
|
||
/* new register
|
||
===================================*/
|
||
SoundManager.playCursor();
|
||
var categories = Object.keys($dataTrpMapObjectGroups.data);
|
||
// categories.sort((a,b)=>{
|
||
// return $dataTrpMapObjectGroups.data[a].length-$dataTrpMapObjectGroups.data[b].length;
|
||
// });
|
||
var text = 'カテゴリ名または番号を入力してください。';
|
||
var length = Math.min(10,categories.length);
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
text += '\n';
|
||
var num = 0;
|
||
$dataTrpMapObjectGroups.data[categories[i]].forEach(d=>{if(d)num+=1});
|
||
text += (i+1)+':'+categories[i]+'(%1個)'.format(num);
|
||
}
|
||
|
||
|
||
var fileName;
|
||
while(true){
|
||
category = prompt(text,'object');
|
||
if(!category){
|
||
SoundManager.playCancel();
|
||
return;
|
||
}
|
||
|
||
category = fileName = category ? category.trim() : null;
|
||
if(!isNaN(category)){
|
||
category = fileName = categories[Number(category)-1];
|
||
if(!category){
|
||
SoundManager.playBuzzer();
|
||
continue;
|
||
}
|
||
}
|
||
if(!fileName){
|
||
SoundManager.playCancel();
|
||
return;
|
||
}
|
||
|
||
categoryData = $dataTrpMapObjectGroups.data[category];
|
||
if(categoryData){
|
||
fileName += '_'+(categoryData.length).padZero(4)+'.png';
|
||
break;
|
||
}else{
|
||
fileName += '_0000.png';
|
||
if(confirm(
|
||
'このカテゴリに保存済みのデータはありません。\n'
|
||
+ 'ファイル名「'+fileName+'」で保存しますか?'
|
||
)){
|
||
categoryData = $dataTrpMapObjectGroups.data[category] = [];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
//save image
|
||
var filePath = MapObject.IMAGE_DIR+fileName;
|
||
_Dev.ensureDirectoriesWithFilePath(filePath);
|
||
_Dev.saveCanvas(bitmap,filePath);
|
||
}else{
|
||
var editObject = modeData.editObject;
|
||
category = editObject.characterName.replace('G::','');
|
||
dataIdx = editObject.characterIndex;
|
||
categoryData = $dataTrpMapObjectGroups.data[category];
|
||
}
|
||
|
||
var collisions = null;
|
||
if(modeData.priority===1){
|
||
var row = modeData.collisionRow;
|
||
var col = modeData.collisionCol;
|
||
collisions = [];
|
||
for(var r=0; r<row; r=(r+1)|0){
|
||
var rowFlags = [];
|
||
collisions.push(rowFlags);
|
||
for(var c=0; c<col; c=(c+1)|0){
|
||
var collisionIdx = c+r*width*4;
|
||
rowFlags.push(modeData.collisions[collisionIdx]?1:0);
|
||
}
|
||
}
|
||
}
|
||
|
||
if(dataIdx<0){
|
||
dataIdx = categoryData.length;
|
||
}
|
||
|
||
// if(modeData.mock){
|
||
// modeData.mock.x0 -= modeData.cx;
|
||
// }
|
||
|
||
var objData = {
|
||
characterName:'G::'+category,
|
||
characterIndex:dataIdx,
|
||
blendMode:modeData.blendMode,
|
||
priority:modeData.priority,
|
||
cx:modeData.cx,
|
||
_collisions:collisions,
|
||
tileW:bitmap.width,
|
||
tileH:bitmap.height,
|
||
// mock:modeData.mockMap,
|
||
}
|
||
|
||
var dataArr = MapObject.GROUP_OBJ_IDXES.map(key=>objData[key]);
|
||
categoryData[dataIdx] = dataArr;
|
||
|
||
|
||
// save $dataTrpMapObjectGroups
|
||
_Dev.saveFile($dataTrpMapObjectGroups,MapObject.GROUP_DATA_PATH);
|
||
|
||
|
||
//save assets
|
||
var assets = [];
|
||
var categories = Object.keys($dataTrpMapObjectGroups.data);
|
||
for(const category of categories){
|
||
var groupArr = $dataTrpMapObjectGroups.data[category];
|
||
var groupLen = groupArr.length;
|
||
for(var gi=0; gi<groupLen; gi=(gi+1)|0){
|
||
if(!groupArr[gi])continue;
|
||
assets.push('img/trp_map_objects/'+category+'_'+(gi).padZero(4));
|
||
}
|
||
}
|
||
_Dev.setCategoryAllAssets('mapObjectGroup',assets);
|
||
|
||
|
||
|
||
var selected = this.modeData.selected;
|
||
|
||
//mode -> manualLocate
|
||
this.setMode('manualLocate');
|
||
// this.quitObjectGroupingMode();
|
||
|
||
|
||
/* replace selected->GroupObj
|
||
===================================*/
|
||
if(selected){
|
||
var obj = MapObject.objectFromGroupData(dataArr,true);
|
||
var x = modeData.originalX;
|
||
var y = modeData.originalY;
|
||
obj.x = x+obj.anchorX*obj.spriteW;
|
||
obj.y = y+obj.anchorY*obj.spriteH;
|
||
|
||
var tx = Math.floor(obj.x/tileW);
|
||
var ty = Math.ceil(obj.y/tileH);
|
||
var idx = tx+width*ty;
|
||
|
||
var dx = obj.x - (tx+1/2)*tileW;
|
||
var dy = obj.y - (ty+1)*tileH;
|
||
|
||
var roomId = proc.roomIdxMapForUserProc[idx];
|
||
if(roomId>=0){
|
||
this.deleteMapObjects(selected);
|
||
|
||
proc.lastObjInfoArr[roomId] = proc.lastObjInfoArr[roomId]||[];
|
||
proc.lastObjInfoArr[roomId].push([idx,obj,dx,dy]);
|
||
// this.registerMapObjectTemplateWithMapObject(obj);
|
||
|
||
obj.setupCommonAfter();
|
||
this.restoreMap(true);
|
||
}else{
|
||
MapObject.cache(obj);
|
||
}
|
||
}else{
|
||
//update objSetting
|
||
var editObject = modeData.editObject;
|
||
var cx = modeData.cx;
|
||
var anchorX = cx/editObject.spriteW;
|
||
for(const obj of $dataTrpMapObjects){
|
||
if(editObject.characterName!==obj.characterName)continue;
|
||
if(editObject.characterIndex!==obj.characterIndex)continue;
|
||
|
||
obj.blendMode = editObject.blendMode;
|
||
obj.priority = editObject.priority;
|
||
obj._collisions = collisions ? collisions.concat() : null;
|
||
|
||
var objCx = obj.anchorX*obj.spriteW;
|
||
if(cx!==objCx){
|
||
obj.anchorX = anchorX;
|
||
obj.x += cx-objCx;
|
||
if(obj.sprite){
|
||
obj.sprite.x += cx-objCx;
|
||
}
|
||
}
|
||
obj.tryRefreshSpriteState();
|
||
}
|
||
}
|
||
|
||
this.saveState('オブジェグループ化');
|
||
SoundManager.playSave();
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: UserProcess
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.userProcess = [
|
||
'【置換プロセスモード】',
|
||
'左クリック:置換やり直し',
|
||
'右クリック:ロック',
|
||
'Esc:モード終了',
|
||
'※置換処理は"抽選作業の途中"に行わないこと',
|
||
];
|
||
MapDecorator.clearUserProcessParams = function(){
|
||
var modeData = this.modeData = this.modeData||{};
|
||
modeData.type = 'userProcess';
|
||
|
||
modeData.timing = null;
|
||
modeData.lastProc = null;
|
||
modeData.lockedRoomIds = [];
|
||
modeData.lockedResults = [];
|
||
modeData.lockedAllResults = [];
|
||
modeData.lastResults = null;
|
||
};
|
||
|
||
MapDecorator.startUserProcessMode = function(timing,once=false){
|
||
if(!MapDecorator.processList[timing]){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
if(once){
|
||
this.processUserProcessList(timing);
|
||
originalData = data.concat();
|
||
SoundManager.playOk();
|
||
|
||
this.saveState('置換プロセス実行');
|
||
}else{
|
||
this.setMode('userProcess');
|
||
this.clearUserProcessParams();
|
||
this.modeData.timing = timing;
|
||
|
||
this.saveState('置換プロセスモード開始');
|
||
}
|
||
};
|
||
|
||
MapDecorator.updateInputUserProcess = function(){
|
||
if(Input.isTriggered('cancel')){
|
||
originalData = data.concat();
|
||
this.restoreMode();
|
||
SoundManager.playCancel();
|
||
Input.clear();
|
||
return true;
|
||
}else{
|
||
return false;
|
||
}
|
||
};
|
||
|
||
MapDecorator.onMouseDownLeftUserProcess = function(event,i,x,y,tx,ty){
|
||
if(Input.isPressed('shift')){
|
||
|
||
}else{
|
||
//exec process
|
||
var modeData = this.modeData;
|
||
if(modeData.lastProc){
|
||
data.length = 0;
|
||
data.push(...originalData);
|
||
proc = modeData.lastProc;
|
||
}else{
|
||
modeData.lastProc = JsonEx.makeDeepCopy(proc);
|
||
}
|
||
|
||
var allResults = modeData.lockedAllResults;
|
||
if(allResults.length){
|
||
this.processUserProcessListWithResults(allResults);
|
||
}
|
||
modeData.lastResults = this.processUserProcessList(modeData.timing,modeData.lockedRoomIds,true);
|
||
|
||
this.saveState('置換プロセス実行');
|
||
SoundManager.playCursor();
|
||
}
|
||
};
|
||
MapDecorator.onMouseDownRightUserProcess = function(event,i,x,y,tx,ty){
|
||
var modeData = this.modeData;
|
||
if(!this.modeData.lastProc){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
if(i<0){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
if(Input.isPressed('shift')){
|
||
//try back to paintFloor
|
||
if(modeData.lockedRoomIds.contains(i)){
|
||
TRP_CORE.remove(modeData.lockedRoomIds,i);
|
||
var results = modeData.lockedResults[i];
|
||
TRP_CORE.removeArray(modeData.lockedAllResults,modeData.lockedResults[i]);
|
||
modeData.lockedRoomIds[i] = null;
|
||
|
||
var text = 'プロセスアンロック!';
|
||
showInfoText(text);
|
||
this.saveState(text);
|
||
SoundManager.playCancel();
|
||
}else{
|
||
SoundManager.playBuzzer();
|
||
}
|
||
}else if(!modeData.lastProc){
|
||
//not processed yet
|
||
SoundManager.playBuzzer();
|
||
}else if(modeData.lockedRoomIds.contains(i)){
|
||
//already locked
|
||
SoundManager.playBuzzer();
|
||
}else{
|
||
//userProc lock
|
||
TRP_CORE.uniquePush(modeData.lockedRoomIds,i);
|
||
var results = modeData.lockedResults[i] = [];
|
||
var allResults = modeData.lockedAllResults;
|
||
|
||
for(const result of modeData.lastResults){
|
||
var idx = result[0];
|
||
if(proc.roomIdxMapForUserProc[idx]!==i)continue;
|
||
|
||
allResults.push(result);
|
||
results.push(result);
|
||
}
|
||
|
||
var text = 'プロセスロック!';
|
||
showInfoText(text);
|
||
this.saveState(text);
|
||
SoundManager.playOk();
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// User Process
|
||
//=============================================================================
|
||
var PROCESS_TYPES = MapDecorator.PROCESS_TYPES = {
|
||
replace:0,
|
||
};
|
||
var PROCESS_FLAGS = MapDecorator.PROCESS_FLAGS = {
|
||
none:0,
|
||
condNot:1,
|
||
noShape:2,
|
||
noErase:3,
|
||
reverseOrder:4,
|
||
noConnect:5,
|
||
connectFloor:6,
|
||
};
|
||
|
||
MapDecorator.processUserProcessList = function(timing,lockedRoomIds=null,needsResult=false){
|
||
var list = MapDecorator.processList[timing];
|
||
if(!list)return;
|
||
|
||
var autoTileIdxes = [];
|
||
var resultList = needsResult ? [] : null;
|
||
for(const proc of list){
|
||
switch(proc.type){
|
||
case PROCESS_TYPES.replace:
|
||
this.processReplaceTiles(proc,autoTileIdxes,lockedRoomIds,resultList);
|
||
break;
|
||
}
|
||
}
|
||
|
||
for(const idx of autoTileIdxes){
|
||
data[idx] = connectAutoTileWithIdx(idx,1);
|
||
}
|
||
|
||
this.requestRefreshTilemap();
|
||
|
||
return resultList;
|
||
};
|
||
MapDecorator.processUserProcessListWithResults = function(results){
|
||
var autoTileIdxes = [];
|
||
for(const result of results){
|
||
var type = result[1];
|
||
var params = result[2];
|
||
switch(type){
|
||
case PROCESS_TYPES.replace:
|
||
this.executeReplaceTileIds(...params,autoTileIdxes);
|
||
break;
|
||
}
|
||
}
|
||
|
||
for(const idx of autoTileIdxes){
|
||
data[idx] = connectAutoTileWithIdx(idx,1);
|
||
}
|
||
};
|
||
|
||
MapDecorator.quickCheckTileId = function(ids){
|
||
if(!ids)return null;
|
||
|
||
var noShape = false;
|
||
var reverseOrder = false;
|
||
var tileId = ids[0];
|
||
if(Array.isArray(ids[ids.length-1])){
|
||
var flags = ids[ids.length-1];
|
||
if(flags.contains(PROCESS_FLAGS.condNot)){
|
||
return null;
|
||
}
|
||
if(flags.contains(PROCESS_FLAGS.noShape)){
|
||
noShape = true;
|
||
tileId = baseTileId(tileId);
|
||
}
|
||
if(flags.contains(PROCESS_FLAGS.reverseOrder)){
|
||
reverseOrder = true;
|
||
}
|
||
}
|
||
if(tileId<=0 || !tileId){
|
||
return null;
|
||
}
|
||
|
||
return {
|
||
tileId,
|
||
noShape,
|
||
reverseOrder,
|
||
};
|
||
}
|
||
MapDecorator.processReplaceTiles = function(userProc,autoTileIdxes,lockedRoomIds=null,resultList=null){
|
||
var tileIds = userProc.tileIds;
|
||
|
||
var candidates = userProc.candidates;
|
||
var candidatesLen = candidates.length;
|
||
|
||
var rate = userProc.rate;
|
||
if(!candidatesLen || rate<=0)return;
|
||
var needsDraw = rate<1;
|
||
|
||
var w,h;
|
||
var isBigObj = Array.isArray(tileIds[0]);
|
||
|
||
var qIdx = 0;
|
||
var quickCheck = null;
|
||
var qcFound = false;
|
||
var reverseOrder = false;
|
||
|
||
if(isBigObj){
|
||
w = tileIds.length;
|
||
h = tileIds[0].length;
|
||
for(var dx=0; dx<w&&!qcFound; dx=(dx+1)|0){
|
||
for(var dy=0; dy<h&&!qcFound; dy=(dy+1)|0){
|
||
var checkInfo = this.quickCheckTileId(tileIds[dx][dy]);
|
||
if(!checkInfo)continue;
|
||
|
||
if(checkInfo.noShape && quickCheck)continue;
|
||
qcFound = !checkInfo.noShape;
|
||
|
||
quickCheck = checkInfo;
|
||
qIdx = dx+dy*width;
|
||
}
|
||
}
|
||
}else{
|
||
w = h = 1;
|
||
quickCheck = this.quickCheckTileId(tileIds);
|
||
}
|
||
var qcFlag = !!quickCheck;
|
||
var qId = quickCheck ? quickCheck.tileId : 0;
|
||
|
||
var targetTileIds = candidates[0];
|
||
|
||
var sign = 1;
|
||
var x0 = 0;
|
||
var y0 = 0;
|
||
if(quickCheck && quickCheck.reverseOrder){
|
||
sign = -1;
|
||
x0 = width-w;
|
||
y0 = height-h;
|
||
}
|
||
for(var xi=0, x=x0; xi<width-w+1; xi=(xi+1)|0, x=(x+sign)|0){
|
||
for(var yi=0, y=y0; yi<height-h+1; yi=(yi+1)|0, y=(y+sign)|0){
|
||
var idx = x+y*width;
|
||
|
||
// if(_Dev.inDev && userProc.sx===147 && idx===667){
|
||
// debugger;
|
||
// }
|
||
|
||
if(invalidIdxes && invalidIdxes.contains(idx))continue;
|
||
if(lockedRoomIds){
|
||
var roomId = proc.roomIdxMapForUserProc[idx];
|
||
if(roomId>=0 && lockedRoomIds.contains(roomId)){
|
||
continue;
|
||
}
|
||
}
|
||
|
||
//quick check
|
||
if(qcFlag){
|
||
if(quickCheck.noShape){
|
||
if(!(//noShape
|
||
|
||
(data[idx+qIdx]&&baseTileId(data[idx+qIdx])===qId)
|
||
||(data[idx+qIdx+zAcc]&&baseTileId(data[idx+qIdx+zAcc])===qId)
|
||
||(data[idx+qIdx+zObj1]&&baseTileId(data[idx+qIdx+zObj1])===qId)
|
||
||(data[idx+qIdx+zObj2]&&baseTileId(data[idx+qIdx+zObj2])===qId))
|
||
)continue;
|
||
}else{
|
||
if(!(data[idx+qIdx]===qId
|
||
||data[idx+qIdx+zAcc]===qId
|
||
||data[idx+qIdx+zObj1]===qId
|
||
||data[idx+qIdx+zObj2]===qId)
|
||
)continue;
|
||
}
|
||
}
|
||
|
||
//draw rate
|
||
if(needsDraw && Math.random()>rate)continue;
|
||
|
||
//check all tileIds
|
||
var checkOk = true;
|
||
for(var dx=0; dx<w&&checkOk; dx=(dx+1)|0){
|
||
for(var dy=0; dy<h; dy=(dy+1)|0){
|
||
if(invalidIdxes && invalidIdxes.contains(idx+dx+dy*width))continue;
|
||
|
||
if(!this._checkLayeredTileIdsMatchWithFlags(
|
||
idx+dx+dy*width,
|
||
isBigObj?tileIds[dx][dy]:tileIds,
|
||
)){
|
||
checkOk = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if(!checkOk)continue;
|
||
|
||
|
||
//draw candidates
|
||
if(candidatesLen>1){
|
||
targetTileIds = candidates[Math.randomInt(candidatesLen)];
|
||
}
|
||
if(resultList){
|
||
resultList.push([idx,PROCESS_TYPES.replace,[isBigObj,tileIds,w,h,targetTileIds,idx,x,y]]);
|
||
}
|
||
|
||
//apply tileIds
|
||
this.executeReplaceTileIds(isBigObj,tileIds,w,h,targetTileIds,idx,x,y,autoTileIdxes);
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
MapDecorator._checkLayeredTileIdsMatchWithFlags = function(idx,tileIds,removeFlag=false){
|
||
if(!tileIds)return true;
|
||
|
||
var flags = Array.isArray(tileIds[tileIds.length-1]) ? tileIds[tileIds.length-1] : null;
|
||
|
||
var success = true;
|
||
var failure = false;
|
||
var noShape = false;
|
||
if(flags){
|
||
if(flags.contains(PROCESS_FLAGS.condNot)){
|
||
if(removeFlag)return true;
|
||
success = false;
|
||
failure = true;
|
||
}
|
||
if(flags.contains(PROCESS_FLAGS.noShape)){
|
||
noShape = true;
|
||
}
|
||
if(flags.contains(PROCESS_FLAGS.noErase)){
|
||
if(removeFlag)return true;
|
||
}
|
||
|
||
}
|
||
|
||
var usedZ = 0;
|
||
var shape = 0;
|
||
var bestShape = 0;
|
||
var i = tileIds.length-1 - (flags?1:0);
|
||
for(; i>=0; i=(i-1)|0){
|
||
var tileId = tileIds[i];
|
||
if(tileId<0){
|
||
if(tileId<=MapDecorator.REGION_ID_BEGIN && tileId>=MapDecorator.REGION_ID_END){
|
||
//regionId
|
||
if(data[idx+zRegion]!==(-(tileId-MapDecorator.REGION_ID_BEGIN)))return failure;
|
||
|
||
//match
|
||
if(removeFlag)data[idx+zRegion] = 0;
|
||
}else if(tileId<=MapDecorator.SHADOW_ID_BEGIN && tileId>=MapDecorator.SHADOW_ID_END){
|
||
//shadow
|
||
if(data[idx+zShadow]!==(-(tileId-MapDecorator.SHADOW_ID_BEGIN)))return failure;
|
||
|
||
//match
|
||
if(removeFlag)data[idx+zShadow] = 0;
|
||
}else{
|
||
//invalid tileId
|
||
continue;
|
||
}
|
||
}else{
|
||
//normal tile
|
||
if(noShape){
|
||
tileId = baseTileId(tileId);
|
||
}
|
||
|
||
var found = false;
|
||
for(var z=0; z<4; z=(z+1)|0){
|
||
if(usedZ & 1<<z)continue;
|
||
|
||
var tId = data[idx+z*zLayerSize];
|
||
if(noShape&&tId){
|
||
shape = tId-baseTileId(tId);
|
||
tId -= shape;
|
||
}
|
||
|
||
if(tId===tileId){
|
||
//match
|
||
found = true;
|
||
usedZ |= (1<<z);
|
||
if(removeFlag){
|
||
data[idx+z*zLayerSize] = 0;
|
||
}
|
||
if(shape){
|
||
if(!Tilemap.isWallSideTile(tId)){
|
||
bestShape = shape;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if(!found)return failure;
|
||
}
|
||
}
|
||
|
||
if(removeFlag){
|
||
return bestShape;
|
||
}else{
|
||
return success;
|
||
}
|
||
};
|
||
|
||
|
||
MapDecorator.executeReplaceTileIds = function(isBigObj,tileIds,w,h,targetTileIds,idx,x,y,autoTileIdxes){
|
||
var shapes = null;
|
||
var shape = 0;
|
||
for(var dx=0; dx<w; dx=(dx+1)|0){
|
||
for(var dy=0; dy<h; dy=(dy+1)|0){
|
||
shape = this._checkLayeredTileIdsMatchWithFlags(
|
||
idx+dx+dy*width,
|
||
isBigObj?tileIds[dx][dy]:tileIds,
|
||
true//removeFlag
|
||
);
|
||
if(shape){
|
||
//shapes=[deltaIdx,shape,...]
|
||
shapes = shapes||[];
|
||
shapes.push(dx+dy*width);
|
||
shapes.push(shape);
|
||
}
|
||
}
|
||
}
|
||
|
||
var w1 = isBigObj ? targetTileIds.length : 1;
|
||
var h1 = isBigObj ? targetTileIds[0].length : 1;
|
||
for(var dx=0; dx<w1; dx=(dx+1)|0){
|
||
if(x+dx>=width)continue;
|
||
for(var dy=0; dy<h1; dy=(dy+1)|0){
|
||
if(y+dy>=height)continue;
|
||
if(invalidIdxes && invalidIdxes.contains(idx+dx+dy*width))continue;
|
||
|
||
if(shapes && shapes[0]===dx+dy*width){
|
||
shapes.shift();
|
||
shape = shapes.shift();
|
||
}
|
||
this.applyLayeredTileIdsWithFlags(
|
||
idx+dx+dy*width,
|
||
isBigObj?targetTileIds[dx][dy]:targetTileIds,
|
||
autoTileIdxes,
|
||
shape, //for sustainShape(noShape)
|
||
);
|
||
}
|
||
}
|
||
};
|
||
MapDecorator.applyLayeredTileIdsWithFlags = function(idx,targetTileIds,autoTileIdxes=null,shape=0){
|
||
if(!targetTileIds)return;
|
||
|
||
//flags
|
||
var flags = Array.isArray(targetTileIds[targetTileIds.length-1]) ? targetTileIds[targetTileIds.length-1] : null;
|
||
var sustainShape=false, noConnect=false;
|
||
if(flags){
|
||
sustainShape = flags.contains(PROCESS_FLAGS.noShape);
|
||
noConnect = flags.contains(PROCESS_FLAGS.noConnect);
|
||
if(flags.contains(PROCESS_FLAGS.connectFloor)){
|
||
TRP_CORE.uniquePush(proc.connectFloorIdxes,idx);
|
||
}
|
||
}
|
||
|
||
|
||
//apply
|
||
var i = 0;
|
||
var maxI = targetTileIds.length-1 - (flags ? 1 : 0);
|
||
var needsShadow = false;
|
||
for(var z=0; z<4; z=(z+1)|0){
|
||
if(data[z*zLayerSize+idx])continue;
|
||
|
||
var tileId = targetTileIds[i++];
|
||
var skip = false;
|
||
if(tileId<0){
|
||
if(tileId===MapDecorator.SUPPLY_BACK_TILE_ID){
|
||
//supply back -> needs z=0 empty
|
||
skip = true;
|
||
needsShadow = true;
|
||
if(z==0){
|
||
this.supplyBackTile(idx);
|
||
}
|
||
}else if(tileId===MapDecorator.NO_ACC_TILE_ID){
|
||
//noAcc
|
||
TRP_CORE.uniquePush(proc.noAccIdxes,idx);
|
||
z -= 1;
|
||
continue;
|
||
}else if(tileId<=MapDecorator.REGION_ID_BEGIN && tileId>=MapDecorator.REGION_ID_END){
|
||
//regionId
|
||
data[zRegion+idx] = -(tileId-MapDecorator.REGION_ID_BEGIN);
|
||
z -= 1;
|
||
continue;
|
||
}else if(tileId<=MapDecorator.SHADOW_ID_BEGIN && tileId>=MapDecorator.SHADOW_ID_END){
|
||
//shadow
|
||
data[zShadow+idx] = -(tileId-MapDecorator.SHADOW_ID_BEGIN);
|
||
z -= 1;
|
||
continue;
|
||
}
|
||
}
|
||
if(!skip){
|
||
var isAutotile = Tilemap.isAutotile(tileId);
|
||
if(sustainShape){
|
||
if(isAutotile && !Tilemap.isWallSideTile(tileId)){
|
||
tileId = baseTileId(tileId)+shape;
|
||
}
|
||
}
|
||
data[z*zLayerSize+idx] = tileId;
|
||
if(!sustainShape && autoTileIdxes && isAutotile){
|
||
if(Tilemap.isTileA2(tileId)||Tilemap.isWaterTile(tileId)/*||Tilemap.isWallTopTile(tileId)*/){
|
||
TRP_CORE.uniquePush(autoTileIdxes,z*zLayerSize+idx);
|
||
}
|
||
}
|
||
|
||
if(noConnect && isAutotile){
|
||
proc.noConnectMap[idx+':'+tileId] = true;
|
||
}
|
||
}
|
||
if(i>maxI)break;
|
||
}
|
||
if(needsShadow){
|
||
this.supplyShadow(idx);
|
||
}
|
||
|
||
//try make empty with zAcc layer
|
||
var tileId = baseTileId(data[idx+zAcc]);
|
||
if(tileId && !allFloorLevelTileIds.contains(tileId)){
|
||
var isLayerFull = false;
|
||
if(data[idx+zAcc]){
|
||
if(data[idx+zObj1]){
|
||
if(data[idx+zObj2]){
|
||
isLayerFull = true;
|
||
}
|
||
if(!isLayerFull)data[idx+zObj2] = data[idx+zObj1];
|
||
}
|
||
if(!isLayerFull)data[idx+zObj1] = data[idx+zAcc];
|
||
}
|
||
if(!isLayerFull){
|
||
// if(!allFloorLevelTileIds.contains(data[idx+zAcc])){
|
||
data[idx+zAcc] = 0;
|
||
// }
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// ParamEditor
|
||
//=============================================================================
|
||
var EditorBase = TRP_CORE.EditorBase;
|
||
MapDecorator._paramEditors = {};
|
||
MapDecorator.paramEditor = null;
|
||
MapDecorator.MODE_PARAMS = null;
|
||
MapDecorator.MODE_PARAM_KEYS = {
|
||
paintFloor:[
|
||
'rateRange',
|
||
null,
|
||
'floorPaintRate',
|
||
'floorPaintChankMin',
|
||
'floorPaintChankMax',
|
||
'floorPaintPatternsWithTiles',
|
||
null,
|
||
'waterLocateMode',
|
||
'waterLocateRate',
|
||
'waterPaintRate',
|
||
'waterChankMin',
|
||
'waterChankMax',
|
||
'waterAccPaintRate',
|
||
'waterPaintChankMin',
|
||
'waterPaintChankMax',
|
||
'diasbleWaterConnect',
|
||
],
|
||
locateObject:[
|
||
'rateRange',
|
||
null,
|
||
'floorObjRate',
|
||
'floorBigObjRate',
|
||
null,
|
||
'waterObjRate',
|
||
'waterBigObjRate',
|
||
'waterObjOnEdge',
|
||
],
|
||
};
|
||
|
||
MapDecorator.editorBack = null;
|
||
MapDecorator.showParamEditor = function(mode){
|
||
if(this._paramEditors[mode] === undefined){
|
||
this._paramEditors[mode] = this._tryCreateParamEditor(mode);
|
||
}
|
||
|
||
var editor = this._paramEditors[mode];
|
||
if(!editor)return;
|
||
|
||
if(this.paramEditor === editor)return;
|
||
this.paramEditor = editor;
|
||
SceneManager._scene.addChild(editor);
|
||
|
||
editor.deactivate();
|
||
};
|
||
MapDecorator.hideParamEditor = function(){
|
||
if(!this.paramEditor)return;
|
||
|
||
this.tryDeactivateParamEditor();
|
||
if(this.paramEditor.parent){
|
||
this.paramEditor.parent.removeChild(this.paramEditor)
|
||
}
|
||
this.paramEditor = null;
|
||
};
|
||
|
||
MapDecorator.tryActivateParamEditor = function(){
|
||
if(!this.paramEditor){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
if(!this.editorBack){
|
||
this.editorBack = new PIXI.Graphics();
|
||
this.editorBack.beginFill(0x000000,0.25)
|
||
.drawRect(0,0,Graphics.width,Graphics.height);
|
||
}
|
||
SceneManager._scene.addChild(this.editorBack);
|
||
SceneManager._scene.addChild(this.paramEditor);
|
||
|
||
SoundManager.playCursor();
|
||
this.paramEditor.activate(INFO_SETTINGS[allInfo[MapDecorator.paramInfoIdx].floorBaseId]);
|
||
};
|
||
MapDecorator.tryDeactivateParamEditor = function(){
|
||
if(!this.paramEditor || !this.paramEditor.active)return;
|
||
|
||
SoundManager.playCursor();
|
||
this.paramEditor.deactivate();
|
||
if(this.editorBack && this.editorBack.parent){
|
||
this.editorBack.parent.removeChild(this.editorBack)
|
||
}
|
||
}
|
||
|
||
MapDecorator.paramInfoIdx = 0;
|
||
MapDecorator._refreshParamInfoIdx = function(){
|
||
var container = MapDecorator._paramEditorInfoSprite;
|
||
if(!container)return;
|
||
|
||
var idx = MapDecorator.paramInfoIdx;
|
||
var top = container.children[1];
|
||
var last = TRP_CORE.last(container.children);
|
||
var m = 4;
|
||
var x0 = top.x-m;
|
||
var y0 = top.y-m;
|
||
var w = -x0;
|
||
var h = top.y+top.height*top.scale.y+m;
|
||
|
||
var graphics = container.children[0];
|
||
graphics.clear();
|
||
graphics.beginFill(0x000000,0.5)
|
||
.drawRect(x0,y0,w,h);
|
||
|
||
var target = container.children[1+MapDecorator.paramInfoIdx];
|
||
graphics.beginFill(0xff0000,0.8)
|
||
.drawRect(target.x-m,target.y-m,target.width*target.scale.x+2*m,target.height*target.scale.y+2*m);
|
||
|
||
var editor = this.paramEditor;
|
||
if(editor){
|
||
editor.setData(INFO_SETTINGS[allInfo[MapDecorator.paramInfoIdx].floorBaseId]);
|
||
}
|
||
};
|
||
MapDecorator.onKeyDownParamEditor = function(event){
|
||
if(event.metaKey||event.ctrlKey){
|
||
if(event.key==='c'){
|
||
this.copyParamsToClipboard();
|
||
}
|
||
}else{
|
||
if(event.code==='Space'){
|
||
this.tryDeactivateParamEditor();
|
||
Input.clear();
|
||
}else if(event.code==='Tab'){
|
||
MapDecorator.paramInfoIdx += 1;
|
||
if(MapDecorator.paramInfoIdx>=allInfo.length)MapDecorator.paramInfoIdx = 0;
|
||
this._refreshParamInfoIdx();
|
||
SoundManager.playCursor();
|
||
}
|
||
}
|
||
};
|
||
|
||
MapDecorator.copyParamsToClipboard = function(){
|
||
var src = MapDecorator.SETTING_TEXT;
|
||
src = src.substring(
|
||
src.indexOf('// <<ベース床設定>'),
|
||
src.indexOf('// <<その他タイル設定>>')
|
||
).trim();
|
||
|
||
var setting = INFO_SETTINGS[allInfo[MapDecorator.paramInfoIdx].floorBaseId];
|
||
|
||
var text = '';
|
||
var lines = src.split('\n');
|
||
for(var line of lines){
|
||
if(text)text+='\n';
|
||
|
||
line = line.trim();
|
||
var match = line.match(/(.+)\:.+,$/);
|
||
if(match){
|
||
var key = match[1];
|
||
var obj = setting;
|
||
var keys = key.split('_');
|
||
var length = keys.length;
|
||
for(var i=0; i<length-1; i=(i+1)|0){
|
||
obj = obj[keys[i]];
|
||
}
|
||
var value = obj[TRP_CORE.last(keys)];
|
||
text += key+':'+JSON.stringify(value)+',';
|
||
}else{
|
||
text += line;
|
||
}
|
||
}
|
||
|
||
//add rate range
|
||
var param = MapDecorator.ALL_ANALYZED_PARAMS.rateRange;
|
||
if(param){
|
||
text = '//'+param.help.slice(1,param.help.length-1).join('\n//')+'\n'
|
||
+ param.key+':'+setting.rateRange+',\n\n'
|
||
+ text;
|
||
}
|
||
_Dev.copyToClipboard(text);
|
||
SoundManager.playSave();
|
||
};
|
||
MapDecorator.onPasteParamEditor = function(e){
|
||
e.preventDefault();
|
||
var clipboardData = e.clipboardData;
|
||
if(!clipboardData){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
var text = clipboardData.getData("text/plain");
|
||
var allParams = this._analyzeSettingParams(text);
|
||
Object.keys(allParams).forEach(key=>{
|
||
allParams[key] = eval(allParams[key].default);
|
||
})
|
||
|
||
var current = SETTING;
|
||
|
||
var _info = allInfo[MapDecorator.paramInfoIdx];
|
||
SETTING = INFO_SETTINGS[_info.floorBaseId];
|
||
this.overwriteSettings(allParams);
|
||
|
||
if(this.paramEditor){
|
||
this.paramEditor.setData(SETTING,true);
|
||
}
|
||
SETTING = current;
|
||
|
||
SoundManager.playLoad();
|
||
};
|
||
|
||
|
||
/* helper
|
||
===================================*/
|
||
MapDecorator._paramEditorInfoSprite = null;
|
||
MapDecorator._tryCreateParamEditor = function(mode){
|
||
if(!MapDecorator.MODE_PARAMS){
|
||
this.tryAnalyzeSettingParams();
|
||
}
|
||
if(!MapDecorator.MODE_PARAMS)return null;
|
||
|
||
var modeParams = MapDecorator.MODE_PARAMS[mode];
|
||
if(!modeParams){
|
||
return null;
|
||
}
|
||
|
||
var allData = [];
|
||
if(allInfo.length>1){
|
||
allData.push({
|
||
category:'《ベース床設定:Tabで切り替え》',
|
||
});
|
||
|
||
if(!MapDecorator._paramEditorInfoSprite){
|
||
var sprite = new PIXI.Container();
|
||
MapDecorator._paramEditorInfoSprite = sprite;
|
||
var back = new PIXI.Graphics();
|
||
sprite.addChild(back);
|
||
|
||
var mx = 50;
|
||
var x = -allInfo.length*mx;
|
||
var y = 4;
|
||
for(const info of allInfo){
|
||
var tileId = info.floorBaseId;
|
||
var tileSprite = this.layeredTilesSprite([tileId]);
|
||
tileSprite.x = x;
|
||
tileSprite.y = y;
|
||
tileSprite.scale.set(2/3,2/3);
|
||
sprite.addChild(tileSprite);
|
||
x += mx;
|
||
}
|
||
}
|
||
allData.push({
|
||
sprite:MapDecorator._paramEditorInfoSprite
|
||
});
|
||
}
|
||
|
||
//params
|
||
allData.push({
|
||
category:'《パラメータ》',
|
||
newLine:allInfo.length>1,
|
||
});
|
||
for(const param of modeParams){
|
||
allData.push({
|
||
key:param.key,
|
||
unit:param.unit,
|
||
integer:param.integer,
|
||
data:SETTING,
|
||
help:param.help,
|
||
newLine:param.newLine,
|
||
});
|
||
}
|
||
|
||
var editor = new EditorBase(allData);
|
||
var help = editor.baseHelpData();
|
||
help.unshift('【パラメータ設定】');
|
||
help.push('Space:設定終了');
|
||
editor.setHelp(help);
|
||
this._refreshParamInfoIdx();
|
||
|
||
return editor;
|
||
};
|
||
|
||
MapDecorator._onceAnalyzeSettingParams = false;
|
||
MapDecorator.SETTING_TEXT = null;
|
||
MapDecorator.ALL_ANALYZED_PARAMS = null;
|
||
MapDecorator.tryAnalyzeSettingParams = function(){
|
||
if(this.SETTING_PARAMS)return;
|
||
if(MapDecorator._onceAnalyzeSettingParams)return;
|
||
MapDecorator._onceAnalyzeSettingParams = true;
|
||
|
||
var filePath = parameters.pluginPath||'js/plugins/TRP_MapDecorator.js';
|
||
var file = _Dev.readFile(filePath);
|
||
if(!file)return;
|
||
|
||
var idx = file.indexOf('var SETTING =');
|
||
if(idx<0)return;
|
||
|
||
file = file.substring(idx,file.indexOf(/^}/));
|
||
file = file.substr(file.indexOf('\n')+1);
|
||
file = file.trim();
|
||
MapDecorator.SETTING_TEXT = file;
|
||
|
||
var allParams = this._analyzeSettingParams(file);
|
||
MapDecorator.ALL_ANALYZED_PARAMS = allParams;
|
||
|
||
/* setup modeParams
|
||
===================================*/
|
||
this.MODE_PARAMS = {};
|
||
var modes = Object.keys(MapDecorator.MODE_PARAM_KEYS);
|
||
for(const mode of modes){
|
||
this.MODE_PARAMS[mode] = [];
|
||
var newLine = false;
|
||
for(const key of MapDecorator.MODE_PARAM_KEYS[mode]){
|
||
if(!key){
|
||
//category top
|
||
newLine = true;
|
||
continue;
|
||
}
|
||
|
||
var param = allParams[key];
|
||
var help = param.help;
|
||
var defStr = param.default;
|
||
var unit = param.unit || analyzeParamUnit(param.default);
|
||
|
||
var defHelp = '(デフォ値:'+defStr+')';
|
||
if(!help.contains(defHelp)){
|
||
help.push(defHelp);
|
||
}
|
||
this.MODE_PARAMS[mode].push({
|
||
key,
|
||
help:param.help,
|
||
unit:param.unit||unit,
|
||
integer:defStr.indexOf('.')<0,
|
||
newLine,
|
||
});
|
||
newLine = false;
|
||
}
|
||
};
|
||
};
|
||
|
||
MapDecorator._analyzeSettingParams = function(file){
|
||
var lines = file.split('\n');
|
||
|
||
var allParams = {};
|
||
var help = null;
|
||
var unit = 0;
|
||
for(var line of lines){
|
||
line = line.trim();
|
||
|
||
if(!line
|
||
|| line.indexOf('// <<')===0
|
||
|| line.indexOf('//==')===0
|
||
){
|
||
//category header or empty
|
||
continue;
|
||
}else if(line.indexOf('//')===0){
|
||
line = line.replace('//','');
|
||
line = line.replace('true/false','1=ON/0=OFF');
|
||
|
||
var unitMatch = line.match(/\<unit\:([0-9\.]+)\>/);
|
||
if(unitMatch){
|
||
line = line.replace(unitMatch[0],'');
|
||
unit = Number(unitMatch[1]);
|
||
}
|
||
|
||
help = help||[];
|
||
help.push(line);
|
||
}else if(line.indexOf('}')===0){
|
||
//end SETTING define
|
||
break;
|
||
}else{
|
||
line = line.replace(/,$/,'');
|
||
var elems = line.split(':');
|
||
var key = elems[0];
|
||
if(help){
|
||
help.unshift('<'+key+'>');
|
||
}
|
||
allParams[key] = {
|
||
key,
|
||
default:elems[1],
|
||
help,
|
||
unit,
|
||
};
|
||
help = null;
|
||
unit = 0;
|
||
}
|
||
}
|
||
return allParams;
|
||
};
|
||
function analyzeParamUnit(defStr){
|
||
var unit;
|
||
if(defStr==='true' || defStr==='false'){
|
||
unit = 1;
|
||
}else if(!isNaN(defStr)){
|
||
var unitStr = '';
|
||
var validNumFound = false;
|
||
var unitAdjust = 10;
|
||
for(var idx=0; idx<defStr.length; idx=(idx+1)|0){
|
||
switch(defStr[idx]){
|
||
case '-':
|
||
continue;
|
||
case '.':
|
||
if(validNumFound)break;
|
||
case '0':
|
||
unitStr += defStr[idx];
|
||
continue;
|
||
case '1':
|
||
if(!validNumFound){
|
||
validNumFound = true;
|
||
unitAdjust = 10;
|
||
unitStr += defStr[idx];
|
||
if(unitStr.indexOf('.')>=0)break;
|
||
}else{
|
||
unitStr += '0';
|
||
}
|
||
continue;
|
||
default:
|
||
if(!validNumFound){
|
||
validNumFound = true;
|
||
unitAdjust = 1;
|
||
unitStr += '1';
|
||
if(unitStr.indexOf('.')>=0)break;
|
||
}else{
|
||
unitStr += '0';
|
||
}
|
||
|
||
continue;
|
||
}
|
||
if(unitStr[unitStr.length-1]==='1')break;
|
||
}
|
||
unit = Number(unitStr)/unitAdjust;
|
||
if(defStr.indexOf('.')<0){
|
||
unit = Math.max(unit,1);
|
||
}
|
||
}
|
||
return unit;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MapObject
|
||
//=============================================================================
|
||
MapDecorator.analyzeMapObjects = function(){
|
||
var objects = $dataTrpMapObjects;
|
||
if(!objects)return;
|
||
|
||
var setupTemplates = MapObject._setupEventTemplates;
|
||
var templates = this.mapObjectTemplate;
|
||
var templateConvertMap = setupTemplates ? {} : null;
|
||
|
||
|
||
/* convert setupEventTemplates
|
||
===================================*/
|
||
var setupTags = setupTemplates ? Object.keys(setupTemplates) : null;
|
||
var length = setupTags ? setupTags.length : 0;
|
||
var newRegisterTemplates = [];
|
||
var needsRefreshTags = [];
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
var tag = setupTags[i];
|
||
if(!isNaN(tag))tag = Number(tag);
|
||
|
||
var target = setupTemplates[tag];
|
||
if(!target)continue;
|
||
|
||
var bestFitValue = Number.MAX_SAFE_INTEGER;
|
||
var bestFitTemplate = null;
|
||
for(const template of templates){
|
||
if(!template)continue;
|
||
|
||
var fitValue = MapObject.templateFitValue(target,template);
|
||
if(fitValue<bestFitValue){
|
||
bestFitValue = fitValue;
|
||
bestFitTemplate = template;
|
||
}
|
||
}
|
||
|
||
if(!bestFitTemplate){
|
||
bestFitTemplate = JsonEx.makeDeepCopy(target);
|
||
bestFitTemplate.tag = templates.length + newRegisterTemplates.length;
|
||
newRegisterTemplates.push(bestFitTemplate);
|
||
}else if(bestFitValue>0){
|
||
needsRefreshTags.push(tag);
|
||
}
|
||
templateConvertMap[tag] = bestFitTemplate.tag;
|
||
}
|
||
|
||
if(setupTemplates && newRegisterTemplates && newRegisterTemplates.length){
|
||
templates.push(...newRegisterTemplates);
|
||
}
|
||
|
||
/* register located objects
|
||
===================================*/
|
||
var spriteset = SceneManager._scene._spriteset;
|
||
for(const obj of objects){
|
||
var x = obj.x/tileW-0.5;
|
||
var y = obj.y/tileH-1;
|
||
if(obj.tileId){
|
||
x -= (obj.tileW-1)/2;
|
||
y -= (obj.tileH-1);
|
||
}
|
||
x = Math.floor(x);
|
||
y = Math.floor(y);
|
||
|
||
if(templateConvertMap && templateConvertMap[obj.tag]){
|
||
var needsRefresh = needsRefreshTags.contains(obj.tag);
|
||
obj.tag = templateConvertMap[obj.tag];
|
||
if(needsRefresh){
|
||
obj.setupWithTemplate(templates[obj.tag]);
|
||
if(obj.sprite){
|
||
obj.releaseSprite();
|
||
obj.setupSprite(spriteset);
|
||
}
|
||
}
|
||
}
|
||
|
||
var idx = x+y*width;
|
||
var roomId = idxOfRoom(idx);
|
||
if(roomId<0){
|
||
continue;
|
||
}
|
||
|
||
var lastRoomObjects = proc.lastObjInfoArr[roomId] = proc.lastObjInfoArr[roomId]||[];
|
||
lastRoomObjects.push([idx,obj]);
|
||
TRP_CORE.uniquePush(proc.lockedObjRoomIds,roomId);
|
||
|
||
}
|
||
};
|
||
MapDecorator.analyzeTileObjects = function(){
|
||
/* make initial tileId map
|
||
===================================*/
|
||
var map = {};
|
||
for(const obj of allObjects){
|
||
var tileId;
|
||
if(MapObject && obj instanceof MapObject){
|
||
if(!obj.tileId)continue;
|
||
tileId = obj.tileId;
|
||
}else{
|
||
if(Array.isArray(obj[0])){
|
||
tileId = obj[0][0][0];
|
||
}else{
|
||
tileId = obj[0];
|
||
}
|
||
}
|
||
map[tileId] = map[tileId]||[];
|
||
map[tileId].push(obj);
|
||
}
|
||
|
||
var replaced = false;
|
||
for(var i=0; i<zLayerSize; i=(i+1)|0){
|
||
var roomId = proc.roomIdxMapForUserProc[i];
|
||
if(roomId<0)continue;
|
||
|
||
for(var z=0; z<4; z=(z+1)|0){
|
||
var tileId = data[i+z*zLayerSize];
|
||
var objects = map[tileId];
|
||
if(!objects)continue;
|
||
|
||
for(const obj of objects){
|
||
var tileIds = (MapObject && obj instanceof MapObject) ? obj.tileIds() : obj;
|
||
if(MapObject && MapObject._tryReplaceTilesInIdx(tileIds,i)){
|
||
//retry this tile
|
||
var lastRoomObjects = proc.lastObjInfoArr[roomId] = proc.lastObjInfoArr[roomId]||[];
|
||
lastRoomObjects.push([i,obj]);
|
||
TRP_CORE.uniquePush(proc.lockedObjRoomIds,roomId);
|
||
|
||
replaced = true;
|
||
z = -1;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if(replaced){
|
||
originalData = data;
|
||
this.restoreMap(true);
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
//for manual locate
|
||
MapDecorator._convertedMapObjMap = {};
|
||
MapDecorator._mapObjTemplateKeys = [];
|
||
MapDecorator.mapObjectTemplateWithTileObject = function(objArr,noAlert=false){
|
||
if(!objArr)return null;
|
||
|
||
var key = JSON.stringify(objArr);
|
||
if(!this._convertedMapObjMap[key]){
|
||
this._convertedMapObjMap[key] = this._mapObjectTemplateWithTileObject(objArr,noAlert);
|
||
this._mapObjTemplateKeys.push(key);
|
||
}
|
||
return this._convertedMapObjMap[key];
|
||
};
|
||
MapDecorator._mapObjectTemplateWithTileObject = function(objArr,noAlert=false){
|
||
var w = 1;
|
||
var h = 1;
|
||
var tileId;
|
||
var isBigObj = false;
|
||
if(Array.isArray(objArr[0])){
|
||
//bigObj
|
||
isBigObj = true;
|
||
tileId = objArr[0][0][0];
|
||
w = objArr.length;
|
||
h = objArr[0].length;
|
||
}else{
|
||
tileId = objArr[0];
|
||
}
|
||
if(!tileId){
|
||
if(!noAlert){
|
||
_Dev.showTempAlert('ドット配置できないオブジェクトです');
|
||
SoundManager.playBuzzer();
|
||
}
|
||
return null;
|
||
}
|
||
|
||
var obj = MapObject.object();
|
||
obj.setupCommonBefore();
|
||
obj.tileId = tileId;
|
||
obj.tileW = w;
|
||
obj.tileH = h;
|
||
|
||
if(isBigObj){
|
||
//check tileIds is in sequence
|
||
var tileIds = obj.tileIds(true);
|
||
if(!tileIds.equals(objArr)){
|
||
if(!noAlert){
|
||
_Dev.showTempAlert('ドット配置できないオブジェクトです');
|
||
SoundManager.playBuzzer();
|
||
}
|
||
MapObject.cache(obj);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
|
||
var tileId = obj.tileId;
|
||
var flags = null;
|
||
if(tileId<0){
|
||
var otherTilesetData = MapObject.otherTilesetDataWithTileId(tileId);
|
||
if(otherTilesetData){
|
||
var tileset = otherTilesetData[0];
|
||
tileId = otherTilesetData[1];
|
||
flags = tileset.flags;
|
||
}
|
||
}else{
|
||
flags = $gameMap.tileset().flags;
|
||
}
|
||
|
||
if(flags){
|
||
var bottomId = MapObject.tileIdInImage(tileId,0,h-1);
|
||
var bottomFlag = flags[bottomId];
|
||
var topId = tileId;
|
||
var topFlag = flags[topId];
|
||
//check bottom heigher
|
||
if(bottomFlag & 0x10){
|
||
obj.priority = 2;
|
||
}else if(topFlag & 0x10){
|
||
//top heigher
|
||
obj.priority = 1;
|
||
}else{
|
||
obj.priority = 0;
|
||
}
|
||
}else{
|
||
obj.priority = 0;
|
||
}
|
||
obj.setupCommonAfter();
|
||
|
||
this.registerMapObjectTemplateWithMapObject(obj);
|
||
|
||
return obj;
|
||
};
|
||
|
||
|
||
|
||
//save objData to mapEvent
|
||
MapDecorator.saveMapObjectData = function(noLink=false){
|
||
/* search mapObjectSave event
|
||
===================================*/
|
||
var event = null;
|
||
$dataMap.events.some(e=>{
|
||
if(e && this.infoCharacterTypeWithEvent(e)==='mapObjectSave'){
|
||
event = e;
|
||
return true;
|
||
}
|
||
return false;
|
||
});
|
||
|
||
/* make mapObjectSave event
|
||
===================================*/
|
||
if(!event){
|
||
event = {"id":0,"name":"EV011","note":"<trpMapObjSetup>","pages":[{"conditions":{"actorId":1,"actorValid":false,"itemId":1,"itemValid":false,"selfSwitchCh":"A","selfSwitchValid":false,"switch1Id":1,"switch1Valid":false,"switch2Id":1,"switch2Valid":false,"variableId":1,"variableValid":false,"variableValue":0},"directionFix":false,"image":{"tileId":0,"characterName":"DecorationInfo","direction":4,"pattern":0,"characterIndex":7},"list":[{"code":0,"indent":0,"parameters":[]}],"moveFrequency":3,"moveRoute":{"list":[{"code":0,"parameters":[]}],"repeat":true,"skippable":false,"wait":false},"moveSpeed":3,"moveType":0,"priorityType":1,"stepAnime":false,"through":false,"trigger":0,"walkAnime":false}],"x":0,"y":0};
|
||
event.id = $dataMap.events.length;
|
||
$dataMap.events.push(event);
|
||
|
||
//prepare pos event map
|
||
var posEventMap = [];
|
||
TRP_CORE.packValues(posEventMap,zLayerSize,0);
|
||
$dataMap.events.forEach(event=>{
|
||
if(!event)return;
|
||
posEventMap[event.x+event.y*width] = event;
|
||
});
|
||
|
||
//search empty pos
|
||
for(var i=0; i<zLayerSize; i=(i+1)|0){
|
||
if(posEventMap[i])continue;
|
||
|
||
event.x = i%width;
|
||
event.y = Math.floor(i/width);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* prepare comment command
|
||
===================================*/
|
||
var list = event.pages[0].list;
|
||
var command = list[0];
|
||
if(!command || command.code!==108){
|
||
//insert comment
|
||
command = {
|
||
code:108,
|
||
indent:0,
|
||
parameters:[''],
|
||
};
|
||
list.unshift(command);
|
||
}
|
||
|
||
|
||
/* make location data
|
||
===================================*/
|
||
var locations = [];
|
||
var template = {};
|
||
var objects = $dataTrpMapObjects;
|
||
for(var i=objects.length-1; i>=0; i=(i-1)|0){
|
||
var obj = objects[i];
|
||
if(MapDecorator.tryConvertMapObjectToMapData(obj)){
|
||
//obj -> tileData
|
||
this.requestRefreshTilemap();
|
||
continue;
|
||
}
|
||
|
||
var temp = null;
|
||
if(obj.tag && !isNaN(obj.tag)){
|
||
temp = template[obj.tag] = this.mapObjectTemplate[obj.tag];
|
||
}
|
||
|
||
var location = obj.locationData(temp);
|
||
if(!noLink && this.tryLinkMapObject(obj)){
|
||
location.push('LINK');
|
||
}
|
||
locations.push(location);
|
||
}
|
||
|
||
|
||
/* make save data
|
||
===================================*/
|
||
var saveData = {
|
||
template,
|
||
locations:locations,
|
||
};
|
||
|
||
command.parameters[0] = JSON.stringify(saveData);
|
||
};
|
||
MapDecorator.tryLinkMapObject = function(obj){
|
||
var tileIds = obj.tileIds();
|
||
if(!tileIds)return false;
|
||
var w = obj.tileW;
|
||
var h = obj.tileH;
|
||
|
||
|
||
// var mock = obj.mockTileData();
|
||
// if(!mock)return false;
|
||
// var tileIds,w,h;
|
||
var dx = 0; var dy = 0;
|
||
// if(Array.isArray(mock)){
|
||
// tileIds = mock;
|
||
// w = obj.tileW;
|
||
// h = obj.tileH;
|
||
// }else{
|
||
// //mock
|
||
// tileIds = mock.tileIds;
|
||
// w = mock.tileW;
|
||
// h = mock.tileH;
|
||
// dx = mock.dx;
|
||
// dy = mock.dy;
|
||
// }
|
||
|
||
var x = (obj.x/$gameMap.tileWidth())-w/2+dx;
|
||
var y = (obj.y/$gameMap.tileHeight())-h+dy;
|
||
x = Math.round(x);
|
||
y = Math.round(y);
|
||
|
||
return this._tryReplaceTilesWithLocation(tileIds,x,y,w,h);
|
||
};
|
||
|
||
MapDecorator._tryReplaceTilesWithLocation = function(tileIds,x,y,w,h){
|
||
var idx = x+y*width;
|
||
|
||
if(x<0||x+(w-1)>=$dataMap.width)return false;
|
||
if(y<0||y+(h-1)>=$dataMap.height)return false;
|
||
|
||
//check tileIds
|
||
for(var dx=0; dx<w; dx=(dx+1)|0){
|
||
for(var dy=0; dy<h; dy=(dy+1)|0){
|
||
var tileId = tileIds[dx][dy];
|
||
if(!tileId)continue;
|
||
|
||
var tIdx = idx+dx+dy*width;
|
||
var isEmpty = false;
|
||
for(var z=0; z<4; z=(z+1)|0){
|
||
if(!data[z*zLayerSize+tIdx]){
|
||
isEmpty = true;
|
||
break;
|
||
}
|
||
}
|
||
if(!isEmpty)return false;
|
||
}
|
||
}
|
||
|
||
//addTile
|
||
for(var dx=0; dx<w; dx=(dx+1)|0){
|
||
for(var dy=0; dy<h; dy=(dy+1)|0){
|
||
var tIdx = idx+dx+dy*width;
|
||
var tileId = tileIds[dx][dy];
|
||
if(tileId){
|
||
addObjTile(data,tIdx,tileId);
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
|
||
/* mapObjectCollision mode
|
||
===================================*/
|
||
MapDecorator.mapObjCollisionMode = 0;
|
||
MapDecorator.showMapObjectCollisions = function(){
|
||
if(!MapObject || !$dataTrpMapObjectCollisions){
|
||
SoundManager.playBuzzer();
|
||
_Dev.showTempAlert('衝突判定のあるスプライトオブジェトはありません');
|
||
return;
|
||
}
|
||
|
||
if(MapObject){
|
||
MapObject.refreshCollisions();
|
||
}
|
||
|
||
this.setMode('mapObjectCollision');
|
||
this._showMapObjectCollisionBlocks();
|
||
|
||
this.setObjectsOutline();
|
||
};
|
||
MapDecorator.endModeMapObjectCollision = function(){
|
||
this.removeObjectsOutline();
|
||
};
|
||
MapDecorator.setObjectsOutline = function(color=0x0000ff,size=1){
|
||
this.showingObjOutline = true;
|
||
|
||
for(const obj of $dataTrpMapObjects){
|
||
obj.setOutlineFilter(color,size);
|
||
}
|
||
};
|
||
MapDecorator.removeObjectsOutline = function(){
|
||
this.showingObjOutline = false;
|
||
for(const obj of $dataTrpMapObjects){
|
||
obj.removeOutlineFilter();
|
||
}
|
||
};
|
||
|
||
|
||
MapDecorator._showMapObjectCollisionBlocks = function(){
|
||
this.mapObjCollisionMode = 0;
|
||
|
||
var positions = [];
|
||
var color = 'rgba(255,0,0,0.5)';
|
||
var texts = null;
|
||
|
||
var width = $dataMap.width;
|
||
var zLayerSize = $dataMap.width*$dataMap.height;
|
||
var tileW = $gameMap.tileWidth();
|
||
var tileH = $gameMap.tileHeight();
|
||
|
||
|
||
var collisions = MapObject.collisionsMap();
|
||
var res = MapObject.CollisionResolution;
|
||
var rowIdx = width*res;
|
||
for(var i=zLayerSize-1; i>=0; i=(i-1)|0){
|
||
var baseIdx = (i%width)*res + (Math.floor(i/width))*res*rowIdx;
|
||
for(var xi=res-1; xi>=0; xi=(xi-1)|0){
|
||
for(var yi=res-1; yi>=0; yi=(yi-1)|0){
|
||
if(collisions[baseIdx+xi+yi*rowIdx]){
|
||
positions.push(i);
|
||
break;
|
||
}
|
||
}
|
||
if(positions.contains(i))break;
|
||
}
|
||
}
|
||
|
||
|
||
var sw = tileW/res;
|
||
var sh = tileH/res;
|
||
var tonnerTiles = (ctx,x0,y0)=>{
|
||
/* draw blocks
|
||
===================================*/
|
||
ctx.fillStyle = color;
|
||
ctx.beginPath();
|
||
|
||
for(var i=zLayerSize-1; i>=0; i=(i-1)|0){
|
||
var x = i%width;
|
||
var y = Math.floor(i/width);
|
||
var baseIdx = x*res + y*res*rowIdx;
|
||
for(var xi=res-1; xi>=0; xi=(xi-1)|0){
|
||
for(var yi=res-1; yi>=0; yi=(yi-1)|0){
|
||
if(collisions[baseIdx+xi+yi*rowIdx]){
|
||
var tx = ((x-x0)*res+xi)*sw;
|
||
var ty = ((y-y0)*res+yi)*sh;
|
||
ctx.moveTo(tx,ty);
|
||
ctx.lineTo(tx+sw,ty);
|
||
ctx.lineTo(tx+sw,ty+sh);
|
||
ctx.lineTo(tx,ty+sh);
|
||
ctx.lineTo(tx,ty);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
ctx.closePath();
|
||
ctx.fill();
|
||
ctx.lineWidth = 1;
|
||
ctx.strokeStyle = 'rgb(100,0,0)'
|
||
ctx.stroke();
|
||
ctx.restore();
|
||
|
||
/* draw outlines
|
||
===================================*/
|
||
ctx.beginPath();
|
||
ctx.strokeStyle = 'rgb(0,0,0)'
|
||
for(const i of positions){
|
||
var x = i%width;
|
||
var y = Math.floor(i/width);
|
||
var tx = (x-x0)*tileW;
|
||
var ty = (y-y0)*tileH;
|
||
ctx.moveTo(tx,ty);
|
||
ctx.lineTo(tx+tileW,ty);
|
||
ctx.lineTo(tx+tileW,ty+tileH);
|
||
ctx.lineTo(tx,ty+tileH);
|
||
ctx.lineTo(tx,ty);
|
||
}
|
||
ctx.lineWidth = 2;
|
||
ctx.closePath();
|
||
ctx.stroke();
|
||
};
|
||
var drawText = (bitmap,x,y,text,i)=>{};
|
||
|
||
this.tonnerTiles(positions,texts,color,tonnerTiles,drawText);
|
||
};
|
||
|
||
MapDecorator._showMapObjectCollisionDirs = function(){
|
||
this.mapObjCollisionMode = 1;
|
||
|
||
var positions = [];
|
||
var color = 'rgba(0,0,255,0.2)';
|
||
var texts = [];
|
||
for(var i=zLayerSize-1; i>=0; i=(i-1)|0){
|
||
var collision = $dataTrpMapObjectCollisions[i];
|
||
if(!collision)continue;
|
||
|
||
positions.push(i);
|
||
texts.push(collision);
|
||
}
|
||
|
||
var tonnerTiles = null;
|
||
var drawText = (bitmap,x,y,text,i)=>{
|
||
if(text===15){
|
||
bitmap.fontSize = 32;
|
||
bitmap.drawText('x',x,y,48,48,'center');
|
||
return;
|
||
}
|
||
bitmap.fontSize = 20;
|
||
if(text&1<<0){
|
||
bitmap.drawText('↓',x,y+24,48,24,'center');
|
||
bitmap.drawText('x',x,y+24,48,24,'center');
|
||
}
|
||
if(text&1<<1){
|
||
bitmap.drawText('←',x,y,24,48,'center');
|
||
bitmap.drawText('x',x,y,24,48,'center');
|
||
}
|
||
if(text&1<<2){
|
||
bitmap.drawText('→',x+24,y,24,48,'center');
|
||
bitmap.drawText('x',x+24,y,24,48,'center');
|
||
}
|
||
if(text&1<<3){
|
||
bitmap.drawText('↑',x,y,48,24,'center');
|
||
bitmap.drawText('x',x,y,48,24,'center');
|
||
}
|
||
};
|
||
this.tonnerTiles(positions,texts,color,tonnerTiles,drawText);
|
||
};
|
||
|
||
MapDecorator.MODE_GUIDE.mapObjectCollision = [
|
||
'【スプライトオブジェの衝突判定確認モード】',
|
||
'左クリック:表示切り替え',
|
||
'右クリック:確認モード終了',
|
||
];
|
||
MapDecorator.onMouseDownRightMapObjectCollision = MapDecorator.restoreModeByMouse;
|
||
MapDecorator.updateInputMapObjectCollision = MapDecorator.updateInputToCheckRestoreMode;
|
||
|
||
MapDecorator.onMouseDownLeftMapObjectCollision = function(){
|
||
SoundManager.playCursor();
|
||
|
||
if(this.mapObjCollisionMode===0){
|
||
this._showMapObjectCollisionDirs();
|
||
}else{
|
||
this._showMapObjectCollisionBlocks();
|
||
}
|
||
};
|
||
|
||
|
||
/* analyzeOtherTilesetObjects
|
||
===================================*/
|
||
MapDecorator.otherTilesetIdsReplaceMap = {};
|
||
MapDecorator.tryAnalyzeOtherTilesetObjects = async function(){
|
||
var objects = [];
|
||
|
||
for(const roomInfoArr of proc.lastObjInfoArr){
|
||
for(const objInfo of roomInfoArr){
|
||
var obj = objInfo[1];
|
||
if(Array.isArray(obj))continue;
|
||
if(obj.tileId>=0)continue;
|
||
objects.push(obj);
|
||
}
|
||
}
|
||
|
||
SoundManager.playCursor();
|
||
|
||
|
||
var executed = false;
|
||
var objLeft = false;
|
||
for(const obj of objects){
|
||
if(MapDecorator.otherTilesetIdsReplaceMap[obj.tileId]){
|
||
obj.tileId = MapDecorator.otherTilesetIdsReplaceMap[obj.tileId];
|
||
obj.loadBitmap();
|
||
continue;
|
||
}
|
||
executed = true;
|
||
|
||
var srcTileIds = obj.tileIds();
|
||
var bitmap = new Bitmap(tileW*obj.tileW,tileH*obj.tileH);
|
||
var src = obj.bitmap;
|
||
TRP_CORE.bltImage(bitmap,src,obj.fx,obj.fy,obj.fw,obj.fh,0,0);
|
||
|
||
await new Promise(resolve=>this.startTilesetEdit(bitmap,(tileIds)=>{
|
||
if(tileIds){
|
||
obj.tileId = tileIds[0];
|
||
obj.loadBitmap();
|
||
|
||
for(const row of srcTileIds){
|
||
for(const tileId of row){
|
||
var dstTileId = tileIds.shift();
|
||
if(tileId && dstTileId){
|
||
MapDecorator.otherTilesetIdsReplaceMap[tileId] = dstTileId;
|
||
}
|
||
}
|
||
}
|
||
}else{
|
||
objLeft = true;
|
||
}
|
||
resolve();
|
||
}));
|
||
}
|
||
|
||
if(!objLeft){
|
||
_Dev.showTempText('decorator:otherTile',null);
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// MODE: PlayerMove
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.playerMove = [
|
||
'Esc:移動テストモード終了',
|
||
];
|
||
MapDecorator.setModePlayerMove = function(){
|
||
this.modeData = {
|
||
editorUpdate:SceneManager._scene.update,
|
||
menuEnabled:SceneManager._scene.isMenuEnabled,
|
||
};
|
||
|
||
SceneManager._scene.update = this._sceneUpDate;
|
||
$gamePlayer._transparent = false;
|
||
$gamePlayer.moveByInput = this._playerMoveByInput;
|
||
SceneManager._scene.isMenuEnabled = ()=>false;
|
||
|
||
var onKeyDown = this.modeData.onKeyDown = event=>{
|
||
if(event.key==='Escape'){
|
||
this.restoreMode(true);
|
||
SoundManager.playCancel();
|
||
}
|
||
}
|
||
document.addEventListener('keydown',onKeyDown);
|
||
|
||
if(MapObject){
|
||
MapObject.refreshCollisions();
|
||
}
|
||
};
|
||
MapDecorator.endModePlayerMove = function(){
|
||
SceneManager._scene.update = this.modeData.editorUpdate;
|
||
SceneManager._scene.isMenuEnabled = this.modeData.isMenuEnabled;
|
||
document.removeEventListener('keydown',this.modeData.onKeyDown);
|
||
|
||
$gamePlayer._transparent = true;
|
||
if($gamePlayer._followers){
|
||
$gamePlayer._followers.update();
|
||
}
|
||
SceneManager._scene._spriteset.update();
|
||
|
||
$gamePlayer.moveByInput = ()=>{};
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Util Funcs
|
||
//=============================================================================
|
||
var anyTileId = MapDecorator.anyTileId = function(idx,env=ENV_VARS){
|
||
return env.data[idx]||env.data[idx+env.zAcc]||env.data[idx+env.zObj1]||env.data[idx+env.zObj2];
|
||
};
|
||
|
||
var layeredTileIds = MapDecorator.layeredTileIds = function(idx,env=ENV_VARS){
|
||
var tileIds = null;
|
||
for(var z=0; z<4; z=(z+1)|0){
|
||
if(!env.data[idx+z*env.zLayerSize])continue;
|
||
|
||
tileIds = tileIds||[];
|
||
tileIds.push(env.data[idx+z*env.zLayerSize]);
|
||
}
|
||
return tileIds
|
||
}
|
||
|
||
var baseTileId = MapDecorator.baseTileId = function baseTileId(tileId){
|
||
if(Tilemap.isAutotile(tileId)){
|
||
return tileId - Tilemap.getAutotileShape(tileId);
|
||
}else{
|
||
return tileId;
|
||
}
|
||
}
|
||
|
||
function isEmptyTile(idx){
|
||
return isEmptyTileId(anyTileId(idx));
|
||
}
|
||
function isEmptyTileId(tileId){
|
||
if(!tileId)return true;
|
||
if(ceilingBaseIds.contains(baseTileId(tileId)))return true;
|
||
return false;
|
||
}
|
||
|
||
function idxOfRoom(idx){
|
||
for(var i=proc.allRoomIdxes.length-1; i>=0; i=(i-1)|0){
|
||
if(proc.allRoomIdxes[i].contains(idx)){
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
};
|
||
|
||
function idxForNeighborDir(idx,ni,zIdx=0){
|
||
if(ni<=3){
|
||
idx += width;
|
||
if(idx>zLayerSize+zIdx)return -1;
|
||
}else if(ni>=7){
|
||
idx -= width;
|
||
if(idx<zIdx)return -1;
|
||
}
|
||
if(ni%3===1){
|
||
if(idx%width===0)return -1;
|
||
idx -= 1;
|
||
}else if(ni%3===0){
|
||
if(idx%width===width-1)return -1;
|
||
idx += 1;
|
||
}
|
||
return idx;
|
||
}
|
||
|
||
|
||
/* analyzeNeibors
|
||
===================================*/
|
||
// analyzer=((nx,ny,ox,oy)=>{})
|
||
var analyzeNeighbors = MapDecorator.analyzeNeighbors = function(cx,cy,analyzer,checkTileExists=false,env=ENV_VARS){
|
||
var data = env.data;
|
||
var width = env.width;
|
||
var height = env.height;
|
||
var zLayerSize = env.zLayerSize;
|
||
|
||
cx = Math.floor(cx);
|
||
cy = Math.floor(cy);
|
||
|
||
if(!analyzer(cx,cy)){
|
||
return null;
|
||
}
|
||
|
||
var positions = [cx+cy*width];
|
||
|
||
var foundIdxes = [];
|
||
var currentIdxes = [];
|
||
var checkedIdxes = [];
|
||
|
||
var dirs = [width,-1,1,-width];
|
||
var dirLen = dirs.length;
|
||
|
||
var idx = cy*width+cx;
|
||
foundIdxes.push(idx);
|
||
checkedIdxes.push(idx);
|
||
|
||
while(foundIdxes.length>0){
|
||
var tempIdxes = currentIdxes;
|
||
currentIdxes = foundIdxes;
|
||
foundIdxes = tempIdxes;
|
||
foundIdxes.length = 0;
|
||
|
||
var length = currentIdxes.length;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
idx = currentIdxes[i];
|
||
var tx = idx%width;
|
||
var ty = Math.floor(idx/width);
|
||
for(var d=0;d<dirLen;d=(d+1)|0){
|
||
var neighbor = idx+dirs[d];
|
||
if(checkedIdxes.contains(neighbor)){
|
||
continue;
|
||
}
|
||
checkedIdxes.push(neighbor);
|
||
|
||
if(checkTileExists){
|
||
if(!data[neighbor]
|
||
&& !data[neighbor+1*zLayerSize]
|
||
&& !data[neighbor+2*zLayerSize]
|
||
&& !data[neighbor+3*zLayerSize]
|
||
){
|
||
continue;
|
||
}
|
||
}
|
||
|
||
//check neighbor inside map size
|
||
if(d===1 && tx===0)continue;
|
||
if(d===2 && tx===width-1)continue;
|
||
if(neighbor<0 || neighbor>=zLayerSize)continue;
|
||
|
||
//check regionId same
|
||
if(!analyzer(neighbor%width,Math.floor(neighbor/width),tx,ty,positions,checkedIdxes)){
|
||
continue;
|
||
}
|
||
|
||
foundIdxes.push(neighbor);
|
||
positions.push(neighbor);
|
||
}
|
||
}
|
||
}
|
||
|
||
return positions;
|
||
};
|
||
|
||
|
||
/* show info on touch
|
||
===================================*/
|
||
var infoTextSpriteCache = [];
|
||
function showInfoText(text,x=TouchInput.x,y=TouchInput.y){
|
||
var sprite = infoTextSpriteCache.pop();
|
||
var bitmap;
|
||
if(!sprite){
|
||
bitmap = new Bitmap(200,26);
|
||
sprite = new TRP_CORE.FadableSprite(bitmap);
|
||
sprite.anchor.set(0.5,0.5);
|
||
|
||
bitmap.fontSize = bitmap.height-4;
|
||
bitmap.outlineWidth = 4;
|
||
bitmap.outlineColor = 'black';
|
||
}else{
|
||
bitmap = sprite.bitmap;
|
||
bitmap.clear();
|
||
}
|
||
|
||
SceneManager._scene.addChild(sprite);
|
||
sprite.x = x;
|
||
sprite.y = y;
|
||
bitmap.drawText(text,0,0,bitmap.width,bitmap.height,'center');
|
||
|
||
MapDecorator.updateList.push(sprite);
|
||
sprite.startFadeOut(30,10,()=>{
|
||
if(sprite.parent){
|
||
sprite.parent.removeChild(sprite);
|
||
}
|
||
infoTextSpriteCache.push(sprite);
|
||
TRP_CORE.remove(MapDecorator.updateList,sprite)
|
||
});
|
||
};
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Restore Map
|
||
//=============================================================================
|
||
MapDecorator.restoreMap = function(noClear=false){
|
||
data = originalData.concat();
|
||
$dataMap.data = data;
|
||
|
||
|
||
/* restore floor acc
|
||
===================================*/
|
||
for(const waterInfo of proc.lastWaterInfoArr){
|
||
if(!waterInfo)continue;
|
||
var infoLen = waterInfo.length;
|
||
for(var i=0; i<infoLen; i=(i+3)|0){
|
||
var idx = waterInfo[i];
|
||
data[idx] = waterInfo[i+1];
|
||
data[idx+zAcc] = waterInfo[i+2];
|
||
proc.waterIdxes.push(idx);
|
||
}
|
||
}
|
||
for(const paintInfo of proc.lastFloorPaintInfoArr){
|
||
if(!paintInfo)continue;
|
||
var infoLen = paintInfo.length;
|
||
for(var i=0; i<infoLen; i=(i+3)|0){
|
||
var idx = paintInfo[i];
|
||
data[idx] = paintInfo[i+1];
|
||
data[idx+zAcc] = paintInfo[i+2];
|
||
}
|
||
}
|
||
for(const idxes of proc.autoConnectRequestIdxes){
|
||
if(!idxes)continue;
|
||
for(const idx of idxes){
|
||
data[idx] = connectAutoTileWithIdx(idx);
|
||
}
|
||
}
|
||
|
||
|
||
/* locate obj
|
||
===================================*/
|
||
if(!noClear && proc.locateObj){
|
||
this.clearNonLockedObjects();
|
||
}
|
||
|
||
// data = info.lockedData.concat();
|
||
for(const objInfo of proc.lastObjInfoArr){
|
||
if(!objInfo)continue;
|
||
addObjTilesWithObjInfoArr(objInfo);
|
||
}
|
||
if(MapObject){
|
||
MapObject.refreshCollisions();
|
||
}
|
||
|
||
|
||
SceneManager._scene._spriteset._tilemap._mapData = $dataMap.data;
|
||
this.requestRefreshTilemap();
|
||
}
|
||
|
||
MapDecorator.clearNonLockedObjects = function(){
|
||
//clear non locked info
|
||
var length = proc.allRoomIdxes.length;
|
||
var mapObjRemoved = false;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
if(!proc.lockedObjRoomIds.contains(i)){
|
||
mapObjRemoved = this.clearLastObjects(i) || mapObjRemoved;
|
||
}
|
||
}
|
||
if(mapObjRemoved && MapObject){
|
||
MapObject.refreshCollisions();
|
||
}
|
||
};
|
||
|
||
MapDecorator.objInfoOfObj = function(obj){
|
||
for(const roomObjInfo of proc.lastObjInfoArr){
|
||
if(!roomObjInfo)continue;
|
||
for(const objInfo of roomObjInfo){
|
||
if(obj===objInfo[1]){
|
||
return objInfo;
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
|
||
MapDecorator.clearLastObjects = function(roomId){
|
||
var mapObjRemoved = false;
|
||
if(!proc.lastObjInfoArr[roomId]){
|
||
return mapObjRemoved;
|
||
}
|
||
|
||
var roomObjInfo = proc.lastObjInfoArr[roomId];
|
||
if(roomObjInfo && MapObject){
|
||
for(const objInfo of roomObjInfo){
|
||
if(objInfo[1] instanceof MapObject){
|
||
var mapObj = objInfo[1];
|
||
MapObject.remove(mapObj,true);
|
||
if(this.modeData && mapObj===this.modeData.lastLocateMapObj){
|
||
this.modeData.lastLocateMapObj = null;
|
||
}
|
||
mapObjRemoved = true;
|
||
}
|
||
}
|
||
}
|
||
proc.lastObjInfoArr[roomId] = [];
|
||
|
||
return mapObjRemoved
|
||
}
|
||
|
||
MapDecorator.sprite = function(bitmap){
|
||
var sprite = MapDecorator._cachedSprites.pop();
|
||
sprite = sprite || new Sprite();
|
||
sprite.scale.set(1,1);
|
||
sprite.anchor.set(0,0);
|
||
sprite.x = sprite.y = 0;
|
||
sprite.opacity = 255;
|
||
sprite._frame.x = sprite._frame.y = 0;
|
||
sprite.bitmap = bitmap;
|
||
return sprite;
|
||
};
|
||
MapDecorator.bitmap = function(w,h){
|
||
for(const bitmap of MapDecorator._cachedBitmaps){
|
||
if(bitmap.width === w && bitmap.height===h){
|
||
TRP_CORE.remove(MapDecorator._cachedBitmaps,bitmap);
|
||
bitmap.clear();
|
||
return bitmap;
|
||
}
|
||
}
|
||
return new Bitmap(w,h);
|
||
};
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Auto Tile Connection
|
||
//=============================================================================
|
||
// var CONNECT_TYPE = MapDecorator.CONNECT_TYPE = {
|
||
// default:0,
|
||
// };
|
||
|
||
function connectAutoTileWithIdx(idx,connectEmpty=0){
|
||
var tid = data[idx];
|
||
|
||
if(proc.noConnectMap[(idx%zLayerSize)+':'+tid]){
|
||
return tid;
|
||
}
|
||
|
||
var baseId = baseTileId(tid);
|
||
if(!baseId || !Tilemap.isAutotile(baseId) || Tilemap.isWallSideTile(baseId)){
|
||
return baseId;
|
||
}
|
||
if(baseId === info.waterBaseId){
|
||
connectEmpty = 2;
|
||
}
|
||
if(connectEmpty===2){
|
||
if(SETTING.diasbleWaterConnect){
|
||
connectEmpty = 0;
|
||
}
|
||
}
|
||
|
||
var bottomIdx = idx%zLayerSize;
|
||
var layerIdx = idx-bottomIdx;
|
||
// var roomId = idxOfRoom(bottomIdx);
|
||
var roomId = proc.roomIdxMapForUserProc[bottomIdx];
|
||
var z = proc.floorLevelZMap[bottomIdx];
|
||
|
||
var nf = TRP_CORE.packValues([],0,10);
|
||
var noTileIds = connectEmpty ? TRP_CORE.packValues([],0,10) : null;
|
||
for(var ni=1; ni<=9; ni=(ni+1)|0){
|
||
if(ni===5){
|
||
nf[ni] = 1;
|
||
continue;
|
||
}
|
||
|
||
var neighbor = idxForNeighborDir(idx,ni,layerIdx);
|
||
if(neighbor<0){
|
||
//outsideMap -> connect
|
||
nf[ni] = 1;
|
||
continue;
|
||
}
|
||
if(proc.connectFloorIdxes.contains(neighbor%zLayerSize)){
|
||
//connectFloor flags;
|
||
nf[ni] = 1;
|
||
continue;
|
||
}
|
||
|
||
var neighborBottomIdx = neighbor%zLayerSize
|
||
var neiborBottomId = data[neighborBottomIdx];
|
||
var tileId = data[neighbor];
|
||
if(connectEmpty){
|
||
//connect to ceiling or walls
|
||
if(!neiborBottomId || proc.ceilingIdxes.contains(neighborBottomIdx) || proc.wallIdxes.contains(neighborBottomIdx)
|
||
|| (invalidIdxes&&invalidIdxes.contains(neighborBottomIdx))
|
||
){
|
||
if(!proc.floorSuppliedIdxes.contains(neighborBottomIdx)){
|
||
noTileIds[ni] = 1;
|
||
nf[ni] = 1;
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
|
||
//check same tile
|
||
if(!tileId)continue;
|
||
if(baseId !== baseTileId(tileId))continue;
|
||
|
||
//check same z
|
||
if(proc.floorLevelZMap[neighborBottomIdx]!==z){
|
||
if(/*proc.ceilingIdxes.contains(neighborBottomIdx) ||*/ proc.wallIdxes.contains(neighborBottomIdx)){
|
||
//neighbor is wall or ceiling -> maybe replace any tile -> OK
|
||
TRP_CORE.uniquePush(proc.autoConnectRequestIdxes[roomId],neighbor);
|
||
}else if(/*proc.ceilingIdxes.contains(bottomIdx) ||*/ proc.wallIdxes.contains(bottomIdx)){
|
||
//self is wall or ceiling -> maybe replace any tile -> OK
|
||
}else{
|
||
continue;
|
||
}
|
||
}
|
||
|
||
//check same room
|
||
// if(idxOfRoom(neighborBottomIdx)!==roomId){
|
||
// continue;
|
||
// }
|
||
|
||
//connect ok
|
||
nf[ni] = 1;
|
||
}
|
||
|
||
if(connectEmpty===2){
|
||
//water tile
|
||
if(nf[2]&&!noTileIds[2]){
|
||
if(noTileIds[6] && !noTileIds[3]){
|
||
nf[3] = 0;
|
||
if(noTileIds[8]){
|
||
nf[6] = 0;
|
||
}
|
||
}
|
||
if(noTileIds[4] && !noTileIds[1]){
|
||
nf[1] = 0;
|
||
if(noTileIds[8]){
|
||
nf[4] = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(noTileIds[8]){
|
||
nf[7] = 0;
|
||
nf[8] = 0;
|
||
nf[9] = 0;
|
||
}else if(nf[8]){
|
||
if(noTileIds[9] && nf[6]&&!noTileIds[6]){
|
||
nf[9] = 0;
|
||
}
|
||
if(noTileIds[7] && nf[4]&&!noTileIds[4]){
|
||
nf[7] = 0;
|
||
}
|
||
}else if(noTileIds[9]){
|
||
nf[9] = 0;
|
||
}else if(noTileIds[7]){
|
||
nf[7] = 0;
|
||
}
|
||
}
|
||
|
||
return connectAutoTile(baseId,nf);
|
||
};
|
||
|
||
function getShape(nf){
|
||
var neighborConnectNum = nf[2]+nf[4]+nf[6]+nf[8];
|
||
|
||
var s;
|
||
if(neighborConnectNum===4){
|
||
s = 0;
|
||
if(!nf[7])s+=1;
|
||
if(!nf[9])s+=2;
|
||
if(!nf[3])s+=4;
|
||
if(!nf[1])s+=8;
|
||
}else if(neighborConnectNum===3){
|
||
s = 16;
|
||
//var link3dirs = [[4,9,3],[8,3,1],[6,1,7],[2,7,9]];
|
||
if(!nf[4]){
|
||
if(nf[9]&&nf[3])s+=0;
|
||
else if(!nf[9]&&nf[3])s+=1;
|
||
else if(!nf[3]&&nf[9])s+=2;
|
||
else s+=3;
|
||
}else if(!nf[8]){
|
||
if(nf[3]&&nf[1])s+=4;
|
||
else if(!nf[3]&&nf[1])s+=5;
|
||
else if(!nf[1]&&nf[3])s+=6;
|
||
else s+=7;
|
||
}else if(!nf[6]){
|
||
if(nf[1]&&nf[7])s+=8;
|
||
else if(!nf[1]&&nf[7])s+=9;
|
||
else if(!nf[7]&&nf[1])s+=10;
|
||
else s+=11;
|
||
}else if(!nf[2]){
|
||
if(nf[7]&&nf[9])s+=12;
|
||
else if(!nf[7]&&nf[9])s+=13;
|
||
else if(!nf[9]&&nf[7])s+=14;
|
||
else s+=15;
|
||
}
|
||
}else if(neighborConnectNum===2){
|
||
s = 32;
|
||
if(nf[2]&&nf[8])s+=0;
|
||
else if(nf[4]&&nf[6])s+=1;
|
||
else if(nf[2]&&nf[6]){
|
||
if(nf[3])s+=2;
|
||
else s+=3;
|
||
}else if(nf[2]&&nf[4]){
|
||
if(nf[1])s+=4;
|
||
else s+=5;
|
||
}else if(nf[4]&&nf[8]){
|
||
if(nf[7])s+=6;
|
||
|
||
|
||
else s+=7;
|
||
}else if(nf[8]&&nf[6]){
|
||
if(nf[9])s+=8;
|
||
else s+=9;
|
||
}
|
||
}else if(neighborConnectNum===1){
|
||
s = 42;
|
||
if(nf[2])s+=0;
|
||
else if(nf[6])s+=1;
|
||
else if(nf[8])s+=2;
|
||
else if(nf[4])s+=3;
|
||
}else{
|
||
s = 46
|
||
}
|
||
return s;
|
||
}
|
||
function connectAutoTile(baseId,nf,s=getShape(nf)){
|
||
var tileId = baseId + s;
|
||
if(!tileId){
|
||
connectAutoTile(baseId,nf)
|
||
}
|
||
|
||
return tileId;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// ColorPicker
|
||
//=============================================================================
|
||
MapDecorator._colorPicker = null;
|
||
MapDecorator._pickingColor = null;
|
||
MapDecorator.startPickColor = function(handler){
|
||
if(!this._colorPicker){
|
||
var size = 144;
|
||
this._colorPicker = new ColorPicker(size);
|
||
}
|
||
var picker = this._colorPicker;
|
||
picker.x = 10;
|
||
picker.y = 30;
|
||
picker.visible = true;
|
||
|
||
this._pickingColor = {
|
||
handler,
|
||
color:null,
|
||
rgb:[null,null,null],
|
||
};
|
||
|
||
this.refreshColorPickGuideText();
|
||
};
|
||
MapDecorator.refreshColorPickGuideText = function(){
|
||
var rgb = this._pickingColor.rgb;
|
||
var color = this._pickingColor.color||'#ffffff';
|
||
color = color.substring(1);
|
||
var colors = [color.substring(0,2),color.substring(2,4),color.substring(4)];
|
||
_Dev.showText('objColorPick',[
|
||
'【色味の変更】',
|
||
'0~9:ランダムな色味',
|
||
'Shift+0~9:同種オブジェすべて変更',
|
||
'R/G/B:各色固定',
|
||
'R:%1%4,G:%2%5,B:%3%6'.format(
|
||
parseInt(colors[0],16),parseInt(colors[1],16),parseInt(colors[2],16),
|
||
rgb[0]?'固':'',
|
||
rgb[1]?'固':'',
|
||
rgb[2]?'固':'',
|
||
)
|
||
],'rgb(255,150,150)');
|
||
SceneManager._scene.addChild(this._colorPicker);
|
||
}
|
||
MapDecorator.updateColorPicker = function(){
|
||
var picking = this._pickingColor;
|
||
this._colorPicker.update();
|
||
var color = this._colorPicker.color();
|
||
if(color!==picking.color){
|
||
picking.color = color;
|
||
if(picking.handler){
|
||
picking.handler(color);
|
||
}
|
||
this.refreshColorPickGuideText();
|
||
}
|
||
|
||
if(Input.isTriggered('ok')
|
||
|| Input.isTriggered('cancel')
|
||
|| TouchInput.isCancelled()
|
||
|| (TouchInput.isTriggered()&&!this._colorPicker._touching)
|
||
){
|
||
_Dev.showText('objColorPick',null);
|
||
this._pickingColor = null;
|
||
this._colorPicker.visible = false;
|
||
SoundManager.playOk();
|
||
}
|
||
};
|
||
MapDecorator.onKeyDownPickingColor = function(event){
|
||
if(event.code.indexOf('Digit')===0){
|
||
var keyNum = Number(event.code.replace('Digit',''));
|
||
var rate = keyNum*0.1;
|
||
if(!rate){
|
||
rate = 0.05;
|
||
}
|
||
|
||
if(event.shiftKey){
|
||
this.setRandomColorsToAllEditingKindMapObjects(rate);
|
||
}else{
|
||
this.setRandomColor(rate);
|
||
}
|
||
SoundManager.playCursor();
|
||
}else if(event.key==='r'){
|
||
this.switchRGBLock(0);
|
||
}else if(event.key==='g'){
|
||
this.switchRGBLock(1);
|
||
}else if(event.key==='b'){
|
||
this.switchRGBLock(2);
|
||
}
|
||
};
|
||
|
||
MapDecorator.switchRGBLock = function(idx){
|
||
if(!this._pickingColor)return;
|
||
var rgb = this._pickingColor.rgb;
|
||
if(!rgb)return;
|
||
|
||
if(rgb[idx]){
|
||
rgb[idx]=null;
|
||
}else{
|
||
var color = this._pickingColor.color;
|
||
if(!color){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
var value = color.substring(1+idx*2,1+idx*2+2);
|
||
rgb[idx] = value;
|
||
}
|
||
SoundManager.playCursor();
|
||
MapDecorator.refreshColorPickGuideText();
|
||
};
|
||
MapDecorator.setRandomColor = function(rate){
|
||
var color = this.randomColorWithRate(rate);
|
||
this._colorPicker.setColor(color);
|
||
|
||
if(this._pickingColor.handler){
|
||
this._pickingColor.handler(color);
|
||
}
|
||
};
|
||
MapDecorator.setRandomColorsToAllEditingKindMapObjects = function(rate){
|
||
var locObj = this.modeData.lastLocateMapObj;
|
||
if(Array.isArray(locObj)){
|
||
locObj = this._convertedMapObjMap[JSON.stringify(locObj)];
|
||
}
|
||
if(!locObj){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
var tag = locObj.tag;
|
||
for(const obj of $dataTrpMapObjects){
|
||
if(!obj || obj.tag!==tag)continue;
|
||
|
||
var color = this.randomColorWithRate(rate);
|
||
color = Number(color.replace('#','0x'));
|
||
obj.tint = color;
|
||
if(obj.sprite){
|
||
obj.sprite.tint = color;
|
||
}
|
||
}
|
||
};
|
||
MapDecorator.randomColorWithRate = function(rate){
|
||
var color = '#';
|
||
for(var i=0; i<3; i=(i+1)|0){
|
||
if(this._pickingColor.rgb[i]){
|
||
//locked color
|
||
color += this._pickingColor.rgb[i];
|
||
}else{
|
||
var r10 = 255-Math.floor(Math.randomInt(256)*rate);
|
||
var r16 = r10.toString(16);
|
||
if(r16.length===0)r16 = '0'+r16;
|
||
color += r16;
|
||
}
|
||
}
|
||
return color;
|
||
};
|
||
|
||
|
||
/* ColorPicker
|
||
===================================*/
|
||
function ColorPicker(){
|
||
this.initialize.apply(this, arguments);
|
||
};
|
||
ColorPicker.colorWithHsv = function(h,s,v){
|
||
var max = v;
|
||
var min = max-((s/255)*max);
|
||
var r,g,b;
|
||
if(h<=60){
|
||
r = max;
|
||
g = (h/60)*(max-min)+min;
|
||
b = min;
|
||
}else if(h<=120){
|
||
r = ((120-h)/60)*(max-min)+min;
|
||
g = max;
|
||
b = min;
|
||
}else if(h<=180){
|
||
r = min;
|
||
g = max;
|
||
b = ((h-120)/60)*(max-min)+min;
|
||
}else if(h<=240){
|
||
r = min;
|
||
g = ((240-h)/60)*(max-min)+min;
|
||
b = max;
|
||
}else if(h<=300){
|
||
r = ((h-240)/60)*(max-min)+min;
|
||
g = min;
|
||
b = max;
|
||
}else{
|
||
r = max;
|
||
g = min;
|
||
b = ((360-h)/60)*(max-min)+min;
|
||
}
|
||
r = Math.round(r).toString(16);
|
||
g = Math.round(g).toString(16);
|
||
b = Math.round(b).toString(16);
|
||
if(r.length===1)r='0'+r;
|
||
if(g.length===1)g='0'+g;
|
||
if(b.length===1)b='0'+b;
|
||
var color = '#'+r+g+b;
|
||
return color;
|
||
};
|
||
|
||
ColorPicker.HUE_WIDTH = 20;
|
||
ColorPicker.MARGIN = 3;
|
||
|
||
ColorPicker.prototype = Object.create(PIXI.Container.prototype);
|
||
ColorPicker.prototype.constructor = ColorPicker;
|
||
ColorPicker.prototype.initialize = function(size){
|
||
PIXI.Container.call(this);
|
||
|
||
this._size = size;
|
||
|
||
this._hue = -1;
|
||
this._saturation = -1;
|
||
this._value = -1;
|
||
this._color = null;
|
||
|
||
this._touchingHue = false;
|
||
this._touchingSv = false;
|
||
this._touching = false;
|
||
|
||
var margin = ColorPicker.MARGIN;
|
||
var hueWidth = ColorPicker.HUE_WIDTH;
|
||
var totalWidth = margin*3 + size + hueWidth;
|
||
var totalHeight = margin*2 + size;
|
||
|
||
var bitmap,sprite;
|
||
|
||
//this > backBitmap
|
||
bitmap = new Bitmap(16,16);
|
||
bitmap.fillAll('rgba(0,0,0,0.5)');
|
||
sprite = new Sprite(bitmap);
|
||
this.addChild(sprite);
|
||
sprite.scale.set(totalWidth/16,totalHeight/16);
|
||
this._backSprite = sprite;
|
||
|
||
|
||
//pickerSprite
|
||
bitmap = new Bitmap(size,size);
|
||
sprite = new Sprite(bitmap);
|
||
this.addChild(sprite);
|
||
sprite.x = margin;
|
||
sprite.y = margin;
|
||
this._pickerSprite = sprite;
|
||
this.bitmap = bitmap;
|
||
|
||
//huePicker
|
||
bitmap = new Bitmap(hueWidth,size);
|
||
sprite = new Sprite(bitmap);
|
||
this.addChild(sprite);
|
||
sprite.x = margin*2 + size;
|
||
sprite.y = margin;
|
||
this._huePicker = sprite;
|
||
|
||
//pointer
|
||
bitmap = new Bitmap(16,16);
|
||
sprite = new Sprite(bitmap);
|
||
this.addChild(sprite);
|
||
sprite.anchor.set(0.5,0.5);
|
||
this._pointer = sprite;
|
||
var ctx = bitmap._context;
|
||
ctx.beginPath();
|
||
ctx.arc(8,8,6,0,360*Math.PI/180,false);
|
||
ctx.fillStyle = 'rgb(255,255,255)';
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
ctx.arc(8,8,3,0,360*Math.PI/180,false);
|
||
ctx.globalCompositeOperation = "destination-out";
|
||
ctx.fill();
|
||
|
||
//huePointer
|
||
var lineWidth = 2;
|
||
var spaceHeight = 2;
|
||
bitmap = new Bitmap(hueWidth+lineWidth*2,spaceHeight+lineWidth*2);
|
||
sprite = new Sprite(bitmap);
|
||
this.addChild(sprite);
|
||
sprite.anchor.set(0.5,0.5);
|
||
this._huePointer = sprite;
|
||
bitmap.fillAll('black');
|
||
bitmap.clearRect(lineWidth,lineWidth,bitmap.width-lineWidth*2,bitmap.height-lineWidth*2);
|
||
|
||
|
||
this.setupHuePicker();
|
||
this.setColor('rgb(255,255,255)');
|
||
};
|
||
|
||
ColorPicker.prototype.setupHuePicker = function(){
|
||
var bitmap = this._huePicker.bitmap;
|
||
var width = bitmap.width;
|
||
var height = bitmap.height;
|
||
|
||
var s = 255;
|
||
var v = 255;
|
||
for(var y=0; y<height; y=(y+1)|0){
|
||
var h = 360*(y/height);
|
||
var color = ColorPicker.colorWithHsv(h,s,v);
|
||
bitmap.fillRect(0,y,width,1,color);
|
||
}
|
||
};
|
||
|
||
ColorPicker.prototype.setupPalette = function(h){
|
||
var bitmap = this._pickerSprite.bitmap;
|
||
bitmap.clear();
|
||
|
||
var width = this.width;
|
||
var height = this.height;
|
||
|
||
var r,g,b;
|
||
for(var x=0; x<width; x=(x+1)|0){
|
||
var s = 255*x/width;
|
||
for(var y=0; y<height; y=(y+1)|0){
|
||
var v = 255*y/height;
|
||
var color = ColorPicker.colorWithHsv(h,s,v);
|
||
bitmap.fillRect(x,height-y-1,1,1,color);
|
||
}
|
||
}
|
||
};
|
||
|
||
ColorPicker.prototype.setColor = function(color){
|
||
var r,g,b;
|
||
if(color.indexOf('rgb')!==0){
|
||
if(color[0] == "#"){
|
||
color = color.substr(1);
|
||
}else if(color.indexOf("0x")===0){
|
||
color = color.substr(2);
|
||
}
|
||
if(color.length == 8){
|
||
color = color.substr(2);
|
||
}
|
||
r = parseInt(color.substr(0, 2), 16);
|
||
g = parseInt(color.substr(2, 2), 16);
|
||
b = parseInt(color.substr(4, 2), 16);
|
||
}else{
|
||
var args = color.match(/\((.+)\)/)[1].split(',');
|
||
r = Number(args[0]);
|
||
g = Number(args[1]);
|
||
b = Number(args[2]);
|
||
}
|
||
|
||
var h,s,v;
|
||
var max = Math.max(r,g,b);
|
||
var min = Math.min(r,g,b);
|
||
if(r===g && g===b){
|
||
h = Math.max(0,this._hue);
|
||
}else if(r>=g && r>=b){
|
||
h = 60*(g-b)/(max-min);
|
||
}else if(g>=r && g>=b){
|
||
h = 60*(b-r)/(max-min)+120;
|
||
}else{
|
||
h = 60*(r-g)/(max-min)+240;
|
||
}
|
||
|
||
s = (max-min)/max*255;
|
||
v = max;
|
||
|
||
if(h<0){
|
||
h += 360;
|
||
}else if(h>360){
|
||
h -= 360;
|
||
}
|
||
|
||
this.setHue(h);
|
||
this.setSV(s,v);
|
||
};
|
||
|
||
ColorPicker.prototype.updateResultColor = function(){
|
||
this._color = ColorPicker.colorWithHsv(this._hue,this._saturation,this._value);
|
||
};
|
||
|
||
ColorPicker.prototype.color = function(){
|
||
return this._color;
|
||
};
|
||
|
||
ColorPicker.prototype.setHue = function(h){
|
||
h = h.clamp(0,360);
|
||
if(this._hue === h)return;
|
||
|
||
var dh = h-this._hue;
|
||
this._hue = h;
|
||
this.setupPalette(this._hue);
|
||
|
||
var sprite = this._huePicker;
|
||
var pointer = this._huePointer;
|
||
pointer.x = sprite.x+sprite.width/2;
|
||
pointer.y = sprite.y+sprite.height*h/360;
|
||
|
||
this.updateResultColor();
|
||
};
|
||
|
||
ColorPicker.prototype.setSV = function(s,v){
|
||
if(this._saturation===s && this._value===v)return;
|
||
|
||
this._saturation = s;
|
||
this._value = v;
|
||
|
||
var margin = ColorPicker.MARGIN
|
||
var size = this._size;
|
||
|
||
var pointer = this._pointer;
|
||
pointer.x = margin+Math.round((s/255)*size);
|
||
pointer.y = margin+Math.round(size-(v/255)*size-1);
|
||
|
||
this.updateResultColor();
|
||
};
|
||
|
||
ColorPicker.prototype.update = function(){
|
||
if(!this.visible){
|
||
this._touchingHue = false;
|
||
this._touchingSv = false;
|
||
return;
|
||
}
|
||
if(!TouchInput.isTriggered() && !TouchInput.isPressed()){
|
||
this._touchingHue = false;
|
||
this._touchingSv = false;
|
||
return;
|
||
}
|
||
this._touching = false;
|
||
|
||
var x = TouchInput.x-this.x;
|
||
var y = TouchInput.y-this.y;
|
||
var dx,dy,touchInside;
|
||
|
||
var hPicker = this._huePicker;
|
||
dx = x-hPicker.x;
|
||
dy = y-hPicker.y;
|
||
|
||
touchInside = (dx>=0 && dx<=hPicker.width && dy>=0 && dy<=hPicker.height);
|
||
if(this._touchingHue || (!this._touchingSv&&touchInside)){
|
||
dy = dy.clamp(0,hPicker.height-1);
|
||
var hue = Math.round(dy/(hPicker.height-1)*360);
|
||
this.setHue(hue);
|
||
this._touchingHue = true;
|
||
this._touching = true;
|
||
return;
|
||
}
|
||
|
||
var svPicker = this._pickerSprite;
|
||
dx = x-svPicker.x;
|
||
dy = y-svPicker.y;
|
||
touchInside = (dx>=0 && dx<=svPicker.width && dy>=0 && dy<=svPicker.height);
|
||
if(this._touchingSv || (!this._touchingHue&&touchInside)){
|
||
dx = dx.clamp(0,svPicker.width-1);
|
||
dy = dy.clamp(0,svPicker.height-1);
|
||
var s = Math.round(dx/(svPicker.width-1)*255);
|
||
var v = Math.round((svPicker.height-1-dy)/(svPicker.height-1)*255);
|
||
this.setSV(s,v);
|
||
this._touchingSv = true;
|
||
this._touching = true;
|
||
return;
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// Palette
|
||
//=============================================================================
|
||
MapDecorator.showingPalette = null;
|
||
MapDecorator.paletteBackSprite = null;
|
||
MapDecorator.clearShowingPalette = function(notEnd=false){
|
||
var palette = this.showingPalette;
|
||
this.showingPaldette = null;
|
||
if(!palette)return;
|
||
|
||
this.tryDeletePaletteTilesetCache();
|
||
|
||
palette.selected = null;
|
||
palette.completion = null;
|
||
for(const objects of palette.objectsArr){
|
||
for(const obj of objects){
|
||
if(MapObject && obj instanceof MapObject){
|
||
// obj.releaseSprite();
|
||
// if(obj.cachable && !notEnd){
|
||
// delete obj.cachabe;
|
||
// MapObject.cache(obj);
|
||
// }
|
||
}
|
||
}
|
||
}
|
||
palette.objectsArr = null;
|
||
if(palette.sprites){
|
||
for(const sprite of palette.sprites){
|
||
if(sprite.parent){
|
||
sprite.parent.removeChild(sprite);
|
||
}
|
||
}
|
||
}
|
||
palette.sprites = null;
|
||
|
||
if(this.paletteBackSprite && this.paletteBackSprite.parent){
|
||
this.paletteBackSprite.parent.removeChild(this.paletteBackSprite);
|
||
this.paletteBackSprite.removeChildren();
|
||
}
|
||
|
||
this.showingPalette = null;
|
||
_Dev.showText('paletteIndexes',null);
|
||
};
|
||
|
||
MapDecorator.showPalette = function(objectsArr,pageNames,pageIdx,size,m,x0Num,completion,currentIdsArr=null,keySearchEnable=true){
|
||
this.clearShowingPalette(true);
|
||
|
||
this.cantShowMenu = true;
|
||
var sprites = null;
|
||
|
||
/* black sprite
|
||
===================================*/
|
||
if(!this.paletteBackSprite){
|
||
this.paletteBackSprite = new PIXI.Graphics();
|
||
}
|
||
|
||
var backSprite = this.paletteBackSprite;
|
||
SceneManager._scene.addChild(backSprite);
|
||
_Dev.prepareDebugTextContainer();
|
||
|
||
|
||
/* objects
|
||
===================================*/
|
||
pageIdx = pageIdx.clamp(0,objectsArr.length-1);
|
||
var container = new PIXI.Container();
|
||
backSprite.addChild(container);
|
||
|
||
var selectedArr = this._selectedIdsWithCurrentIds(objectsArr,currentIdsArr);
|
||
|
||
var cacheKeys = null;
|
||
if(isMZ){
|
||
cacheKeys = ImageManager._cache ? Object.keys(ImageManager._cache) : null;
|
||
}
|
||
|
||
this.showingPalette = {
|
||
objectPaletteMaxY:0,
|
||
scrollY:0,
|
||
lastWheelFrame:0,
|
||
|
||
objectsArr,
|
||
pageNames,
|
||
pageIdx,
|
||
sprites,
|
||
size,
|
||
m,
|
||
x0Num,
|
||
selected:selectedArr,
|
||
completion,
|
||
rects:null,
|
||
isTileset:false,
|
||
tileImageIdx:0,
|
||
|
||
imageCacheKeys:cacheKeys,
|
||
lastTilesetUrl:null,
|
||
keySearchEnable,
|
||
searchInput:'',
|
||
};
|
||
|
||
/* topSprite
|
||
===================================*/
|
||
if(!this.topSprite){
|
||
this.topSprite = new PIXI.Graphics();
|
||
}
|
||
this.topSprite.clear();
|
||
backSprite.addChild(this.topSprite);
|
||
|
||
this.refreshPaletteObjects();
|
||
SoundManager.playCursor();
|
||
|
||
return true;
|
||
};
|
||
|
||
MapDecorator._cachedSprites = [];
|
||
MapDecorator._cachedBitmaps = [];
|
||
MapDecorator._cachePaletteObjects = function(container){
|
||
for(var i=container.children.length-1; i>=0; i=(i-1)|0){
|
||
var child = container.children[i];
|
||
if(child.constructor===Sprite){
|
||
MapDecorator._cachedSprites.push(child);
|
||
if(child.bitmap){
|
||
MapDecorator._cachedBitmaps.push(child.bitmap);
|
||
}
|
||
child.bitmap = null;
|
||
}
|
||
container.removeChild(child);
|
||
}
|
||
};
|
||
MapDecorator.refreshPaletteObjects = function(){
|
||
var palette = this.showingPalette;
|
||
var container = this.paletteBackSprite.children[0];
|
||
this._cachePaletteObjects(container);
|
||
|
||
this.tryDeletePaletteTilesetCache();
|
||
|
||
var objects = palette.objectsArr[palette.pageIdx];
|
||
if(typeof objects ==='string'){
|
||
palette.isTileset = true;
|
||
this._refreshPaletteTileset(palette,container,objects);
|
||
}else{
|
||
palette.isTileset = false;
|
||
this._refreshPaletteObjects(palette,container,objects);
|
||
}
|
||
|
||
/* pageIndexGuide
|
||
===================================*/
|
||
if(palette.pageNames && palette.pageNames.length>1){
|
||
var texts = ['【表示ページ】'];
|
||
texts.push('ホイール/←→:ページ切り替え');
|
||
if(palette.objectPaletteMaxY>Graphics.height){
|
||
texts.push('Alt+ホイール:スクロール');
|
||
}
|
||
texts.push('Ctrl+Q/W:ページ±%1'.format(palettePageNum));
|
||
if(palette.keySearchEnable){
|
||
texts.push('A~Zキー:頭文字検索');
|
||
}
|
||
|
||
var length = palette.pageNames.length;
|
||
var i0 = Math.floor(palette.pageIdx/palettePageNum)*palettePageNum;
|
||
var i1 = (i0+palettePageNum-1).clamp(0,length-1);
|
||
for(var i=i0; i<=i1; i=(i+1)|0){
|
||
var name = '%1:%2'.format(i+1,palette.pageNames[i]);
|
||
if(i===palette.pageIdx){
|
||
name = '\\H[255,50,50,0.9]'+name;
|
||
}
|
||
texts.push(name);
|
||
}
|
||
if(i1 !== length-1){
|
||
texts.push(' ︙');
|
||
}
|
||
_Dev.showText('paletteIndexes',texts);
|
||
}
|
||
};
|
||
MapDecorator.tryDeletePaletteTilesetCache = function(){
|
||
var palette = this.showingPalette;
|
||
if(!palette)return;
|
||
if(isMZ && palette.lastTilesetUrl && palette.imageCacheKeys){
|
||
if(!palette.imageCacheKeys.contains(palette.lastTilesetUrl)){
|
||
var cache = ImageManager._cache[palette.lastTilesetUrl];
|
||
if(cache)cache.destroy();
|
||
delete ImageManager._cache[palette.lastTilesetUrl];
|
||
}
|
||
}
|
||
palette.lastTilesetUrl = null;
|
||
};
|
||
|
||
MapDecorator._refreshPaletteObjects = function(palette,container,objects){
|
||
var size = palette.size;
|
||
var m = palette.m;
|
||
var x0Num = palette.x0Num;
|
||
|
||
var x0 = m+(size+m)*x0Num;//avoid guide
|
||
var x = x0;
|
||
var y = m;
|
||
var rects = [];
|
||
for(let obj of objects){
|
||
var sprite = null;
|
||
if(typeof obj==='number'){
|
||
if(obj===MapDecorator.VARIATION_FLAG_NO_SUPPLY){
|
||
sprite = this._paletteButton('追加\n抽選☓');
|
||
}else if(obj===MapDecorator.VARIATION_FLAG_WATER){
|
||
sprite = this._paletteButton('水場\n固定','rgb(100,200,255)');
|
||
}else{
|
||
obj = [obj];
|
||
}
|
||
// }else if(typeof obj==='string'){
|
||
// //category
|
||
// var elems = obj.split('::');
|
||
// var category = elems[1];
|
||
// var idx = Number(elems[2]);
|
||
// var data = $dataTrpMapObjectGroups.data[category][idx];
|
||
// obj = MapObject.objectFromGroupData(data);
|
||
}
|
||
|
||
|
||
if(sprite){
|
||
//sprite button
|
||
}else if(Array.isArray(obj)){
|
||
sprite = this.layeredTilesSprite(obj,size);
|
||
}else if(MapObject && obj instanceof MapObject){
|
||
//mapObj
|
||
sprite = obj.setupSprite(null);
|
||
sprite.bitmap.addLoadListener(function(sprite){
|
||
var sprSize = Math.max(sprite.width,sprite.height,1);
|
||
if(sprSize>size){
|
||
sprite.scale.set(size/sprSize,size/sprSize);
|
||
}else{
|
||
sprite.scale.set(1,1);
|
||
}
|
||
}.bind(this,sprite));
|
||
}
|
||
|
||
if(x+size>=Graphics.width-m){
|
||
x = x0;
|
||
y += size+m;
|
||
}
|
||
if(sprite){
|
||
container.addChild(sprite);
|
||
sprite.x = x;
|
||
sprite.y = y;
|
||
if(sprite instanceof PIXI.Sprite){
|
||
sprite.anchor.set(0.5,0.5);
|
||
sprite.x += size/2;
|
||
sprite.y += size/2;
|
||
}
|
||
}
|
||
rects.push([x,y,size,size]);
|
||
|
||
x += size+m;
|
||
}
|
||
palette.objectPaletteMaxY = y+size+m;
|
||
palette.rects = rects;
|
||
|
||
this.refreshPaletteBackSprite();
|
||
};
|
||
|
||
MapDecorator._refreshPaletteTileset = function(palette,container,tilesetArg){
|
||
var argElems = tilesetArg.split(':');
|
||
argElems.shift();
|
||
palette.tileImageIdx = Number(argElems.shift());
|
||
|
||
var name = argElems.join(':');
|
||
|
||
var bitmap = ImageManager.loadTileset(name);
|
||
palette.lastTilesetUrl = 'img/tilesets/'+name+'.png';
|
||
|
||
var sprite = this.sprite(bitmap);
|
||
container.addChild(sprite);
|
||
|
||
var x0Num = palette.x0Num;
|
||
var mx0 = x0Num*palette.size;
|
||
|
||
sprite.x = mx0;
|
||
sprite.y = 0;
|
||
|
||
var pageIdx = palette.pageIdx;
|
||
var rects = [];
|
||
palette.objectPaletteMaxY = 0;
|
||
palette.rects = rects;
|
||
|
||
bitmap.addLoadListener(()=>{
|
||
if(pageIdx!==palette.pageIdx)return;
|
||
this.refreshPaletteBackSprite();
|
||
|
||
palette.objectPaletteMaxY = bitmap.height;
|
||
});
|
||
};
|
||
|
||
MapDecorator.refreshPaletteBackSprite = function(){
|
||
var backSprite = this.paletteBackSprite;
|
||
backSprite.clear();
|
||
backSprite.beginFill(0x888888,0.5)
|
||
.drawRect(0,0,Graphics.width,Graphics.height);
|
||
|
||
var topSprite = this.topSprite;
|
||
topSprite.clear();
|
||
|
||
var palette = this.showingPalette;
|
||
if(palette.isTileset){
|
||
var x0 = palette.x0Num*palette.size;
|
||
|
||
//centerline
|
||
var sprite = backSprite.children[0].children[0];
|
||
topSprite.beginFill(0x000000,1.0)
|
||
.drawRect(x0+8*tileW-2,0,4,sprite.height||Graphics.height);
|
||
|
||
|
||
//selected mask
|
||
for(const objIdx of palette.selected[palette.pageIdx]){
|
||
var col = objIdx%16;
|
||
var row = Math.floor(objIdx/16);
|
||
topSprite.beginFill(0xffffff,0.5)
|
||
.drawRect(x0+col*tileW,row*tileH,tileW,tileH);
|
||
};
|
||
}else{
|
||
var m = 4;
|
||
for(const objIdx of palette.selected[palette.pageIdx]){
|
||
var rect = palette.rects[objIdx];
|
||
backSprite.beginFill(0xff0000,0.8)
|
||
.drawRect(rect[0]-m,rect[1]-m,rect[2]+2*m,rect[3]+2*m);
|
||
}
|
||
}
|
||
};
|
||
|
||
MapDecorator.onWheelValueChangePalette = function(delta){
|
||
var palette = this.showingPalette;
|
||
if(this.onKeyAlt){
|
||
var container = this.paletteBackSprite.children[0];
|
||
container.y += delta;
|
||
container.y = container.y.clamp(-(palette.objectPaletteMaxY-Graphics.height),0);
|
||
palette.scrollY = -container.y;
|
||
}else{
|
||
if(palette.pageNames.length>1){
|
||
if(Graphics.frameCount-palette.lastWheelFrame>=6 || Math.abs(delta)>=50){
|
||
if(delta>0){
|
||
this.exceedPalettePageIdx(-1);
|
||
}else{
|
||
this.exceedPalettePageIdx(1);
|
||
}
|
||
palette.lastWheelFrame = Graphics.frameCount;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
MapDecorator.onKeyDownPalette = function(event){
|
||
var palette = this.showingPalette
|
||
if(!palette)return false;
|
||
|
||
if(event.key==='ArrowLeft'||event.key==='ArrowUp'){
|
||
this.exceedPalettePageIdx(-1);
|
||
}else if(event.key==='ArrowRight'||event.key==='ArrowDown'){
|
||
this.exceedPalettePageIdx(1);
|
||
}else if(event.ctrlKey&&event.key==='q'){
|
||
this.exceedPalettePageIdx(-palettePageNum);
|
||
}else if(event.ctrlKey&&event.key==='w'){
|
||
this.exceedPalettePageIdx(palettePageNum);
|
||
|
||
}else if(!isNaN(event.key)){
|
||
var pageIdx = Number(event.key)-1;
|
||
if(this.showingPalette.objectsArr[pageIdx]){
|
||
this.showingPalette.pageIdx = pageIdx;
|
||
this.refreshPaletteObjects();
|
||
SoundManager.playCursor();
|
||
}else{
|
||
SoundManager.playBuzzer();
|
||
}
|
||
}else if(palette.keySearchEnable && event.key.length===1 && /[a-zA-Z0-9\.\_\- ]/.test(event.key)){
|
||
this.trySearchPalettePage(event.key);
|
||
}else if(event.key==='q'){
|
||
this.exceedPalettePageIdx(-1);
|
||
}else if(event.key==='w'){
|
||
this.exceedPalettePageIdx(1);
|
||
}else{
|
||
return false;
|
||
}
|
||
return true;
|
||
};
|
||
MapDecorator.exceedPalettePageIdx = function(value=1){
|
||
if(this.showingPalette.objectsArr.length<=1){
|
||
SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
var pageIdx = this.showingPalette.pageIdx+value;
|
||
if(pageIdx<0)pageIdx = this.showingPalette.objectsArr.length-1;
|
||
if(pageIdx>=this.showingPalette.objectsArr.length)pageIdx = 0;
|
||
this.showingPalette.pageIdx = pageIdx;
|
||
this.refreshPaletteObjects();
|
||
SoundManager.playCursor();
|
||
};
|
||
MapDecorator.trySwitchPalettePageForTilesetNumber = function(number){
|
||
var length = this.showingPalette.objectsArr.length;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
var obj = this.showingPalette.objectsArr[i];
|
||
if(typeof obj !== 'string')continue;
|
||
if(obj.indexOf('tileset:'+number+':')<0)continue;
|
||
|
||
this.showingPalette.pageIdx = i;
|
||
this.refreshPaletteObjects();
|
||
SoundManager.playCursor();
|
||
return;
|
||
}
|
||
SoundManager.playBuzzer();
|
||
};
|
||
|
||
|
||
MapDecorator.onMouseDownLeftPaletteCommon = function(event,i,x,y,tx,ty,handler=null){
|
||
var palette = this.showingPalette;
|
||
if(!palette)return;
|
||
|
||
if(palette.editingObj)return;
|
||
|
||
ty += palette.scrollY;
|
||
if(palette.isTileset){
|
||
this._tryTouchPaletteTileset(event,i,x,y,tx,ty,handler);
|
||
}else{
|
||
this._tryTouchPaletteObjects(event,i,x,y,tx,ty,handler);
|
||
}
|
||
};
|
||
|
||
MapDecorator._tryTouchPaletteObjects = function(event,i,x,y,tx,ty,handler){
|
||
var palette = this.showingPalette;
|
||
var pageIdx = palette.pageIdx;
|
||
|
||
var rects = palette.rects;
|
||
var objIdx = -1;
|
||
|
||
for(var i=rects.length-1; i>=0; i=(i-1)|0){
|
||
var rect = rects[i];
|
||
if(tx>=rect[0] && tx<=rect[0]+rect[2]
|
||
&& ty>=rect[1] && ty<=rect[1]+rect[3]
|
||
){
|
||
objIdx = i;
|
||
}
|
||
}
|
||
if(objIdx<0){
|
||
if(!handler)SoundManager.playBuzzer();
|
||
return;
|
||
}
|
||
|
||
var objects = palette.objectsArr[pageIdx];
|
||
var obj = objects[objIdx];
|
||
|
||
if(handler){
|
||
handler(obj,objIdx);
|
||
return;
|
||
}
|
||
|
||
var selected = palette.selected[pageIdx];
|
||
if(selected.contains(objIdx)){
|
||
TRP_CORE.remove(selected,objIdx);
|
||
}else{
|
||
selected.push(objIdx);
|
||
}
|
||
this.refreshPaletteBackSprite();
|
||
|
||
if(palette.completion){
|
||
palette.completion(obj,palette.selected.map(idx=>objects[idx]));
|
||
}
|
||
|
||
SoundManager.playCursor();
|
||
};
|
||
|
||
|
||
MapDecorator._tryTouchPaletteTileset = function(event,i,x,y,tx,ty,handler=null){
|
||
var idx = this._paletteTilesetTouchIdx(tx,ty);
|
||
if(idx<0)return;
|
||
|
||
var palette = this.showingPalette;
|
||
palette.selected[palette.pageIdx] = [idx];
|
||
SoundManager.playCursor();
|
||
|
||
this.refreshPaletteBackSprite();
|
||
};
|
||
|
||
MapDecorator.onMousePressPalette = function(tx,ty){
|
||
var palette = this.showingPalette;
|
||
if(!palette.isTileset)return;
|
||
|
||
var idx = this._paletteTilesetTouchIdx(tx,ty);
|
||
if(idx<0)return;
|
||
|
||
var selected = palette.selected[palette.pageIdx];
|
||
if(selected[selected.length-1]===idx)return;
|
||
|
||
var idx0 = selected[0];
|
||
var col0 = idx0%16;
|
||
var row0 = Math.floor(idx0/16);
|
||
var halfIdx0 = Math.floor(col0/8);
|
||
|
||
var col = idx%16;
|
||
var row = Math.floor(idx/16);
|
||
var halfIdx1 = Math.floor(col/8);
|
||
if(halfIdx0!==halfIdx1){
|
||
_Dev.showTempText('tilesetPickError','タイルセット画像の左右をまたいだオブジェクトは設定できません','red')
|
||
return;
|
||
}
|
||
|
||
selected.length = 1;
|
||
if(idx0!==idx){
|
||
var dc = col>col0 ? 1 : -1;
|
||
var dr = row>row0 ? 1 : -1;
|
||
|
||
for(var c=col0;; c=(c+dc)|0){
|
||
for(var r=row0;; r=(r+dr)|0){
|
||
var i = r*16+c;
|
||
if(!selected.contains(i)){
|
||
selected.push(i);
|
||
}
|
||
if(r===row)break;
|
||
}
|
||
if(c===col)break;
|
||
}
|
||
}
|
||
this.refreshPaletteBackSprite();
|
||
|
||
SoundManager.playCursor();
|
||
}
|
||
|
||
MapDecorator.onMouseUpLeftShowingPalette = function(event,tx,ty){
|
||
var palette = this.showingPalette;
|
||
if(!palette)return;
|
||
if(palette.editingObj)return;
|
||
|
||
var selected = palette.selected[palette.pageIdx];
|
||
if(!selected)return;
|
||
if(!selected.length)return;
|
||
if(!palette.completion)return;
|
||
|
||
var baseId;
|
||
var tileIdSign = 1;
|
||
if(palette.tileImageIdx>=0){
|
||
baseId = (palette.tileImageIdx-5)*256;
|
||
}else{
|
||
var tilesetImage = TRP_CORE.last(palette.objectsArr[palette.pageIdx].split(':'));
|
||
MapObject.registerObjectGroupTilesetImage(tilesetImage);
|
||
baseId = -256*$dataTrpMapObjectGroups.tilesetImageIds.indexOf(tilesetImage);
|
||
tileIdSign = -1;
|
||
}
|
||
var selected = palette.selected[palette.pageIdx];
|
||
|
||
var idx0 = selected[0];
|
||
var idx1 = selected[selected.length-1];
|
||
|
||
var col0 = idx0%16;
|
||
var row0 = Math.floor(idx0/16);
|
||
var col1 = idx1%16;
|
||
var row1 = Math.floor(idx1/16);
|
||
|
||
var col = Math.min(col0,col1);
|
||
var row = Math.min(row0,row1);
|
||
var w = Math.abs(col1-col0)+1;
|
||
var h = Math.abs(row1-row0)+1;
|
||
|
||
var halfIdx = Math.floor(col/8);
|
||
col = col%8;
|
||
var innerIdx = halfIdx*128 + row*8+col;
|
||
var tileId = baseId + tileIdSign*innerIdx;
|
||
|
||
var obj;
|
||
if(tileIdSign<0){
|
||
//other tilesetImage -> mapObj
|
||
obj = MapObject.object();
|
||
obj.setupCommonBefore();
|
||
obj.tileId = tileId;
|
||
obj.tileW = w;
|
||
obj.tileH = h;
|
||
obj.setupCommonAfter();
|
||
|
||
palette.lastTilesetUrl = null;
|
||
MapDecorator.registerMapObjectTemplateWithMapObject(obj);
|
||
|
||
_Dev.showText('decorator:otherTile',[
|
||
'Ctrl+T:他のタイルセット画像を登録'
|
||
],'red')
|
||
}else{
|
||
obj = [];
|
||
for(var c=0; c<w; c=(c+1)|0){
|
||
var col = [];
|
||
obj.push(col);
|
||
for(var r=0; r<h; r=(r+1)|0){
|
||
col.push([tileId+tileIdSign*(c+r*8)]);
|
||
}
|
||
}
|
||
}
|
||
|
||
palette.completion(obj);
|
||
SoundManager.playCursor();
|
||
};
|
||
|
||
|
||
/* palette -> helper
|
||
===================================*/
|
||
MapDecorator._selectedIdsWithCurrentIds = function(objectsArr,currentIdsArr){
|
||
var selectedArr = [];
|
||
for(var i=objectsArr.length-1; i>=0; i=(i-1)|0){
|
||
selectedArr.push([]);
|
||
}
|
||
if(currentIdsArr){
|
||
for(var pi=0; pi<currentIdsArr.length; pi=(pi+1)|0){
|
||
var selected = selectedArr[pi];
|
||
var objects = objectsArr[pi];
|
||
var currentIds = currentIdsArr[pi];
|
||
if(currentIds){
|
||
for(const ids of currentIds){
|
||
var idsStr = JSON.stringify(ids);
|
||
for(var i=objects.length-1; i>=0; i=(i-1)|0){
|
||
var obj = objects[i];
|
||
if(JSON.stringify(obj) === idsStr){
|
||
selected.push(i);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if(currentIds.contains(MapDecorator.VARIATION_FLAG_SUPPLY)){
|
||
TRP_CORE.remove(selected,0);
|
||
}else if(currentIds.length){
|
||
selected.push(0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return selectedArr;
|
||
};
|
||
|
||
MapDecorator._paletteButton = function(text,color='white',size=48){
|
||
var bitmap = this.bitmap(size,size);
|
||
var lines = text.split('\n');
|
||
var lineH = (size-2)/lines.length;
|
||
var length = lines.length;
|
||
|
||
bitmap.fontSize = lineH/1;
|
||
bitmap.textColor = color;
|
||
bitmap.outlineColor = 'black';
|
||
bitmap.outlineWidth = 4;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
var line = lines[i];
|
||
var y = i*lineH + 1;
|
||
bitmap.drawText(line,0,y,size,lineH,'center');
|
||
}
|
||
|
||
var sprite = new Sprite(bitmap);
|
||
return sprite;
|
||
};
|
||
|
||
MapDecorator.layeredTilesSprite = function(obj,size=0){
|
||
if(!Array.isArray(obj))return null;
|
||
if(!Array.isArray(obj[0])){
|
||
obj = [[obj]];
|
||
}
|
||
|
||
var w = obj.length;
|
||
var h = obj[0].length;
|
||
var bitmap = this.bitmap(w*tileW,h*tileH);
|
||
var sprite = this.sprite(bitmap);
|
||
|
||
var sprSize = Math.max(w*tileW,h*tileH);
|
||
if(size && sprSize>size){
|
||
sprite.scale.set(size/sprSize,size/sprSize);
|
||
}else{
|
||
sprite.scale.set(1,1);
|
||
}
|
||
|
||
var tilemap = SceneManager._scene._spriteset._tilemap;
|
||
var bitmaps = tilemap._bitmaps||tilemap.bitmaps;
|
||
for(var c=0; c<w; c=(c+1)|0){
|
||
var x = c*tileW;
|
||
var col = obj[c];
|
||
for(var r=0; r<h; r=(r+1)|0){
|
||
var y = r*tileH;
|
||
var tileIds = col[r];
|
||
if(!tileIds)continue;
|
||
var tileLen = tileIds.length;
|
||
for(var ti=0; ti<tileLen; ti=(ti+1)|0){
|
||
var tileId = tileIds[ti];
|
||
if(!tileId)continue;
|
||
|
||
if(ti===tileLen-1 && Tilemap.isAutotile(tileId) && !Tilemap.isWallTile(tileId)){
|
||
//autoTile -> close
|
||
tileId = baseTileId(tileId)+47;
|
||
}
|
||
TRP_CORE._drawTile(bitmap,tileId,x,y,bitmaps);
|
||
}
|
||
}
|
||
}
|
||
return sprite;
|
||
};
|
||
MapDecorator._paletteTilesetTouchIdx = function(tx,ty){
|
||
var palette = this.showingPalette;
|
||
var pageIdx = palette.pageIdx;
|
||
var container = this.paletteBackSprite.children[0];
|
||
var sprite = container.children[0];
|
||
if(!sprite)return -1;
|
||
|
||
tx -= sprite.x;
|
||
ty -= sprite.y;
|
||
if(tx<0 || tx>=sprite.width)return -1;
|
||
if(ty<0 || ty>=sprite.height)return -1;
|
||
|
||
var col = Math.floor(tx/tileW);
|
||
var row = Math.floor(ty/tileH);
|
||
var idx = col+row*16;
|
||
return idx;
|
||
};
|
||
|
||
MapDecorator.trySearchPalettePage = function(key){
|
||
var palette = this.showingPalette;
|
||
var inputting = palette.searchInput += key;
|
||
|
||
var files = palette.pageNames;
|
||
var length = files.length;
|
||
for(var i=0; i<length; i=(i+1)|0){
|
||
var file = files[i].toLowerCase();
|
||
if(file.indexOf(inputting) === 0){
|
||
if(palette.pageIdx!==i){
|
||
palette.pageIdx = i;
|
||
this.refreshPaletteObjects();
|
||
SoundManager.playCursor();
|
||
return;
|
||
}else{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(inputting.length>1){
|
||
palette.searchInput = '';
|
||
this.trySearchPalettePage(key);
|
||
}else{
|
||
SoundManager.playCursor();
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
//=============================================================================
|
||
// TilesetEdit
|
||
//=============================================================================
|
||
MapDecorator.MODE_GUIDE.tilesetEdit = [
|
||
'【タイルセット画像登録】',
|
||
'左クリック:タイル位置の決定',
|
||
'右クリック:キャンセル',
|
||
'Q/W:画像切り替え',
|
||
'\\C[255,255,0]■:現マップで使用中'
|
||
];
|
||
|
||
MapDecorator.showingTilesetEditIdx = 0;
|
||
MapDecorator.endModeTilesetEdit = function(){
|
||
var uiCache = this.modeUICache;
|
||
if(uiCache){
|
||
var sprite = uiCache.sprite;
|
||
TRP_CORE.removeFromParent(sprite);
|
||
MapDecorator._cachedSprites.push(sprite);
|
||
|
||
sprite = uiCache.canvasSprite;
|
||
if(sprite)sprite.removeChildren();
|
||
TRP_CORE.removeFromParent(sprite);
|
||
MapDecorator._cachedSprites.push(sprite);
|
||
|
||
var screen = uiCache.screen;
|
||
TRP_CORE.removeFromParent(screen);
|
||
|
||
if(uiCache.completion){
|
||
uiCache.completion(null);
|
||
uiCache.completion = null;
|
||
}
|
||
}
|
||
_Dev.showText('tilesetEditOnSelect',null);
|
||
};
|
||
|
||
MapDecorator.onKeyDownTilesetEdit = function(event){
|
||
if(!this.modeData)return;
|
||
|
||
if(event.key==='q'){
|
||
var idx = MapDecorator.showingTilesetEditIdx-1;
|
||
if(idx<0)idx = this.modeData.tilesetNames.length-1;
|
||
this.setTilesetCanvasPageIdx(idx);
|
||
SoundManager.playCursor();
|
||
}else if(event.key=='w'){
|
||
var idx = MapDecorator.showingTilesetEditIdx+1;
|
||
if(!this.modeData.tilesetNames[idx])idx = 0;
|
||
this.setTilesetCanvasPageIdx(idx);
|
||
SoundManager.playCursor();
|
||
}else if(event.key==='s'){
|
||
this.tryExecuteTilesetEdit();
|
||
}else if(event.key==='Escape'){
|
||
this.restoreMode(true);
|
||
SoundManager.playBuzzer();
|
||
}else if(event.key==='ArrowLeft'){
|
||
this.tryMoveTilesetEditSprite(-1,0);
|
||
}else if(event.key==='ArrowRight'){
|
||
this.tryMoveTilesetEditSprite(1,0);
|
||
}else if(event.key==='ArrowUp'){
|
||
this.tryMoveTilesetEditSprite(0,-1);
|
||
}else if(event.key==='ArrowDown'){
|
||
this.tryMoveTilesetEditSprite(0,1);
|
||
}
|
||
};
|
||
MapDecorator.onWheelValueChangeTilesetEdit = function(delta){
|
||
if(!this.modeData)return;
|
||
|
||
var modeData = this.modeData;
|
||
if(modeData.tilesetNames.length>1){
|
||
if(Graphics.frameCount-modeData.lastWheelFrame>=6 || Math.abs(delta)>=50){
|
||
if(delta>0){
|
||
var idx = MapDecorator.showingTilesetEditIdx-1;
|
||
if(idx<0)idx = this.modeData.tilesetNames.length-1;
|
||
this.setTilesetCanvasPageIdx(idx);
|
||
SoundManager.playCursor();
|
||
}else{
|
||
var idx = MapDecorator.showingTilesetEditIdx+1;
|
||
if(!this.modeData.tilesetNames[idx])idx = 0;
|
||
this.setTilesetCanvasPageIdx(idx);
|
||
SoundManager.playCursor();
|
||
}
|
||
modeData.lastWheelFrame = Graphics.frameCount;
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
MapDecorator.tryExecuteTilesetEdit = function(){
|
||
var modeData = this.modeData;
|
||
var uiCache = this.modeUICache;
|
||
if(!modeData || !uiCache || !uiCache.sprite)return;
|
||
if(modeData.locateXi<0)return;
|
||
|
||
var xi = modeData.locateXi;
|
||
var yi = modeData.locateYi;
|
||
var pageIdx = MapDecorator.showingTilesetEditIdx;
|
||
var allEmpty = modeData.allEmptyPositionsArr[pageIdx].contains(xi+yi*16);
|
||
if(!allEmpty){
|
||
SoundManager.playCursor();
|
||
if(!confirm('空じゃないタイルが含まれています。\n本当に画像を上書きしますか?')){
|
||
return;
|
||
}
|
||
}
|
||
|
||
//edit canvas
|
||
var canvas = uiCache.canvas;
|
||
var bitmap = uiCache.bitmap;
|
||
|
||
var tx = xi*tileW;
|
||
var ty = yi*tileH;
|
||
canvas.clearRect(tx,ty,modeData.tileW*tileW,modeData.tileH*tileH);
|
||
|
||
tx += modeData.locateDx;
|
||
ty += modeData.locateDy;
|
||
TRP_CORE.bltImage(canvas,bitmap,0,0,bitmap.width,bitmap.height,tx,ty);
|
||
|
||
|
||
//save image
|
||
var name = modeData.tilesetNames[MapDecorator.showingTilesetEditIdx];
|
||
var filePath = 'img/tilesets/'+name+'.png';
|
||
_Dev.saveCanvas(canvas,filePath);
|
||
|
||
//replace all bitmap
|
||
if(isMZ){
|
||
if(ImageManager._cache){
|
||
ImageManager._cache[filePath] = canvas;
|
||
}
|
||
}else{
|
||
if(ImageManager._imageCache){
|
||
ImageManager._imageCache._items[filePath] = canvas;
|
||
}
|
||
}
|
||
|
||
var completion = uiCache.completion;
|
||
uiCache.completion = null;
|
||
|
||
var setNumber = modeData.tilesetNumbers[pageIdx];
|
||
var tileIds = [];
|
||
var tileIdBase = 256*(setNumber-5);
|
||
for(var dx=0; dx<modeData.tileW; dx=(dx+1)|0){
|
||
for(var dy=0; dy<modeData.tileH; dy=(dy+1)|0){
|
||
var x = xi+dx;
|
||
var y = yi+dy;
|
||
var tileId = tileIdBase+128*Math.floor(x/8)+x%8+y*8;
|
||
tileIds.push(tileId);
|
||
}
|
||
}
|
||
|
||
|
||
//end
|
||
SoundManager.playSave();
|
||
|
||
this.restoreMode(true);
|
||
|
||
if(completion){
|
||
completion(tileIds);
|
||
}
|
||
};
|
||
MapDecorator.tryMoveTilesetEditSprite = function(dx=0,dy=0){
|
||
var modeData = this.modeData;
|
||
var uiCache = this.modeUICache;
|
||
if(!modeData || !uiCache || !uiCache.sprite)return;
|
||
if(modeData.locateXi<0)return;
|
||
|
||
modeData.locateDx += dx;
|
||
modeData.locateDy += dy;
|
||
|
||
var sprite = uiCache.sprite;
|
||
var maxX = tileW-(sprite.width-1)%tileW-1;
|
||
var maxY = tileH-(sprite.height-1)%tileH-1;
|
||
modeData.locateDx = (modeData.locateDx+dx).clamp(0,maxX);
|
||
modeData.locateDy = (modeData.locateDy+dy).clamp(0,maxY);
|
||
|
||
var canvasSprite = uiCache.canvasSprite;
|
||
sprite.x = canvasSprite.x + modeData.locateXi*tileW+modeData.locateDx;
|
||
sprite.y = canvasSprite.y + modeData.locateYi*tileH+modeData.locateDy;
|
||
|
||
SoundManager.playCursor();
|
||
}
|
||
MapDecorator.onMouseDownRightTilesetEdit = function(){
|
||
this.restoreMode(true);
|
||
SoundManager.playCancel();
|
||
};
|
||
MapDecorator.onMouseDownLeftTilesetEdit = function(event,roomId,x,y,tx,ty,dx,dy){
|
||
var modeData = this.modeData;
|
||
var uiCache = this.modeUICache;
|
||
if(!modeData || !uiCache || !uiCache.sprite)return;
|
||
|
||
var sprite = uiCache.sprite;
|
||
var canvasSprite = uiCache.canvasSprite;
|
||
var targetArea = uiCache.targetArea;
|
||
var x = tx-canvasSprite.x;
|
||
var y = ty-canvasSprite.y;
|
||
var xi = Math.floor(x/tileW);
|
||
var yi = Math.floor(y/tileH);
|
||
|
||
if(modeData.locateXi===xi && modeData.locateYi===yi){
|
||
modeData.locateXi = -1;
|
||
modeData.locateYi = -1;
|
||
SoundManager.playCursor();
|
||
targetArea.visible = false;
|
||
_Dev.showText('tilesetEditOnSelect',null);
|
||
}else if(xi<0 || xi>16-modeData.tileW
|
||
|| yi<0 || yi>=16-modeData.tileH
|
||
){
|
||
SoundManager.playBuzzer();
|
||
}else{
|
||
var canvasSprite = uiCache.canvasSprite;
|
||
modeData.locateXi = xi;
|
||
modeData.locateYi = yi;
|
||
modeData.locateDx = 0;
|
||
modeData.locateDy = 0;
|
||
sprite.x = canvasSprite.x+xi*tileW;
|
||
sprite.y = canvasSprite.y+yi*tileH;
|
||
sprite.opacity = 255;
|
||
SoundManager.playCursor();
|
||
|
||
targetArea.visible = true;
|
||
targetArea.clear();
|
||
targetArea.beginFill(0xff0000,0.5)
|
||
.drawRect(xi*tileW,yi*tileH,tileW*modeData.tileW,tileH*modeData.tileH);
|
||
|
||
|
||
var allEmpty = modeData.allEmptyPositionsArr[MapDecorator.showingTilesetEditIdx].contains(xi+yi*16);
|
||
var help = [
|
||
'カーソルキー:位置の微調整',
|
||
'Sキー:タイルセット画像に登録',
|
||
];
|
||
if(!allEmpty){
|
||
help.push('\\C[255,0,0]※既存タイルが上書きされます!!');
|
||
}
|
||
_Dev.showText('tilesetEditOnSelect',help);
|
||
}
|
||
};
|
||
|
||
MapDecorator.updateTilesetEdit = function(){
|
||
var modeData = this.modeData;
|
||
var uiCache = this.modeUICache;
|
||
if(!modeData || !uiCache || !uiCache.sprite)return;
|
||
if(modeData.locateXi>=0)return;
|
||
|
||
var canvasSprite = uiCache.canvasSprite;
|
||
var sprite = uiCache.sprite;
|
||
var x = TouchInput.x-canvasSprite.x;
|
||
var y = TouchInput.y-canvasSprite.y;
|
||
var xi = Math.floor(x/tileW);
|
||
var yi = Math.floor(y/tileH);
|
||
if(x<0 || x>=canvasSprite.width
|
||
|| y<0 || y>=canvasSprite.height
|
||
){
|
||
sprite.visible = false;
|
||
}else{
|
||
sprite.visible = true;
|
||
sprite.opacity = 128;
|
||
sprite.x = canvasSprite.x + xi*tileW;
|
||
sprite.y = canvasSprite.y + yi*tileH;
|
||
}
|
||
};
|
||
|
||
MapDecorator.startTilesetEdit = function(bitmap,completion=null){
|
||
this.setMode('tilesetEdit');
|
||
this.cantScroll = true;
|
||
|
||
//screen
|
||
var screen = new PIXI.Graphics();
|
||
screen.beginFill(0x000000,0.8)
|
||
.drawRect(0,0,Graphics.width,Graphics.height);
|
||
SceneManager._scene.addChild(screen);
|
||
|
||
//canvas back
|
||
var canvasBack = new PIXI.Graphics();
|
||
screen.addChild(canvasBack);
|
||
for(var c=0; c<16*4; c+=1){
|
||
for(var r=0; r<16*4; r+=1){
|
||
canvasBack.beginFill((r+c)%2===0 ? 0xdcdcdc : 0xffffff)
|
||
.drawRect(c*tileW/4,r*tileH/4,tileW/4,tileH/4);
|
||
}
|
||
}
|
||
|
||
//canvas sprite
|
||
var canvas = new Bitmap(16*tileW,16*tileH);
|
||
var canvasSprite = this.sprite(canvas);
|
||
screen.addChild(canvasSprite);
|
||
canvasSprite.x = (Graphics.width-canvas.width)/2;
|
||
canvasSprite.y = (Graphics.height-canvas.height)/2;
|
||
canvasBack.x = canvasSprite.x;
|
||
canvasBack.y = canvasSprite.y;
|
||
|
||
//usingScreen
|
||
var usingScreen = new PIXI.Graphics();
|
||
canvasSprite.addChild(usingScreen);
|
||
|
||
//grid
|
||
var grid = this.tileGridGraphic(16,16);
|
||
canvasSprite.addChild(grid);
|
||
|
||
//targetArea
|
||
var targetArea = new PIXI.Graphics();
|
||
canvasSprite.addChild(targetArea);
|
||
|
||
|
||
//prepare tilesetNames
|
||
var srcTileNames = $gameMap.tileset().tilesetNames;
|
||
var tilesetNames = [];
|
||
var tilesetNumbers = [];
|
||
for(var i=5; i<srcTileNames.length; i=(i+1)|0){
|
||
var tileName = srcTileNames[i];
|
||
if(!tileName)continue;
|
||
tilesetNames.push(tileName);
|
||
tilesetNumbers.push(i);
|
||
};
|
||
|
||
//target sprite
|
||
var sprite = this.sprite(bitmap);
|
||
screen.addChild(sprite);
|
||
|
||
|
||
//setup modeData
|
||
this.modeData = {
|
||
tilesetNames,tilesetNumbers,
|
||
w:bitmap.width,
|
||
h:bitmap.height,
|
||
tileW:Math.ceil(bitmap.width/tileW),
|
||
tileH:Math.ceil(bitmap.height/tileH),
|
||
emptyPositionsArr:[],
|
||
usingTilePositionsArr:[],
|
||
allEmptyPositionsArr:[],
|
||
locateXi:-1,locateYi:-1,
|
||
locateDx:0,locateDy:0,
|
||
usingTileIds:this.usingTileIds(),
|
||
};
|
||
this.modeUICache = {
|
||
bitmap,sprite,screen,canvas,canvasSprite,usingScreen,grid,targetArea,completion
|
||
};
|
||
|
||
_Dev.prepareDebugTextContainer();
|
||
|
||
this.setTilesetCanvasPageIdx(MapDecorator.showingTilesetEditIdx,true);
|
||
};
|
||
MapDecorator.usingTileIds = function(){
|
||
var result = [];
|
||
var map = {};
|
||
for(var i=data.length-1; i>=0; i=(i-1)|0){
|
||
var tileId = data[i];
|
||
if(tileId && !map[tileId]){
|
||
map[tileId] = true;
|
||
result.push(tileId);
|
||
}
|
||
}
|
||
|
||
for(const event of $dataMap.events){
|
||
if(!event)continue;
|
||
for(const page of event.pages){
|
||
if(!page)continue;
|
||
var tileId = page.image.tileId;
|
||
if(tileId && !map[tileId]){
|
||
map[tileId] = true;
|
||
result.push(tileId);
|
||
}
|
||
}
|
||
}
|
||
|
||
var current = [];
|
||
var next = [];
|
||
for(const roomObjInfoArr of proc.lastObjInfoArr){
|
||
if(!roomObjInfoArr)continue;
|
||
for(const objInfo of roomObjInfoArr){
|
||
var obj = objInfo[1];
|
||
var tileIds;
|
||
if(Array.isArray(obj)){
|
||
tileIds = obj;
|
||
}else if(MapObject){
|
||
tileIds = obj.tileIds();
|
||
}
|
||
if(!tileIds)continue;
|
||
|
||
current.length = 0;
|
||
next.length = 0;
|
||
next.push(tileIds);
|
||
while(next.length){
|
||
var temp = current;
|
||
current = next;
|
||
next = temp;
|
||
next.length = 0;
|
||
for(const arr of current){
|
||
for(const elem of arr){
|
||
if(Array.isArray(elem)){
|
||
next.push(elem);
|
||
}else{
|
||
if(elem && !map[elem]){
|
||
map[elem] = true;
|
||
result.push(elem);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
|
||
MapDecorator.setTilesetCanvasPageIdx = async function(idx,force=false){
|
||
var modeData = this.modeData;
|
||
var uiCache = this.modeUICache;
|
||
if(!modeData || !uiCache)return;
|
||
|
||
var name = modeData.tilesetNames[idx];
|
||
var tilesetNumber = modeData.tilesetNumbers[idx];
|
||
if(!name)return;
|
||
|
||
if(!force && MapDecorator.showingTilesetEditIdx===idx)return;
|
||
MapDecorator.showingTilesetEditIdx = idx;
|
||
|
||
modeData.locateXi = modeData.locateYi = -1;
|
||
modeData.locateDx = modeData.locateDy = 0;
|
||
uiCache.targetArea.visible = false;
|
||
|
||
_Dev.showText('tilesetEditOnSelect',null);
|
||
|
||
|
||
|
||
var src = ImageManager.loadTileset(name);
|
||
await new Promise(resolve=>src.addLoadListener(resolve));
|
||
|
||
var canvas = uiCache.canvas;
|
||
canvas.clear();
|
||
TRP_CORE.bltImage(canvas,src,0,0,Math.min(canvas.width,src.width),Math.min(canvas.height,src.height),0,0);
|
||
|
||
|
||
var usingScreen = uiCache.usingScreen;
|
||
usingScreen.clear();
|
||
|
||
var col = Math.ceil(src.width/tileW);
|
||
var row = Math.ceil(src.height/tileH);
|
||
|
||
var usingTileIds = modeData.usingTileIds;
|
||
var emptyPositionsArr = modeData.emptyPositionsArr;
|
||
var allEmptyPositionsArr = modeData.allEmptyPositionsArr;
|
||
var usingTilePositionsArr = modeData.usingTilePositionsArr;
|
||
if(!emptyPositionsArr[idx]){
|
||
/* analyze empty tile positions
|
||
===================================*/
|
||
var emptyPositions = emptyPositionsArr[idx] = [];
|
||
var allEmptyPositions = allEmptyPositionsArr[idx] = [];
|
||
var usingTilePositions = usingTilePositionsArr[idx] = [];
|
||
|
||
var width = src.width;
|
||
var height = src.height;
|
||
var imageData = src.context.getImageData(0,0,width,height);
|
||
var data = imageData.data;
|
||
var length = data.length;
|
||
for(var c=0; c<16; c=(c+1)|0){
|
||
for(var r=0; r<16; r=(r+1)|0){
|
||
var tileId = 256*(tilesetNumber-5)+128*Math.floor(c/8)+c%8+r*8;
|
||
// if(tileId)console.log(tileId);
|
||
if(tileId && usingTileIds.contains(tileId)){
|
||
usingTilePositions.push(c+r*16);
|
||
continue;
|
||
}
|
||
|
||
var baseX = c*tileW;
|
||
var baseY = r*tileH;
|
||
var baseIdx = (baseX + width*baseY);
|
||
var tileUsing = false;
|
||
// canvas.drawText(c+','+r,baseX,baseY,tileW,tileH)
|
||
|
||
for(var dx=0; dx<tileW; dx=(dx+1)|0){
|
||
if(baseX+dx >= width){
|
||
break;
|
||
}
|
||
for(var dy=0; dy<tileH; dy=(dy+1)|0){
|
||
if(baseY+dy >= height){
|
||
// if(stop)debugger;
|
||
break;
|
||
}
|
||
var i = baseIdx + (dx+width*dy);
|
||
if(data[4*i+3]>3){
|
||
tileUsing = true;
|
||
// usingScreen.beginFill(0xff0000,1)
|
||
// .drawRect(baseX+dx,baseY+dy,3,3);
|
||
break;
|
||
}
|
||
}
|
||
if(tileUsing)break;
|
||
}
|
||
if(!tileUsing){
|
||
emptyPositions.push(c+r*16);
|
||
}
|
||
}
|
||
}
|
||
|
||
var targetW = Math.ceil(uiCache.sprite.width/tileW);
|
||
var targetH = Math.ceil(uiCache.sprite.height/tileH);
|
||
for(var c=0; c<=16-targetW; c=(c+1)|0){
|
||
for(var r=0; r<=16-targetH; r=(r+1)|0){
|
||
var allEmpty = true;
|
||
for(var dx=0; dx<targetW; dx=(dx+1)|0){
|
||
for(var dy=0; dy<targetH; dy=(dy+1)|0){
|
||
if(!emptyPositions.contains(c+dx+(r+dy)*16)){
|
||
allEmpty = false;
|
||
break;
|
||
}
|
||
}
|
||
if(!allEmpty)break;
|
||
}
|
||
if(allEmpty){
|
||
allEmptyPositions.push(c+r*16);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
var emptyPositions = emptyPositionsArr[idx];
|
||
var usingTilePositions = usingTilePositionsArr[idx];
|
||
for(var c=0; c<row; c=(c+1)|0){
|
||
for(var r=0; r<col; r=(r+1)|0){
|
||
|
||
if(emptyPositions.contains(c+r*16))continue;
|
||
if(usingTilePositions.contains(c+r*16)){
|
||
usingScreen.beginFill(0xffff00,0.5)
|
||
.drawRect(c*tileW,r*tileH,tileW,tileH);
|
||
}else{
|
||
usingScreen.beginFill(0x000000,0.5)
|
||
.drawRect(c*tileW,r*tileH,tileW,tileH);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
//=============================================================================
|
||
// ParallaxSave
|
||
//=============================================================================
|
||
MapDecorator.saveAsParallaxMock = function(){
|
||
var visibles = [];
|
||
|
||
var spriteset = SceneManager._scene._spriteset;
|
||
var tilemap = spriteset._tilemap;
|
||
var canvasW = width*tileW;
|
||
var canvasH = height*tileH;
|
||
|
||
var saveData = {
|
||
displayX:$gameMap._displayX,
|
||
displayY:$gameMap._displayY,
|
||
mapData:$dataMap.data.concat(),
|
||
};
|
||
var dx = $gameMap._displayX*tileW;
|
||
var dy = $gameMap._displayY*tileH;
|
||
$gameMap._displayX = 0;
|
||
$gameMap._displayY = 0;
|
||
|
||
var tilemapSave = {
|
||
margin:tilemap._margin,
|
||
ox:tilemap.origin.x,
|
||
oy:tilemap.origin.y,
|
||
};
|
||
if(isMZ){
|
||
tilemapSave.width = tilemap.width;
|
||
tilemapSave.height = tilemap.height;
|
||
tilemap.width = canvasW;
|
||
tilemap.height = canvasH;
|
||
}else{
|
||
//MV -> ShaderTilmeap
|
||
tilemapSave.width = tilemap._width;
|
||
tilemapSave.height = tilemap._height;
|
||
tilemap._width = canvasW;
|
||
tilemap._height = canvasH;
|
||
}
|
||
tilemap._margin = 0;
|
||
tilemap.origin.x = 0;
|
||
tilemap.origin.y = 0;
|
||
|
||
tilemap._needsRepaint = true;
|
||
tilemap.updateTransform();
|
||
|
||
|
||
//clear shadows
|
||
for(var i=0; i<zLayerSize; i=(i+1)|0){
|
||
$dataMap.data[zLayerSize*4+i] = 0;
|
||
}
|
||
|
||
|
||
|
||
/* activate mapObjSprite
|
||
===================================*/
|
||
var dispX = 0;
|
||
var dispY = 0;
|
||
for(const obj of $dataTrpMapObjects){
|
||
var x = obj.x + obj.aX - dispX;
|
||
var y = obj.y + obj.aY - dispY;
|
||
if(!obj.sprite){
|
||
obj.setupSprite(spriteset);
|
||
}
|
||
var sprite = obj.sprite;
|
||
if(sprite.baseX!==x || sprite.baseY!==y){
|
||
sprite.setPosition(x,y);
|
||
}
|
||
}
|
||
|
||
|
||
for(var proc=0; proc<2; proc=(proc+1)|0){
|
||
//proc:[0=setVisibility, 1:restoreVisibility]
|
||
var nexts = [spriteset];
|
||
var currents = [];
|
||
while(nexts.length){
|
||
var temp = currents;
|
||
currents = nexts;
|
||
nexts = temp;
|
||
nexts.length = 0;
|
||
for(const parent of currents){
|
||
for(const child of parent.children){
|
||
if(child===tilemap){
|
||
nexts.push(child);
|
||
}else if(child===tilemap._lowerLayer||child===tilemap._upperLayer||child===tilemap.lowerZLayer||child===tilemap.upperZLayer){
|
||
//mainLayer -> ok
|
||
}else{
|
||
switch(child.constructor){
|
||
case PIXI.Container:
|
||
case TRP_CORE.TRP_Container:
|
||
//container -> ok
|
||
nexts.push(child);
|
||
break;
|
||
|
||
case TRP_CORE.MapObjectSprite:
|
||
//mapObj -> ok
|
||
break;
|
||
|
||
default:
|
||
nexts.push(child);
|
||
if(proc===0){
|
||
visibles.push(child.visible);
|
||
child.visible = false;
|
||
}else{
|
||
child.visible = visibles.shift();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if(proc===0){
|
||
//save mock image
|
||
var bitmap = TRP_CORE.snap(tilemap,canvasW,canvasH);
|
||
bitmap.fontSize = 32;
|
||
bitmap.outlineWidth = 6;
|
||
bitmap.drawText('モック表示中(遠景)',2,2,canvasW,Math.min(100,canvasH));
|
||
|
||
|
||
var imageName = TRP_CORE.MOCK_IMAGE_DIR+TRP_CORE.mapFileName().replace('.json','');
|
||
var imageFilePath = 'img/parallaxes/'+imageName+'.png';
|
||
_Dev.ensureDirectoriesWithFilePath(imageFilePath);
|
||
_Dev.saveCanvas(bitmap,imageFilePath);
|
||
|
||
//save mockMapData
|
||
_Dev.saveMapFile(undefined,undefined,true);
|
||
}
|
||
}
|
||
|
||
/* restore state
|
||
===================================*/
|
||
$gameMap._displayX = saveData.displayX;
|
||
$gameMap._displayY = saveData.displayY;
|
||
$dataMap.data = saveData.mapData;
|
||
|
||
if(isMZ){
|
||
tilemap.width = tilemapSave.width;;
|
||
tilemap.height = tilemapSave.height;
|
||
}else{
|
||
tilemap._width = tilemapSave.width;
|
||
tilemap._height = tilemapSave.height;
|
||
}
|
||
tilemap._margin = tilemapSave.margin;
|
||
tilemap.origin.x = tilemapSave.ox;
|
||
tilemap.origin.y = tilemapSave.oy;
|
||
tilemap._needsRepaint = true;
|
||
tilemap.updateTransform();
|
||
|
||
/* restore mapObj
|
||
===================================*/
|
||
for(const obj of $dataTrpMapObjects){
|
||
obj.update(spriteset,$gameMap._displayX,$gameMap._displayY)
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//================================================
|
||
// dev test func
|
||
//================================================
|
||
MapDecorator.devTest = function(){
|
||
if(!_Dev.inDev)return;
|
||
|
||
|
||
|
||
};
|
||
|
||
|
||
})(); |