Merge pull request #27565 from SpechtMagnus/tileset_autotile_ignore_flags

Added ignore flag / wildcard bit to tileset autotile
This commit is contained in:
Rémi Verschelde 2019-04-08 10:04:30 +02:00 committed by GitHub
commit de33c37196
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 120 additions and 49 deletions

View File

@ -481,10 +481,10 @@ void TileMapEditor::_update_palette() {
if (sel_tile != TileMap::INVALID_CELL) { if (sel_tile != TileMap::INVALID_CELL) {
if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE) { if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE) {
const Map<Vector2, uint16_t> &tiles2 = tileset->autotile_get_bitmask_map(sel_tile); const Map<Vector2, uint32_t> &tiles2 = tileset->autotile_get_bitmask_map(sel_tile);
Vector<Vector2> entries2; Vector<Vector2> entries2;
for (const Map<Vector2, uint16_t>::Element *E = tiles2.front(); E; E = E->next()) { for (const Map<Vector2, uint32_t>::Element *E = tiles2.front(); E; E = E->next()) {
entries2.push_back(E->key()); entries2.push_back(E->key());
} }
entries2.sort(); entries2.sort();

View File

@ -734,7 +734,7 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
tools[SHAPE_KEEP_INSIDE_TILE]->hide(); tools[SHAPE_KEEP_INSIDE_TILE]->hide();
tools[TOOL_SELECT]->set_pressed(true); tools[TOOL_SELECT]->set_pressed(true);
tools[TOOL_SELECT]->set_tooltip(TTR("LMB: Set bit on.\nRMB: Set bit off.\nClick on another Tile to edit it.")); tools[TOOL_SELECT]->set_tooltip(TTR("LMB: Set bit on.\nRMB: Set bit off.\nShift+LMB: Set wildcard bit.\nClick on another Tile to edit it."));
spin_priority->hide(); spin_priority->hide();
} break; } break;
case EDITMODE_Z_INDEX: case EDITMODE_Z_INDEX:
@ -818,52 +818,92 @@ void TileSetEditor::_on_workspace_draw() {
} break; } break;
case EDITMODE_BITMASK: { case EDITMODE_BITMASK: {
Color c(1, 0, 0, 0.5); Color c(1, 0, 0, 0.5);
Color ci(0.3, 0.6, 1, 0.5);
for (float x = 0; x < region.size.x / (spacing + size.x); x++) { for (float x = 0; x < region.size.x / (spacing + size.x); x++) {
for (float y = 0; y < region.size.y / (spacing + size.y); y++) { for (float y = 0; y < region.size.y / (spacing + size.y); y++) {
Vector2 coord(x, y); Vector2 coord(x, y);
Point2 anchor(coord.x * (spacing + size.x), coord.y * (spacing + size.y)); Point2 anchor(coord.x * (spacing + size.x), coord.y * (spacing + size.y));
anchor += WORKSPACE_MARGIN; anchor += WORKSPACE_MARGIN;
anchor += region.position; anchor += region.position;
uint16_t mask = tileset->autotile_get_bitmask(get_current_tile(), coord); uint32_t mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
if (tileset->autotile_get_bitmask_mode(get_current_tile()) == TileSet::BITMASK_2X2) { if (tileset->autotile_get_bitmask_mode(get_current_tile()) == TileSet::BITMASK_2X2) {
if (mask & TileSet::BIND_TOPLEFT) { if (mask & TileSet::BIND_IGNORE_TOPLEFT) {
workspace->draw_rect(Rect2(anchor, size / 4), ci);
workspace->draw_rect(Rect2(anchor + size / 4, size / 4), ci);
} else if (mask & TileSet::BIND_TOPLEFT) {
workspace->draw_rect(Rect2(anchor, size / 2), c); workspace->draw_rect(Rect2(anchor, size / 2), c);
} }
if (mask & TileSet::BIND_TOPRIGHT) { if (mask & TileSet::BIND_IGNORE_TOPRIGHT) {
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 2, 0), size / 4), ci);
workspace->draw_rect(Rect2(anchor + Vector2(size.x * 3 / 4, size.y / 4), size / 4), ci);
} else if (mask & TileSet::BIND_TOPRIGHT) {
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 2, 0), size / 2), c); workspace->draw_rect(Rect2(anchor + Vector2(size.x / 2, 0), size / 2), c);
} }
if (mask & TileSet::BIND_BOTTOMLEFT) { if (mask & TileSet::BIND_IGNORE_BOTTOMLEFT) {
workspace->draw_rect(Rect2(anchor + Vector2(0, size.y / 2), size / 4), ci);
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 4, size.y * 3 / 4), size / 4), ci);
} else if (mask & TileSet::BIND_BOTTOMLEFT) {
workspace->draw_rect(Rect2(anchor + Vector2(0, size.y / 2), size / 2), c); workspace->draw_rect(Rect2(anchor + Vector2(0, size.y / 2), size / 2), c);
} }
if (mask & TileSet::BIND_BOTTOMRIGHT) { if (mask & TileSet::BIND_IGNORE_BOTTOMRIGHT) {
workspace->draw_rect(Rect2(anchor + size / 2, size / 4), ci);
workspace->draw_rect(Rect2(anchor + size * 3 / 4, size / 4), ci);
} else if (mask & TileSet::BIND_BOTTOMRIGHT) {
workspace->draw_rect(Rect2(anchor + size / 2, size / 2), c); workspace->draw_rect(Rect2(anchor + size / 2, size / 2), c);
} }
} else { } else {
if (mask & TileSet::BIND_TOPLEFT) { if (mask & TileSet::BIND_IGNORE_TOPLEFT) {
workspace->draw_rect(Rect2(anchor, size / 6), ci);
workspace->draw_rect(Rect2(anchor + size / 6, size / 6), ci);
} else if (mask & TileSet::BIND_TOPLEFT) {
workspace->draw_rect(Rect2(anchor, size / 3), c); workspace->draw_rect(Rect2(anchor, size / 3), c);
} }
if (mask & TileSet::BIND_TOP) { if (mask & TileSet::BIND_IGNORE_TOP) {
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 3, 0), size / 6), ci);
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 2, size.y / 6), size / 6), ci);
} else if (mask & TileSet::BIND_TOP) {
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 3, 0), size / 3), c); workspace->draw_rect(Rect2(anchor + Vector2(size.x / 3, 0), size / 3), c);
} }
if (mask & TileSet::BIND_TOPRIGHT) { if (mask & TileSet::BIND_IGNORE_TOPRIGHT) {
workspace->draw_rect(Rect2(anchor + Vector2(size.x * 4 / 6, 0), size / 6), ci);
workspace->draw_rect(Rect2(anchor + Vector2(size.x * 5 / 6, size.y / 6), size / 6), ci);
} else if (mask & TileSet::BIND_TOPRIGHT) {
workspace->draw_rect(Rect2(anchor + Vector2((size.x / 3) * 2, 0), size / 3), c); workspace->draw_rect(Rect2(anchor + Vector2((size.x / 3) * 2, 0), size / 3), c);
} }
if (mask & TileSet::BIND_LEFT) { if (mask & TileSet::BIND_IGNORE_LEFT) {
workspace->draw_rect(Rect2(anchor + Vector2(0, size.y / 3), size / 6), ci);
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 6, size.y / 2), size / 6), ci);
} else if (mask & TileSet::BIND_LEFT) {
workspace->draw_rect(Rect2(anchor + Vector2(0, size.y / 3), size / 3), c); workspace->draw_rect(Rect2(anchor + Vector2(0, size.y / 3), size / 3), c);
} }
if (mask & TileSet::BIND_CENTER) { if (mask & TileSet::BIND_IGNORE_CENTER) {
workspace->draw_rect(Rect2(anchor + size / 3, size / 6), ci);
workspace->draw_rect(Rect2(anchor + size / 2, size / 6), ci);
} else if (mask & TileSet::BIND_CENTER) {
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 3, size.y / 3), size / 3), c); workspace->draw_rect(Rect2(anchor + Vector2(size.x / 3, size.y / 3), size / 3), c);
} }
if (mask & TileSet::BIND_RIGHT) { if (mask & TileSet::BIND_IGNORE_RIGHT) {
workspace->draw_rect(Rect2(anchor + Vector2(size.x * 4 / 6, size.y / 3), size / 6), ci);
workspace->draw_rect(Rect2(anchor + Vector2(size.x * 5 / 6, size.y / 2), size / 6), ci);
} else if (mask & TileSet::BIND_RIGHT) {
workspace->draw_rect(Rect2(anchor + Vector2((size.x / 3) * 2, size.y / 3), size / 3), c); workspace->draw_rect(Rect2(anchor + Vector2((size.x / 3) * 2, size.y / 3), size / 3), c);
} }
if (mask & TileSet::BIND_BOTTOMLEFT) { if (mask & TileSet::BIND_IGNORE_BOTTOMLEFT) {
workspace->draw_rect(Rect2(anchor + Vector2(0, size.y * 4 / 6), size / 6), ci);
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 6, size.y * 5 / 6), size / 6), ci);
} else if (mask & TileSet::BIND_BOTTOMLEFT) {
workspace->draw_rect(Rect2(anchor + Vector2(0, (size.y / 3) * 2), size / 3), c); workspace->draw_rect(Rect2(anchor + Vector2(0, (size.y / 3) * 2), size / 3), c);
} }
if (mask & TileSet::BIND_BOTTOM) { if (mask & TileSet::BIND_IGNORE_BOTTOM) {
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 3, size.y * 4 / 6), size / 6), ci);
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 2, size.y * 5 / 6), size / 6), ci);
} else if (mask & TileSet::BIND_BOTTOM) {
workspace->draw_rect(Rect2(anchor + Vector2(size.x / 3, (size.y / 3) * 2), size / 3), c); workspace->draw_rect(Rect2(anchor + Vector2(size.x / 3, (size.y / 3) * 2), size / 3), c);
} }
if (mask & TileSet::BIND_BOTTOMRIGHT) { if (mask & TileSet::BIND_IGNORE_BOTTOMRIGHT) {
workspace->draw_rect(Rect2(anchor + size * 4 / 6, size / 6), ci);
workspace->draw_rect(Rect2(anchor + size * 5 / 6, size / 6), ci);
} else if (mask & TileSet::BIND_BOTTOMRIGHT) {
workspace->draw_rect(Rect2(anchor + (size / 3) * 2, size / 3), c); workspace->draw_rect(Rect2(anchor + (size / 3) * 2, size / 3), c);
} }
} }
@ -882,10 +922,10 @@ void TileSetEditor::_on_workspace_draw() {
} break; } break;
case EDITMODE_PRIORITY: { case EDITMODE_PRIORITY: {
spin_priority->set_value(tileset->autotile_get_subtile_priority(get_current_tile(), edited_shape_coord)); spin_priority->set_value(tileset->autotile_get_subtile_priority(get_current_tile(), edited_shape_coord));
uint16_t mask = tileset->autotile_get_bitmask(get_current_tile(), edited_shape_coord); uint32_t mask = tileset->autotile_get_bitmask(get_current_tile(), edited_shape_coord);
Vector<Vector2> queue_others; Vector<Vector2> queue_others;
int total = 0; int total = 0;
for (Map<Vector2, uint16_t>::Element *E = tileset->autotile_get_bitmask_map(get_current_tile()).front(); E; E = E->next()) { for (Map<Vector2, uint32_t>::Element *E = tileset->autotile_get_bitmask_map(get_current_tile()).front(); E; E = E->next()) {
if (E->value() == mask) { if (E->value() == mask) {
total += tileset->autotile_get_subtile_priority(get_current_tile(), E->key()); total += tileset->autotile_get_subtile_priority(get_current_tile(), E->key());
if (E->key() != edited_shape_coord) { if (E->key() != edited_shape_coord) {
@ -1037,6 +1077,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
static bool dragging; static bool dragging;
static bool erasing; static bool erasing;
static bool alternative;
draw_edited_region = false; draw_edited_region = false;
Rect2 current_tile_region = Rect2(); Rect2 current_tile_region = Rect2();
@ -1220,10 +1261,11 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
if ((mb->get_button_index() == BUTTON_RIGHT || mb->get_button_index() == BUTTON_LEFT) && current_tile_region.has_point(mb->get_position())) { if ((mb->get_button_index() == BUTTON_RIGHT || mb->get_button_index() == BUTTON_LEFT) && current_tile_region.has_point(mb->get_position())) {
dragging = true; dragging = true;
erasing = (mb->get_button_index() == BUTTON_RIGHT); erasing = (mb->get_button_index() == BUTTON_RIGHT);
alternative = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y))); Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y)); Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y));
pos = mb->get_position() - (pos + current_tile_region.position); pos = mb->get_position() - (pos + current_tile_region.position);
uint16_t bit = 0; uint32_t bit = 0;
if (tileset->autotile_get_bitmask_mode(get_current_tile()) == TileSet::BITMASK_2X2) { if (tileset->autotile_get_bitmask_mode(get_current_tile()) == TileSet::BITMASK_2X2) {
if (pos.x < size.x / 2) { if (pos.x < size.x / 2) {
if (pos.y < size.y / 2) { if (pos.y < size.y / 2) {
@ -1266,13 +1308,19 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
} }
} }
uint16_t old_mask = tileset->autotile_get_bitmask(get_current_tile(), coord); uint32_t old_mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
uint16_t new_mask = old_mask; uint32_t new_mask = old_mask;
if (erasing) { if (alternative) {
new_mask &= ~bit; new_mask &= ~bit;
new_mask |= (bit << 16);
} else if (erasing) {
new_mask &= ~bit;
new_mask &= ~(bit << 16);
} else { } else {
new_mask |= bit; new_mask |= bit;
new_mask &= ~(bit << 16);
} }
if (old_mask != new_mask) { if (old_mask != new_mask) {
undo_redo->create_action(TTR("Edit Tile Bitmask")); undo_redo->create_action(TTR("Edit Tile Bitmask"));
undo_redo->add_do_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), coord, new_mask); undo_redo->add_do_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), coord, new_mask);
@ -1286,6 +1334,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
if ((erasing && mb->get_button_index() == BUTTON_RIGHT) || (!erasing && mb->get_button_index() == BUTTON_LEFT)) { if ((erasing && mb->get_button_index() == BUTTON_RIGHT) || (!erasing && mb->get_button_index() == BUTTON_LEFT)) {
dragging = false; dragging = false;
erasing = false; erasing = false;
alternative = false;
} }
} }
} }
@ -1294,7 +1343,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
Vector2 coord((int)((mm->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mm->get_position().y - current_tile_region.position.y) / (spacing + size.y))); Vector2 coord((int)((mm->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mm->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y)); Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y));
pos = mm->get_position() - (pos + current_tile_region.position); pos = mm->get_position() - (pos + current_tile_region.position);
uint16_t bit = 0; uint32_t bit = 0;
if (tileset->autotile_get_bitmask_mode(get_current_tile()) == TileSet::BITMASK_2X2) { if (tileset->autotile_get_bitmask_mode(get_current_tile()) == TileSet::BITMASK_2X2) {
if (pos.x < size.x / 2) { if (pos.x < size.x / 2) {
if (pos.y < size.y / 2) { if (pos.y < size.y / 2) {
@ -1337,12 +1386,17 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
} }
} }
uint16_t old_mask = tileset->autotile_get_bitmask(get_current_tile(), coord); uint32_t old_mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
uint16_t new_mask = old_mask; uint32_t new_mask = old_mask;
if (erasing) { if (alternative) {
new_mask &= ~bit; new_mask &= ~bit;
new_mask |= (bit << 16);
} else if (erasing) {
new_mask &= ~bit;
new_mask &= ~(bit << 16);
} else { } else {
new_mask |= bit; new_mask |= bit;
new_mask &= ~(bit << 16);
} }
if (old_mask != new_mask) { if (old_mask != new_mask) {
undo_redo->create_action(TTR("Edit Tile Bitmask")); undo_redo->create_action(TTR("Edit Tile Bitmask"));
@ -1529,10 +1583,10 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
undo_redo->create_action(TTR("Paste Tile Bitmask")); undo_redo->create_action(TTR("Paste Tile Bitmask"));
undo_redo->add_do_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile()); undo_redo->add_do_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile());
undo_redo->add_undo_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile()); undo_redo->add_undo_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile());
for (Map<Vector2, uint16_t>::Element *E = bitmask_map_copy.front(); E; E = E->next()) { for (Map<Vector2, uint32_t>::Element *E = bitmask_map_copy.front(); E; E = E->next()) {
undo_redo->add_do_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value()); undo_redo->add_do_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value());
} }
for (Map<Vector2, uint16_t>::Element *E = tileset->autotile_get_bitmask_map(get_current_tile()).front(); E; E = E->next()) { for (Map<Vector2, uint32_t>::Element *E = tileset->autotile_get_bitmask_map(get_current_tile()).front(); E; E = E->next()) {
undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value()); undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value());
} }
undo_redo->add_do_method(workspace, "update"); undo_redo->add_do_method(workspace, "update");
@ -1541,7 +1595,7 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
} else if (p_tool == BITMASK_CLEAR) { } else if (p_tool == BITMASK_CLEAR) {
undo_redo->create_action(TTR("Clear Tile Bitmask")); undo_redo->create_action(TTR("Clear Tile Bitmask"));
undo_redo->add_do_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile()); undo_redo->add_do_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile());
for (Map<Vector2, uint16_t>::Element *E = tileset->autotile_get_bitmask_map(get_current_tile()).front(); E; E = E->next()) { for (Map<Vector2, uint32_t>::Element *E = tileset->autotile_get_bitmask_map(get_current_tile()).front(); E; E = E->next()) {
undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value()); undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value());
} }
undo_redo->add_do_method(workspace, "update"); undo_redo->add_do_method(workspace, "update");
@ -2139,8 +2193,8 @@ void TileSetEditor::_undo_tile_removal(int p_id) {
for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = navigation_map.front(); E; E = E->next()) { for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = navigation_map.front(); E; E = E->next()) {
undo_redo->add_undo_method(tileset.ptr(), "autotile_set_navigation_polygon", p_id, E->value(), E->key()); undo_redo->add_undo_method(tileset.ptr(), "autotile_set_navigation_polygon", p_id, E->value(), E->key());
} }
Map<Vector2, uint16_t> bitmask_map = tileset->autotile_get_bitmask_map(p_id); Map<Vector2, uint32_t> bitmask_map = tileset->autotile_get_bitmask_map(p_id);
for (Map<Vector2, uint16_t>::Element *E = bitmask_map.front(); E; E = E->next()) { for (Map<Vector2, uint32_t>::Element *E = bitmask_map.front(); E; E = E->next()) {
undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", p_id, E->key(), E->value()); undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", p_id, E->key(), E->value());
} }
Map<Vector2, int> priority_map = tileset->autotile_get_priority_map(p_id); Map<Vector2, int> priority_map = tileset->autotile_get_priority_map(p_id);

