Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes TileSet set as local to scene #78477

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/classes/TileSet.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<description>
Adds a [TileSetSource] to the TileSet. If [param atlas_source_id_override] is not -1, also set its source ID. Otherwise, a unique identifier is automatically generated.
The function returns the added source ID or -1 if the source could not be added.
[b]Warning:[/b] A source cannot belong to two TileSets at the same time. If the added source was attached to another [TileSet], it will be removed from that one.
</description>
</method>
<method name="add_terrain">
Expand Down
1 change: 1 addition & 0 deletions doc/classes/TileSetSource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
Tiles in a source are indexed with two IDs, coordinates ID (of type Vector2i) and an alternative ID (of type int), named according to their use in the [TileSetAtlasSource] class.
Depending on the TileSet source type, those IDs might have restrictions on their values, this is why the base [TileSetSource] class only exposes getters for them.
You can iterate over all tiles exposed by a TileSetSource by first iterating over coordinates IDs using [method get_tiles_count] and [method get_tile_id], then over alternative IDs using [method get_alternative_tiles_count] and [method get_alternative_tile_id].
[b]Warning:[/b] [TileSetSource] can only be added to one TileSet at the same time. Calling [method TileSet.add_source] on a second [TileSet] will remove the source from the first one.
</description>
<tutorials>
</tutorials>
Expand Down
24 changes: 22 additions & 2 deletions scene/resources/tile_set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,11 @@ int TileSet::add_source(Ref<TileSetSource> p_tile_set_source, int p_atlas_source
sources[new_source_id] = p_tile_set_source;
source_ids.push_back(new_source_id);
source_ids.sort();
TileSet *old_tileset = p_tile_set_source->get_tile_set();
if (old_tileset != this && old_tileset != nullptr) {
// If the source is already in a TileSet (might happen when duplicating), remove it from the other TileSet.
old_tileset->remove_source_ptr(p_tile_set_source.ptr());
}
p_tile_set_source->set_tile_set(this);
_compute_next_source_id();

Expand All @@ -504,6 +509,16 @@ void TileSet::remove_source(int p_source_id) {
emit_changed();
}

void TileSet::remove_source_ptr(TileSetSource *p_tile_set_source) {
for (const KeyValue<int, Ref<TileSetSource>> &kv : sources) {
if (kv.value.ptr() == p_tile_set_source) {
remove_source(kv.key);
return;
}
}
ERR_FAIL_MSG(vformat("Attempting to remove source from a tileset, but the tileset doesn't have it: %s", p_tile_set_source));
}

void TileSet::set_source_id(int p_source_id, int p_new_source_id) {
ERR_FAIL_COND(p_new_source_id < 0);
ERR_FAIL_COND_MSG(!sources.has(p_source_id), vformat("Cannot change TileSet atlas source ID. No tileset atlas source with id %d.", p_source_id));
Expand Down Expand Up @@ -3140,9 +3155,10 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
// Create source only if it does not exists.
int source_id = components[1].to_int();

if (!has_source(source_id)) {
add_source(p_value, source_id);
if (has_source(source_id)) {
remove_source(source_id);
}
add_source(p_value, source_id);
return true;
} else if (components.size() == 2 && components[0] == "tile_proxies") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::ARRAY, false);
Expand Down Expand Up @@ -3587,6 +3603,10 @@ void TileSetSource::set_tile_set(const TileSet *p_tile_set) {
tile_set = p_tile_set;
}

TileSet *TileSetSource::get_tile_set() const {
return (TileSet *)tile_set;
}

void TileSetSource::reset_state() {
tile_set = nullptr;
};
Expand Down
2 changes: 2 additions & 0 deletions scene/resources/tile_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ class TileSet : public Resource {
int add_source(Ref<TileSetSource> p_tile_set_source, int p_source_id_override = -1);
void set_source_id(int p_source_id, int p_new_id);
void remove_source(int p_source_id);
void remove_source_ptr(TileSetSource *p_tile_set_source); // Not exposed
bool has_source(int p_source_id) const;
Ref<TileSetSource> get_source(int p_source_id) const;

Expand Down Expand Up @@ -555,6 +556,7 @@ class TileSetSource : public Resource {

// Not exposed.
virtual void set_tile_set(const TileSet *p_tile_set);
TileSet *get_tile_set() const;
virtual void notify_tile_data_properties_should_change(){};
virtual void add_occlusion_layer(int p_index){};
virtual void move_occlusion_layer(int p_from_index, int p_to_pos){};
Expand Down