Work on layered tile maps.

This commit is contained in:
Relintai 2024-03-03 09:39:24 +01:00
parent 75a41eaf34
commit 275a9124de
13 changed files with 272 additions and 319 deletions

View File

@ -9823,7 +9823,7 @@ msgid ""
"[PoolRealArray] or [PoolIntArray] of bone indices. Each element in groups of "
"4 floats."
msgstr ""
"[PackedFloat32Array] o [PackedInt32Array] de indices de hueso. Cada element "
"[PackedFloat32Array] o [PoolIntArray] de indices de hueso. Cada element "
"en grupos de 4 reales."
#: doc/classes/ArrayMesh.xml
@ -9846,7 +9846,7 @@ msgid ""
"vertices of each triangle. For lines, the index array is in pairs indicating "
"the start and end of each line."
msgstr ""
"[PackedInt32Array] de enteros utilizados como indices referenciando "
"[PoolIntArray] de enteros utilizados como indices referenciando "
"vertices, colores, normales, tangentes y texturas. Todos estos arrays deben "
"tener el mismo numero de elemento que el array de vertices. Ningun indice "
"puede ser mayor que el tamaño del array de vertices. Cuando el array de "
@ -33927,11 +33927,11 @@ msgid ""
msgstr ""
"Triangula el área especificada por un conjunto discreto de [code]points[/"
"code] de tal manera que ningún punto está dentro del círculo de cualquier "
"triángulo resultante. Devuelve un [PackedInt32Array] donde cada triángulo "
"triángulo resultante. Devuelve un [PoolIntArray] donde cada triángulo "
"consiste en tres índices de puntos consecutivos en [code]points[/code] (es "
"decir, el array devuelto tendrá [code]n * 3[/code] elementos, siendo "
"[code]n[/code] el número de triángulos encontrados). Si la triangulación no "
"tuvo éxito, se devuelve un [PackedInt32Array] vacío."
"tuvo éxito, se devuelve un [PoolIntArray] vacío."
#: doc/classes/Geometry.xml
#, fuzzy
@ -33945,11 +33945,11 @@ msgid ""
"succeed, an empty [PoolIntArray] is returned."
msgstr ""
"Triangula el polígono especificado por los puntos en [code]polygon[/code]. "
"Devuelve un [PackedInt32Array] donde cada triángulo consiste en tres índices "
"Devuelve un [PoolIntArray] donde cada triángulo consiste en tres índices "
"de puntos consecutivos en [code]polygon[/code] (es decir, el array devuelto "
"tendrá [code]n * 3[/code] elementos, siendo [code]n[/code] el número de "
"triángulos encontrados). Si la triangulación no tuvo éxito, se devuelve un "
"[PackedInt32Array] vacío."
"[PoolIntArray] vacío."
#: doc/classes/Geometry.xml
msgid ""
@ -48088,7 +48088,7 @@ msgid ""
"Returns a [PoolIntArray] containing the indices of the vertices of a created "
"polygon."
msgstr ""
"Devuelve un [PackedInt32Array] que contiene los índices de los vértices de "
"Devuelve un [PoolIntArray] que contiene los índices de los vértices de "
"un polígono creado."
#: doc/classes/NavigationMesh.xml
@ -48617,7 +48617,7 @@ msgstr ""
"var vertices = PackedVector2Array([Vector2(0, 0), Vector2(0, 50), "
"Vector2(50, 50), Vector2(50, 0)])\n"
"poligono.set_vertices(vertices)\n"
"var indices = PackedInt32Array(0, 3, 1)\n"
"var indices = PoolIntArray(0, 3, 1)\n"
"polygon.add_polygon(indices)\n"
"$NavigationRegion2D.navpoly = poligono\n"
"[/codeblock]"
@ -60496,13 +60496,13 @@ msgid ""
"Constructs a new [PoolIntArray]. Optionally, you can pass in a generic "
"[Array] that will be converted."
msgstr ""
"Construye un nuevo [PackedInt32Array]. Opcionalmente, puedes pasar un "
"Construye un nuevo [PoolIntArray]. Opcionalmente, puedes pasar un "
"[Array] genérico que será convertido."
#: doc/classes/PoolIntArray.xml
#, fuzzy
msgid "Appends a [PoolIntArray] at the end of this array."
msgstr "Añade un [PackedInt32Array] al final de este array."
msgstr "Añade un [PoolIntArray] al final de este array."
#: doc/classes/PoolIntArray.xml
#, fuzzy

View File

@ -9774,7 +9774,7 @@ msgid ""
"[PoolRealArray] or [PoolIntArray] of bone indices. Each element in groups of "
"4 floats."
msgstr ""
"ボーンのインデックスの[PackedFloat32Array]または[PackedInt32Array]。各要素は4"
"ボーンのインデックスの[PackedFloat32Array]または[PoolIntArray]。各要素は4"
"つの浮動小数点数のグループで構成されています。"
#: doc/classes/ArrayMesh.xml
@ -9799,7 +9799,7 @@ msgid ""
"the start and end of each line."
msgstr ""
"頂点、色、法線、接線、テクスチャを参照するインデックスとして使用される整数の "
"[PackedInt32Array]。これらの配列はすべて、頂点配列と同じ要素数でなければなり"
"[PoolIntArray]。これらの配列はすべて、頂点配列と同じ要素数でなければなり"
"ません。頂点配列のサイズを超えるインデックスにはできません。このインデックス"
"配列が存在する場合、関数は「インデックスモード」になり、インデックスが *i* 番"
"目の頂点、法線、接線、色、UVなどを選択します。つまり、辺に沿って法線や色を変"

View File

@ -1,6 +1,6 @@
def can_build(env, platform):
return False
return True
def configure(env):
pass

View File

@ -1,62 +0,0 @@
/*************************************************************************/
/* tile_map.compat.inc */
/*************************************************************************/
/* This file is part of: */
/* PANDEMONIUM ENGINE */
/* https://github.com/Relintai/pandemonium_engine */
/*************************************************************************/
/* Copyright (c) 2022-present Péter Magyar. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef DISABLE_DEPRECATED
Rect2i LayeredTileMap::_get_used_rect_bind_compat_78328() {
return get_used_rect();
}
void LayeredTileMap::_set_quadrant_size_compat_81070(int p_quadrant_size) {
set_rendering_quadrant_size(p_quadrant_size);
}
int LayeredTileMap::_get_quadrant_size_compat_81070() const {
return get_rendering_quadrant_size();
}
TileMap::VisibilityMode LayeredTileMap::_get_collision_visibility_mode_bind_compat_87115() {
return get_collision_visibility_mode();
}
TileMap::VisibilityMode LayeredTileMap::_get_navigation_visibility_mode_bind_compat_87115() {
return get_navigation_visibility_mode();
}
void LayeredTileMap::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("get_used_rect"), &LayeredTileMap::_get_used_rect_bind_compat_78328);
ClassDB::bind_compatibility_method(D_METHOD("set_quadrant_size", "quadrant_size"), &LayeredTileMap::_set_quadrant_size_compat_81070);
ClassDB::bind_compatibility_method(D_METHOD("get_quadrant_size"), &LayeredTileMap::_get_quadrant_size_compat_81070);
ClassDB::bind_compatibility_method(D_METHOD("get_collision_visibility_mode"), &LayeredTileMap::_get_collision_visibility_mode_bind_compat_87115);
ClassDB::bind_compatibility_method(D_METHOD("get_navigation_visibility_mode"), &LayeredTileMap::_get_navigation_visibility_mode_bind_compat_87115);
}
#endif

View File

@ -30,8 +30,8 @@
/*************************************************************************/
#include "layered_tile_map.h"
#include "layered_tile_map.compat.inc"
#include "core/config/engine.h"
#include "core/core_string_names.h"
#include "layered_tile_map_layer.h"
#include "scene/main/control.h"
@ -258,19 +258,21 @@ void LayeredTileMap::add_layer(int p_to_pos) {
// Must clear before adding the layer.
LayeredTileMapLayer *new_layer = memnew(LayeredTileMapLayer);
layers.insert(p_to_pos, new_layer);
add_child(new_layer, false, INTERNAL_MODE_FRONT);
add_child(new_layer, false);
move_child(new_layer, 0);
new_layer->set_name(vformat("Layer%d", p_to_pos));
move_child(new_layer, p_to_pos);
for (uint32_t i = 0; i < layers.size(); i++) {
layers[i]->set_as_tile_map_internal_node(i);
}
new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LayeredTileMap::_emit_changed));
new_layer->connect(CoreStringNames::get_singleton()->changed, this, "_emit_changed");
property_list_changed_notify();
_emit_changed();
update_configuration_warnings();
update_configuration_warning();
}
void LayeredTileMap::move_layer(int p_layer, int p_to_pos) {
@ -289,14 +291,15 @@ void LayeredTileMap::move_layer(int p_layer, int p_to_pos) {
_emit_changed();
update_configuration_warnings();
update_configuration_warning();
}
void LayeredTileMap::remove_layer(int p_layer) {
ERR_FAIL_INDEX(p_layer, (int)layers.size());
// Clear before removing the layer.
layers[p_layer]->queue_free();
layers[p_layer]->queue_delete();
layers.remove(p_layer);
for (uint32_t i = 0; i < layers.size(); i++) {
layers[i]->set_as_tile_map_internal_node(i);
@ -305,7 +308,7 @@ void LayeredTileMap::remove_layer(int p_layer) {
_emit_changed();
update_configuration_warnings();
update_configuration_warning();
}
void LayeredTileMap::set_layer_name(int p_layer, String p_name) {
@ -337,7 +340,7 @@ void LayeredTileMap::set_layer_y_sort_enabled(int p_layer, bool p_y_sort_enabled
}
bool LayeredTileMap::is_layer_y_sort_enabled(int p_layer) const {
TILEMAP_CALL_FOR_LAYER_V(p_layer, false, is_y_sort_enabled);
TILEMAP_CALL_FOR_LAYER_V(p_layer, false, is_sort_enabled);
}
void LayeredTileMap::set_layer_y_sort_origin(int p_layer, int p_y_sort_origin) {
@ -379,7 +382,10 @@ void LayeredTileMap::set_collision_animatable(bool p_collision_animatable) {
collision_animatable = p_collision_animatable;
set_notify_local_transform(p_collision_animatable);
set_physics_process_internal(p_collision_animatable);
for (LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];
layer->set_use_kinematic_bodies(layer);
}
}
@ -393,9 +399,13 @@ void LayeredTileMap::set_collision_visibility_mode(LayeredTileMap::VisibilityMod
return;
}
collision_visibility_mode = p_show_collision;
for (LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];
layer->set_collision_visibility_mode(LayeredTileMapLayer::VisibilityMode(p_show_collision));
}
_emit_changed();
}
@ -408,9 +418,12 @@ void LayeredTileMap::set_navigation_visibility_mode(LayeredTileMap::VisibilityMo
return;
}
navigation_visibility_mode = p_show_navigation;
for (LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];
layer->set_navigation_visibility_mode(LayeredTileMapLayer::VisibilityMode(p_show_navigation));
}
_emit_changed();
}
@ -419,15 +432,20 @@ LayeredTileMap::VisibilityMode LayeredTileMap::get_navigation_visibility_mode()
}
void LayeredTileMap::set_y_sort_enabled(bool p_enable) {
if (is_y_sort_enabled() == p_enable) {
if (is_sort_enabled() == p_enable) {
return;
}
Node2D::set_y_sort_enabled(p_enable);
for (LayeredTileMapLayer *layer : layers) {
YSort::set_sort_enabled(p_enable);
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];
layer->set_y_sort_enabled(p_enable);
}
_emit_changed();
update_configuration_warnings();
update_configuration_warning();
}
void LayeredTileMap::set_cell(int p_layer, const Vector2i &p_coords, int p_source_id, const Vector2i p_atlas_coords, int p_alternative_tile) {
@ -500,11 +518,14 @@ LayeredTileMapCell LayeredTileMap::get_cell(int p_layer, const Vector2i &p_coord
}
Vector2i LayeredTileMap::get_coords_for_body_rid(RID p_physics_body) {
for (const LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
const LayeredTileMapLayer *layer = layers[i];
if (layer->has_body_rid(p_physics_body)) {
return layer->get_coords_for_body_rid(p_physics_body);
}
}
ERR_FAIL_V_MSG(Vector2i(), vformat("No tiles for the given body RID %d.", p_physics_body.get_id()));
}
@ -518,7 +539,8 @@ int LayeredTileMap::get_layer_for_body_rid(RID p_physics_body) {
}
void LayeredTileMap::fix_invalid_tiles() {
for (LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];
layer->fix_invalid_tiles();
}
}
@ -528,13 +550,15 @@ void LayeredTileMap::clear_layer(int p_layer) {
}
void LayeredTileMap::clear() {
for (LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];
layer->clear();
}
}
void LayeredTileMap::update_internals() {
for (LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];
layer->update_internals();
}
}
@ -543,7 +567,8 @@ void LayeredTileMap::notify_runtime_tile_data_update(int p_layer) {
if (p_layer >= 0) {
TILEMAP_CALL_FOR_LAYER(p_layer, notify_runtime_tile_data_update);
} else {
for (LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];
layer->notify_runtime_tile_data_update();
}
}
@ -582,10 +607,11 @@ bool LayeredTileMap::_set(const StringName &p_name, const Variant &p_value) {
if (p_value.is_array()) {
if (layers.size() == 0) {
LayeredTileMapLayer *new_layer = memnew(LayeredTileMapLayer);
add_child(new_layer, false, INTERNAL_MODE_FRONT);
add_child(new_layer);
move_child(new_layer, 0);
new_layer->set_as_tile_map_internal_node(0);
new_layer->set_name("Layer0");
new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LayeredTileMap::_emit_changed));
new_layer->connect(CoreStringNames::get_singleton()->changed, this, "_emit_changed");
layers.push_back(new_layer);
}
layers[0]->set_tile_data(format, p_value);
@ -607,16 +633,17 @@ bool LayeredTileMap::_set(const StringName &p_name, const Variant &p_value) {
if (index >= (int)layers.size()) {
while (index >= (int)layers.size()) {
LayeredTileMapLayer *new_layer = memnew(LayeredTileMapLayer);
add_child(new_layer, false, INTERNAL_MODE_FRONT);
add_child(new_layer);
move_child(new_layer, 0);
new_layer->set_as_tile_map_internal_node(index);
new_layer->set_name(vformat("Layer%d", index));
new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LayeredTileMap::_emit_changed));
new_layer->connect(CoreStringNames::get_singleton()->changed, this, "_emit_changed");
layers.push_back(new_layer);
}
property_list_changed_notify();
_emit_changed();
update_configuration_warnings();
update_configuration_warning();
}
if (components[1] == "name") {
@ -704,10 +731,10 @@ void LayeredTileMap::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::NIL, "Layers", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
#define MAKE_LAYER_PROPERTY(m_type, m_name, m_hint) \
{ \
const String property_name = vformat("layer_%d/" m_name, i); \
p_list->push_back(PropertyInfo(m_type, property_name, PROPERTY_HINT_NONE, m_hint, (get(property_name) == property_get_revert(property_name)) ? PROPERTY_USAGE_EDITOR : PROPERTY_USAGE_DEFAULT)); \
#define MAKE_LAYER_PROPERTY(m_type, m_name, m_hint) \
{ \
const String property_name = vformat("layer_%d/" m_name, i); \
p_list->push_back(PropertyInfo(m_type, property_name, PROPERTY_HINT_NONE, m_hint, PROPERTY_USAGE_DEFAULT)); \
}
for (uint32_t i = 0; i < layers.size(); i++) {
@ -739,7 +766,7 @@ bool LayeredTileMap::_property_can_revert(const StringName &p_name) const {
} else if (components[1] == "modulate") {
return layers[index]->get_modulate() != default_layer->get_modulate();
} else if (components[1] == "y_sort_enabled") {
return layers[index]->is_y_sort_enabled() != default_layer->is_y_sort_enabled();
return layers[index]->is_sort_enabled() != default_layer->is_sort_enabled();
} else if (components[1] == "y_sort_origin") {
return layers[index]->get_y_sort_origin() != default_layer->get_y_sort_origin();
} else if (components[1] == "z_index") {
@ -770,7 +797,7 @@ bool LayeredTileMap::_property_get_revert(const StringName &p_name, Variant &r_p
r_property = default_layer->get_modulate();
return true;
} else if (components[1] == "y_sort_enabled") {
r_property = default_layer->is_y_sort_enabled();
r_property = default_layer->is_sort_enabled();
return true;
} else if (components[1] == "y_sort_origin") {
r_property = default_layer->get_y_sort_origin();
@ -819,7 +846,10 @@ Rect2i LayeredTileMap::get_used_rect() const {
// Return the visible rect of the tilemap.
bool first = true;
Rect2i rect = Rect2i();
for (const LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
const LayeredTileMapLayer *layer = layers[i];
Rect2i layer_rect = layer->get_used_rect();
if (layer_rect == Rect2i()) {
continue;
@ -839,7 +869,8 @@ Rect2i LayeredTileMap::get_used_rect() const {
void LayeredTileMap::set_light_mask(int p_light_mask) {
// Set light mask for occlusion and applies it to all layers too.
CanvasItem::set_light_mask(p_light_mask);
for (LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];
layer->set_light_mask(p_light_mask);
}
}
@ -847,27 +878,12 @@ void LayeredTileMap::set_light_mask(int p_light_mask) {
void LayeredTileMap::set_self_modulate(const Color &p_self_modulate) {
// Set self_modulation and applies it to all layers too.
CanvasItem::set_self_modulate(p_self_modulate);
for (LayeredTileMapLayer *layer : layers) {
for (uint32_t i = 0; i < layers.size(); ++i) {
LayeredTileMapLayer *layer = layers[i];
layer->set_self_modulate(p_self_modulate);
}
}
void LayeredTileMap::set_texture_filter(TextureFilter p_texture_filter) {
// Set a default texture filter and applies it to all layers too.
CanvasItem::set_texture_filter(p_texture_filter);
for (LayeredTileMapLayer *layer : layers) {
layer->set_texture_filter(p_texture_filter);
}
}
void LayeredTileMap::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) {
// Set a default texture repeat and applies it to all layers too.
CanvasItem::set_texture_repeat(p_texture_repeat);
for (LayeredTileMapLayer *layer : layers) {
layer->set_texture_repeat(p_texture_repeat);
}
}
PoolVector2iArray LayeredTileMap::get_surrounding_cells(const Vector2i &p_coords) {
if (!tile_set.is_valid()) {
return PoolVector2iArray();
@ -876,53 +892,76 @@ PoolVector2iArray LayeredTileMap::get_surrounding_cells(const Vector2i &p_coords
return tile_set->get_surrounding_cells(p_coords);
}
PoolStringArray LayeredTileMap::get_configuration_warnings() const {
PoolStringArray warnings = Node::get_configuration_warnings();
bool LayeredTileMap::use_tile_data_runtime_update(const int p_layer, const Vector2i &p_pos) {
return call("_use_tile_data_runtime_update", p_layer, p_pos);
}
void LayeredTileMap::tile_data_runtime_update(const int p_layer, const Vector2i &p_pos, LayeredTileData *p_tile_data) {
call("_tile_data_runtime_update", p_layer, p_pos, p_tile_data);
}
bool LayeredTileMap::_use_tile_data_runtime_update(const int p_layer, const Vector2i &p_pos) {
return false;
}
void LayeredTileMap::_tile_data_runtime_update(const int p_layer, const Vector2i &p_pos, LayeredTileData *p_tile_data) {
}
String LayeredTileMap::get_configuration_warning() const {
String warnings = Node::get_configuration_warning();
// Retrieve the set of Z index values with a Y-sorted layer.
RBSet<int> y_sorted_z_index;
for (const LayeredTileMapLayer *layer : layers) {
if (layer->is_y_sort_enabled()) {
for (uint32_t i = 0; i < layers.size(); ++i) {
const LayeredTileMapLayer *layer = layers[i];
if (layer->is_sort_enabled()) {
y_sorted_z_index.insert(layer->get_z_index());
}
}
// Check if we have a non-sorted layer in a Z-index with a Y-sorted layer.
for (const LayeredTileMapLayer *layer : layers) {
if (!layer->is_y_sort_enabled() && y_sorted_z_index.has(layer->get_z_index())) {
warnings.push_back(RTR("A Y-sorted layer has the same Z-index value as a not Y-sorted layer.\nThis may lead to unwanted behaviors, as a layer that is not Y-sorted will be Y-sorted as a whole with tiles from Y-sorted layers."));
for (uint32_t i = 0; i < layers.size(); ++i) {
const LayeredTileMapLayer *layer = layers[i];
if (!layer->is_sort_enabled() && y_sorted_z_index.has(layer->get_z_index())) {
warnings += RTR("A Y-sorted layer has the same Z-index value as a not Y-sorted layer.\nThis may lead to unwanted behaviors, as a layer that is not Y-sorted will be Y-sorted as a whole with tiles from Y-sorted layers.") + "\n";
break;
}
}
if (!is_y_sort_enabled()) {
if (!is_sort_enabled()) {
// Check if Y-sort is enabled on a layer but not on the node.
for (const LayeredTileMapLayer *layer : layers) {
if (layer->is_y_sort_enabled()) {
warnings.push_back(RTR("A LayeredTileMap layer is set as Y-sorted, but Y-sort is not enabled on the LayeredTileMap node itself."));
for (uint32_t i = 0; i < layers.size(); ++i) {
const LayeredTileMapLayer *layer = layers[i];
if (layer->is_sort_enabled()) {
warnings += RTR("A LayeredTileMap layer is set as Y-sorted, but Y-sort is not enabled on the LayeredTileMap node itself.") + "\n";
break;
}
}
} else {
// Check if Y-sort is enabled on the node, but not on any of the layers.
bool need_warning = true;
for (const LayeredTileMapLayer *layer : layers) {
if (layer->is_y_sort_enabled()) {
for (uint32_t i = 0; i < layers.size(); ++i) {
const LayeredTileMapLayer *layer = layers[i];
if (layer->is_sort_enabled()) {
need_warning = false;
break;
}
}
if (need_warning) {
warnings.push_back(RTR("The LayeredTileMap node is set as Y-sorted, but Y-sort is not enabled on any of the LayeredTileMap's layers.\nThis may lead to unwanted behaviors, as a layer that is not Y-sorted will be Y-sorted as a whole."));
warnings += RTR("The LayeredTileMap node is set as Y-sorted, but Y-sort is not enabled on any of the LayeredTileMap's layers.\nThis may lead to unwanted behaviors, as a layer that is not Y-sorted will be Y-sorted as a whole.") + "\n";
}
}
// Check if we are in isometric mode without Y-sort enabled.
if (tile_set.is_valid() && tile_set->get_tile_shape() == LayeredTileSet::TILE_SHAPE_ISOMETRIC) {
bool warn = !is_y_sort_enabled();
bool warn = !is_sort_enabled();
if (!warn) {
for (const LayeredTileMapLayer *layer : layers) {
if (!layer->is_y_sort_enabled()) {
for (uint32_t i = 0; i < layers.size(); ++i) {
const LayeredTileMapLayer *layer = layers[i];
if (!layer->is_sort_enabled()) {
warn = true;
break;
}
@ -930,7 +969,7 @@ PoolStringArray LayeredTileMap::get_configuration_warnings() const {
}
if (warn) {
warnings.push_back(RTR("Isometric LayeredTileSet will likely not look as intended without Y-sort enabled for the LayeredTileMap and all of its layers."));
warnings += RTR("Isometric LayeredTileSet will likely not look as intended without Y-sort enabled for the LayeredTileMap and all of its layers.") + "\n";
}
}
@ -1011,8 +1050,22 @@ void LayeredTileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_neighbor_cell", "coords", "neighbor"), &LayeredTileMap::get_neighbor_cell);
GDVIRTUAL_BIND(_use_tile_data_runtime_update, "layer", "coords");
GDVIRTUAL_BIND(_tile_data_runtime_update, "layer", "coords", "tile_data");
BIND_VMETHOD(MethodInfo("_use_tile_data_runtime_update",
PropertyInfo(Variant::INT, "layer"),
PropertyInfo(Variant::VECTOR2I, "pos")));
BIND_VMETHOD(MethodInfo("_tile_data_runtime_update",
PropertyInfo(Variant::INT, "layer"),
PropertyInfo(Variant::VECTOR2I, "pos"),
PropertyInfo(Variant::OBJECT, "tile_data", PROPERTY_HINT_RESOURCE_TYPE, "LayeredTileData")));
ClassDB::bind_method(D_METHOD("use_tile_data_runtime_update", "layer", "pos"), &LayeredTileMap::use_tile_data_runtime_update);
ClassDB::bind_method(D_METHOD("tile_data_runtime_update", "layer", "pos", "tile_data"), &LayeredTileMap::tile_data_runtime_update);
ClassDB::bind_method(D_METHOD("_use_tile_data_runtime_update", "layer", "pos"), &LayeredTileMap::_use_tile_data_runtime_update);
ClassDB::bind_method(D_METHOD("_tile_data_runtime_update", "layer", "pos", "tile_data"), &LayeredTileMap::_tile_data_runtime_update);
ClassDB::bind_method(D_METHOD("_emit_changed"), &LayeredTileMap::_emit_changed);
ADD_PROPERTY(PropertyInfo(Variant::INT, "rendering_quadrant_size", PROPERTY_HINT_RANGE, "1,128,1"), "set_rendering_quadrant_size", "get_rendering_quadrant_size");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_animatable"), "set_collision_animatable", "is_collision_animatable");
@ -1032,10 +1085,11 @@ void LayeredTileMap::_bind_methods() {
LayeredTileMap::LayeredTileMap() {
LayeredTileMapLayer *new_layer = memnew(LayeredTileMapLayer);
add_child(new_layer, false, INTERNAL_MODE_FRONT);
add_child(new_layer);
move_child(new_layer, 0);
new_layer->set_as_tile_map_internal_node(0);
new_layer->set_name("Layer0");
new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LayeredTileMap::_emit_changed));
new_layer->connect(CoreStringNames::get_singleton()->changed, this, "_emit_changed");
layers.push_back(new_layer);
default_layer = memnew(LayeredTileMapLayer);
}

View File

@ -91,16 +91,6 @@ protected:
void _notification(int p_what);
static void _bind_methods();
#ifndef DISABLE_DEPRECATED
Rect2i _get_used_rect_bind_compat_78328();
void _set_quadrant_size_compat_81070(int p_quadrant_size);
int _get_quadrant_size_compat_81070() const;
VisibilityMode _get_collision_visibility_mode_bind_compat_87115();
VisibilityMode _get_navigation_visibility_mode_bind_compat_87115();
static void _bind_compatibility_methods();
#endif
public:
#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
@ -190,8 +180,6 @@ public:
// Override some methods of the CanvasItem class to pass the changes to the quadrants CanvasItems.
virtual void set_light_mask(int p_light_mask);
virtual void set_self_modulate(const Color &p_self_modulate);
virtual void set_texture_filter(CanvasItem::TextureFilter p_texture_filter);
virtual void set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat);
// For finding tiles from collision.
Vector2i get_coords_for_body_rid(RID p_physics_body);
@ -213,11 +201,14 @@ public:
PoolVector2iArray get_surrounding_cells(const Vector2i &p_coords);
// Virtual function to modify the LayeredTileData at runtime.
GDVIRTUAL2R(bool, _use_tile_data_runtime_update, int, Vector2i);
GDVIRTUAL3(_tile_data_runtime_update, int, Vector2i, LayeredTileData *);
bool use_tile_data_runtime_update(const int p_layer, const Vector2i &p_pos);
void tile_data_runtime_update(const int p_layer, const Vector2i &p_pos, LayeredTileData *p_tile_data);
virtual bool _use_tile_data_runtime_update(const int p_layer, const Vector2i &p_pos);
virtual void _tile_data_runtime_update(const int p_layer, const Vector2i &p_pos, LayeredTileData *p_tile_data);
// Configuration warnings.
PoolStringArray get_configuration_warnings() const;
String get_configuration_warning() const;
LayeredTileMap();
~LayeredTileMap();

View File

@ -2559,7 +2559,7 @@ void LayeredTileMapLayer::set_enabled(bool p_enabled) {
emit_signal(CoreStringNames::get_singleton()->changed);
if (tile_map_node) {
tile_map_node->update_configuration_warnings();
tile_map_node->update_configuration_warning();
}
}
@ -2587,7 +2587,7 @@ void LayeredTileMapLayer::set_y_sort_enabled(bool p_y_sort_enabled) {
emit_signal(CoreStringNames::get_singleton()->changed);
if (tile_map_node) {
tile_map_node->update_configuration_warnings();
tile_map_node->update_configuration_warning();
}
_update_notify_local_transform();
}
@ -2616,7 +2616,7 @@ void LayeredTileMapLayer::set_z_index(int p_z_index) {
emit_signal(CoreStringNames::get_singleton()->changed);
if (tile_map_node) {
tile_map_node->update_configuration_warnings();
tile_map_node->update_configuration_warning();
}
}

View File

@ -34,6 +34,7 @@
#include "layered_tile_set.h"
#include "layered_tile_map.h"
#include "scene/2d/y_sort.h"
class LayeredTileSetAtlasSource;
@ -215,8 +216,8 @@ public:
}
};
class LayeredTileMapLayer : public Node2D {
GDCLASS(LayeredTileMapLayer, Node2D);
class LayeredTileMapLayer : public YSort {
GDCLASS(LayeredTileMapLayer, YSort);
public:
enum VisibilityMode {

View File

@ -58,7 +58,7 @@ void LayeredTileMapLayerGroup::_tile_set_changed() {
}
}
update_configuration_warnings();
update_configuration_warning();
}
#ifdef TOOLS_ENABLED

View File

@ -32,12 +32,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "scene/main/node_2d.h"
#include "scene/2d/y_sort.h"
class LayeredTileSet;
class LayeredTileMapLayerGroup : public Node2D {
GDCLASS(LayeredTileMapLayerGroup, Node2D);
class LayeredTileMapLayerGroup : public YSort {
GDCLASS(LayeredTileMapLayerGroup, YSort);
private:
mutable Vector<StringName> selected_layers;

View File

@ -1,49 +0,0 @@
/*************************************************************************/
/* tile_set.compat.inc */
/*************************************************************************/
/* This file is part of: */
/* PANDEMONIUM ENGINE */
/* https://github.com/Relintai/pandemonium_engine */
/*************************************************************************/
/* Copyright (c) 2022-present Péter Magyar. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef DISABLE_DEPRECATED
#include "layered_tile_set.h"
Ref<NavigationPolygon> LayeredTileData::_get_navigation_polygon_bind_compat_84660(int p_layer_id) const {
return get_navigation_polygon(p_layer_id, false, false, false);
}
Ref<OccluderPolygon2D> LayeredTileData::_get_occluder_bind_compat_84660(int p_layer_id) const {
return get_occluder(p_layer_id, false, false, false);
}
void TileData::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("get_navigation_polygon"), &LayeredTileData::_get_navigation_polygon_bind_compat_84660);
ClassDB::bind_compatibility_method(D_METHOD("get_occluder"), &LayeredTileData::_get_occluder_bind_compat_84660);
}
#endif

View File

@ -30,7 +30,6 @@
/*************************************************************************/
#include "layered_tile_set.h"
#include "layered_tile_set.compat.inc"
#include "core/containers/local_vector.h"
#include "core/containers/rb_set.h"
@ -1545,7 +1544,7 @@ Vector<Vector2> LayeredTileSet::get_tile_shape_polygon() const {
return points;
}
void LayeredTileSet::draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled, Ref<Texture> p_texture) {
void LayeredTileSet::draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled, Ref<Texture> p_texture, Ref<Texture> p_normal_texture) {
if (tile_meshes_dirty) {
Vector<Vector2> shape = get_tile_shape_polygon();
Vector<Vector2> uvs;
@ -1584,7 +1583,7 @@ void LayeredTileSet::draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_tr
}
if (p_filled) {
p_canvas_item->draw_mesh(tile_filled_mesh, p_texture, Ref<Texture>(), p_transform, p_color);
p_canvas_item->draw_mesh(tile_filled_mesh, p_texture, p_normal_texture, p_transform, p_color);
} else {
p_canvas_item->draw_mesh(tile_lines_mesh, Ref<Texture>(), Ref<Texture>(), p_transform, p_color);
}
@ -5216,9 +5215,13 @@ real_t LayeredTileSetAtlasSource::get_tile_animation_total_duration(const Vector
ERR_FAIL_COND_V_MSG(!tiles.has(p_atlas_coords), 1, vformat("LayeredTileSetAtlasSource has no tile at %s.", Vector2i(p_atlas_coords)));
real_t sum = 0.0;
for (const real_t &duration : tiles[p_atlas_coords].animation_frames_durations) {
sum += duration;
const LocalVector<real_t> &animation_frames_durations = tiles[p_atlas_coords].animation_frames_durations;
for (uint32_t i = 0; i < animation_frames_durations.size(); ++i) {
sum += animation_frames_durations[i];
}
return sum;
}
@ -5266,20 +5269,31 @@ bool LayeredTileSetAtlasSource::has_room_for_tile(Vector2i p_atlas_coords, Vecto
}
bool LayeredTileSetAtlasSource::has_tiles_outside_texture() const {
for (const KeyValue<Vector2i, LayeredTileSetAtlasSource::TileAlternativesData> &E : tiles) {
if (!has_room_for_tile(E.key, E.value.size_in_atlas, E.value.animation_columns, E.value.animation_separation, E.value.animation_frames_durations.size(), E.key)) {
for (const HashMap<Vector2i, TileAlternativesData>::Element *E = tiles.front(); E; E = E->next) {
if (!has_room_for_tile(E->key(),
E->value().size_in_atlas,
E->value().animation_columns,
E->value().animation_separation,
E->value().animation_frames_durations.size(),
E->key())) {
return true;
}
}
return false;
}
Vector<Vector2i> LayeredTileSetAtlasSource::get_tiles_outside_texture() const {
Vector<Vector2i> to_return;
for (const KeyValue<Vector2i, LayeredTileSetAtlasSource::TileAlternativesData> &E : tiles) {
if (!has_room_for_tile(E.key, E.value.size_in_atlas, E.value.animation_columns, E.value.animation_separation, E.value.animation_frames_durations.size(), E.key)) {
to_return.push_back(E.key);
for (const HashMap<Vector2i, TileAlternativesData>::Element *E = tiles.front(); E; E = E->next) {
if (!has_room_for_tile(E->key(),
E->value().size_in_atlas,
E->value().animation_columns,
E->value().animation_separation,
E->value().animation_frames_durations.size(),
E->key())) {
to_return.push_back(E->key());
}
}
return to_return;
@ -5288,14 +5302,19 @@ Vector<Vector2i> LayeredTileSetAtlasSource::get_tiles_outside_texture() const {
void LayeredTileSetAtlasSource::clear_tiles_outside_texture() {
LocalVector<Vector2i> to_remove;
for (const KeyValue<Vector2i, LayeredTileSetAtlasSource::TileAlternativesData> &E : tiles) {
if (!has_room_for_tile(E.key, E.value.size_in_atlas, E.value.animation_columns, E.value.animation_separation, E.value.animation_frames_durations.size(), E.key)) {
to_remove.push_back(E.key);
for (const HashMap<Vector2i, TileAlternativesData>::Element *E = tiles.front(); E; E = E->next) {
if (!has_room_for_tile(E->key(),
E->value().size_in_atlas,
E->value().animation_columns,
E->value().animation_separation,
E->value().animation_frames_durations.size(),
E->key())) {
to_remove.push_back(E->key());
}
}
for (const Vector2i &v : to_remove) {
remove_tile(v);
for (uint32_t i = 0; i < to_remove.size(); ++i) {
remove_tile(to_remove[i]);
}
}
@ -5316,17 +5335,19 @@ PoolVector2Array LayeredTileSetAtlasSource::get_tiles_to_be_removed_on_change(Re
}
}
Vector<Vector2> output;
for (KeyValue<Vector2i, TileAlternativesData> &E : tiles) {
for (unsigned int frame = 0; frame < E.value.animation_frames_durations.size(); frame++) {
Vector2i frame_coords = E.key + (E.value.size_in_atlas + E.value.animation_separation) * ((E.value.animation_columns > 0) ? Vector2i(frame % E.value.animation_columns, frame / E.value.animation_columns) : Vector2i(frame, 0));
frame_coords += E.value.size_in_atlas;
PoolVector2Array output;
for (HashMap<Vector2i, TileAlternativesData>::Element *E = tiles.front(); E; E = E->next) {
for (unsigned int frame = 0; frame < E->value().animation_frames_durations.size(); frame++) {
Vector2i frame_coords = E->key() + (E->value().size_in_atlas + E->value().animation_separation) * ((E->value().animation_columns > 0) ? Vector2i(frame % E->value().animation_columns, frame / E->value().animation_columns) : Vector2i(frame, 0));
frame_coords += E->value().size_in_atlas;
if (frame_coords.x > new_grid_size.x || frame_coords.y > new_grid_size.y) {
output.push_back(E.key);
output.push_back(E->key());
break;
}
}
}
return output;
}
@ -5425,7 +5446,7 @@ int LayeredTileSetAtlasSource::create_alternative_tile(const Vector2i p_atlas_co
tiles[p_atlas_coords].alternatives[new_alternative_id] = memnew(LayeredTileData);
tiles[p_atlas_coords].alternatives[new_alternative_id]->set_tile_set(tile_set);
tiles[p_atlas_coords].alternatives[new_alternative_id]->set_allow_transform(true);
tiles[p_atlas_coords].alternatives[new_alternative_id]->connect("changed", callable_mp((Resource *)this, &LayeredTileSetAtlasSource::emit_changed));
tiles[p_atlas_coords].alternatives[new_alternative_id]->connect("changed", this, "emit_changed");
//tiles[p_atlas_coords].alternatives[new_alternative_id]->property_list_changed_notify();
tiles[p_atlas_coords].alternatives[new_alternative_id]->_change_notify();
tiles[p_atlas_coords].alternatives_ids.push_back(new_alternative_id);
@ -5574,14 +5595,15 @@ void LayeredTileSetAtlasSource::_bind_methods() {
LayeredTileSetAtlasSource::~LayeredTileSetAtlasSource() {
// Free everything needed.
for (KeyValue<Vector2i, TileAlternativesData> &E_alternatives : tiles) {
for (KeyValue<int, TileData *> &E_tile_data : E_alternatives.value.alternatives) {
memdelete(E_tile_data.value);
for (HashMap<Vector2i, TileAlternativesData>::Element *E_alternatives = tiles.front(); E_alternatives; E_alternatives = E_alternatives->next) {
for (HashMap<int, LayeredTileData *>::Element *E_tile_data = E_alternatives->value().alternatives.front(); E_tile_data; E_tile_data = E_tile_data->next) {
memdelete(E_tile_data->value());
}
}
}
TileData *LayeredTileSetAtlasSource::_get_atlas_tile_data(Vector2i p_atlas_coords, int p_alternative_tile) {
LayeredTileData *LayeredTileSetAtlasSource::_get_atlas_tile_data(Vector2i p_atlas_coords, int p_alternative_tile) {
ERR_FAIL_COND_V_MSG(!tiles.has(p_atlas_coords), nullptr, vformat("LayeredTileSetAtlasSource has no tile at %s.", String(p_atlas_coords)));
p_alternative_tile = alternative_no_transform(p_alternative_tile);
ERR_FAIL_COND_V_MSG(!tiles[p_atlas_coords].alternatives.has(p_alternative_tile), nullptr, vformat("LayeredTileSetAtlasSource has no alternative with id %d for tile coords %s.", p_alternative_tile, String(p_atlas_coords)));
@ -5589,7 +5611,7 @@ TileData *LayeredTileSetAtlasSource::_get_atlas_tile_data(Vector2i p_atlas_coord
return tiles[p_atlas_coords].alternatives[p_alternative_tile];
}
const TileData *LayeredTileSetAtlasSource::_get_atlas_tile_data(Vector2i p_atlas_coords, int p_alternative_tile) const {
const LayeredTileData *LayeredTileSetAtlasSource::_get_atlas_tile_data(Vector2i p_atlas_coords, int p_alternative_tile) const {
ERR_FAIL_COND_V_MSG(!tiles.has(p_atlas_coords), nullptr, vformat("LayeredTileSetAtlasSource has no tile at %s.", String(p_atlas_coords)));
ERR_FAIL_COND_V_MSG(!tiles[p_atlas_coords].alternatives.has(p_alternative_tile), nullptr, vformat("LayeredTileSetAtlasSource has no alternative with id %d for tile coords %s.", p_alternative_tile, String(p_atlas_coords)));
@ -5645,7 +5667,8 @@ void LayeredTileSetAtlasSource::_create_coords_mapping_cache(Vector2i p_atlas_co
void LayeredTileSetAtlasSource::_queue_update_padded_texture() {
padded_texture_needs_update = true;
callable_mp(this, &LayeredTileSetAtlasSource::_update_padded_texture).call_deferred();
call_deferred("_update_padded_texture");
}
Ref<ImageTexture> LayeredTileSetAtlasSource::_create_padded_image_texture(const Ref<Texture> &p_source) {
@ -5659,12 +5682,14 @@ Ref<ImageTexture> LayeredTileSetAtlasSource::_create_padded_image_texture(const
}
Size2 size = get_atlas_grid_size() * (texture_region_size + Vector2i(2, 2));
Ref<Image> image = Image::create_empty(size.x, size.y, false, src_image->get_format());
Ref<Image> image;
image.instance();
image->create(size.x, size.y, false, src_image->get_format());
for (KeyValue<Vector2i, TileAlternativesData> kv : tiles) {
for (int frame = 0; frame < (int)kv.value.animation_frames_durations.size(); frame++) {
for (HashMap<Vector2i, TileAlternativesData>::Element *kv = tiles.front(); kv; kv = kv->next) {
for (int frame = 0; frame < (int)kv->value().animation_frames_durations.size(); frame++) {
// Compute the source rects.
Rect2i src_rect = get_tile_texture_region(kv.key, frame);
Rect2i src_rect = get_tile_texture_region(kv->key(), frame);
Rect2i top_src_rect = Rect2i(src_rect.position, Vector2i(src_rect.size.x, 1));
Rect2i bottom_src_rect = Rect2i(src_rect.position + Vector2i(0, src_rect.size.y - 1), Vector2i(src_rect.size.x, 1));
@ -5672,7 +5697,7 @@ Ref<ImageTexture> LayeredTileSetAtlasSource::_create_padded_image_texture(const
Rect2i right_src_rect = Rect2i(src_rect.position + Vector2i(src_rect.size.x - 1, 0), Vector2i(1, src_rect.size.y));
// Copy the tile and the paddings.
Vector2i frame_coords = kv.key + (kv.value.size_in_atlas + kv.value.animation_separation) * ((kv.value.animation_columns > 0) ? Vector2i(frame % kv.value.animation_columns, frame / kv.value.animation_columns) : Vector2i(frame, 0));
Vector2i frame_coords = kv->key() + (kv->value().size_in_atlas + kv->value().animation_separation) * ((kv->value().animation_columns > 0) ? Vector2i(frame % kv->value().animation_columns, frame / kv->value().animation_columns) : Vector2i(frame, 0));
Vector2i base_pos = frame_coords * (texture_region_size + Vector2i(2, 2)) + Vector2i(1, 1);
image->blit_rect(*src_image, src_rect, base_pos);
@ -5691,20 +5716,26 @@ Ref<ImageTexture> LayeredTileSetAtlasSource::_create_padded_image_texture(const
}
}
return ImageTexture::create_from_image(image);
Ref<ImageTexture> tex;
tex.instance();
tex->create_from_image(image);
return tex;
}
void LayeredTileSetAtlasSource::_update_padded_texture() {
if (!padded_texture_needs_update) {
return;
}
padded_texture_needs_update = false;
if (padded_texture.is_valid()) {
padded_texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LayeredTileSetAtlasSource::_queue_update_padded_texture));
padded_texture->disconnect(CoreStringNames::get_singleton()->changed, this, "_queue_update_padded_texture");
}
padded_texture = Ref<Texture>();
padded_normal_texture = Ref<Texture>();
if (texture.is_null()) {
return;
@ -5714,41 +5745,19 @@ void LayeredTileSetAtlasSource::_update_padded_texture() {
return;
}
padded_texture.instance();
Ref<Texture> src_canvas_texture = texture;
if (src_canvas_texture.is_valid()) {
// Use all textures.
// Diffuse
Ref<Texture> src = src_canvas_texture->get_diffuse_texture();
Ref<ImageTexture> image_texture;
if (src.is_valid()) {
padded_texture->set_diffuse_texture(_create_padded_image_texture(src));
}
// Normal
src = src_canvas_texture->get_normal_texture();
if (src.is_valid()) {
padded_texture->set_normal_texture(_create_padded_image_texture(src));
}
// Specular
src = src_canvas_texture->get_specular_texture();
if (src.is_valid()) {
padded_texture->set_specular_texture(_create_padded_image_texture(src));
}
// Other properties.
padded_texture->set_specular_color(src_canvas_texture->get_specular_color());
padded_texture->set_specular_shininess(src_canvas_texture->get_specular_shininess());
padded_texture->set_texture_filter(src_canvas_texture->get_texture_filter());
padded_texture->set_texture_repeat(src_canvas_texture->get_texture_repeat());
if (texture.is_valid()) {
padded_texture = _create_padded_image_texture(texture);
} else {
// Use only diffuse.
Ref<ImageTexture> image_texture = _create_padded_image_texture(texture);
padded_texture->set_diffuse_texture(image_texture);
padded_texture.instance();
}
padded_texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LayeredTileSetAtlasSource::_queue_update_padded_texture));
if (normal_texture.is_valid()) {
padded_normal_texture = _create_padded_image_texture(normal_texture);
} else {
padded_normal_texture.instance();
}
padded_texture->connect(CoreStringNames::get_singleton()->changed, this, "_queue_update_padded_texture");
emit_changed();
}
@ -5836,9 +5845,12 @@ void LayeredTileSetScenesCollectionSource::set_scene_tile_scene(int p_id, Ref<Pa
type = scene_state->get_node_type(0);
scene_state = scene_state->get_base_scene_state();
}
ERR_FAIL_COND_EDMSG(type.empty(), vformat("Invalid PackedScene for LayeredTileSetScenesCollectionSource: %s. Could not get the type of the root node.", p_packed_scene->get_path()));
ERR_FAIL_COND_MSG(type.empty(), vformat("Invalid PackedScene for LayeredTileSetScenesCollectionSource: %s. Could not get the type of the root node.", p_packed_scene->get_path()));
bool extends_correct_class = ClassDB::is_parent_class(type, "CanvasItem");
ERR_FAIL_COND_EDMSG(!extends_correct_class, vformat("Invalid PackedScene for LayeredTileSetScenesCollectionSource: %s. Root node should extend CanvasItem. Found %s instead.", p_packed_scene->get_path(), type));
ERR_FAIL_COND_MSG(!extends_correct_class, vformat("Invalid PackedScene for LayeredTileSetScenesCollectionSource: %s. Root node should extend CanvasItem. Found %s instead.", p_packed_scene->get_path(), type));
scenes[p_id].scene = p_packed_scene;
} else {
@ -5919,12 +5931,13 @@ bool LayeredTileSetScenesCollectionSource::_get(const StringName &p_name, Varian
void LayeredTileSetScenesCollectionSource::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < scenes_ids.size(); i++) {
p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("%s/%d/%s", PNAME("scenes"), scenes_ids[i], PNAME("scene")), PROPERTY_HINT_RESOURCE_TYPE, "LayeredTileSetScenesCollectionSource"));
p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("%s/%d/%s", "scenes", scenes_ids[i], "scene"), PROPERTY_HINT_RESOURCE_TYPE, "LayeredTileSetScenesCollectionSource"));
PropertyInfo property_info = PropertyInfo(Variant::BOOL, vformat("%s/%d/%s", PNAME("scenes"), scenes_ids[i], PNAME("display_placeholder")));
PropertyInfo property_info = PropertyInfo(Variant::BOOL, vformat("%s/%d/%s", "scenes", scenes_ids[i], "display_placeholder"));
if (scenes[scenes_ids[i]].display_placeholder == false) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
p_list->push_back(property_info);
}
}
@ -5969,12 +5982,12 @@ void LayeredTileData::notify_tile_data_properties_should_change() {
for (int i = 0; i < custom_data.size(); i++) {
if (custom_data[i].get_type() != tile_set->get_custom_data_layer_type(i)) {
Variant new_val;
Callable::CallError error;
Variant::CallError error;
if (Variant::can_convert(custom_data[i].get_type(), tile_set->get_custom_data_layer_type(i))) {
const Variant *args[] = { &custom_data[i] };
Variant::construct(tile_set->get_custom_data_layer_type(i), new_val, args, 1, error);
new_val = Variant::construct(tile_set->get_custom_data_layer_type(i), args, 1, error);
} else {
Variant::construct(tile_set->get_custom_data_layer_type(i), new_val, nullptr, 0, error);
new_val = Variant::construct(tile_set->get_custom_data_layer_type(i), nullptr, 0, error);
}
custom_data.write[i] = new_val;
}
@ -6148,7 +6161,7 @@ bool LayeredTileData::is_allowing_transform() const {
}
LayeredTileData *LayeredTileData::duplicate() {
TileData *output = memnew(TileData);
LayeredTileData *output = memnew(LayeredTileData);
output->tile_set = tile_set;
output->allow_transform = allow_transform;
@ -6269,7 +6282,7 @@ Ref<OccluderPolygon2D> LayeredTileData::get_occluder(int p_layer_id, bool p_flip
return Ref<OccluderPolygon2D>();
}
HashMap<int, Ref<OccluderPolygon2D>>::Iterator I = layer_tile_data.transformed_occluders.find(key);
HashMap<int, Ref<OccluderPolygon2D>>::Element *I = layer_tile_data.transformed_occluders.find(key);
if (!I) {
Ref<OccluderPolygon2D> transformed_polygon;
transformed_polygon.instance();
@ -6277,7 +6290,7 @@ Ref<OccluderPolygon2D> LayeredTileData::get_occluder(int p_layer_id, bool p_flip
layer_tile_data.transformed_occluders[key] = transformed_polygon;
return transformed_polygon;
} else {
return I->value;
return I->value();
}
}
@ -6338,7 +6351,7 @@ void LayeredTileData::set_collision_polygon_points(int p_layer_id, int p_polygon
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
ERR_FAIL_COND_MSG(p_polygon.size() != 0 && p_polygon.size() < 3, "Invalid polygon. Needs either 0 or more than 3 points.");
TileData::PhysicsLayerTileData::PolygonShapeTileData &polygon_shape_tile_data = physics.write[p_layer_id].polygons.write[p_polygon_index];
LayeredTileData::PhysicsLayerTileData::PolygonShapeTileData &polygon_shape_tile_data = physics.write[p_layer_id].polygons.write[p_polygon_index];
if (p_polygon.empty()) {
polygon_shape_tile_data.shapes.clear();
@ -6414,19 +6427,24 @@ Ref<ConvexPolygonShape2D> LayeredTileData::get_collision_polygon_shape(int p_lay
return Ref<ConvexPolygonShape2D>();
}
HashMap<int, LocalVector<Ref<ConvexPolygonShape2D>>>::Iterator I = shapes_data.transformed_shapes.find(key);
HashMap<int, LocalVector<Ref<ConvexPolygonShape2D>>>::Element *I = shapes_data.transformed_shapes.find(key);
if (!I) {
int size = shapes_data.shapes.size();
shapes_data.transformed_shapes[key].resize(size);
for (int i = 0; i < size; i++) {
Ref<ConvexPolygonShape2D> transformed_polygon;
transformed_polygon.instance();
transformed_polygon->set_points(get_transformed_vertices(shapes_data.shapes[shape_index]->get_points(), p_flip_h, p_flip_v, p_transpose));
PoolVector2Array points = Variant(shapes_data.shapes[shape_index]->get_points());
PoolVector2Array tv = get_transformed_vertices(points, p_flip_h, p_flip_v, p_transpose);
transformed_polygon->set_points(Variant(tv));
shapes_data.transformed_shapes[key][i] = transformed_polygon;
}
return shapes_data.transformed_shapes[key][shape_index];
} else {
return I->value[shape_index];
return I->value()[shape_index];
}
}
@ -6524,7 +6542,7 @@ Ref<NavigationPolygon> LayeredTileData::get_navigation_polygon(int p_layer_id, b
return Ref<NavigationPolygon>();
}
HashMap<int, Ref<NavigationPolygon>>::Iterator I = layer_tile_data.transformed_navigation_polygon.find(key);
HashMap<int, Ref<NavigationPolygon>>::Element *I = layer_tile_data.transformed_navigation_polygon.find(key);
if (!I) {
Ref<NavigationPolygon> transformed_polygon;
transformed_polygon.instance();
@ -6537,7 +6555,7 @@ Ref<NavigationPolygon> LayeredTileData::get_navigation_polygon(int p_layer_id, b
transformed_polygon->add_outline(new_outline);
}
PackedInt32Array indices;
Vector<int> indices;
indices.resize(new_points.size());
int *w = indices.ptrw();
for (int i = 0; i < new_points.size(); i++) {
@ -6547,7 +6565,7 @@ Ref<NavigationPolygon> LayeredTileData::get_navigation_polygon(int p_layer_id, b
layer_tile_data.transformed_navigation_polygon[key] = transformed_polygon;
return transformed_polygon;
} else {
return I->value;
return I->value();
}
}
@ -6588,12 +6606,14 @@ Variant LayeredTileData::get_custom_data_by_layer_id(int p_layer_id) const {
}
PoolVector2Array LayeredTileData::get_transformed_vertices(const PoolVector2Array &p_vertices, bool p_flip_h, bool p_flip_v, bool p_transpose) {
const Vector2 *r = p_vertices.ptr();
PoolVector2Array::Read vread = p_vertices.read();
const Vector2 *r = vread.ptr();
int size = p_vertices.size();
PoolVector2Array new_points;
new_points.resize(size);
Vector2 *w = new_points.ptrw();
PoolVector2Array::Write nwrite = new_points.write();
Vector2 *w = nwrite.ptr();
for (int i = 0; i < size; i++) {
Vector2 v;
@ -6611,6 +6631,7 @@ PoolVector2Array LayeredTileData::get_transformed_vertices(const PoolVector2Arra
}
w[i] = v;
}
return new_points;
}
@ -6860,10 +6881,12 @@ void LayeredTileData::_get_property_list(List<PropertyInfo> *p_list) const {
for (int j = 0; j < physics[i].polygons.size(); j++) {
// physics_layer_%d/points
property_info = PropertyInfo(Variant::ARRAY, vformat("physics_layer_%d/polygon_%d/%s", i, j, "points"), PROPERTY_HINT_ARRAY_TYPE, "Vector2", PROPERTY_USAGE_DEFAULT);
property_info = PropertyInfo(Variant::POOL_VECTOR2_ARRAY, vformat("physics_layer_%d/polygon_%d/%s", i, j, "points"));
if (physics[i].polygons[j].polygon.empty()) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
p_list->push_back(property_info);
// physics_layer_%d/polygon_%d/one_way
@ -6911,8 +6934,8 @@ void LayeredTileData::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::NIL, "Custom Data", PROPERTY_HINT_NONE, "custom_data_", PROPERTY_USAGE_GROUP));
for (int i = 0; i < custom_data.size(); i++) {
Variant default_val;
Callable::CallError error;
Variant::construct(custom_data[i].get_type(), default_val, nullptr, 0, error);
Variant::CallError error;
default_val = Variant::construct(custom_data[i].get_type(), nullptr, 0, error);
property_info = PropertyInfo(tile_set->get_custom_data_layer_type(i), vformat("custom_data_%d", i), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
if (custom_data[i] == default_val) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;

View File

@ -530,7 +530,7 @@ public:
// Helpers
Vector<Vector2> get_tile_shape_polygon() const;
void draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled = false, Ref<Texture> p_texture = Ref<Texture>());
void draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled = false, Ref<Texture> p_texture = Ref<Texture>(), Ref<Texture> p_normal_texture = Ref<Texture>());
// Used by LayeredTileMap/LayeredTileMapLayer
Vector2 map_to_local(const Vector2i &p_pos) const;
@ -638,6 +638,7 @@ private:
};
Ref<Texture> texture;
Ref<Texture> normal_texture;
Vector2i margins;
Vector2i separation;
Size2i texture_region_size = Size2i(16, 16);
@ -656,6 +657,7 @@ private:
bool use_texture_padding = true;
Ref<Texture> padded_texture;
Ref<Texture> padded_normal_texture;
bool padded_texture_needs_update = false;
void _queue_update_padded_texture();
Ref<ImageTexture> _create_padded_image_texture(const Ref<Texture> &p_source);
@ -751,7 +753,7 @@ public:
virtual int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const;
// Get data associated to a tile.
TileData *get_tile_data(const Vector2i p_atlas_coords, int p_alternative_tile) const;
LayeredTileData *get_tile_data(const Vector2i p_atlas_coords, int p_alternative_tile) const;
// Helpers.
Vector2i get_atlas_grid_size() const;
@ -876,13 +878,6 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const;
static void _bind_methods();
#ifndef DISABLE_DEPRECATED
Ref<NavigationPolygon> _get_navigation_polygon_bind_compat_84660(int p_layer_id) const;
Ref<OccluderPolygon2D> _get_occluder_bind_compat_84660(int p_layer_id) const;
static void _bind_compatibility_methods();
#endif
public:
// Not exposed.
void set_tile_set(const LayeredTileSet *p_tile_set);