View File

@ -126,7 +126,7 @@ class TileSetEditor : public HSplitContainer {
Vector2 edited_shape_coord; Vector2 edited_shape_coord;
PoolVector2Array current_shape; PoolVector2Array current_shape;
Map<Vector2i, SubtileData> current_tile_data; Map<Vector2i, SubtileData> current_tile_data;
Map<Vector2, uint16_t> bitmask_map_copy; Map<Vector2, uint32_t> bitmask_map_copy;
Vector2 snap_step; Vector2 snap_step;
Vector2 snap_offset; Vector2 snap_offset;

View File

@ -215,7 +215,7 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = autotile_get_spacing(id); r_ret = autotile_get_spacing(id);
else if (what == "bitmask_flags") { else if (what == "bitmask_flags") {
Array p; Array p;
for (Map<Vector2, uint16_t>::Element *E = tile_map[id].autotile_data.flags.front(); E; E = E->next()) { for (Map<Vector2, uint32_t>::Element *E = tile_map[id].autotile_data.flags.front(); E; E = E->next()) {
p.push_back(E->key()); p.push_back(E->key());
p.push_back(E->value()); p.push_back(E->value());
} }
@ -544,7 +544,7 @@ const Map<Vector2, int> &TileSet::autotile_get_z_index_map(int p_id) const {
return tile_map[p_id].autotile_data.z_index_map; return tile_map[p_id].autotile_data.z_index_map;
} }
void TileSet::autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag) { void TileSet::autotile_set_bitmask(int p_id, Vector2 p_coord, uint32_t p_flag) {
ERR_FAIL_COND(!tile_map.has(p_id)); ERR_FAIL_COND(!tile_map.has(p_id));
if (p_flag == 0) { if (p_flag == 0) {
@ -555,7 +555,7 @@ void TileSet::autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag) {
} }
} }
uint16_t TileSet::autotile_get_bitmask(int p_id, Vector2 p_coord) { uint32_t TileSet::autotile_get_bitmask(int p_id, Vector2 p_coord) {
ERR_FAIL_COND_V(!tile_map.has(p_id), 0); ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
if (!tile_map[p_id].autotile_data.flags.has(p_coord)) { if (!tile_map[p_id].autotile_data.flags.has(p_coord)) {
@ -564,13 +564,13 @@ uint16_t TileSet::autotile_get_bitmask(int p_id, Vector2 p_coord) {
return tile_map[p_id].autotile_data.flags[p_coord]; return tile_map[p_id].autotile_data.flags[p_coord];
} }
const Map<Vector2, uint16_t> &TileSet::autotile_get_bitmask_map(int p_id) { const Map<Vector2, uint32_t> &TileSet::autotile_get_bitmask_map(int p_id) {
static Map<Vector2, uint16_t> dummy; static Map<Vector2, uint32_t> dummy;
static Map<Vector2, uint16_t> dummy_atlas; static Map<Vector2, uint32_t> dummy_atlas;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy); ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
if (tile_get_tile_mode(p_id) == ATLAS_TILE) { if (tile_get_tile_mode(p_id) == ATLAS_TILE) {
dummy_atlas = Map<Vector2, uint16_t>(); dummy_atlas = Map<Vector2, uint32_t>();
Rect2 region = tile_get_region(p_id); Rect2 region = tile_get_region(p_id);
Size2 size = autotile_get_size(p_id); Size2 size = autotile_get_size(p_id);
float spacing = autotile_get_spacing(p_id); float spacing = autotile_get_spacing(p_id);
@ -600,18 +600,25 @@ Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask,
} }
List<Vector2> coords; List<Vector2> coords;
uint16_t mask; uint32_t mask;
for (Map<Vector2, uint16_t>::Element *E = tile_map[p_id].autotile_data.flags.front(); E; E = E->next()) { uint16_t mask_;
uint16_t mask_ignore;
for (Map<Vector2, uint32_t>::Element *E = tile_map[p_id].autotile_data.flags.front(); E; E = E->next()) {
mask = E->get(); mask = E->get();
if (tile_map[p_id].autotile_data.bitmask_mode == BITMASK_2X2) { if (tile_map[p_id].autotile_data.bitmask_mode == BITMASK_2X2) {
mask &= (BIND_BOTTOMLEFT | BIND_BOTTOMRIGHT | BIND_TOPLEFT | BIND_TOPRIGHT); mask |= (BIND_IGNORE_TOP | BIND_IGNORE_LEFT | BIND_IGNORE_CENTER | BIND_IGNORE_RIGHT | BIND_IGNORE_BOTTOM);
} }
if (mask == p_bitmask) {
mask_ = mask & 0xFFFF;
mask_ignore = mask >> 16;
if (((mask_ & (~mask_ignore)) == (p_bitmask & (~mask_ignore))) && (((~mask_) | mask_ignore) == ((~p_bitmask) | mask_ignore))) {
for (int i = 0; i < autotile_get_subtile_priority(p_id, E->key()); i++) { for (int i = 0; i < autotile_get_subtile_priority(p_id, E->key()); i++) {
coords.push_back(E->key()); coords.push_back(E->key());
} }
} }
} }
if (coords.size() == 0) { if (coords.size() == 0) {
return autotile_get_icon_coordinate(p_id); return autotile_get_icon_coordinate(p_id);
} else { } else {

View File

@ -72,7 +72,17 @@ public:
BIND_RIGHT = 32, BIND_RIGHT = 32,
BIND_BOTTOMLEFT = 64, BIND_BOTTOMLEFT = 64,
BIND_BOTTOM = 128, BIND_BOTTOM = 128,
BIND_BOTTOMRIGHT = 256 BIND_BOTTOMRIGHT = 256,
BIND_IGNORE_TOPLEFT = 1 << 16,
BIND_IGNORE_TOP = 1 << 17,
BIND_IGNORE_TOPRIGHT = 1 << 18,
BIND_IGNORE_LEFT = 1 << 19,
BIND_IGNORE_CENTER = 1 << 20,
BIND_IGNORE_RIGHT = 1 << 21,
BIND_IGNORE_BOTTOMLEFT = 1 << 22,
BIND_IGNORE_BOTTOM = 1 << 23,
BIND_IGNORE_BOTTOMRIGHT = 1 << 24
}; };
enum TileMode { enum TileMode {
@ -86,7 +96,7 @@ public:
Size2 size; Size2 size;
int spacing; int spacing;
Vector2 icon_coord; Vector2 icon_coord;
Map<Vector2, uint16_t> flags; Map<Vector2, uint32_t> flags;
Map<Vector2, Ref<OccluderPolygon2D> > occluder_map; Map<Vector2, Ref<OccluderPolygon2D> > occluder_map;
Map<Vector2, Ref<NavigationPolygon> > navpoly_map; Map<Vector2, Ref<NavigationPolygon> > navpoly_map;
Map<Vector2, int> priority_map; Map<Vector2, int> priority_map;
@ -181,9 +191,9 @@ public:
int autotile_get_z_index(int p_id, const Vector2 &p_coord); int autotile_get_z_index(int p_id, const Vector2 &p_coord);
const Map<Vector2, int> &autotile_get_z_index_map(int p_id) const; const Map<Vector2, int> &autotile_get_z_index_map(int p_id) const;
void autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag); void autotile_set_bitmask(int p_id, Vector2 p_coord, uint32_t p_flag);
uint16_t autotile_get_bitmask(int p_id, Vector2 p_coord); uint32_t autotile_get_bitmask(int p_id, Vector2 p_coord);
const Map<Vector2, uint16_t> &autotile_get_bitmask_map(int p_id); const Map<Vector2, uint32_t> &autotile_get_bitmask_map(int p_id);
Vector2 autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node = NULL, const Vector2 &p_tile_location = Vector2()); Vector2 autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node = NULL, const Vector2 &p_tile_location = Vector2());
void tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_shape); void tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_shape);