Skip to content

Instantly share code, notes, and snippets.

@miahmie
Last active Jul 10, 2022
Embed
What would you like to do?
旧KAG3系の実装でもquakeが使いたい@吉里吉里Z

吉里吉里ZにはsetLayerPosが廃止されているので…

quakeタグが使えない,といっても割とどうとでもなります。 現に,

KAG3 for 吉里吉里Z や, 鱧入りKAG3 for 吉里吉里Z

では普通にquakeタグは使えるようになっています。(実際のところ揺らす先を変更しているだけ)

旧KAG3では fore.base がプライマリレイヤになっているので,上記のquake系の実装をそのまま移植することはできません。 直接 fore.base を揺らしてもいいのですが,スクリプト側でも座標を弄る可能性があるため,予期した動作にならないケースもありえます。 なので,間に揺らす用のレイヤを挟んで,プライマリレイヤを騙す方向で作ったのが下記スクリプトです。

御託はいいのでさっさと見せろ

はい,Override.tjs なんかに下記を追加してください。

/**
 * 吉里吉里Zで廃止されたWindow.setLayerPosの代替実装サンプル(Override定義)
 *
 * 実装概要:
 * KAG3の「fore.base=プライマリレイヤ」から脱却してQuake用の中間レイヤを作る
 *   Window
 *   +-primaryLayer(fore.baseより前に作ってしまう)
 *     +-floatingLayer (合わせて作る/これを動かすとfore.baseも動く=quake操作対象)
 *       +-fore.base
 *
 * 注意事項:
 * このスクリプトは吉里吉里2付属のKAG3系における「fore.base=プライマリレイヤ」の実装でしか機能しません
 * (※KAGEX系や吉里吉里Z向けのKAGの実装は最初から Window.setLayerPos を使用しない実装になっています)
 * 
 * また別のプラグイン(プライマリレイヤを操作する系統のもの)と相性が悪い可能性があります
 */

// BaseLayerのコンストラクタにフックをいれる
&BaseLayer.BaseLayer_ctor = &BaseLayer.BaseLayer; // 旧コンストラクタ
&BaseLayer.BaseLayer = function(win, par, *) {
	// fore.baseを作る場合に特殊処理を行いparを差し替える
	var hooked = (par === null);
	if (hooked) par = CreatePrimaryAndFloatingLayer(win);

	// 従来のコンストラクタを呼ぶ
	this.BaseLayer_ctor(win, par, *);

	// プライマリレイヤは暗黙でvisibleにされるため対処
	if (hooked) this.visible = true;
} incontextof null;

// BaseLayerコンストラクタのフック処理本体
function CreatePrimaryAndFloatingLayer(win) {
	// レイヤのサイズ(scWidth/scHeightを参照)
	var w = win.scWidth, h = win.scHeight;

	// レイヤ生成用ローカル関数
	var create = function (win, par, name, w, h, color=0xFF000000) {
		var lay = new global.Layer(win, par);
		win.add(lay);
		with (lay) {
			.name = name;
			.setImageSize(w, h);
			.setSizeToImageSize();
			.fillRect(0, 0, w, h, color);
			.type = ltOpaque; // or ltCoverRect;
			.visible = true;
		}
		return lay;
	};

	// プライマリレイヤを先に作ってしまう
	var prim = create(win, null, "*primary*", w, h);
	win.__primaryLayer = prim; // 念のため保存しておく

	// floatingLayerを作る
	var floating = create(win, prim, "*floating*", w, h);
	win.__floatingLayer = floating; // 参照用に保存しておく

	// setLayerPos 差し替え関数
	var setLayerPos = &floating.setPos; // 直でメソッドをコピーするのが単純で簡単だが...
//  (0)=コメントアウトのため無効 (1)=有効
@if (0)
	// 独自の関数の実装にしておくと特殊処理など入れられる
	// ↓例えばQuakeで揺れた外側が黒塗りだと寂しいのでダブリ画像を表示したりとか
	var setLayerPos = function (ox, oy) { 
		ox = int(ox), oy = int(oy); // 整数補正
		// はみ出る部分の短冊領域のみを 実際のprimaryLayer へ piledCopy する
		var copy = __primaryLayer.piledCopy, prim = primaryLayer/*==fore.base*/;
		var w=scWidth, h=scHeight, dx=(ox > 0 ? 0 : w+ox), dy=(oy > 0 ? 0 : h+oy), rx=(ox > 0 ? ox : 0);
		if (ox != 0) copy(dx,  0, prim, dx,  0, Math.abs(ox), h           );
		if (oy != 0) copy(rx, dy, prim, rx, dy, w-rx,         Math.abs(oy)); // rx:既にoxでpiledCopyされている領域を避ける調整
		// floatingLayerの位置をずらす(メインの処理)
		__floatingLayer.setPos(ox, oy);
	} incontextof win;
@endif

	// setLayerPos関数を差し替える
	&win.setLayerPos = setLayerPos;

	// primaryLayerプロパティを差し替える
	&win.primaryLayer = &KAGWindow_ForeBasePrimaryLayer incontextof win;

	// fore.base の親を差し替え
	return floating;
}

// KAGWindow.primaryLayer プロパティ差し替え(CreatePrimaryAndFloatingLayer内で差し替え処理)
property KAGWindow_ForeBasePrimaryLayer {
	getter {
		// 常に fore.base をプライマリレイヤのように振舞わせる
		return fore.base;
	}
} // incontextof kag


// Layer.isPrimary プロパティの差し替え(レイヤオブジェクト全体に適用)
property Layer_isPrimary {
	getter {
		// window.primaryLayerと等しいかどうかで判断させる
		return window.primaryLayer === this;
	}
}
// クラスにプロパティを追加する場合はcontextをnullにしておく
//(newしたときにnullコンテキストの場合にのみthisコンテキストへの変換がされるため)
&Layer.isPrimary = &Layer_isPrimary incontextof null;

諸注意など

このスクリプトは無保証です。色々書き替える都合,他の特殊なプラグインなどと相性問題がある可能性があります。 一応軽く動作確認はしてありますが,実際にうまく動作しなくても怒らないで頑張って自分で解決してください…。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment