mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-12-27 23:46:56 +01:00
522 lines
No EOL
17 KiB
Text
522 lines
No EOL
17 KiB
Text
function tiler_rule_replacement(_index) constructor {
|
|
index = _index;
|
|
}
|
|
|
|
function tiler_rule() constructor {
|
|
name = "rule";
|
|
open = false;
|
|
active = true;
|
|
|
|
range = 1;
|
|
size = [ 1, 1 ];
|
|
scanSize = [ 1, 1 ];
|
|
probability = 100;
|
|
_probability = 1;
|
|
|
|
selection_rules = array_create(9, -1);
|
|
selection_rules[4] = -10000;
|
|
replacements = [];
|
|
|
|
sl_prop = new textBox(TEXTBOX_INPUT.number, function(v) /*=>*/ { probability = v; })
|
|
.setSlideRange(0, 100);
|
|
sl_prop.suffix = "%";
|
|
sl_prop.font = f_p3;
|
|
|
|
__aut = [];
|
|
__sel = [];
|
|
|
|
static shader_select = function(tileset) {
|
|
var _sw = size[0] + range * 2;
|
|
var _sh = size[1] + range * 2;
|
|
|
|
selection_rules = array_verify_ext(selection_rules, _sw * _sh, function() /*=>*/ {return -1} );
|
|
|
|
__aut = [];
|
|
__sel = [];
|
|
var autI = [];
|
|
var minX = 999, maxX = 0;
|
|
var minY = 999, maxY = 0;
|
|
|
|
// print($"{size}, {range}")
|
|
|
|
for( var i = 0, n = array_length(selection_rules); i < n; i++ ) {
|
|
var _s = selection_rules[i];
|
|
var _r = floor(i / _sw);
|
|
var _c = i % _sw;
|
|
|
|
if(_s != -1 && (_r < range || _r >= size[1] + range || _c < range || _c >= size[0] + range)) {
|
|
minX = min(minX, _c);
|
|
maxX = max(maxX, _c);
|
|
minY = min(minY, _r);
|
|
maxY = max(maxY, _r);
|
|
|
|
// print($"{_s}: {_c}, {_r}");
|
|
}
|
|
|
|
if(is_array(_s)) {
|
|
var _auI = _s[1];
|
|
array_push(__sel, 10000 + _auI);
|
|
array_push(autI, _auI);
|
|
} else
|
|
array_push(__sel, _s);
|
|
}
|
|
|
|
scanSize = minX < maxX? [ max(1, maxX - minX + 1), max(1, maxY - minY + 1) ] : size;
|
|
// print($"{maxX}, {minX} | {maxY}, {minY} | {scanSize}");
|
|
|
|
autI = array_unique(autI);
|
|
for( var i = 0, n = array_length(autI); i < n; i++ ) {
|
|
var _i = autI[i];
|
|
var _t = array_safe_get(tileset.autoterrain, _i, noone);
|
|
if(_t == noone) continue;
|
|
|
|
var _ind = 64 * i;
|
|
__aut[_ind] = array_length(_t.index);
|
|
for( var j = 0, m = array_length(_t.index); j < m; j++ )
|
|
__aut[_ind + 1 + j] = _t.index[j];
|
|
}
|
|
|
|
var _selu = array_unique(__sel);
|
|
|
|
shader_set_f("selection", _selu);
|
|
shader_set_i("selectionSize", array_length(_selu));
|
|
shader_set_f("selectionGroup", __aut);
|
|
|
|
}
|
|
|
|
static shader_submit = function(tileset) {
|
|
shader_set_i("range", range);
|
|
shader_set_f("size", size);
|
|
shader_set_f("scanSize", scanSize);
|
|
shader_set_f("probability", probability / 100);
|
|
|
|
shader_set_f("selection", __sel);
|
|
shader_set_f("selectionGroup", __aut);
|
|
|
|
var rep = [];
|
|
var rsz = size[0] * size[1];
|
|
|
|
for( var i = 0, n = array_length(replacements); i < n; i++ ) {
|
|
var _r = replacements[i];
|
|
_r.index = array_verify_ext(_r.index, rsz, function() /*=>*/ {return -1} );
|
|
array_append(rep, _r.index);
|
|
}
|
|
|
|
// print($"selection: {__sel}");
|
|
// print($"selectGroup: {__aut}\n");
|
|
|
|
shader_set_f("replacements", rep);
|
|
shader_set_i("replacementCount", array_length(replacements));
|
|
}
|
|
|
|
static deserialize = function(_struct) {
|
|
name = struct_try_get(_struct, "name", name);
|
|
size = struct_try_get(_struct, "size", size);
|
|
range = struct_try_get(_struct, "range", range);
|
|
active = struct_try_get(_struct, "active", active);
|
|
|
|
selection_rules = struct_try_get(_struct, "selection_rules", selection_rules);
|
|
probability = struct_try_get(_struct, "probability", probability);
|
|
|
|
var _rep = struct_try_get(_struct, "replacements", noone);
|
|
if(_rep != noone) {
|
|
for( var i = 0, n = array_length(_rep); i < n; i++ )
|
|
replacements[i] = new tiler_rule_replacement(_rep[i].index);
|
|
}
|
|
|
|
return self;
|
|
}
|
|
}
|
|
|
|
function Tileset_Rule(_tileset) : Inspector_Custom_Renderer(noone, noone) constructor {
|
|
name = "Tile Riles";
|
|
tileset = _tileset;
|
|
ruleTiles = [];
|
|
|
|
rule_dragging = noone;
|
|
rule_selector_h = 0;
|
|
|
|
renaming = noone;
|
|
rename_text = "";
|
|
tb_rename = new textBox(TEXTBOX_INPUT.text, function(_name) {
|
|
if(renaming == noone) return;
|
|
renaming.name = _name;
|
|
renaming = noone;
|
|
});
|
|
tb_rename.font = f_p2;
|
|
tb_rename.hide = true;
|
|
|
|
temp_surface = [ noone, noone, noone ];
|
|
|
|
function setTileset(_tileset) { tileset = _tileset; return self; }
|
|
|
|
function draw(_x, _y, _w, _m, _hover, _focus, _panel = noone) {
|
|
var _yy = _y;
|
|
var _h = 0;
|
|
|
|
if(tileset == noone) return _h;
|
|
|
|
var _tileSet = tileset.texture;
|
|
var _tileSiz = tileset.tileSize;
|
|
|
|
if(!is_surface(_tileSet)) return _h;
|
|
var _tdim = surface_get_dimension(_tileSet);
|
|
var _tileAmo = [ floor(_tdim[0] / _tileSiz[0]), floor(_tdim[1] / _tileSiz[1]) ];
|
|
|
|
var bx = _x;
|
|
var by = _yy;
|
|
var bs = ui(24);
|
|
|
|
if(buttonInstant(THEME.button_hide, bx, by, bs, bs, _m, _focus, _hover, "New rule", THEME.add_16, 0, COLORS._main_value_positive) == 2) {
|
|
var _new_rl = new tiler_rule();
|
|
_new_rl.name = $"rule {array_length(ruleTiles)}"
|
|
_new_rl.open = true;
|
|
array_push(ruleTiles, _new_rl);
|
|
tileset.triggerRender();
|
|
}
|
|
|
|
_h += bs + ui(4);
|
|
_yy += bs + ui(4);
|
|
|
|
var _pd = ui(4);
|
|
var _ah = _pd * 2;
|
|
var del = -1;
|
|
var rl_iHover = 0;
|
|
|
|
draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, _x, _yy, _w, rule_selector_h, COLORS.node_composite_bg_blend, 1);
|
|
|
|
_yy += _pd;
|
|
|
|
for( var i = 0, n = array_length(ruleTiles); i < n; i++ ) {
|
|
var _hg = ui(32);
|
|
var _rl = ruleTiles[i];
|
|
|
|
var _pw = ui(24);
|
|
var _ph = ui(24);
|
|
var _px = _x + ui(8);
|
|
var _py = _yy + ui(4);
|
|
|
|
if(_m[1] > _yy) rl_iHover = i;
|
|
|
|
var _prin = array_safe_get(_rl.replacements, 0, undefined);
|
|
|
|
if(_prin == undefined)
|
|
draw_sprite_stretched_ext(THEME.ui_panel, 1, _px, _py, _pw, _ph, COLORS._main_icon);
|
|
else if(is(_prin, tiler_rule_replacement)) {
|
|
var _ind = array_safe_get(_prin.index, 0);
|
|
tileset.drawTile(_ind, _px, _py, _pw, _ph);
|
|
}
|
|
|
|
var _tx = _px + _pw + ui(8);
|
|
var _hov = _hover && point_in_rectangle(_m[0], _m[1], _x, _yy, _x + _w, _yy + _hg - 1);
|
|
|
|
if(renaming == _rl) {
|
|
tb_rename.setFocusHover(_focus, _hover);
|
|
tb_rename.draw(_tx, _yy, _w - _pw - ui(8), _hg, rename_text, _m);
|
|
|
|
} else {
|
|
var _cc = _hov? COLORS._main_text : COLORS._main_text_sub;
|
|
if(rule_dragging == _rl) _cc = COLORS._main_accent;
|
|
|
|
draw_set_text(f_p2, fa_left, fa_center, _cc);
|
|
draw_text_add(_tx, _yy + _hg / 2, _rl.name);
|
|
|
|
var bs = ui(24);
|
|
var bx = _w - bs - ui(4);
|
|
var by = _yy + _hg / 2 - bs / 2;
|
|
if(buttonInstant(THEME.button_hide, bx, by, bs, bs, _m, _focus, _hover, "", THEME.minus_16, 0, _hov? COLORS._main_value_negative : COLORS._main_icon) == 2)
|
|
del = i;
|
|
}
|
|
|
|
if(_hov && _m[0] < _x + _w - ui(32 + 160)) {
|
|
if(_m[0] > _tx) {
|
|
|
|
if(DOUBLE_CLICK && _focus) {
|
|
renaming = _rl;
|
|
rename_text = _rl.name;
|
|
|
|
tb_rename._current_text = _rl.name;
|
|
tb_rename.activate();
|
|
|
|
} else if(mouse_press(mb_left, _focus)) {
|
|
rule_dragging = _rl;
|
|
}
|
|
|
|
} else {
|
|
draw_sprite_stretched_ext(THEME.ui_panel, 1, _px, _py, _pw, _ph, COLORS._main_accent);
|
|
|
|
if(mouse_press(mb_left, _focus))
|
|
_rl.open = !_rl.open;
|
|
}
|
|
}
|
|
|
|
var _atWid = _rl.sl_prop;
|
|
var _scw = ui(120);
|
|
var _sch = ui(20);
|
|
var _scx = _x + _w - _scw - ui(32 + 8);
|
|
var _scy = _yy + _hg / 2 - _sch / 2;
|
|
|
|
_atWid.setFocusHover(_focus, _hover);
|
|
_atWid.rx = rx;
|
|
_atWid.ry = ry;
|
|
_atWid.draw(_scx, _scy, _scw, _sch, _rl.probability, _m);
|
|
if(_rl.probability != _rl._probability) {
|
|
_rl._probability = _rl.probability;
|
|
tileset.triggerRender();
|
|
}
|
|
|
|
var _acw = ui(20);
|
|
var _ach = ui(20);
|
|
var _acx = _scx - _acw - ui(8);
|
|
var _acy = _yy + _hg / 2 - _sch / 2;
|
|
var _ahv = _hover && point_in_rectangle(_m[0], _m[1], _acx, _acy, _acx + _acw, _acy + _ach);
|
|
|
|
if(_ahv) {
|
|
TOOLTIP = "Active";
|
|
if(mouse_press(mb_left, _focus)) {
|
|
_rl.active = !_rl.active;
|
|
tileset.triggerRender();
|
|
}
|
|
}
|
|
|
|
draw_sprite_stretched_ext(THEME.checkbox_def, _ahv, _acx, _acy, _acw, _ach, c_white);
|
|
if(_rl.active) draw_sprite_stretched_ext(THEME.checkbox_def, 2, _acx, _acy, _acw, _ach, COLORS._main_accent);
|
|
|
|
_yy += _hg;
|
|
_ah += _hg;
|
|
|
|
if(_rl.open) {
|
|
_yy += ui(4);
|
|
_ah += ui(4);
|
|
|
|
var _sls = ui(28);
|
|
|
|
var _rep = _rl.replacements;
|
|
var _siz = _rl.size;
|
|
|
|
var _rpw = _sls * _siz[0];
|
|
var _rph = _sls * _siz[1];
|
|
|
|
var _radw = _rl.size[0] + _rl.range * 2;
|
|
var _radh = _rl.size[1] + _rl.range * 2;
|
|
var _slw = ui(16) + _radw * _sls;
|
|
var _slh = ui(16) + _radh * _sls;
|
|
var _hh0 = _slh;
|
|
|
|
var _dx = ui(8) + _slw + ui(16);
|
|
var _nln = (_rpw + ui(4)) * 2 > _w - _dx - ui(24);
|
|
var _sx = _x + ui(8);
|
|
|
|
if(_nln) {
|
|
_sx = _w / 2 - _slw / 2 + ui(4);
|
|
_slw = _w - ui(16);
|
|
}
|
|
|
|
draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, _x + ui(8), _yy, _slw, _slh, COLORS.node_composite_bg_blend, 1);
|
|
|
|
for( var j = 0, m = array_length(_rl.selection_rules); j < m; j++ ) {
|
|
var _rl_sel = _rl.selection_rules[j];
|
|
var _rl_col = j % _radw;
|
|
var _rl_row = floor(j / _radw);
|
|
|
|
var _cen = _rl_col >= _rl.range && _rl_col < _rl.range + _rl.size[0] &&
|
|
_rl_row >= _rl.range && _rl_row < _rl.range + _rl.size[1];
|
|
|
|
var _rl_x = _sx + ui(8) + _rl_col * _sls;
|
|
var _rl_y = _yy + ui(8) + _rl_row * _sls;
|
|
|
|
var _rl_selected = tileset.object_selecting == _rl && tileset.object_select_id == j;
|
|
var _rl_hov = _hover && point_in_rectangle(_m[0], _m[1], _rl_x, _rl_y, _rl_x + _sls - 1, _rl_y + _sls - 1);
|
|
var _pad = ui(2);
|
|
|
|
var _cc = _rl_selected? COLORS._main_accent : COLORS._main_icon;
|
|
var _aa = _rl_selected? 1 : .5 + _rl_hov * .5;
|
|
|
|
if(is_array(_rl_sel)) {
|
|
var _autt = array_safe_get(tileset.autoterrain, _rl_sel[1], noone);
|
|
|
|
tileset.drawTile(_autt == noone? 0 : _autt.index[0], _rl_x + ui(2), _rl_y + ui(2), _sls - ui(4), _sls - ui(4));
|
|
draw_sprite_uniform(THEME.circle, 0, _rl_x + _sls - ui(8), _rl_y + _sls - ui(8), 1, COLORS._main_accent);
|
|
|
|
} else if (_rl_sel == -10000) {
|
|
draw_sprite_uniform(THEME.cross, 0, _rl_x + _sls / 2, _rl_y + _sls / 2, 1, _cc, _aa);
|
|
|
|
} else if(_rl_sel != -1) {
|
|
tileset.drawTile(_rl_sel, _rl_x + ui(2), _rl_y + ui(2), _sls - ui(4), _sls - ui(4));
|
|
|
|
} else if(!_cen) _pad = ui(10);
|
|
|
|
draw_sprite_stretched_ext(THEME.ui_panel, 1 + _cen, _rl_x + _pad, _rl_y + _pad, _sls - _pad * 2, _sls - _pad * 2, _cc, _aa);
|
|
|
|
if(_rl_hov) {
|
|
if(mouse_press(mb_left, _focus)) {
|
|
tileset.object_selecting = _rl_selected? noone : _rl;
|
|
tileset.object_select_id = j;
|
|
tileset.triggerRender();
|
|
}
|
|
|
|
if(mouse_press(mb_right, _focus)) {
|
|
_rl.selection_rules[j] = -1;
|
|
tileset.object_selecting = noone;
|
|
tileset.object_select_id = noone;
|
|
tileset.triggerRender();
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var _rx, _rpww;
|
|
|
|
if(_nln) {
|
|
_rx = _x + ui(8);
|
|
_rpww = _w - ui(16);
|
|
_hh0 = 0;
|
|
|
|
_yy += _slh + ui(8);
|
|
_ah += _slh + ui(8);
|
|
|
|
draw_sprite_uniform(THEME.arrow, 3, _x + _w / 2, _yy + ui(2), 1, COLORS._main_icon, 1);
|
|
|
|
_yy += ui(8);
|
|
_ah += ui(8);
|
|
|
|
} else {
|
|
_rx = _x + _dx;
|
|
_rpww = _w - _dx - ui(8);
|
|
|
|
draw_sprite_uniform(THEME.arrow, 0, _rx - ui(8), _yy + _slh / 2, 1, COLORS._main_icon, 1);
|
|
}
|
|
|
|
var _col = max(1, floor((_rpww - ui(16)) / (_rpw + ui(4))));
|
|
var _row = ceil((array_length(_rep) + 1) / _col);
|
|
var _rphh = ui(16) + _row * _rph;
|
|
|
|
draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, _rx, _yy, _rpww, max(_hh0, _rphh), COLORS.node_composite_bg_blend, 1);
|
|
|
|
var del_rep = -1;
|
|
|
|
for( var j = 0, m = array_length(_rep) + 1; j < m; j++ ) {
|
|
var _rcl = j % _col;
|
|
var _rrw = floor(j / _col);
|
|
|
|
var _rpx = _rx + ui(8) + _rcl * (_rpw + ui(4));
|
|
var _rpy = _yy + ui(8) + _rrw * _rph;
|
|
var _rl_hov = _hover && point_in_rectangle(_m[0], _m[1], _rpx, _rpy, _rpx + _rpw, _rpy + _rph);
|
|
|
|
if(j == 0) {
|
|
var _cc = _rl_hov? COLORS._main_value_positive : COLORS._main_icon;
|
|
draw_sprite_uniform(THEME.add_16, 0, _rpx + _rpw / 2, _rpy + _rph / 2, 1, _cc);
|
|
|
|
if(_rl_hov && mouse_press(mb_left, _focus)) {
|
|
var _new_rep = new tiler_rule_replacement([-1]);
|
|
array_push(_rl.replacements, _new_rep);
|
|
tileset.object_selecting = _new_rep;
|
|
tileset.object_select_id = _rl;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
var _replace = _rep[j - 1];
|
|
var _repIndex = _replace.index;
|
|
if(!is_array(_repIndex)) continue;
|
|
|
|
for( var k = 0, q = array_length(_repIndex); k < q; k++ ) {
|
|
var _repBlockCol = k % _siz[0];
|
|
var _repBlockRow = floor(k / _siz[0]);
|
|
var _rpbx = _rpx + _repBlockCol * _sls;
|
|
var _rpby = _rpy + _repBlockRow * _sls;
|
|
|
|
if(_replace.index[k] != -1) tileset.drawTile(_replace.index[k], _rpbx, _rpby, _sls, _sls);
|
|
}
|
|
|
|
var _rl_selected = tileset.object_selecting == _replace;
|
|
var _cc = _rl_selected? COLORS._main_accent : COLORS._main_icon;
|
|
var _aa = _rl_selected? 1 : .5 + _rl_hov * .5;
|
|
draw_sprite_stretched_ext(THEME.ui_panel, 1, _rpx, _rpy, _rpw, _rph, _cc, _aa);
|
|
|
|
if(_rl_hov) {
|
|
if(mouse_press(mb_left, _focus)) {
|
|
tileset.object_selecting = tileset.object_selecting == _replace? noone : _replace;
|
|
tileset.object_select_id = _rl;
|
|
tileset.triggerRender();
|
|
}
|
|
|
|
if(mouse_press(mb_right, _focus))
|
|
del_rep = j - 1;
|
|
}
|
|
}
|
|
|
|
if(del_rep != -1) {
|
|
array_delete(_rep, del_rep, 1);
|
|
tileset.triggerRender();
|
|
}
|
|
|
|
_yy += max(_hh0, _rphh) + ui(8);
|
|
_ah += max(_hh0, _rphh) + ui(8);
|
|
|
|
}
|
|
}
|
|
|
|
if(rule_dragging != noone) {
|
|
array_remove(ruleTiles, rule_dragging);
|
|
array_insert(ruleTiles, rl_iHover, rule_dragging);
|
|
|
|
if(mouse_release(mb_left)) {
|
|
rule_dragging = noone;
|
|
tileset.triggerRender();
|
|
}
|
|
}
|
|
|
|
if(del != -1) {
|
|
array_delete(ruleTiles, del, 1);
|
|
tileset.triggerRender();
|
|
}
|
|
|
|
rule_selector_h = max(ui(12), _ah);
|
|
return _h + _ah;
|
|
}
|
|
|
|
function apply(_tilemap, _seed) {
|
|
var _mapSize = surface_get_dimension(_tilemap);
|
|
temp_surface[0] = surface_verify(temp_surface[0], _mapSize[0], _mapSize[1], surface_rgba16float);
|
|
temp_surface[1] = surface_verify(temp_surface[1], _mapSize[0], _mapSize[1], surface_rgba16float);
|
|
temp_surface[2] = surface_verify(temp_surface[2], _mapSize[0], _mapSize[1], surface_r16float);
|
|
|
|
var bg = 0;
|
|
surface_set_shader(temp_surface[1], noone, true, BLEND.over);
|
|
draw_surface(_tilemap, 0, 0);
|
|
surface_reset_shader();
|
|
|
|
for( var i = 0, n = array_length(ruleTiles); i < n; i++ ) {
|
|
var _rule = ruleTiles[i];
|
|
|
|
if(!_rule.active) continue;
|
|
if(array_empty(_rule.replacements)) continue;
|
|
|
|
surface_set_shader(temp_surface[2], sh_tile_rule_select, true, BLEND.over);
|
|
shader_set_2("dimension", _mapSize);
|
|
_rule.shader_select(tileset);
|
|
|
|
draw_surface(_tilemap, 0, 0);
|
|
surface_reset_shader();
|
|
|
|
surface_set_shader(temp_surface[bg], sh_tile_rule_apply, true, BLEND.over);
|
|
shader_set_2("dimension", _mapSize);
|
|
shader_set_f("seed", _seed);
|
|
shader_set_surface("group", temp_surface[2]);
|
|
_rule.shader_submit(tileset);
|
|
|
|
draw_surface(temp_surface[!bg], 0, 0);
|
|
surface_reset_shader();
|
|
|
|
bg = !bg;
|
|
}
|
|
|
|
surface_set_shader(_tilemap, noone, true, BLEND.over);
|
|
draw_surface(temp_surface[!bg], 0, 0);
|
|
surface_reset_shader();
|
|
|
|
return _tilemap;
|
|
}
|
|
} |