Implement properties arrays in the Inspector.
This commit is contained in:
parent
b0b30aaf41
commit
4bd7700e89
|
@ -593,6 +593,7 @@ void register_global_constants() {
|
|||
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFERRED_SET_RESOURCE);
|
||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT);
|
||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR_BASIC_SETTING);
|
||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_ARRAY);
|
||||
|
||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT);
|
||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT_INTL);
|
||||
|
|
|
@ -1028,6 +1028,18 @@ void ClassDB::add_property_subgroup(const StringName &p_class, const String &p_n
|
|||
type->property_list.push_back(PropertyInfo(Variant::NIL, p_name, PROPERTY_HINT_NONE, p_prefix, PROPERTY_USAGE_SUBGROUP));
|
||||
}
|
||||
|
||||
void ClassDB::add_property_array_count(const StringName &p_class, const String &p_label, const StringName &p_count_property, const StringName &p_count_setter, const StringName &p_count_getter, const String &p_array_element_prefix, uint32_t p_count_usage) {
|
||||
add_property(p_class, PropertyInfo(Variant::INT, p_count_property, PROPERTY_HINT_NONE, "", p_count_usage | PROPERTY_USAGE_ARRAY, vformat("%s,%s", p_label, p_array_element_prefix)), p_count_setter, p_count_getter);
|
||||
}
|
||||
|
||||
void ClassDB::add_property_array(const StringName &p_class, const StringName &p_path, const String &p_array_element_prefix) {
|
||||
OBJTYPE_WLOCK;
|
||||
ClassInfo *type = classes.getptr(p_class);
|
||||
ERR_FAIL_COND(!type);
|
||||
|
||||
type->property_list.push_back(PropertyInfo(Variant::NIL, p_path, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, p_array_element_prefix));
|
||||
}
|
||||
|
||||
// NOTE: For implementation simplicity reasons, this method doesn't allow setters to have optional arguments at the end.
|
||||
void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
|
||||
lock.read_lock();
|
||||
|
|
|
@ -353,6 +353,8 @@ public:
|
|||
|
||||
static void add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix = "");
|
||||
static void add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix = "");
|
||||
static void add_property_array_count(const StringName &p_class, const String &p_label, const StringName &p_count_property, const StringName &p_count_setter, const StringName &p_count_getter, const String &p_array_element_prefix, uint32_t p_count_usage = PROPERTY_USAGE_EDITOR);
|
||||
static void add_property_array(const StringName &p_class, const StringName &p_path, const String &p_array_element_prefix);
|
||||
static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
|
||||
static void set_property_default_value(const StringName &p_class, const StringName &p_name, const Variant &p_default);
|
||||
static void add_linked_property(const StringName &p_class, const String &p_property, const String &p_linked_property);
|
||||
|
|
|
@ -132,7 +132,8 @@ enum PropertyUsageFlags {
|
|||
PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 << 26, // when loading, the resource for this property can be set at the end of loading
|
||||
PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 27, // For Object properties, instantiate them when creating in editor.
|
||||
PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 << 28, //for project or editor settings, show when basic settings are selected
|
||||
PROPERTY_USAGE_READ_ONLY = 1 << 29,
|
||||
PROPERTY_USAGE_READ_ONLY = 1 << 29, // Mark a property as read-only in the inspector.
|
||||
PROPERTY_USAGE_ARRAY = 1 << 30, // Used in the inspector to group properties as elements of an array.
|
||||
|
||||
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
|
||||
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
|
||||
|
@ -147,6 +148,10 @@ enum PropertyUsageFlags {
|
|||
#define ADD_SUBGROUP(m_name, m_prefix) ::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix)
|
||||
#define ADD_LINKED_PROPERTY(m_property, m_linked_property) ::ClassDB::add_linked_property(get_class_static(), m_property, m_linked_property)
|
||||
|
||||
#define ADD_ARRAY_COUNT(m_label, m_count_property, m_count_property_setter, m_count_property_getter, m_prefix) ClassDB::add_property_array_count(get_class_static(), m_label, m_count_property, _scs_create(m_count_property_setter), _scs_create(m_count_property_getter), m_prefix)
|
||||
#define ADD_ARRAY_COUNT_WITH_USAGE_FLAGS(m_label, m_count_property, m_count_property_setter, m_count_property_getter, m_prefix, m_property_usage_flags) ClassDB::add_property_array_count(get_class_static(), m_label, m_count_property, _scs_create(m_count_property_setter), _scs_create(m_count_property_getter), m_prefix, m_property_usage_flags)
|
||||
#define ADD_ARRAY(m_array_path, m_prefix) ClassDB::add_property_array(get_class_static(), m_array_path, m_prefix)
|
||||
|
||||
struct PropertyInfo {
|
||||
Variant::Type type = Variant::NIL;
|
||||
String name;
|
||||
|
|
|
@ -169,7 +169,8 @@ CallableCustomUnbind::~CallableCustomUnbind() {
|
|||
}
|
||||
|
||||
Callable callable_bind(const Callable &p_callable, const Variant &p_arg1) {
|
||||
return p_callable.bind((const Variant **)&p_arg1, 1);
|
||||
const Variant *args[1] = { &p_arg1 };
|
||||
return p_callable.bind(args, 1);
|
||||
}
|
||||
|
||||
Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2) {
|
||||
|
|
|
@ -2425,6 +2425,8 @@
|
|||
</constant>
|
||||
<constant name="PROPERTY_USAGE_EDITOR_BASIC_SETTING" value="268435456" enum="PropertyUsageFlags">
|
||||
</constant>
|
||||
<constant name="PROPERTY_USAGE_ARRAY" value="1073741824" enum="PropertyUsageFlags">
|
||||
</constant>
|
||||
<constant name="PROPERTY_USAGE_DEFAULT" value="7" enum="PropertyUsageFlags">
|
||||
Default usage (storage, editor and network).
|
||||
</constant>
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
<link title="2D Kinematic Character Demo">https://godotengine.org/asset-library/asset/113</link>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="add_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="arg0" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="clear">
|
||||
<return type="void" />
|
||||
<description>
|
||||
|
@ -71,6 +77,11 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_layers_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_neighbor_cell" qualifiers="const">
|
||||
<return type="Vector2i" />
|
||||
<argument index="0" name="coords" type="Vector2i" />
|
||||
|
@ -116,6 +127,19 @@
|
|||
Returns the local position corresponding to the given tilemap (grid-based) coordinates.
|
||||
</description>
|
||||
</method>
|
||||
<method name="move_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="arg0" type="int" />
|
||||
<argument index="1" name="arg1" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="arg0" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_cell">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer" type="int" />
|
||||
|
@ -176,8 +200,6 @@
|
|||
</member>
|
||||
<member name="collision_visibility_mode" type="int" setter="set_collision_visibility_mode" getter="get_collision_visibility_mode" enum="TileMap.VisibilityMode" default="0">
|
||||
</member>
|
||||
<member name="layers_count" type="int" setter="set_layers_count" getter="get_layers_count" default="1">
|
||||
</member>
|
||||
<member name="navigation_visibility_mode" type="int" setter="set_navigation_visibility_mode" getter="get_navigation_visibility_mode" enum="TileMap.VisibilityMode" default="0">
|
||||
</member>
|
||||
<member name="tile_set" type="TileSet" setter="set_tileset" getter="get_tileset">
|
||||
|
|
|
@ -17,6 +17,30 @@
|
|||
<link title="2D Kinematic Character Demo">https://godotengine.org/asset-library/asset/113</link>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="add_custom_data_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="to_position" type="int" default="-1" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_navigation_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="to_position" type="int" default="-1" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_occlusion_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="to_position" type="int" default="-1" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_physics_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="to_position" type="int" default="-1" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_source">
|
||||
<return type="int" />
|
||||
<argument index="0" name="atlas_source_id_override" type="TileSetSource" />
|
||||
|
@ -24,6 +48,19 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_terrain">
|
||||
<return type="void" />
|
||||
<argument index="0" name="terrain_set" type="int" />
|
||||
<argument index="1" name="to_position" type="int" default="-1" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_terrain_set">
|
||||
<return type="void" />
|
||||
<argument index="0" name="to_position" type="int" default="-1" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="cleanup_invalid_tile_proxies">
|
||||
<return type="void" />
|
||||
<description>
|
||||
|
@ -49,12 +86,22 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_custom_data_layers_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_navigation_layer_layers" qualifiers="const">
|
||||
<return type="int" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_navigation_layers_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_next_source_id" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
|
@ -72,6 +119,11 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_occlusion_layers_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_physics_layer_collision_layer" qualifiers="const">
|
||||
<return type="int" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
|
@ -90,6 +142,11 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_physics_layers_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_source" qualifiers="const">
|
||||
<return type="TileSetSource" />
|
||||
<argument index="0" name="index" type="int" />
|
||||
|
@ -133,6 +190,11 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_terrain_sets_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_terrains_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<argument index="0" name="terrain_set" type="int" />
|
||||
|
@ -174,6 +236,49 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="move_custom_data_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<argument index="1" name="to_position" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="move_navigation_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<argument index="1" name="to_position" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="move_occlusion_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<argument index="1" name="to_position" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="move_physics_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<argument index="1" name="to_position" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="move_terrain">
|
||||
<return type="void" />
|
||||
<argument index="0" name="terrain_set" type="int" />
|
||||
<argument index="1" name="terrain_index" type="int" />
|
||||
<argument index="2" name="to_position" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="move_terrain_set">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<argument index="1" name="to_position" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_alternative_level_tile_proxy">
|
||||
<return type="void" />
|
||||
<argument index="0" name="source_from" type="int" />
|
||||
|
@ -189,6 +294,30 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_custom_data_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_navigation_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_occlusion_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_physics_layer">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_source">
|
||||
<return type="void" />
|
||||
<argument index="0" name="source_id" type="int" />
|
||||
|
@ -201,6 +330,19 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_terrain">
|
||||
<return type="void" />
|
||||
<argument index="0" name="terrain_set" type="int" />
|
||||
<argument index="1" name="terrain_index" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_terrain_set">
|
||||
<return type="void" />
|
||||
<argument index="0" name="layer_index" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_alternative_level_tile_proxy">
|
||||
<return type="void" />
|
||||
<argument index="0" name="source_from" type="int" />
|
||||
|
@ -300,25 +442,8 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_terrains_count">
|
||||
<return type="void" />
|
||||
<argument index="0" name="terrain_set" type="int" />
|
||||
<argument index="1" name="terrains_count" type="int" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="custom_data_layers_count" type="int" setter="set_custom_data_layers_count" getter="get_custom_data_layers_count" default="0">
|
||||
</member>
|
||||
<member name="navigation_layers_count" type="int" setter="set_navigation_layers_count" getter="get_navigation_layers_count" default="0">
|
||||
</member>
|
||||
<member name="occlusion_layers_count" type="int" setter="set_occlusion_layers_count" getter="get_occlusion_layers_count" default="0">
|
||||
</member>
|
||||
<member name="physics_layers_count" type="int" setter="set_physics_layers_count" getter="get_physics_layers_count" default="0">
|
||||
</member>
|
||||
<member name="terrains_sets_count" type="int" setter="set_terrain_sets_count" getter="get_terrain_sets_count" default="0">
|
||||
</member>
|
||||
<member name="tile_layout" type="int" setter="set_tile_layout" getter="get_tile_layout" enum="TileSet.TileLayout" default="0">
|
||||
</member>
|
||||
<member name="tile_offset_axis" type="int" setter="set_tile_offset_axis" getter="get_tile_offset_axis" enum="TileSet.TileOffsetAxis" default="0">
|
||||
|
|
|
@ -277,7 +277,7 @@ void DocTools::generate(bool p_basic_types) {
|
|||
EO = EO->next();
|
||||
}
|
||||
|
||||
if (E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP || E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_INTERNAL) {
|
||||
if (E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP || E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_INTERNAL || (E.type == Variant::NIL && E.usage & PROPERTY_USAGE_ARRAY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -438,6 +438,21 @@ const Vector<Callable> EditorData::get_undo_redo_inspector_hook_callback() {
|
|||
return undo_redo_callbacks;
|
||||
}
|
||||
|
||||
void EditorData::add_move_array_element_function(const StringName &p_class, Callable p_callable) {
|
||||
move_element_functions.insert(p_class, p_callable);
|
||||
}
|
||||
|
||||
void EditorData::remove_move_array_element_function(const StringName &p_class) {
|
||||
move_element_functions.erase(p_class);
|
||||
}
|
||||
|
||||
Callable EditorData::get_move_array_element_function(const StringName &p_class) const {
|
||||
if (move_element_functions.has(p_class)) {
|
||||
return move_element_functions[p_class];
|
||||
}
|
||||
return Callable();
|
||||
}
|
||||
|
||||
void EditorData::remove_editor_plugin(EditorPlugin *p_plugin) {
|
||||
p_plugin->undo_redo = nullptr;
|
||||
editor_plugins.erase(p_plugin);
|
||||
|
|
|
@ -133,6 +133,7 @@ private:
|
|||
List<PropertyData> clipboard;
|
||||
UndoRedo undo_redo;
|
||||
Vector<Callable> undo_redo_callbacks;
|
||||
Map<StringName, Callable> move_element_functions;
|
||||
|
||||
void _cleanup_history();
|
||||
|
||||
|
@ -167,10 +168,14 @@ public:
|
|||
EditorPlugin *get_editor_plugin(int p_idx);
|
||||
|
||||
UndoRedo &get_undo_redo();
|
||||
void add_undo_redo_inspector_hook_callback(Callable p_callable); // Callbacks should have 4 args: (Object* undo_redo, Object *modified_object, String property, Variant new_value)
|
||||
void add_undo_redo_inspector_hook_callback(Callable p_callable); // Callbacks should have this signature: void (Object* undo_redo, Object *modified_object, String property, Variant new_value)
|
||||
void remove_undo_redo_inspector_hook_callback(Callable p_callable);
|
||||
const Vector<Callable> get_undo_redo_inspector_hook_callback();
|
||||
|
||||
void add_move_array_element_function(const StringName &p_class, Callable p_callable); // Function should have this signature: void (Object* undo_redo, Object *modified_object, String array_prefix, int element_index, int new_position)
|
||||
void remove_move_array_element_function(const StringName &p_class);
|
||||
Callable get_move_array_element_function(const StringName &p_class) const;
|
||||
|
||||
void save_editor_global_states();
|
||||
void restore_editor_global_states();
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,8 +32,12 @@
|
|||
#define EDITOR_INSPECTOR_H
|
||||
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/dialogs.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/panel_container.h"
|
||||
#include "scene/gui/scroll_container.h"
|
||||
#include "scene/gui/texture_rect.h"
|
||||
|
||||
class UndoRedo;
|
||||
|
||||
|
@ -251,9 +255,7 @@ class EditorInspectorSection : public Container {
|
|||
|
||||
String label;
|
||||
String section;
|
||||
Object *object;
|
||||
VBoxContainer *vbox;
|
||||
bool vbox_added; //optimization
|
||||
bool vbox_added; // Optimization.
|
||||
Color bg_color;
|
||||
bool foldable;
|
||||
|
||||
|
@ -263,6 +265,9 @@ class EditorInspectorSection : public Container {
|
|||
void _test_unfold();
|
||||
|
||||
protected:
|
||||
Object *object;
|
||||
VBoxContainer *vbox;
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
||||
|
@ -281,6 +286,118 @@ public:
|
|||
~EditorInspectorSection();
|
||||
};
|
||||
|
||||
class EditorInspectorArray : public EditorInspectorSection {
|
||||
GDCLASS(EditorInspectorArray, EditorInspectorSection);
|
||||
|
||||
UndoRedo *undo_redo;
|
||||
|
||||
enum Mode {
|
||||
MODE_NONE,
|
||||
MODE_USE_COUNT_PROPERTY,
|
||||
MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION,
|
||||
} mode;
|
||||
StringName count_property;
|
||||
StringName array_element_prefix;
|
||||
|
||||
int count = 0;
|
||||
|
||||
VBoxContainer *elements_vbox;
|
||||
|
||||
Control *control_dropping;
|
||||
bool dropping = false;
|
||||
|
||||
Button *add_button;
|
||||
|
||||
AcceptDialog *resize_dialog;
|
||||
int new_size = 0;
|
||||
LineEdit *new_size_line_edit;
|
||||
|
||||
// Pagination
|
||||
int page_lenght = 5;
|
||||
int page = 0;
|
||||
int max_page = 0;
|
||||
int begin_array_index = 0;
|
||||
int end_array_index = 0;
|
||||
HBoxContainer *hbox_pagination;
|
||||
Button *first_page_button;
|
||||
Button *prev_page_button;
|
||||
LineEdit *page_line_edit;
|
||||
Label *page_count_label;
|
||||
Button *next_page_button;
|
||||
Button *last_page_button;
|
||||
|
||||
enum MenuOptions {
|
||||
OPTION_MOVE_UP = 0,
|
||||
OPTION_MOVE_DOWN,
|
||||
OPTION_NEW_BEFORE,
|
||||
OPTION_NEW_AFTER,
|
||||
OPTION_REMOVE,
|
||||
OPTION_CLEAR_ARRAY,
|
||||
OPTION_RESIZE_ARRAY,
|
||||
};
|
||||
int popup_array_index_pressed = -1;
|
||||
PopupMenu *rmb_popup;
|
||||
|
||||
struct ArrayElement {
|
||||
PanelContainer *panel;
|
||||
MarginContainer *margin;
|
||||
HBoxContainer *hbox;
|
||||
TextureRect *move_texture_rect;
|
||||
VBoxContainer *vbox;
|
||||
};
|
||||
LocalVector<ArrayElement> array_elements;
|
||||
|
||||
Ref<StyleBoxFlat> odd_style;
|
||||
Ref<StyleBoxFlat> even_style;
|
||||
|
||||
int _get_array_count();
|
||||
void _add_button_pressed();
|
||||
|
||||
void _first_page_button_pressed();
|
||||
void _prev_page_button_pressed();
|
||||
void _page_line_edit_text_submitted(String p_text);
|
||||
void _next_page_button_pressed();
|
||||
void _last_page_button_pressed();
|
||||
|
||||
void _rmb_popup_id_pressed(int p_id);
|
||||
|
||||
void _control_dropping_draw();
|
||||
|
||||
void _vbox_visibility_changed();
|
||||
|
||||
void _panel_draw(int p_index);
|
||||
void _panel_gui_input(Ref<InputEvent> p_event, int p_index);
|
||||
void _move_element(int p_element_index, int p_to_pos);
|
||||
void _clear_array();
|
||||
void _resize_array(int p_size);
|
||||
Array _extract_properties_as_array(const List<PropertyInfo> &p_list);
|
||||
int _drop_position() const;
|
||||
|
||||
void _new_size_line_edit_text_changed(String p_text);
|
||||
void _new_size_line_edit_text_submitted(String p_text);
|
||||
void _resize_dialog_confirmed();
|
||||
|
||||
void _update_elements_visibility();
|
||||
void _setup();
|
||||
|
||||
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
|
||||
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
||||
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_undo_redo(UndoRedo *p_undo_redo);
|
||||
|
||||
void setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable);
|
||||
void setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable);
|
||||
VBoxContainer *get_vbox(int p_index);
|
||||
|
||||
EditorInspectorArray();
|
||||
};
|
||||
|
||||
class EditorInspector : public ScrollContainer {
|
||||
GDCLASS(EditorInspector, ScrollContainer);
|
||||
|
||||
|
@ -342,7 +459,7 @@ class EditorInspector : public ScrollContainer {
|
|||
|
||||
void _property_changed(const String &p_path, const Variant &p_value, const String &p_name = "", bool p_changing = false);
|
||||
void _property_changed_update_all(const String &p_path, const Variant &p_value, const String &p_name = "", bool p_changing = false);
|
||||
void _multiple_properties_changed(Vector<String> p_paths, Array p_values);
|
||||
void _multiple_properties_changed(Vector<String> p_paths, Array p_values, bool p_changing = false);
|
||||
void _property_keyed(const String &p_path, bool p_advance);
|
||||
void _property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance);
|
||||
void _property_deleted(const String &p_path);
|
||||
|
@ -355,6 +472,9 @@ class EditorInspector : public ScrollContainer {
|
|||
|
||||
void _node_removed(Node *p_node);
|
||||
|
||||
Map<StringName, int> per_array_page;
|
||||
void _page_change_request(int p_new_page, const StringName &p_array_prefix);
|
||||
|
||||
void _changed_callback();
|
||||
void _edit_request_change(Object *p_object, const String &p_prop);
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
width="12"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="PageFirst.svg"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs8" />
|
||||
<sodipodi:namedview
|
||||
id="namedview6"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="true"
|
||||
inkscape:zoom="74.25"
|
||||
inkscape:cx="18.053872"
|
||||
inkscape:cy="6.5252525"
|
||||
inkscape:window-width="3838"
|
||||
inkscape:window-height="1582"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="16"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid989" />
|
||||
</sodipodi:namedview>
|
||||
<path
|
||||
d="M 6,9 3,6 6,3"
|
||||
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path2" />
|
||||
<path
|
||||
d="M 9,9 V 3"
|
||||
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path2211"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
width="12"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="PageLast.svg"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs8" />
|
||||
<sodipodi:namedview
|
||||
id="namedview6"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="true"
|
||||
inkscape:zoom="74.25"
|
||||
inkscape:cx="18.053872"
|
||||
inkscape:cy="6.5252525"
|
||||
inkscape:window-width="3838"
|
||||
inkscape:window-height="1582"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="16"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid989" />
|
||||
</sodipodi:namedview>
|
||||
<path
|
||||
d="m 6.0000414,9 3,-3 -3,-3"
|
||||
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path2" />
|
||||
<path
|
||||
d="M 3.0000414,9 V 3"
|
||||
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path2211"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
width="12"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="PageNext.svg"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs8" />
|
||||
<sodipodi:namedview
|
||||
id="namedview6"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="true"
|
||||
inkscape:zoom="105.00536"
|
||||
inkscape:cx="4.5854803"
|
||||
inkscape:cy="5.9377923"
|
||||
inkscape:window-width="3838"
|
||||
inkscape:window-height="1582"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="16"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid989" />
|
||||
</sodipodi:namedview>
|
||||
<path
|
||||
d="m 4.5000207,9 3,-3 -3,-3"
|
||||
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path2" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
width="12"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="PagePrevious.svg"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs8" />
|
||||
<sodipodi:namedview
|
||||
id="namedview6"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="true"
|
||||
inkscape:zoom="105.00536"
|
||||
inkscape:cx="4.5854803"
|
||||
inkscape:cy="5.9377923"
|
||||
inkscape:window-width="3838"
|
||||
inkscape:window-height="1582"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="16"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid989" />
|
||||
</sodipodi:namedview>
|
||||
<path
|
||||
d="m 7.4999793,9 -3,-3 3,-3"
|
||||
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path2" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -3549,30 +3549,76 @@ void TileMapEditor::_update_layers_selection() {
|
|||
tile_map_editor_plugins[tabs->get_current_tab()]->edit(tile_map_id, tile_map_layer);
|
||||
}
|
||||
|
||||
void TileMapEditor::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value) {
|
||||
void TileMapEditor::_move_tile_map_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos) {
|
||||
UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
|
||||
ERR_FAIL_COND(!undo_redo);
|
||||
|
||||
TileMap *tile_map = Object::cast_to<TileMap>(p_edited);
|
||||
if (tile_map) {
|
||||
if (p_property == "layers_count") {
|
||||
int new_layers_count = (int)p_new_value;
|
||||
if (new_layers_count < tile_map->get_layers_count()) {
|
||||
List<PropertyInfo> property_list;
|
||||
tile_map->get_property_list(&property_list);
|
||||
if (!tile_map) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (PropertyInfo property_info : property_list) {
|
||||
Vector<String> components = String(property_info.name).split("/", true, 2);
|
||||
if (components.size() == 2 && components[0].begins_with("layer_") && components[0].trim_prefix("layer_").is_valid_int()) {
|
||||
int index = components[0].trim_prefix("layer_").to_int();
|
||||
if (index >= new_layers_count) {
|
||||
undo_redo->add_undo_property(tile_map, property_info.name, tile_map->get(property_info.name));
|
||||
}
|
||||
}
|
||||
// Compute the array indices to save.
|
||||
int begin = 0;
|
||||
int end;
|
||||
if (p_array_prefix == "layer_") {
|
||||
end = tile_map->get_layers_count();
|
||||
} else {
|
||||
ERR_FAIL_MSG("Invalid array prefix for TileSet.");
|
||||
}
|
||||
if (p_from_index < 0) {
|
||||
// Adding new.
|
||||
if (p_to_pos >= 0) {
|
||||
begin = p_to_pos;
|
||||
} else {
|
||||
end = 0; // Nothing to save when adding at the end.
|
||||
}
|
||||
} else if (p_to_pos < 0) {
|
||||
// Removing.
|
||||
begin = p_from_index;
|
||||
} else {
|
||||
// Moving.
|
||||
begin = MIN(p_from_index, p_to_pos);
|
||||
end = MIN(MAX(p_from_index, p_to_pos) + 1, end);
|
||||
}
|
||||
|
||||
#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property));
|
||||
// Save layers' properties.
|
||||
if (p_from_index < 0) {
|
||||
undo_redo->add_undo_method(tile_map, "remove_layer", p_to_pos < 0 ? tile_map->get_layers_count() : p_to_pos);
|
||||
} else if (p_to_pos < 0) {
|
||||
undo_redo->add_undo_method(tile_map, "add_layer", p_from_index);
|
||||
}
|
||||
|
||||
List<PropertyInfo> properties;
|
||||
tile_map->get_property_list(&properties);
|
||||
for (PropertyInfo pi : properties) {
|
||||
if (pi.name.begins_with(p_array_prefix)) {
|
||||
String str = pi.name.trim_prefix(p_array_prefix);
|
||||
int to_char_index = 0;
|
||||
while (to_char_index < str.length()) {
|
||||
if (str[to_char_index] < '0' || str[to_char_index] > '9') {
|
||||
break;
|
||||
}
|
||||
to_char_index++;
|
||||
}
|
||||
if (to_char_index > 0) {
|
||||
int array_index = str.left(to_char_index).to_int();
|
||||
if (array_index >= begin && array_index < end) {
|
||||
ADD_UNDO(tile_map, pi.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef ADD_UNDO
|
||||
|
||||
if (p_from_index < 0) {
|
||||
undo_redo->add_do_method(tile_map, "add_layer", p_to_pos);
|
||||
} else if (p_to_pos < 0) {
|
||||
undo_redo->add_do_method(tile_map, "remove_layer", p_from_index);
|
||||
} else {
|
||||
undo_redo->add_do_method(tile_map, "move_layer", p_from_index, p_to_pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool TileMapEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
|
||||
|
@ -3851,7 +3897,7 @@ TileMapEditor::TileMapEditor() {
|
|||
_tab_changed(0);
|
||||
|
||||
// Registers UndoRedo inspector callback.
|
||||
EditorNode::get_singleton()->get_editor_data().add_undo_redo_inspector_hook_callback(callable_mp(this, &TileMapEditor::_undo_redo_inspector_callback));
|
||||
EditorNode::get_singleton()->get_editor_data().add_move_array_element_function(SNAME("TileMap"), callable_mp(this, &TileMapEditor::_move_tile_map_array_element));
|
||||
}
|
||||
|
||||
TileMapEditor::~TileMapEditor() {
|
||||
|
|
|
@ -341,7 +341,7 @@ private:
|
|||
void _update_layers_selection();
|
||||
|
||||
// Inspector undo/redo callback.
|
||||
void _undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value);
|
||||
void _move_tile_map_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos);
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
|
|
@ -1866,7 +1866,7 @@ void TileSetAtlasSourceEditor::_undo_redo_inspector_callback(Object *p_undo_redo
|
|||
UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
|
||||
ERR_FAIL_COND(!undo_redo);
|
||||
|
||||
#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, tile_data->get(property));
|
||||
#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property));
|
||||
|
||||
AtlasTileProxyObject *tile_data = Object::cast_to<AtlasTileProxyObject>(p_edited);
|
||||
if (tile_data) {
|
||||
|
|
|
@ -330,11 +330,192 @@ void TileSetEditor::_tile_set_changed() {
|
|||
tile_set_changed_needs_update = true;
|
||||
}
|
||||
|
||||
void TileSetEditor::_move_tile_set_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos) {
|
||||
UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
|
||||
ERR_FAIL_COND(!undo_redo);
|
||||
|
||||
TileSet *tile_set = Object::cast_to<TileSet>(p_edited);
|
||||
if (!tile_set) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<String> components = String(p_array_prefix).split("/", true, 2);
|
||||
|
||||
// Compute the array indices to save.
|
||||
int begin = 0;
|
||||
int end;
|
||||
if (p_array_prefix == "occlusion_layer_") {
|
||||
end = tile_set->get_occlusion_layers_count();
|
||||
} else if (p_array_prefix == "physics_layer_") {
|
||||
end = tile_set->get_physics_layers_count();
|
||||
} else if (p_array_prefix == "terrain_set_") {
|
||||
end = tile_set->get_terrain_sets_count();
|
||||
} else if (components.size() >= 2 && components[0].begins_with("terrain_set_") && components[0].trim_prefix("terrain_set_").is_valid_int() && components[1] == "terrain_") {
|
||||
int terrain_set = components[0].trim_prefix("terrain_set_").to_int();
|
||||
end = tile_set->get_terrains_count(terrain_set);
|
||||
} else if (p_array_prefix == "navigation_layer_") {
|
||||
end = tile_set->get_navigation_layers_count();
|
||||
} else if (p_array_prefix == "custom_data_layer_") {
|
||||
end = tile_set->get_custom_data_layers_count();
|
||||
} else {
|
||||
ERR_FAIL_MSG("Invalid array prefix for TileSet.");
|
||||
}
|
||||
if (p_from_index < 0) {
|
||||
// Adding new.
|
||||
if (p_to_pos >= 0) {
|
||||
begin = p_to_pos;
|
||||
} else {
|
||||
end = 0; // Nothing to save when adding at the end.
|
||||
}
|
||||
} else if (p_to_pos < 0) {
|
||||
// Removing.
|
||||
begin = p_from_index;
|
||||
} else {
|
||||
// Moving.
|
||||
begin = MIN(p_from_index, p_to_pos);
|
||||
end = MIN(MAX(p_from_index, p_to_pos) + 1, end);
|
||||
}
|
||||
|
||||
#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property));
|
||||
// Save layers' properties.
|
||||
List<PropertyInfo> properties;
|
||||
tile_set->get_property_list(&properties);
|
||||
for (PropertyInfo pi : properties) {
|
||||
if (pi.name.begins_with(p_array_prefix)) {
|
||||
String str = pi.name.trim_prefix(p_array_prefix);
|
||||
int to_char_index = 0;
|
||||
while (to_char_index < str.length()) {
|
||||
if (str[to_char_index] < '0' || str[to_char_index] > '9') {
|
||||
break;
|
||||
}
|
||||
to_char_index++;
|
||||
}
|
||||
if (to_char_index > 0) {
|
||||
int array_index = str.left(to_char_index).to_int();
|
||||
if (array_index >= begin && array_index < end) {
|
||||
ADD_UNDO(tile_set, pi.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save properties for TileSetAtlasSources tile data
|
||||
for (int i = 0; i < tile_set->get_source_count(); i++) {
|
||||
int source_id = tile_set->get_source_id(i);
|
||||
|
||||
Ref<TileSetAtlasSource> tas = tile_set->get_source(source_id);
|
||||
if (tas.is_valid()) {
|
||||
for (int j = 0; j < tas->get_tiles_count(); j++) {
|
||||
Vector2i tile_id = tas->get_tile_id(j);
|
||||
for (int k = 0; k < tas->get_alternative_tiles_count(tile_id); k++) {
|
||||
int alternative_id = tas->get_alternative_tile_id(tile_id, k);
|
||||
TileData *tile_data = Object::cast_to<TileData>(tas->get_tile_data(tile_id, alternative_id));
|
||||
ERR_FAIL_COND(!tile_data);
|
||||
|
||||
// Actually saving stuff.
|
||||
if (p_array_prefix == "occlusion_layer_") {
|
||||
for (int layer_index = begin; layer_index < end; layer_index++) {
|
||||
ADD_UNDO(tile_data, vformat("occlusion_layer_%d/polygon", layer_index));
|
||||
}
|
||||
} else if (p_array_prefix == "physics_layer_") {
|
||||
for (int layer_index = begin; layer_index < end; layer_index++) {
|
||||
ADD_UNDO(tile_data, vformat("physics_layer_%d/polygons_count", layer_index));
|
||||
for (int polygon_index = 0; polygon_index < tile_data->get_collision_polygons_count(layer_index); polygon_index++) {
|
||||
ADD_UNDO(tile_data, vformat("physics_layer_%d/polygon_%d/points", layer_index, polygon_index));
|
||||
ADD_UNDO(tile_data, vformat("physics_layer_%d/polygon_%d/one_way", layer_index, polygon_index));
|
||||
ADD_UNDO(tile_data, vformat("physics_layer_%d/polygon_%d/one_way_margin", layer_index, polygon_index));
|
||||
}
|
||||
}
|
||||
} else if (p_array_prefix == "terrain_set_") {
|
||||
ADD_UNDO(tile_data, "terrain_set");
|
||||
for (int terrain_set_index = begin; terrain_set_index < end; terrain_set_index++) {
|
||||
for (int l = 0; l < TileSet::CELL_NEIGHBOR_MAX; l++) {
|
||||
TileSet::CellNeighbor bit = TileSet::CellNeighbor(l);
|
||||
if (tile_data->is_valid_peering_bit_terrain(bit)) {
|
||||
ADD_UNDO(tile_data, "terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[l]));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (components.size() >= 2 && components[0].begins_with("terrain_set_") && components[0].trim_prefix("terrain_set_").is_valid_int() && components[1] == "terrain_") {
|
||||
for (int terrain_index = 0; terrain_index < TileSet::CELL_NEIGHBOR_MAX; terrain_index++) {
|
||||
TileSet::CellNeighbor bit = TileSet::CellNeighbor(terrain_index);
|
||||
if (tile_data->is_valid_peering_bit_terrain(bit)) {
|
||||
ADD_UNDO(tile_data, "terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[terrain_index]));
|
||||
}
|
||||
}
|
||||
} else if (p_array_prefix == "navigation_layer_") {
|
||||
for (int layer_index = begin; layer_index < end; layer_index++) {
|
||||
ADD_UNDO(tile_data, vformat("navigation_layer_%d/polygon", layer_index));
|
||||
}
|
||||
} else if (p_array_prefix == "custom_data_layer_") {
|
||||
for (int layer_index = begin; layer_index < end; layer_index++) {
|
||||
ADD_UNDO(tile_data, vformat("custom_data_%d", layer_index));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef ADD_UNDO
|
||||
|
||||
// Add do method.
|
||||
if (p_array_prefix == "occlusion_layer_") {
|
||||
if (p_from_index < 0) {
|
||||
undo_redo->add_do_method(tile_set, "add_occlusion_layer", p_to_pos);
|
||||
} else if (p_to_pos < 0) {
|
||||
undo_redo->add_do_method(tile_set, "remove_occlusion_layer", p_from_index);
|
||||
} else {
|
||||
undo_redo->add_do_method(tile_set, "move_occlusion_layer", p_from_index, p_to_pos);
|
||||
}
|
||||
} else if (p_array_prefix == "physics_layer_") {
|
||||
if (p_from_index < 0) {
|
||||
undo_redo->add_do_method(tile_set, "add_physics_layer", p_to_pos);
|
||||
} else if (p_to_pos < 0) {
|
||||
undo_redo->add_do_method(tile_set, "remove_physics_layer", p_from_index);
|
||||
} else {
|
||||
undo_redo->add_do_method(tile_set, "move_physics_layer", p_from_index, p_to_pos);
|
||||
}
|
||||
} else if (p_array_prefix == "terrain_set_") {
|
||||
if (p_from_index < 0) {
|
||||
undo_redo->add_do_method(tile_set, "add_terrain_set", p_to_pos);
|
||||
} else if (p_to_pos < 0) {
|
||||
undo_redo->add_do_method(tile_set, "remove_terrain_set", p_from_index);
|
||||
} else {
|
||||
undo_redo->add_do_method(tile_set, "move_terrain_set", p_from_index, p_to_pos);
|
||||
}
|
||||
} else if (components.size() >= 2 && components[0].begins_with("terrain_set_") && components[0].trim_prefix("terrain_set_").is_valid_int() && components[1] == "terrain_") {
|
||||
int terrain_set = components[0].trim_prefix("terrain_set_").to_int();
|
||||
if (p_from_index < 0) {
|
||||
undo_redo->add_do_method(tile_set, "add_terrain", terrain_set, p_to_pos);
|
||||
} else if (p_to_pos < 0) {
|
||||
undo_redo->add_do_method(tile_set, "remove_terrain", terrain_set, p_from_index);
|
||||
} else {
|
||||
undo_redo->add_do_method(tile_set, "move_terrain", terrain_set, p_from_index, p_to_pos);
|
||||
}
|
||||
} else if (p_array_prefix == "navigation_layer_") {
|
||||
if (p_from_index < 0) {
|
||||
undo_redo->add_do_method(tile_set, "add_navigation_layer", p_to_pos);
|
||||
} else if (p_to_pos < 0) {
|
||||
undo_redo->add_do_method(tile_set, "remove_navigation_layer", p_from_index);
|
||||
} else {
|
||||
undo_redo->add_do_method(tile_set, "move_navigation_layer", p_from_index, p_to_pos);
|
||||
}
|
||||
} else if (p_array_prefix == "custom_data_layer_") {
|
||||
if (p_from_index < 0) {
|
||||
undo_redo->add_do_method(tile_set, "add_custom_data_layer", p_to_pos);
|
||||
} else if (p_to_pos < 0) {
|
||||
undo_redo->add_do_method(tile_set, "remove_custom_data_layer", p_from_index);
|
||||
} else {
|
||||
undo_redo->add_do_method(tile_set, "move_custom_data_layer", p_from_index, p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetEditor::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value) {
|
||||
UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
|
||||
ERR_FAIL_COND(!undo_redo);
|
||||
|
||||
#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, tile_data->get(property));
|
||||
#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property));
|
||||
TileSet *tile_set = Object::cast_to<TileSet>(p_edited);
|
||||
if (tile_set) {
|
||||
Vector<String> components = p_property.split("/", true, 3);
|
||||
|
@ -350,30 +531,7 @@ void TileSetEditor::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p
|
|||
TileData *tile_data = Object::cast_to<TileData>(tas->get_tile_data(tile_id, alternative_id));
|
||||
ERR_FAIL_COND(!tile_data);
|
||||
|
||||
if (p_property == "occlusion_layers_count") {
|
||||
int new_layer_count = p_new_value;
|
||||
int old_layer_count = tile_set->get_occlusion_layers_count();
|
||||
if (new_layer_count < old_layer_count) {
|
||||
for (int occclusion_layer_index = new_layer_count - 1; occclusion_layer_index < old_layer_count; occclusion_layer_index++) {
|
||||
ADD_UNDO(tile_data, vformat("occlusion_layer_%d/polygon", occclusion_layer_index));
|
||||
}
|
||||
}
|
||||
} else if (p_property == "physics_layers_count") {
|
||||
int new_layer_count = p_new_value;
|
||||
int old_layer_count = tile_set->get_physics_layers_count();
|
||||
if (new_layer_count < old_layer_count) {
|
||||
for (int physics_layer_index = new_layer_count - 1; physics_layer_index < old_layer_count; physics_layer_index++) {
|
||||
ADD_UNDO(tile_data, vformat("physics_layer_%d/polygons_count", physics_layer_index));
|
||||
for (int polygon_index = 0; polygon_index < tile_data->get_collision_polygons_count(physics_layer_index); polygon_index++) {
|
||||
ADD_UNDO(tile_data, vformat("physics_layer_%d/polygon_%d/points", physics_layer_index, polygon_index));
|
||||
ADD_UNDO(tile_data, vformat("physics_layer_%d/polygon_%d/one_way", physics_layer_index, polygon_index));
|
||||
ADD_UNDO(tile_data, vformat("physics_layer_%d/polygon_%d/one_way_margin", physics_layer_index, polygon_index));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((p_property == "terrains_sets_count" && tile_data->get_terrain_set() >= (int)p_new_value) ||
|
||||
(components.size() == 2 && components[0].begins_with("terrain_set_") && components[0].trim_prefix("terrain_set_").is_valid_int() && components[1] == "mode") ||
|
||||
(components.size() == 2 && components[0].begins_with("terrain_set_") && components[0].trim_prefix("terrain_set_").is_valid_int() && components[1] == "terrains_count" && tile_data->get_terrain_set() == components[0].trim_prefix("terrain_set_").to_int() && (int)p_new_value < tile_set->get_terrains_count(tile_data->get_terrain_set()))) {
|
||||
if (components.size() == 2 && components[0].begins_with("terrain_set_") && components[0].trim_prefix("terrain_set_").is_valid_int() && components[1] == "mode") {
|
||||
ADD_UNDO(tile_data, "terrain_set");
|
||||
for (int l = 0; l < TileSet::CELL_NEIGHBOR_MAX; l++) {
|
||||
TileSet::CellNeighbor bit = TileSet::CellNeighbor(l);
|
||||
|
@ -381,22 +539,6 @@ void TileSetEditor::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p
|
|||
ADD_UNDO(tile_data, "terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[l]));
|
||||
}
|
||||
}
|
||||
} else if (p_property == "navigation_layers_count") {
|
||||
int new_layer_count = p_new_value;
|
||||
int old_layer_count = tile_set->get_navigation_layers_count();
|
||||
if (new_layer_count < old_layer_count) {
|
||||
for (int navigation_layer_index = new_layer_count - 1; navigation_layer_index < old_layer_count; navigation_layer_index++) {
|
||||
ADD_UNDO(tile_data, vformat("navigation_layer_%d/polygon", navigation_layer_index));
|
||||
}
|
||||
}
|
||||
} else if (p_property == "custom_data_layers_count") {
|
||||
int new_layer_count = p_new_value;
|
||||
int old_layer_count = tile_set->get_custom_data_layers_count();
|
||||
if (new_layer_count < old_layer_count) {
|
||||
for (int custom_data_layer_index = new_layer_count - 1; custom_data_layer_index < old_layer_count; custom_data_layer_index++) {
|
||||
ADD_UNDO(tile_data, vformat("custom_data_%d", custom_data_layer_index));
|
||||
}
|
||||
}
|
||||
} else if (components.size() == 2 && components[0].begins_with("custom_data_layer_") && components[0].trim_prefix("custom_data_layer_").is_valid_int() && components[1] == "type") {
|
||||
int custom_data_layer = components[0].trim_prefix("custom_data_layer_").is_valid_int();
|
||||
ADD_UNDO(tile_data, vformat("custom_data_%d", custom_data_layer));
|
||||
|
@ -531,6 +673,7 @@ TileSetEditor::TileSetEditor() {
|
|||
tile_set_scenes_collection_source_editor->hide();
|
||||
|
||||
// Registers UndoRedo inspector callback.
|
||||
EditorNode::get_singleton()->get_editor_data().add_move_array_element_function(SNAME("TileSet"), callable_mp(this, &TileSetEditor::_move_tile_set_array_element));
|
||||
EditorNode::get_singleton()->get_editor_data().add_undo_redo_inspector_hook_callback(callable_mp(this, &TileSetEditor::_undo_redo_inspector_callback));
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ private:
|
|||
|
||||
void _tile_set_changed();
|
||||
|
||||
void _move_tile_set_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos);
|
||||
void _undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -314,16 +314,38 @@ int TileMap::get_quadrant_size() const {
|
|||
return quadrant_size;
|
||||
}
|
||||
|
||||
void TileMap::set_layers_count(int p_layers_count) {
|
||||
ERR_FAIL_COND(p_layers_count < 0);
|
||||
_clear_internals();
|
||||
int TileMap::get_layers_count() const {
|
||||
return layers.size();
|
||||
}
|
||||
|
||||
layers.resize(p_layers_count);
|
||||
void TileMap::add_layer(int p_to_pos) {
|
||||
if (p_to_pos < 0) {
|
||||
p_to_pos = layers.size();
|
||||
}
|
||||
|
||||
ERR_FAIL_INDEX(p_to_pos, (int)layers.size() + 1);
|
||||
|
||||
layers.insert(p_to_pos, TileMapLayer());
|
||||
_recreate_internals();
|
||||
notify_property_list_changed();
|
||||
|
||||
if (selected_layer >= p_layers_count) {
|
||||
selected_layer = -1;
|
||||
emit_signal(SNAME("changed"));
|
||||
|
||||
update_configuration_warnings();
|
||||
}
|
||||
|
||||
void TileMap::move_layer(int p_layer, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_layer, (int)layers.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, (int)layers.size() + 1);
|
||||
|
||||
TileMapLayer tl = layers[p_layer];
|
||||
layers.insert(p_to_pos, tl);
|
||||
layers.remove(p_to_pos < p_layer ? p_layer + 1 : p_layer);
|
||||
_recreate_internals();
|
||||
notify_property_list_changed();
|
||||
|
||||
if (selected_layer == p_layer) {
|
||||
selected_layer = p_to_pos < p_layer ? p_to_pos - 1 : p_to_pos;
|
||||
}
|
||||
|
||||
emit_signal(SNAME("changed"));
|
||||
|
@ -331,8 +353,20 @@ void TileMap::set_layers_count(int p_layers_count) {
|
|||
update_configuration_warnings();
|
||||
}
|
||||
|
||||
int TileMap::get_layers_count() const {
|
||||
return layers.size();
|
||||
void TileMap::remove_layer(int p_layer) {
|
||||
ERR_FAIL_INDEX(p_layer, (int)layers.size());
|
||||
|
||||
layers.remove(p_layer);
|
||||
_recreate_internals();
|
||||
notify_property_list_changed();
|
||||
|
||||
if (selected_layer >= p_layer) {
|
||||
selected_layer -= 1;
|
||||
}
|
||||
|
||||
emit_signal(SNAME("changed"));
|
||||
|
||||
update_configuration_warnings();
|
||||
}
|
||||
|
||||
void TileMap::set_layer_name(int p_layer, String p_name) {
|
||||
|
@ -2896,8 +2930,10 @@ void TileMap::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_quadrant_size", "size"), &TileMap::set_quadrant_size);
|
||||
ClassDB::bind_method(D_METHOD("get_quadrant_size"), &TileMap::get_quadrant_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_layers_count", "layers_count"), &TileMap::set_layers_count);
|
||||
ClassDB::bind_method(D_METHOD("get_layers_count"), &TileMap::get_layers_count);
|
||||
ClassDB::bind_method(D_METHOD("add_layer"), &TileMap::add_layer);
|
||||
ClassDB::bind_method(D_METHOD("move_layer"), &TileMap::move_layer);
|
||||
ClassDB::bind_method(D_METHOD("remove_layer"), &TileMap::remove_layer);
|
||||
ClassDB::bind_method(D_METHOD("set_layer_name", "layer", "name"), &TileMap::set_layer_name);
|
||||
ClassDB::bind_method(D_METHOD("get_layer_name", "layer"), &TileMap::get_layer_name);
|
||||
ClassDB::bind_method(D_METHOD("set_layer_enabled", "layer", "enabled"), &TileMap::set_layer_enabled);
|
||||
|
@ -2942,9 +2978,7 @@ void TileMap::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_collision_visibility_mode", "get_collision_visibility_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_navigation_visibility_mode", "get_navigation_visibility_mode");
|
||||
|
||||
ADD_GROUP("Layers", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "layers_count"), "set_layers_count", "get_layers_count");
|
||||
ADD_PROPERTY_DEFAULT("layers_count", 1);
|
||||
ADD_ARRAY("layers", "layer_");
|
||||
|
||||
ADD_PROPERTY_DEFAULT("format", FORMAT_1);
|
||||
|
||||
|
|
|
@ -308,8 +308,10 @@ public:
|
|||
static void draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0));
|
||||
|
||||
// Layers management.
|
||||
void set_layers_count(int p_layers_count);
|
||||
int get_layers_count() const;
|
||||
void add_layer(int p_to_pos);
|
||||
void move_layer(int p_layer, int p_to_pos);
|
||||
void remove_layer(int p_layer);
|
||||
void set_layer_name(int p_layer, String p_name);
|
||||
String get_layer_name(int p_layer) const;
|
||||
void set_layer_enabled(int p_layer, bool p_visible);
|
||||
|
|
|
@ -205,25 +205,46 @@ bool TileSet::is_uv_clipping() const {
|
|||
return uv_clipping;
|
||||
};
|
||||
|
||||
void TileSet::set_occlusion_layers_count(int p_occlusion_layers_count) {
|
||||
ERR_FAIL_COND(p_occlusion_layers_count < 0);
|
||||
if (occlusion_layers.size() == p_occlusion_layers_count) {
|
||||
return;
|
||||
int TileSet::get_occlusion_layers_count() const {
|
||||
return occlusion_layers.size();
|
||||
};
|
||||
|
||||
void TileSet::add_occlusion_layer(int p_index) {
|
||||
if (p_index < 0) {
|
||||
p_index = occlusion_layers.size();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_index, occlusion_layers.size() + 1);
|
||||
occlusion_layers.insert(p_index, OcclusionLayer());
|
||||
|
||||
occlusion_layers.resize(p_occlusion_layers_count);
|
||||
|
||||
for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
|
||||
E_source->get()->notify_tile_data_properties_should_change();
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->add_occlusion_layer(p_index);
|
||||
}
|
||||
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int TileSet::get_occlusion_layers_count() const {
|
||||
return occlusion_layers.size();
|
||||
};
|
||||
void TileSet::move_occlusion_layer(int p_from_index, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_from_index, occlusion_layers.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, occlusion_layers.size() + 1);
|
||||
occlusion_layers.insert(p_to_pos, occlusion_layers[p_from_index]);
|
||||
occlusion_layers.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->move_occlusion_layer(p_from_index, p_to_pos);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::remove_occlusion_layer(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, occlusion_layers.size());
|
||||
occlusion_layers.remove(p_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->remove_occlusion_layer(p_index);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::set_occlusion_layer_light_mask(int p_layer_index, int p_light_mask) {
|
||||
ERR_FAIL_INDEX(p_layer_index, occlusion_layers.size());
|
||||
|
@ -247,25 +268,45 @@ bool TileSet::get_occlusion_layer_sdf_collision(int p_layer_index) const {
|
|||
return occlusion_layers[p_layer_index].sdf_collision;
|
||||
}
|
||||
|
||||
// Physics
|
||||
void TileSet::set_physics_layers_count(int p_physics_layers_count) {
|
||||
ERR_FAIL_COND(p_physics_layers_count < 0);
|
||||
if (physics_layers.size() == p_physics_layers_count) {
|
||||
return;
|
||||
int TileSet::get_physics_layers_count() const {
|
||||
return physics_layers.size();
|
||||
}
|
||||
|
||||
void TileSet::add_physics_layer(int p_index) {
|
||||
if (p_index < 0) {
|
||||
p_index = physics_layers.size();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_index, physics_layers.size() + 1);
|
||||
physics_layers.insert(p_index, PhysicsLayer());
|
||||
|
||||
physics_layers.resize(p_physics_layers_count);
|
||||
|
||||
for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
|
||||
E_source->get()->notify_tile_data_properties_should_change();
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->add_physics_layer(p_index);
|
||||
}
|
||||
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int TileSet::get_physics_layers_count() const {
|
||||
return physics_layers.size();
|
||||
void TileSet::move_physics_layer(int p_from_index, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_from_index, physics_layers.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, physics_layers.size() + 1);
|
||||
physics_layers.insert(p_to_pos, physics_layers[p_from_index]);
|
||||
physics_layers.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->move_physics_layer(p_from_index, p_to_pos);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::remove_physics_layer(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, physics_layers.size());
|
||||
physics_layers.remove(p_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->remove_physics_layer(p_index);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::set_physics_layer_collision_layer(int p_layer_index, uint32_t p_layer) {
|
||||
|
@ -301,17 +342,45 @@ Ref<PhysicsMaterial> TileSet::get_physics_layer_physics_material(int p_layer_ind
|
|||
}
|
||||
|
||||
// Terrains
|
||||
void TileSet::set_terrain_sets_count(int p_terrains_sets_count) {
|
||||
ERR_FAIL_COND(p_terrains_sets_count < 0);
|
||||
int TileSet::get_terrain_sets_count() const {
|
||||
return terrain_sets.size();
|
||||
}
|
||||
|
||||
terrain_sets.resize(p_terrains_sets_count);
|
||||
void TileSet::add_terrain_set(int p_index) {
|
||||
if (p_index < 0) {
|
||||
p_index = terrain_sets.size();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_index, terrain_sets.size() + 1);
|
||||
terrain_sets.insert(p_index, TerrainSet());
|
||||
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->add_terrain_set(p_index);
|
||||
}
|
||||
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int TileSet::get_terrain_sets_count() const {
|
||||
return terrain_sets.size();
|
||||
void TileSet::move_terrain_set(int p_from_index, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_from_index, terrain_sets.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, terrain_sets.size() + 1);
|
||||
terrain_sets.insert(p_to_pos, terrain_sets[p_from_index]);
|
||||
terrain_sets.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->move_terrain_set(p_from_index, p_to_pos);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::remove_terrain_set(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, terrain_sets.size());
|
||||
terrain_sets.remove(p_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->remove_terrain_set(p_index);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::set_terrain_set_mode(int p_terrain_set, TerrainMode p_terrain_mode) {
|
||||
|
@ -330,36 +399,61 @@ TileSet::TerrainMode TileSet::get_terrain_set_mode(int p_terrain_set) const {
|
|||
return terrain_sets[p_terrain_set].mode;
|
||||
}
|
||||
|
||||
void TileSet::set_terrains_count(int p_terrain_set, int p_terrains_layers_count) {
|
||||
ERR_FAIL_INDEX(p_terrain_set, terrain_sets.size());
|
||||
ERR_FAIL_COND(p_terrains_layers_count < 0);
|
||||
if (terrain_sets[p_terrain_set].terrains.size() == p_terrains_layers_count) {
|
||||
return;
|
||||
}
|
||||
int TileSet::get_terrains_count(int p_terrain_set) const {
|
||||
ERR_FAIL_INDEX_V(p_terrain_set, terrain_sets.size(), -1);
|
||||
return terrain_sets[p_terrain_set].terrains.size();
|
||||
}
|
||||
|
||||
int old_size = terrain_sets[p_terrain_set].terrains.size();
|
||||
terrain_sets.write[p_terrain_set].terrains.resize(p_terrains_layers_count);
|
||||
void TileSet::add_terrain(int p_terrain_set, int p_index) {
|
||||
ERR_FAIL_INDEX(p_terrain_set, terrain_sets.size());
|
||||
Vector<Terrain> &terrains = terrain_sets.write[p_terrain_set].terrains;
|
||||
if (p_index < 0) {
|
||||
p_index = terrains.size();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_index, terrains.size() + 1);
|
||||
terrains.insert(p_index, Terrain());
|
||||
|
||||
// Default name and color
|
||||
for (int i = old_size; i < terrain_sets.write[p_terrain_set].terrains.size(); i++) {
|
||||
float hue_rotate = (i * 2 % 16) / 16.0;
|
||||
Color c;
|
||||
c.set_hsv(Math::fmod(float(hue_rotate), float(1.0)), 0.5, 0.5);
|
||||
terrain_sets.write[p_terrain_set].terrains.write[i].color = c;
|
||||
terrain_sets.write[p_terrain_set].terrains.write[i].name = String(vformat("Terrain %d", i));
|
||||
}
|
||||
float hue_rotate = (terrains.size() % 16) / 16.0;
|
||||
Color c;
|
||||
c.set_hsv(Math::fmod(float(hue_rotate), float(1.0)), 0.5, 0.5);
|
||||
terrains.write[p_index].color = c;
|
||||
terrains.write[p_index].name = String(vformat("Terrain %d", p_index));
|
||||
|
||||
for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
|
||||
E_source->get()->notify_tile_data_properties_should_change();
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->add_terrain(p_terrain_set, p_index);
|
||||
}
|
||||
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int TileSet::get_terrains_count(int p_terrain_set) const {
|
||||
ERR_FAIL_INDEX_V(p_terrain_set, terrain_sets.size(), -1);
|
||||
return terrain_sets[p_terrain_set].terrains.size();
|
||||
void TileSet::move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_terrain_set, terrain_sets.size());
|
||||
Vector<Terrain> &terrains = terrain_sets.write[p_terrain_set].terrains;
|
||||
|
||||
ERR_FAIL_INDEX(p_from_index, terrains.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, terrains.size() + 1);
|
||||
terrains.insert(p_to_pos, terrains[p_from_index]);
|
||||
terrains.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->move_terrain(p_terrain_set, p_from_index, p_to_pos);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::remove_terrain(int p_terrain_set, int p_index) {
|
||||
ERR_FAIL_INDEX(p_terrain_set, terrain_sets.size());
|
||||
Vector<Terrain> &terrains = terrain_sets.write[p_terrain_set].terrains;
|
||||
|
||||
ERR_FAIL_INDEX(p_index, terrains.size());
|
||||
terrains.remove(p_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->remove_terrain(p_terrain_set, p_index);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::set_terrain_name(int p_terrain_set, int p_terrain_index, String p_name) {
|
||||
|
@ -485,24 +579,45 @@ bool TileSet::is_valid_peering_bit_terrain(int p_terrain_set, TileSet::CellNeigh
|
|||
}
|
||||
|
||||
// Navigation
|
||||
void TileSet::set_navigation_layers_count(int p_navigation_layers_count) {
|
||||
ERR_FAIL_COND(p_navigation_layers_count < 0);
|
||||
if (navigation_layers.size() == p_navigation_layers_count) {
|
||||
return;
|
||||
int TileSet::get_navigation_layers_count() const {
|
||||
return navigation_layers.size();
|
||||
}
|
||||
|
||||
void TileSet::add_navigation_layer(int p_index) {
|
||||
if (p_index < 0) {
|
||||
p_index = navigation_layers.size();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_index, navigation_layers.size() + 1);
|
||||
navigation_layers.insert(p_index, NavigationLayer());
|
||||
|
||||
navigation_layers.resize(p_navigation_layers_count);
|
||||
|
||||
for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
|
||||
E_source->get()->notify_tile_data_properties_should_change();
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->add_navigation_layer(p_index);
|
||||
}
|
||||
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int TileSet::get_navigation_layers_count() const {
|
||||
return navigation_layers.size();
|
||||
void TileSet::move_navigation_layer(int p_from_index, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_from_index, navigation_layers.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, navigation_layers.size() + 1);
|
||||
navigation_layers.insert(p_to_pos, navigation_layers[p_from_index]);
|
||||
navigation_layers.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->move_navigation_layer(p_from_index, p_to_pos);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::remove_navigation_layer(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, navigation_layers.size());
|
||||
navigation_layers.remove(p_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->remove_navigation_layer(p_index);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::set_navigation_layer_layers(int p_layer_index, uint32_t p_layers) {
|
||||
|
@ -517,30 +632,52 @@ uint32_t TileSet::get_navigation_layer_layers(int p_layer_index) const {
|
|||
}
|
||||
|
||||
// Custom data.
|
||||
void TileSet::set_custom_data_layers_count(int p_custom_data_layers_count) {
|
||||
ERR_FAIL_COND(p_custom_data_layers_count < 0);
|
||||
if (custom_data_layers.size() == p_custom_data_layers_count) {
|
||||
return;
|
||||
int TileSet::get_custom_data_layers_count() const {
|
||||
return custom_data_layers.size();
|
||||
}
|
||||
|
||||
void TileSet::add_custom_data_layer(int p_index) {
|
||||
if (p_index < 0) {
|
||||
p_index = custom_data_layers.size();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_index, custom_data_layers.size() + 1);
|
||||
custom_data_layers.insert(p_index, CustomDataLayer());
|
||||
|
||||
custom_data_layers.resize(p_custom_data_layers_count);
|
||||
|
||||
for (Map<String, int>::Element *E = custom_data_layers_by_name.front(); E; E = E->next()) {
|
||||
if (E->get() >= custom_data_layers.size()) {
|
||||
custom_data_layers_by_name.erase(E);
|
||||
}
|
||||
}
|
||||
|
||||
for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
|
||||
E_source->get()->notify_tile_data_properties_should_change();
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->add_custom_data_layer(p_index);
|
||||
}
|
||||
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int TileSet::get_custom_data_layers_count() const {
|
||||
return custom_data_layers.size();
|
||||
void TileSet::move_custom_data_layer(int p_from_index, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_from_index, custom_data_layers.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, custom_data_layers.size() + 1);
|
||||
custom_data_layers.insert(p_to_pos, custom_data_layers[p_from_index]);
|
||||
custom_data_layers.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->move_custom_data_layer(p_from_index, p_to_pos);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void TileSet::remove_custom_data_layer(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, custom_data_layers.size());
|
||||
custom_data_layers.remove(p_index);
|
||||
for (KeyValue<String, int> E : custom_data_layers_by_name) {
|
||||
if (E.value == p_index) {
|
||||
custom_data_layers_by_name.erase(E.key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (KeyValue<int, Ref<TileSetSource>> source : sources) {
|
||||
source.value->remove_custom_data_layer(p_index);
|
||||
}
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int TileSet::get_custom_data_layer_by_name(String p_value) const {
|
||||
|
@ -1110,7 +1247,11 @@ Vector<Vector<Ref<Texture2D>>> TileSet::generate_terrains_icons(Size2i p_size) {
|
|||
if (is_valid_peering_bit_terrain(terrain_set, cell_neighbor)) {
|
||||
int terrain = tile_data->get_peering_bit_terrain(cell_neighbor);
|
||||
if (terrain >= 0) {
|
||||
bit_counts[terrain] += 1;
|
||||
if (terrain >= (int)bit_counts.size()) {
|
||||
WARN_PRINT(vformat("Invalid peering bit terrain: %d", terrain));
|
||||
} else {
|
||||
bit_counts[terrain] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1831,13 +1972,13 @@ void TileSet::_compatibility_conversion() {
|
|||
|
||||
if (ctd->occluder.is_valid()) {
|
||||
if (get_occlusion_layers_count() < 1) {
|
||||
set_occlusion_layers_count(1);
|
||||
add_occlusion_layer();
|
||||
}
|
||||
tile_data->set_occluder(0, ctd->occluder);
|
||||
}
|
||||
if (ctd->navigation.is_valid()) {
|
||||
if (get_navigation_layers_count() < 1) {
|
||||
set_navigation_layers_count(1);
|
||||
add_navigation_layer();
|
||||
}
|
||||
tile_data->set_navigation_polygon(0, ctd->autotile_navpoly_map[coords]);
|
||||
}
|
||||
|
@ -1847,7 +1988,7 @@ void TileSet::_compatibility_conversion() {
|
|||
// Add the shapes.
|
||||
if (ctd->shapes.size() > 0) {
|
||||
if (get_physics_layers_count() < 1) {
|
||||
set_physics_layers_count(1);
|
||||
add_physics_layer();
|
||||
}
|
||||
}
|
||||
for (int k = 0; k < ctd->shapes.size(); k++) {
|
||||
|
@ -1922,13 +2063,13 @@ void TileSet::_compatibility_conversion() {
|
|||
tile_data->set_z_index(ctd->z_index);
|
||||
if (ctd->autotile_occluder_map.has(coords)) {
|
||||
if (get_occlusion_layers_count() < 1) {
|
||||
set_occlusion_layers_count(1);
|
||||
add_occlusion_layer();
|
||||
}
|
||||
tile_data->set_occluder(0, ctd->autotile_occluder_map[coords]);
|
||||
}
|
||||
if (ctd->autotile_navpoly_map.has(coords)) {
|
||||
if (get_navigation_layers_count() < 1) {
|
||||
set_navigation_layers_count(1);
|
||||
add_navigation_layer();
|
||||
}
|
||||
tile_data->set_navigation_polygon(0, ctd->autotile_navpoly_map[coords]);
|
||||
}
|
||||
|
@ -1942,7 +2083,7 @@ void TileSet::_compatibility_conversion() {
|
|||
// Add the shapes.
|
||||
if (ctd->shapes.size() > 0) {
|
||||
if (get_physics_layers_count() < 1) {
|
||||
set_physics_layers_count(1);
|
||||
add_physics_layer();
|
||||
}
|
||||
}
|
||||
for (int k = 0; k < ctd->shapes.size(); k++) {
|
||||
|
@ -2206,15 +2347,15 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
|
|||
ERR_FAIL_COND_V(index < 0, false);
|
||||
if (components[1] == "light_mask") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
|
||||
if (index >= occlusion_layers.size()) {
|
||||
set_occlusion_layers_count(index + 1);
|
||||
while (index >= occlusion_layers.size()) {
|
||||
add_occlusion_layer();
|
||||
}
|
||||
set_occlusion_layer_light_mask(index, p_value);
|
||||
return true;
|
||||
} else if (components[1] == "sdf_collision") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::BOOL, false);
|
||||
if (index >= occlusion_layers.size()) {
|
||||
set_occlusion_layers_count(index + 1);
|
||||
while (index >= occlusion_layers.size()) {
|
||||
add_occlusion_layer();
|
||||
}
|
||||
set_occlusion_layer_sdf_collision(index, p_value);
|
||||
return true;
|
||||
|
@ -2225,23 +2366,22 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
|
|||
ERR_FAIL_COND_V(index < 0, false);
|
||||
if (components[1] == "collision_layer") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
|
||||
if (index >= physics_layers.size()) {
|
||||
set_physics_layers_count(index + 1);
|
||||
while (index >= physics_layers.size()) {
|
||||
add_physics_layer();
|
||||
}
|
||||
set_physics_layer_collision_layer(index, p_value);
|
||||
return true;
|
||||
} else if (components[1] == "collision_mask") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
|
||||
if (index >= physics_layers.size()) {
|
||||
set_physics_layers_count(index + 1);
|
||||
while (index >= physics_layers.size()) {
|
||||
add_physics_layer();
|
||||
}
|
||||
set_physics_layer_collision_mask(index, p_value);
|
||||
return true;
|
||||
} else if (components[1] == "physics_material") {
|
||||
Ref<PhysicsMaterial> physics_material = p_value;
|
||||
ERR_FAIL_COND_V(!physics_material.is_valid(), false);
|
||||
if (index >= physics_layers.size()) {
|
||||
set_physics_layers_count(index + 1);
|
||||
while (index >= physics_layers.size()) {
|
||||
add_physics_layer();
|
||||
}
|
||||
set_physics_layer_physics_material(index, physics_material);
|
||||
return true;
|
||||
|
@ -2252,37 +2392,30 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
|
|||
ERR_FAIL_COND_V(terrain_set_index < 0, false);
|
||||
if (components[1] == "mode") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
|
||||
if (terrain_set_index >= terrain_sets.size()) {
|
||||
set_terrain_sets_count(terrain_set_index + 1);
|
||||
while (terrain_set_index >= terrain_sets.size()) {
|
||||
add_terrain_set();
|
||||
}
|
||||
set_terrain_set_mode(terrain_set_index, TerrainMode(int(p_value)));
|
||||
} else if (components[1] == "terrains_count") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
|
||||
if (terrain_set_index >= terrain_sets.size()) {
|
||||
set_terrain_sets_count(terrain_set_index + 1);
|
||||
}
|
||||
set_terrains_count(terrain_set_index, p_value);
|
||||
return true;
|
||||
} else if (components.size() >= 3 && components[1].begins_with("terrain_") && components[1].trim_prefix("terrain_").is_valid_int()) {
|
||||
int terrain_index = components[1].trim_prefix("terrain_").to_int();
|
||||
ERR_FAIL_COND_V(terrain_index < 0, false);
|
||||
if (components[2] == "name") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::STRING, false);
|
||||
if (terrain_set_index >= terrain_sets.size()) {
|
||||
set_terrain_sets_count(terrain_set_index + 1);
|
||||
while (terrain_set_index >= terrain_sets.size()) {
|
||||
add_terrain_set();
|
||||
}
|
||||
if (terrain_index >= terrain_sets[terrain_set_index].terrains.size()) {
|
||||
set_terrains_count(terrain_set_index, terrain_index + 1);
|
||||
while (terrain_index >= terrain_sets[terrain_set_index].terrains.size()) {
|
||||
add_terrain(terrain_set_index);
|
||||
}
|
||||
set_terrain_name(terrain_set_index, terrain_index, p_value);
|
||||
return true;
|
||||
} else if (components[2] == "color") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::COLOR, false);
|
||||
if (terrain_set_index >= terrain_sets.size()) {
|
||||
set_terrain_sets_count(terrain_set_index + 1);
|
||||
while (terrain_set_index >= terrain_sets.size()) {
|
||||
add_terrain_set();
|
||||
}
|
||||
if (terrain_index >= terrain_sets[terrain_set_index].terrains.size()) {
|
||||
set_terrains_count(terrain_set_index, terrain_index + 1);
|
||||
while (terrain_index >= terrain_sets[terrain_set_index].terrains.size()) {
|
||||
add_terrain(terrain_set_index);
|
||||
}
|
||||
set_terrain_color(terrain_set_index, terrain_index, p_value);
|
||||
return true;
|
||||
|
@ -2294,8 +2427,8 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
|
|||
ERR_FAIL_COND_V(index < 0, false);
|
||||
if (components[1] == "layers") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
|
||||
if (index >= navigation_layers.size()) {
|
||||
set_navigation_layers_count(index + 1);
|
||||
while (index >= navigation_layers.size()) {
|
||||
add_navigation_layer();
|
||||
}
|
||||
set_navigation_layer_layers(index, p_value);
|
||||
return true;
|
||||
|
@ -2306,15 +2439,15 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
|
|||
ERR_FAIL_COND_V(index < 0, false);
|
||||
if (components[1] == "name") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::STRING, false);
|
||||
if (index >= custom_data_layers.size()) {
|
||||
set_custom_data_layers_count(index + 1);
|
||||
while (index >= custom_data_layers.size()) {
|
||||
add_custom_data_layer();
|
||||
}
|
||||
set_custom_data_name(index, p_value);
|
||||
return true;
|
||||
} else if (components[1] == "type") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
|
||||
if (index >= custom_data_layers.size()) {
|
||||
set_custom_data_layers_count(index + 1);
|
||||
while (index >= custom_data_layers.size()) {
|
||||
add_custom_data_layer();
|
||||
}
|
||||
set_custom_data_type(index, Variant::Type(int(p_value)));
|
||||
return true;
|
||||
|
@ -2402,9 +2535,6 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
|
|||
if (components[1] == "mode") {
|
||||
r_ret = get_terrain_set_mode(terrain_set_index);
|
||||
return true;
|
||||
} else if (components[1] == "terrains_count") {
|
||||
r_ret = get_terrains_count(terrain_set_index);
|
||||
return true;
|
||||
} else if (components.size() >= 3 && components[1].begins_with("terrain_") && components[1].trim_prefix("terrain_").is_valid_int()) {
|
||||
int terrain_index = components[1].trim_prefix("terrain_").to_int();
|
||||
if (terrain_index < 0 || terrain_index >= terrain_sets[terrain_set_index].terrains.size()) {
|
||||
|
@ -2522,7 +2652,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||
p_list->push_back(PropertyInfo(Variant::NIL, "Terrains", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
|
||||
for (int terrain_set_index = 0; terrain_set_index < terrain_sets.size(); terrain_set_index++) {
|
||||
p_list->push_back(PropertyInfo(Variant::INT, vformat("terrain_set_%d/mode", terrain_set_index), PROPERTY_HINT_ENUM, "Match corners and sides,Match corners,Match sides"));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, vformat("terrain_set_%d/terrains_count", terrain_set_index), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, vformat("terrain_set_%d/terrains", terrain_set_index), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, vformat("terrain_set_%d/terrain_", terrain_set_index)));
|
||||
for (int terrain_index = 0; terrain_index < terrain_sets[terrain_set_index].terrains.size(); terrain_index++) {
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, vformat("terrain_set_%d/terrain_%d/name", terrain_set_index, terrain_index)));
|
||||
p_list->push_back(PropertyInfo(Variant::COLOR, vformat("terrain_set_%d/terrain_%d/color", terrain_set_index, terrain_index)));
|
||||
|
@ -2590,16 +2720,20 @@ void TileSet::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_uv_clipping", "uv_clipping"), &TileSet::set_uv_clipping);
|
||||
ClassDB::bind_method(D_METHOD("is_uv_clipping"), &TileSet::is_uv_clipping);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_occlusion_layers_count", "occlusion_layers_count"), &TileSet::set_occlusion_layers_count);
|
||||
ClassDB::bind_method(D_METHOD("get_occlusion_layers_count"), &TileSet::get_occlusion_layers_count);
|
||||
ClassDB::bind_method(D_METHOD("add_occlusion_layer", "to_position"), &TileSet::add_occlusion_layer, DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("move_occlusion_layer", "layer_index", "to_position"), &TileSet::move_occlusion_layer);
|
||||
ClassDB::bind_method(D_METHOD("remove_occlusion_layer", "layer_index"), &TileSet::remove_occlusion_layer);
|
||||
ClassDB::bind_method(D_METHOD("set_occlusion_layer_light_mask", "layer_index", "light_mask"), &TileSet::set_occlusion_layer_light_mask);
|
||||
ClassDB::bind_method(D_METHOD("get_occlusion_layer_light_mask"), &TileSet::get_occlusion_layer_light_mask);
|
||||
ClassDB::bind_method(D_METHOD("set_occlusion_layer_sdf_collision", "layer_index", "sdf_collision"), &TileSet::set_occlusion_layer_sdf_collision);
|
||||
ClassDB::bind_method(D_METHOD("get_occlusion_layer_sdf_collision"), &TileSet::get_occlusion_layer_sdf_collision);
|
||||
|
||||
// Physics
|
||||
ClassDB::bind_method(D_METHOD("set_physics_layers_count", "physics_layers_count"), &TileSet::set_physics_layers_count);
|
||||
ClassDB::bind_method(D_METHOD("get_physics_layers_count"), &TileSet::get_physics_layers_count);
|
||||
ClassDB::bind_method(D_METHOD("add_physics_layer", "to_position"), &TileSet::add_physics_layer, DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("move_physics_layer", "layer_index", "to_position"), &TileSet::move_physics_layer);
|
||||
ClassDB::bind_method(D_METHOD("remove_physics_layer", "layer_index"), &TileSet::remove_physics_layer);
|
||||
ClassDB::bind_method(D_METHOD("set_physics_layer_collision_layer", "layer_index", "layer"), &TileSet::set_physics_layer_collision_layer);
|
||||
ClassDB::bind_method(D_METHOD("get_physics_layer_collision_layer", "layer_index"), &TileSet::get_physics_layer_collision_layer);
|
||||
ClassDB::bind_method(D_METHOD("set_physics_layer_collision_mask", "layer_index", "mask"), &TileSet::set_physics_layer_collision_mask);
|
||||
|
@ -2608,27 +2742,35 @@ void TileSet::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_physics_layer_physics_material", "layer_index"), &TileSet::get_physics_layer_physics_material);
|
||||
|
||||
// Terrains
|
||||
ClassDB::bind_method(D_METHOD("set_terrain_sets_count", "terrain_sets_count"), &TileSet::set_terrain_sets_count);
|
||||
ClassDB::bind_method(D_METHOD("get_terrain_sets_count"), &TileSet::get_terrain_sets_count);
|
||||
ClassDB::bind_method(D_METHOD("add_terrain_set", "to_position"), &TileSet::add_terrain_set, DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("move_terrain_set", "layer_index", "to_position"), &TileSet::move_terrain_set);
|
||||
ClassDB::bind_method(D_METHOD("remove_terrain_set", "layer_index"), &TileSet::remove_terrain_set);
|
||||
ClassDB::bind_method(D_METHOD("set_terrain_set_mode", "terrain_set", "mode"), &TileSet::set_terrain_set_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_terrain_set_mode", "terrain_set"), &TileSet::get_terrain_set_mode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_terrains_count", "terrain_set", "terrains_count"), &TileSet::set_terrains_count);
|
||||
ClassDB::bind_method(D_METHOD("get_terrains_count", "terrain_set"), &TileSet::get_terrains_count);
|
||||
ClassDB::bind_method(D_METHOD("add_terrain", "terrain_set", "to_position"), &TileSet::add_terrain, DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("move_terrain", "terrain_set", "terrain_index", "to_position"), &TileSet::move_terrain);
|
||||
ClassDB::bind_method(D_METHOD("remove_terrain", "terrain_set", "terrain_index"), &TileSet::remove_terrain);
|
||||
ClassDB::bind_method(D_METHOD("set_terrain_name", "terrain_set", "terrain_index", "name"), &TileSet::set_terrain_name);
|
||||
ClassDB::bind_method(D_METHOD("get_terrain_name", "terrain_set", "terrain_index"), &TileSet::get_terrain_name);
|
||||
ClassDB::bind_method(D_METHOD("set_terrain_color", "terrain_set", "terrain_index", "color"), &TileSet::set_terrain_color);
|
||||
ClassDB::bind_method(D_METHOD("get_terrain_color", "terrain_set", "terrain_index"), &TileSet::get_terrain_color);
|
||||
|
||||
// Navigation
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layers_count", "navigation_layers_count"), &TileSet::set_navigation_layers_count);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layers_count"), &TileSet::get_navigation_layers_count);
|
||||
ClassDB::bind_method(D_METHOD("add_navigation_layer", "to_position"), &TileSet::add_navigation_layer, DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("move_navigation_layer", "layer_index", "to_position"), &TileSet::move_navigation_layer);
|
||||
ClassDB::bind_method(D_METHOD("remove_navigation_layer", "layer_index"), &TileSet::remove_navigation_layer);
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layer_layers", "layer_index", "layers"), &TileSet::set_navigation_layer_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layer_layers", "layer_index"), &TileSet::get_navigation_layer_layers);
|
||||
|
||||
// Custom data
|
||||
ClassDB::bind_method(D_METHOD("set_custom_data_layers_count", "custom_data_layers_count"), &TileSet::set_custom_data_layers_count);
|
||||
ClassDB::bind_method(D_METHOD("get_custom_data_layers_count"), &TileSet::get_custom_data_layers_count);
|
||||
ClassDB::bind_method(D_METHOD("add_custom_data_layer", "to_position"), &TileSet::add_custom_data_layer, DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("move_custom_data_layer", "layer_index", "to_position"), &TileSet::move_custom_data_layer);
|
||||
ClassDB::bind_method(D_METHOD("remove_custom_data_layer", "layer_index"), &TileSet::remove_custom_data_layer);
|
||||
|
||||
// Tile proxies
|
||||
ClassDB::bind_method(D_METHOD("set_source_level_tile_proxy", "source_from", "source_to"), &TileSet::set_source_level_tile_proxy);
|
||||
|
@ -2653,19 +2795,19 @@ void TileSet::_bind_methods() {
|
|||
|
||||
ADD_GROUP("Rendering", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uv_clipping"), "set_uv_clipping", "is_uv_clipping");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "occlusion_layers_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_occlusion_layers_count", "get_occlusion_layers_count");
|
||||
ADD_ARRAY("occlusion_layers", "occlusion_layer_");
|
||||
|
||||
ADD_GROUP("Physics", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "physics_layers_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_physics_layers_count", "get_physics_layers_count");
|
||||
ADD_ARRAY("physics_layers", "physics_layer_");
|
||||
|
||||
ADD_GROUP("Terrains", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "terrains_sets_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_terrain_sets_count", "get_terrain_sets_count");
|
||||
ADD_ARRAY("terrain_sets", "terrain_set_");
|
||||
|
||||
ADD_GROUP("Navigation", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_navigation_layers_count", "get_navigation_layers_count");
|
||||
ADD_ARRAY("navigation_layers", "navigation_layer_");
|
||||
|
||||
ADD_GROUP("Custom data", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "custom_data_layers_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_custom_data_layers_count", "get_custom_data_layers_count");
|
||||
ADD_ARRAY("custom_data_layers", "custom_data_layer_");
|
||||
|
||||
// -- Enum binding --
|
||||
BIND_ENUM_CONSTANT(TILE_SHAPE_SQUARE);
|
||||
|
@ -2750,6 +2892,150 @@ void TileSetAtlasSource::notify_tile_data_properties_should_change() {
|
|||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::add_occlusion_layer(int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->add_occlusion_layer(p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::move_occlusion_layer(int p_from_index, int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->move_occlusion_layer(p_from_index, p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::remove_occlusion_layer(int p_index) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->remove_occlusion_layer(p_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::add_physics_layer(int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->add_physics_layer(p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::move_physics_layer(int p_from_index, int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->move_physics_layer(p_from_index, p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::remove_physics_layer(int p_index) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->remove_physics_layer(p_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::add_terrain_set(int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->add_terrain_set(p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::move_terrain_set(int p_from_index, int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->move_terrain_set(p_from_index, p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::remove_terrain_set(int p_index) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->remove_terrain_set(p_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::add_terrain(int p_terrain_set, int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->add_terrain(p_terrain_set, p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->move_terrain(p_terrain_set, p_from_index, p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::remove_terrain(int p_terrain_set, int p_index) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->remove_terrain(p_terrain_set, p_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::add_navigation_layer(int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->add_navigation_layer(p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::move_navigation_layer(int p_from_index, int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->move_navigation_layer(p_from_index, p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::remove_navigation_layer(int p_index) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->remove_navigation_layer(p_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::add_custom_data_layer(int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->add_custom_data_layer(p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::move_custom_data_layer(int p_from_index, int p_to_pos) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->move_custom_data_layer(p_from_index, p_to_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::remove_custom_data_layer(int p_index) {
|
||||
for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
|
||||
for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
|
||||
E_alternative.value->remove_custom_data_layer(p_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::reset_state() {
|
||||
// Reset all TileData.
|
||||
for (Map<Vector2i, TileAlternativesData>::Element *E_tile = tiles.front(); E_tile; E_tile = E_tile->next()) {
|
||||
|
@ -3575,6 +3861,155 @@ void TileData::notify_tile_data_properties_should_change() {
|
|||
emit_signal(SNAME("changed"));
|
||||
}
|
||||
|
||||
void TileData::add_occlusion_layer(int p_to_pos) {
|
||||
if (p_to_pos < 0) {
|
||||
p_to_pos = occluders.size();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_to_pos, occluders.size() + 1);
|
||||
occluders.insert(p_to_pos, Ref<OccluderPolygon2D>());
|
||||
}
|
||||
|
||||
void TileData::move_occlusion_layer(int p_from_index, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_from_index, occluders.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, occluders.size() + 1);
|
||||
occluders.insert(p_to_pos, occluders[p_from_index]);
|
||||
occluders.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
|
||||
}
|
||||
|
||||
void TileData::remove_occlusion_layer(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, occluders.size());
|
||||
occluders.remove(p_index);
|
||||
}
|
||||
|
||||
void TileData::add_physics_layer(int p_to_pos) {
|
||||
if (p_to_pos < 0) {
|
||||
p_to_pos = physics.size();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_to_pos, physics.size() + 1);
|
||||
physics.insert(p_to_pos, PhysicsLayerTileData());
|
||||
}
|
||||
|
||||
void TileData::move_physics_layer(int p_from_index, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_from_index, physics.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, physics.size() + 1);
|
||||
physics.insert(p_to_pos, physics[p_from_index]);
|
||||
physics.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
|
||||
}
|
||||
|
||||
void TileData::remove_physics_layer(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, physics.size());
|
||||
physics.remove(p_index);
|
||||
}
|
||||
|
||||
void TileData::add_terrain_set(int p_to_pos) {
|
||||
if (p_to_pos >= 0 && p_to_pos <= terrain_set) {
|
||||
terrain_set += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void TileData::move_terrain_set(int p_from_index, int p_to_pos) {
|
||||
if (p_from_index == terrain_set) {
|
||||
terrain_set = (p_from_index < p_to_pos) ? p_to_pos - 1 : p_to_pos;
|
||||
} else {
|
||||
if (p_from_index < terrain_set) {
|
||||
terrain_set -= 1;
|
||||
}
|
||||
if (p_to_pos <= terrain_set) {
|
||||
terrain_set += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileData::remove_terrain_set(int p_index) {
|
||||
if (p_index == terrain_set) {
|
||||
terrain_set = -1;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
terrain_peering_bits[i] = -1;
|
||||
}
|
||||
} else if (terrain_set > p_index) {
|
||||
terrain_set -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void TileData::add_terrain(int p_terrain_set, int p_to_pos) {
|
||||
if (terrain_set == p_terrain_set) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (p_to_pos >= 0 && p_to_pos <= terrain_peering_bits[i]) {
|
||||
terrain_peering_bits[i] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileData::move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) {
|
||||
if (terrain_set == p_terrain_set) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (p_from_index == terrain_peering_bits[i]) {
|
||||
terrain_peering_bits[i] = (p_from_index < p_to_pos) ? p_to_pos - 1 : p_to_pos;
|
||||
} else {
|
||||
if (p_from_index < terrain_peering_bits[i]) {
|
||||
terrain_peering_bits[i] -= 1;
|
||||
}
|
||||
if (p_to_pos <= terrain_peering_bits[i]) {
|
||||
terrain_peering_bits[i] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileData::remove_terrain(int p_terrain_set, int p_index) {
|
||||
if (terrain_set == p_terrain_set) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (terrain_peering_bits[i] == p_index) {
|
||||
terrain_peering_bits[i] = -1;
|
||||
} else if (terrain_peering_bits[i] > p_index) {
|
||||
terrain_peering_bits[i] -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileData::add_navigation_layer(int p_to_pos) {
|
||||
if (p_to_pos < 0) {
|
||||
p_to_pos = navigation.size();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_to_pos, navigation.size() + 1);
|
||||
navigation.insert(p_to_pos, Ref<NavigationPolygon>());
|
||||
}
|
||||
|
||||
void TileData::move_navigation_layer(int p_from_index, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_from_index, navigation.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, navigation.size() + 1);
|
||||
navigation.insert(p_to_pos, navigation[p_from_index]);
|
||||
navigation.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
|
||||
}
|
||||
|
||||
void TileData::remove_navigation_layer(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, navigation.size());
|
||||
navigation.remove(p_index);
|
||||
}
|
||||
|
||||
void TileData::add_custom_data_layer(int p_to_pos) {
|
||||
if (p_to_pos < 0) {
|
||||
p_to_pos = custom_data.size();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_to_pos, custom_data.size() + 1);
|
||||
custom_data.insert(p_to_pos, Variant());
|
||||
}
|
||||
|
||||
void TileData::move_custom_data_layer(int p_from_index, int p_to_pos) {
|
||||
ERR_FAIL_INDEX(p_from_index, custom_data.size());
|
||||
ERR_FAIL_INDEX(p_to_pos, custom_data.size() + 1);
|
||||
custom_data.insert(p_to_pos, navigation[p_from_index]);
|
||||
custom_data.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
|
||||
}
|
||||
|
||||
void TileData::remove_custom_data_layer(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, custom_data.size());
|
||||
custom_data.remove(p_index);
|
||||
}
|
||||
|
||||
void TileData::reset_state() {
|
||||
occluders.clear();
|
||||
physics.clear();
|
||||
|
|
|
@ -225,10 +225,10 @@ private:
|
|||
bool terrain_bits_meshes_dirty = true;
|
||||
|
||||
// Navigation
|
||||
struct Navigationlayer {
|
||||
struct NavigationLayer {
|
||||
uint32_t layers = 1;
|
||||
};
|
||||
Vector<Navigationlayer> navigation_layers;
|
||||
Vector<NavigationLayer> navigation_layers;
|
||||
|
||||
// CustomData
|
||||
struct CustomDataLayer {
|
||||
|
@ -298,16 +298,20 @@ public:
|
|||
void set_uv_clipping(bool p_uv_clipping);
|
||||
bool is_uv_clipping() const;
|
||||
|
||||
void set_occlusion_layers_count(int p_occlusion_layers_count);
|
||||
int get_occlusion_layers_count() const;
|
||||
void add_occlusion_layer(int p_index = -1);
|
||||
void move_occlusion_layer(int p_from_index, int p_to_pos);
|
||||
void remove_occlusion_layer(int p_index);
|
||||
void set_occlusion_layer_light_mask(int p_layer_index, int p_light_mask);
|
||||
int get_occlusion_layer_light_mask(int p_layer_index) const;
|
||||
void set_occlusion_layer_sdf_collision(int p_layer_index, int p_sdf_collision);
|
||||
bool get_occlusion_layer_sdf_collision(int p_layer_index) const;
|
||||
|
||||
// Physics
|
||||
void set_physics_layers_count(int p_physics_layers_count);
|
||||
int get_physics_layers_count() const;
|
||||
void add_physics_layer(int p_index = -1);
|
||||
void move_physics_layer(int p_from_index, int p_to_pos);
|
||||
void remove_physics_layer(int p_index);
|
||||
void set_physics_layer_collision_layer(int p_layer_index, uint32_t p_layer);
|
||||
uint32_t get_physics_layer_collision_layer(int p_layer_index) const;
|
||||
void set_physics_layer_collision_mask(int p_layer_index, uint32_t p_mask);
|
||||
|
@ -315,13 +319,19 @@ public:
|
|||
void set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material);
|
||||
Ref<PhysicsMaterial> get_physics_layer_physics_material(int p_layer_index) const;
|
||||
|
||||
// Terrains
|
||||
void set_terrain_sets_count(int p_terrains_sets_count);
|
||||
// Terrain sets
|
||||
int get_terrain_sets_count() const;
|
||||
void add_terrain_set(int p_index = -1);
|
||||
void move_terrain_set(int p_from_index, int p_to_pos);
|
||||
void remove_terrain_set(int p_index);
|
||||
void set_terrain_set_mode(int p_terrain_set, TerrainMode p_terrain_mode);
|
||||
TerrainMode get_terrain_set_mode(int p_terrain_set) const;
|
||||
void set_terrains_count(int p_terrain_set, int p_terrains_count);
|
||||
|
||||
// Terrains
|
||||
int get_terrains_count(int p_terrain_set) const;
|
||||
void add_terrain(int p_terrain_set, int p_index = -1);
|
||||
void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos);
|
||||
void remove_terrain(int p_terrain_set, int p_index);
|
||||
void set_terrain_name(int p_terrain_set, int p_terrain_index, String p_name);
|
||||
String get_terrain_name(int p_terrain_set, int p_terrain_index) const;
|
||||
void set_terrain_color(int p_terrain_set, int p_terrain_index, Color p_color);
|
||||
|
@ -330,14 +340,18 @@ public:
|
|||
bool is_valid_peering_bit_terrain(int p_terrain_set, TileSet::CellNeighbor p_peering_bit) const;
|
||||
|
||||
// Navigation
|
||||
void set_navigation_layers_count(int p_navigation_layers_count);
|
||||
int get_navigation_layers_count() const;
|
||||
void add_navigation_layer(int p_index = -1);
|
||||
void move_navigation_layer(int p_from_index, int p_to_pos);
|
||||
void remove_navigation_layer(int p_index);
|
||||
void set_navigation_layer_layers(int p_layer_index, uint32_t p_layers);
|
||||
uint32_t get_navigation_layer_layers(int p_layer_index) const;
|
||||
|
||||
// Custom data
|
||||
void set_custom_data_layers_count(int p_custom_data_layers_count);
|
||||
int get_custom_data_layers_count() const;
|
||||
void add_custom_data_layer(int p_index = -1);
|
||||
void move_custom_data_layer(int p_from_index, int p_to_pos);
|
||||
void remove_custom_data_layer(int p_index);
|
||||
int get_custom_data_layer_by_name(String p_value) const;
|
||||
void set_custom_data_name(int p_layer_id, String p_value);
|
||||
String get_custom_data_name(int p_layer_id) const;
|
||||
|
@ -397,6 +411,24 @@ public:
|
|||
// Not exposed.
|
||||
virtual void set_tile_set(const TileSet *p_tile_set);
|
||||
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){};
|
||||
virtual void remove_occlusion_layer(int p_index){};
|
||||
virtual void add_physics_layer(int p_index){};
|
||||
virtual void move_physics_layer(int p_from_index, int p_to_pos){};
|
||||
virtual void remove_physics_layer(int p_index){};
|
||||
virtual void add_terrain_set(int p_index){};
|
||||
virtual void move_terrain_set(int p_from_index, int p_to_pos){};
|
||||
virtual void remove_terrain_set(int p_index){};
|
||||
virtual void add_terrain(int p_terrain_set, int p_index){};
|
||||
virtual void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos){};
|
||||
virtual void remove_terrain(int p_terrain_set, int p_index){};
|
||||
virtual void add_navigation_layer(int p_index){};
|
||||
virtual void move_navigation_layer(int p_from_index, int p_to_pos){};
|
||||
virtual void remove_navigation_layer(int p_index){};
|
||||
virtual void add_custom_data_layer(int p_index){};
|
||||
virtual void move_custom_data_layer(int p_from_index, int p_to_pos){};
|
||||
virtual void remove_custom_data_layer(int p_index){};
|
||||
virtual void reset_state() override{};
|
||||
|
||||
// Tiles.
|
||||
|
@ -448,6 +480,24 @@ public:
|
|||
// Not exposed.
|
||||
virtual void set_tile_set(const TileSet *p_tile_set) override;
|
||||
virtual void notify_tile_data_properties_should_change() override;
|
||||
virtual void add_occlusion_layer(int p_index) override;
|
||||
virtual void move_occlusion_layer(int p_from_index, int p_to_pos) override;
|
||||
virtual void remove_occlusion_layer(int p_index) override;
|
||||
virtual void add_physics_layer(int p_index) override;
|
||||
virtual void move_physics_layer(int p_from_index, int p_to_pos) override;
|
||||
virtual void remove_physics_layer(int p_index) override;
|
||||
virtual void add_terrain_set(int p_index) override;
|
||||
virtual void move_terrain_set(int p_from_index, int p_to_pos) override;
|
||||
virtual void remove_terrain_set(int p_index) override;
|
||||
virtual void add_terrain(int p_terrain_set, int p_index) override;
|
||||
virtual void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) override;
|
||||
virtual void remove_terrain(int p_terrain_set, int p_index) override;
|
||||
virtual void add_navigation_layer(int p_index) override;
|
||||
virtual void move_navigation_layer(int p_from_index, int p_to_pos) override;
|
||||
virtual void remove_navigation_layer(int p_index) override;
|
||||
virtual void add_custom_data_layer(int p_index) override;
|
||||
virtual void move_custom_data_layer(int p_from_index, int p_to_pos) override;
|
||||
virtual void remove_custom_data_layer(int p_index) override;
|
||||
virtual void reset_state() override;
|
||||
|
||||
// Base properties.
|
||||
|
@ -528,7 +578,7 @@ public:
|
|||
int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const override;
|
||||
bool has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const override;
|
||||
|
||||
// Scenes sccessors. Lot are similar to "Alternative tiles".
|
||||
// Scenes accessors. Lot are similar to "Alternative tiles".
|
||||
int get_scene_tiles_count() { return get_alternative_tiles_count(Vector2i()); }
|
||||
int get_scene_tile_id(int p_index) { return get_alternative_tile_id(Vector2i(), p_index); };
|
||||
bool has_scene_tile_id(int p_id) { return has_alternative_tile(Vector2i(), p_id); };
|
||||
|
@ -597,6 +647,24 @@ public:
|
|||
// Not exposed.
|
||||
void set_tile_set(const TileSet *p_tile_set);
|
||||
void notify_tile_data_properties_should_change();
|
||||
void add_occlusion_layer(int p_index);
|
||||
void move_occlusion_layer(int p_from_index, int p_to_pos);
|
||||
void remove_occlusion_layer(int p_index);
|
||||
void add_physics_layer(int p_index);
|
||||
void move_physics_layer(int p_from_index, int p_to_pos);
|
||||
void remove_physics_layer(int p_index);
|
||||
void add_terrain_set(int p_index);
|
||||
void move_terrain_set(int p_from_index, int p_to_pos);
|
||||
void remove_terrain_set(int p_index);
|
||||
void add_terrain(int p_terrain_set, int p_index);
|
||||
void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos);
|
||||
void remove_terrain(int p_terrain_set, int p_index);
|
||||
void add_navigation_layer(int p_index);
|
||||
void move_navigation_layer(int p_from_index, int p_to_pos);
|
||||
void remove_navigation_layer(int p_index);
|
||||
void add_custom_data_layer(int p_index);
|
||||
void move_custom_data_layer(int p_from_index, int p_to_pos);
|
||||
void remove_custom_data_layer(int p_index);
|
||||
void reset_state();
|
||||
void set_allow_transform(bool p_allow_transform);
|
||||
bool is_allowing_transform() const;
|
||||
|
|
|
@ -527,7 +527,7 @@ void add_exposed_classes(Context &r_context) {
|
|||
Map<StringName, StringName> accessor_methods;
|
||||
|
||||
for (const PropertyInfo &property : property_list) {
|
||||
if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY) {
|
||||
if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY || (property.type == Variant::NIL && property.usage & PROPERTY_USAGE_ARRAY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue