/
DarkPlasma_SubtractMode.js
171 lines (154 loc) · 6.24 KB
/
DarkPlasma_SubtractMode.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// DarkPlasma_SubtractMode
// Copyright (c) 2020 DarkPlasma
// This software is released under the MIT license.
// http://opensource.org/licenses/mit-license.php
/**
* 2020/03/15 1.0.2 canvasモードでエラーになる不具合を修正
* 1.0.1 2回動的に減算モードにすると減算から戻せなくなる不具合を修正
* ピクチャ表示前に動的に減算モードにしようとするとエラーになる不具合を修正
* 1.0.0 公開
*/
/*:
* @plugindesc ピクチャを減算モードで合成するプラグイン
* @author DarkPlasma
* @license MIT
*
* @param Subtract Mode Switch
* @desc 減算モードで合成するスイッチ
* @text 減算モードスイッチ
* @type switch
* @default 1
*
* @param Always Subtract Mode Picture Ids
* @desc 常に減算モードで合成するピクチャID
* @text 常時減算合成するピクチャID
* @type number[]
* @default []
*
* @help
* ピクチャの表示/移動において、減算合成をサポートします。
*
* 減算モードスイッチがONであるような間に実行されるピクチャの表示/ピクチャの移動は
* 常に合成方法「減算」で合成されます。
*
* また、動的に合成方法を減算にしたり減算でなくしたりしたい場合には、
* 以下のプラグインコマンドをご利用ください。
*
* addSubtractPictureId X
* Xで指定したIDのピクチャについて、合成モードを減算にします。
*
* removeSubtractPictureId X
* Xで指定したIDのピクチャについて、合成モードを減算でなくします。
*
* 注意:
* - MakeScreenCapture.js には対応していません。
* - 減算合成はWebGLモードで実行される場合のみ有効です。
*/
(function () {
'use strict';
const pluginName = document.currentScript.src.replace(/^.*\/(.*).js$/, function () {
return arguments[1];
});
const pluginParameters = PluginManager.parameters(pluginName);
const settings = {
subtractModeSwitch: Number(pluginParameters['Subtract Mode Switch'] || 1),
subtractPictureIds: JSON.parse(pluginParameters['Always Subtract Mode Picture Ids'] || '[]').map(param => Number(param))
};
const BLEND_MODES = {
SUBTRACT: 28
};
const _Graphics_createRenderer = Graphics._createRenderer;
Graphics._createRenderer = function () {
_Graphics_createRenderer.call(this);
if (this.isWebGL()) {
this._renderer.state.blendModes[BLEND_MODES.SUBTRACT] = [
this._renderer.gl.ZERO,
this._renderer.gl.ONE_MINUS_SRC_COLOR
];
} else {
// Canvasモードでは減算は使えない
this._renderer.blendModes[BLEND_MODES.SUBTRACT] = 'source-over';
}
};
Game_Picture.prototype.subtractMode = function () {
if (this._blendMode !== BLEND_MODES.SUBTRACT) {
this._originalBlendMode = this._blendMode;
this._blendMode = BLEND_MODES.SUBTRACT;
}
};
Game_Picture.prototype.backFromSubtractMode = function () {
if (this._originalBlendMode) {
this._blendMode = this._originalBlendMode;
} else {
// 元の状態が失われていたら通常モード
this._blendMode = Graphics.BLEND_NORMAL;
}
};
const _Game_Screen_clear = Game_Screen.prototype.clear;
Game_Screen.prototype.clear = function () {
_Game_Screen_clear.call(this);
this.clearDynamicSubtractPictureIds();
};
Game_Screen.prototype.addDynamicSubtractPicture = function (pictureId) {
if (!this._dynamicSubtractPictureIds) {
this._dynamicSubtractPictureIds = [];
}
this._dynamicSubtractPictureIds.push(pictureId);
};
Game_Screen.prototype.removeDynamicSubtractPicture = function (pictureId) {
this._dynamicSubtractPictureIds = this._dynamicSubtractPictureIds.filter(id => id !== pictureId);
};
Game_Screen.prototype.clearDynamicSubtractPictureIds = function () {
this._dynamicSubtractPictureIds = [];
};
Game_Screen.prototype.isDynamicSubtractPicture = function (pictureId) {
return this._dynamicSubtractPictureIds && this._dynamicSubtractPictureIds.includes(pictureId);
};
Game_Screen.prototype.isSubtractMode = function (pictureId) {
return settings.subtractPictureIds.includes(pictureId) ||
this.isDynamicSubtractPicture(pictureId) ||
$gameSwitches.value(settings.subtractModeSwitch);
};
const _Game_Screen_showPicture = Game_Screen.prototype.showPicture;
Game_Screen.prototype.showPicture = function (pictureId, name, origin, x, y, scaleX, scaleY, opacity, blendMode) {
if (this.isSubtractMode(pictureId) && blendMode !== BLEND_MODES.SUBTRACT) {
this.showPicture(pictureId, name, origin, x, y, scaleX, scaleY, opacity, BLEND_MODES.SUBTRACT);
} else {
_Game_Screen_showPicture.call(this, pictureId, name, origin, x, y, scaleX, scaleY, opacity, blendMode);
}
};
const _Game_Screen_movePicture = Game_Screen.prototype.movePicture;
Game_Screen.prototype.movePicture = function (pictureId, origin, x, y, scaleX, scaleY, opacity, blendMode, duration) {
if (this.isSubtractMode(pictureId) && blendMode !== BLEND_MODES.SUBTRACT) {
this.movePicture(pictureId, origin, x, y, scaleX, scaleY, opacity, BLEND_MODES.SUBTRACT, duration);
} else {
_Game_Screen_movePicture.call(this, pictureId, origin, x, y, scaleX, scaleY, opacity, blendMode, duration);
}
};
const _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function (command, args) {
_Game_Interpreter_pluginCommand.call(this, command, args);
switch ((command || '')) {
case 'addSubtractPictureId':
if (args.length > 0) {
const pictureId = Number(args[0]);
$gameScreen.addDynamicSubtractPicture(pictureId);
const picture = $gameScreen.picture(pictureId);
if (picture) {
picture.subtractMode();
}
}
break;
case 'removeSubtractPictureId':
if (args.length > 0) {
const pictureId = Number(args[0]);
$gameScreen.removeDynamicSubtractPicture(pictureId);
const picture = $gameScreen.picture(pictureId);
if (picture) {
picture.backFromSubtractMode();
}
}
break;
}
};
})();