Brought in the built in tilemap and prefixed every class that needed it with R so everything works alongside the built in TileMap.

This commit is contained in:
Relintai 2021-12-12 21:54:39 +01:00
parent 368a8948c1
commit a0c8835e95
10 changed files with 10189 additions and 2 deletions

7
SCsub
View File

@ -1,7 +1,10 @@
Import('env')
env.add_source_files(env.modules_sources,"register_types.cpp")
env.add_source_files(env.modules_sources,"tile_map.cpp")
env.add_source_files(env.modules_sources,"tile_set.cpp")
#if env["tools"]:
# env.add_source_files(env.modules_sources, "tile_editor/*.cpp")
if env["tools"]:
env.add_source_files(env.modules_sources, "tile_map_editor_plugin.cpp")
env.add_source_files(env.modules_sources, "tile_set_editor_plugin.cpp")

View File

@ -22,13 +22,22 @@ SOFTWARE.
#include "register_types.h"
#include "tile_map.h"
#include "tile_set.h"
#ifdef TOOLS_ENABLED
#include "tile_map_editor_plugin.h"
#include "tile_set_editor_plugin.h"
#endif
void register_rtile_map_types() {
#ifdef TOOLS_ENABLED
EditorPlugins::add_by_type<RTileMapEditorPlugin>();
EditorPlugins::add_by_type<RTileSetEditorPlugin>();
#endif
ClassDB::register_class<RTileMap>();
ClassDB::register_class<RTileSet>();
}
void unregister_rtile_map_types() {

1934
tile_map.cpp Normal file

File diff suppressed because it is too large Load Diff

360
tile_map.h Normal file
View File

@ -0,0 +1,360 @@
/*************************************************************************/
/* tile_map.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef RTILE_MAP_H
#define RTILE_MAP_H
#include "core/self_list.h"
#include "core/vset.h"
#include "scene/2d/navigation_2d.h"
#include "scene/2d/node_2d.h"
#include "tile_set.h"
class CollisionObject2D;
class RTileMap : public Node2D {
GDCLASS(RTileMap, Node2D);
public:
enum Mode {
MODE_SQUARE,
MODE_ISOMETRIC,
MODE_CUSTOM
};
enum HalfOffset {
HALF_OFFSET_X,
HALF_OFFSET_Y,
HALF_OFFSET_DISABLED,
HALF_OFFSET_NEGATIVE_X,
HALF_OFFSET_NEGATIVE_Y,
};
enum TileOrigin {
TILE_ORIGIN_TOP_LEFT,
TILE_ORIGIN_CENTER,
TILE_ORIGIN_BOTTOM_LEFT
};
private:
enum DataFormat {
FORMAT_1 = 0,
FORMAT_2
};
Ref<RTileSet> tile_set;
Size2i cell_size;
int quadrant_size;
Mode mode;
Transform2D custom_transform;
HalfOffset half_offset;
bool use_parent;
CollisionObject2D *collision_parent;
bool use_kinematic;
Navigation2D *navigation;
bool show_collision = false;
union PosKey {
struct {
int16_t x;
int16_t y;
};
uint32_t key;
//using a more precise comparison so the regions can be sorted later
bool operator<(const PosKey &p_k) const { return (y == p_k.y) ? x < p_k.x : y < p_k.y; }
bool operator==(const PosKey &p_k) const { return (y == p_k.y && x == p_k.x); }
PosKey to_quadrant(const int &p_quadrant_size) const {
// rounding down, instead of simply rounding towards zero (truncating)
return PosKey(
x > 0 ? x / p_quadrant_size : (x - (p_quadrant_size - 1)) / p_quadrant_size,
y > 0 ? y / p_quadrant_size : (y - (p_quadrant_size - 1)) / p_quadrant_size);
}
PosKey(int16_t p_x, int16_t p_y) {
x = p_x;
y = p_y;
}
PosKey() {
x = 0;
y = 0;
}
};
union Cell {
struct {
int32_t id : 24;
bool flip_h : 1;
bool flip_v : 1;
bool transpose : 1;
int16_t autotile_coord_x : 16;
int16_t autotile_coord_y : 16;
};
uint64_t _u64t;
Cell() { _u64t = 0; }
};
Map<PosKey, Cell> tile_map;
List<PosKey> dirty_bitmask;
struct Quadrant {
Vector2 pos;
List<RID> canvas_items;
RID body;
uint32_t shape_owner_id;
SelfList<Quadrant> dirty_list;
struct NavPoly {
int id;
Transform2D xform;
};
struct Occluder {
RID id;
Transform2D xform;
};
Map<PosKey, NavPoly> navpoly_ids;
Map<PosKey, Occluder> occluder_instances;
VSet<PosKey> cells;
void operator=(const Quadrant &q) {
pos = q.pos;
canvas_items = q.canvas_items;
body = q.body;
shape_owner_id = q.shape_owner_id;
cells = q.cells;
navpoly_ids = q.navpoly_ids;
occluder_instances = q.occluder_instances;
}
Quadrant(const Quadrant &q) :
dirty_list(this) {
pos = q.pos;
canvas_items = q.canvas_items;
body = q.body;
shape_owner_id = q.shape_owner_id;
cells = q.cells;
occluder_instances = q.occluder_instances;
navpoly_ids = q.navpoly_ids;
}
Quadrant() :
dirty_list(this) {}
};
Map<PosKey, Quadrant> quadrant_map;
SelfList<Quadrant>::List dirty_quadrant_list;
bool pending_update;
Rect2 rect_cache;
bool rect_cache_dirty;
Rect2 used_size_cache;
bool used_size_cache_dirty;
bool quadrant_order_dirty;
bool y_sort_mode;
bool compatibility_mode;
bool centered_textures;
bool clip_uv;
float fp_adjust;
float friction;
float bounce;
uint32_t collision_layer;
uint32_t collision_mask;
mutable DataFormat format;
TileOrigin tile_origin;
int occluder_light_mask;
void _fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc);
void _add_shape(int &shape_idx, const Quadrant &p_q, const Ref<Shape2D> &p_shape, const RTileSet::ShapeData &p_shape_data, const Transform2D &p_xform, const Vector2 &p_metadata);
Map<PosKey, Quadrant>::Element *_create_quadrant(const PosKey &p_qk);
void _erase_quadrant(Map<PosKey, Quadrant>::Element *Q);
void _make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool update = true);
void _recreate_quadrants();
void _clear_quadrants();
void _update_quadrant_space(const RID &p_space);
void _update_quadrant_transform();
void _recompute_rect_cache();
void _update_all_items_material_state();
_FORCE_INLINE_ void _update_item_material_state(const RID &p_canvas_item);
_FORCE_INLINE_ int _get_quadrant_size() const;
void _set_tile_data(const PoolVector<int> &p_data);
PoolVector<int> _get_tile_data() const;
void _set_old_cell_size(int p_size) { set_cell_size(Size2(p_size, p_size)); }
int _get_old_cell_size() const { return cell_size.x; }
_FORCE_INLINE_ Vector2 _map_to_world(int p_x, int p_y, bool p_ignore_ofs = false) const;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
void _notification(int p_what);
static void _bind_methods();
virtual void _validate_property(PropertyInfo &property) const;
virtual void _changed_callback(Object *p_changed, const char *p_prop);
public:
enum {
INVALID_CELL = -1
};
#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
#endif
void set_tileset(const Ref<RTileSet> &p_tileset);
Ref<RTileSet> get_tileset() const;
void set_cell_size(Size2 p_size);
Size2 get_cell_size() const;
void set_quadrant_size(int p_size);
int get_quadrant_size() const;
void set_cell(int p_x, int p_y, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false, Vector2 p_autotile_coord = Vector2());
int get_cell(int p_x, int p_y) const;
bool is_cell_x_flipped(int p_x, int p_y) const;
bool is_cell_y_flipped(int p_x, int p_y) const;
bool is_cell_transposed(int p_x, int p_y) const;
void set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord);
Vector2 get_cell_autotile_coord(int p_x, int p_y) const;
void _set_celld(const Vector2 &p_pos, const Dictionary &p_data);
void set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false);
int get_cellv(const Vector2 &p_pos) const;
void make_bitmask_area_dirty(const Vector2 &p_pos);
void update_bitmask_area(const Vector2 &p_pos);
void update_bitmask_region(const Vector2 &p_start = Vector2(), const Vector2 &p_end = Vector2());
void update_cell_bitmask(int p_x, int p_y);
void update_dirty_bitmask();
void update_dirty_quadrants();
void set_show_collision(bool p_value);
bool is_show_collision_enabled() const;
void set_collision_layer(uint32_t p_layer);
uint32_t get_collision_layer() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;
void set_collision_mask_bit(int p_bit, bool p_value);
bool get_collision_mask_bit(int p_bit) const;
void set_collision_use_kinematic(bool p_use_kinematic);
bool get_collision_use_kinematic() const;
void set_collision_use_parent(bool p_use_parent);
bool get_collision_use_parent() const;
void set_collision_friction(float p_friction);
float get_collision_friction() const;
void set_collision_bounce(float p_bounce);
float get_collision_bounce() const;
void set_mode(Mode p_mode);
Mode get_mode() const;
void set_half_offset(HalfOffset p_half_offset);
HalfOffset get_half_offset() const;
void set_tile_origin(TileOrigin p_tile_origin);
TileOrigin get_tile_origin() const;
void set_custom_transform(const Transform2D &p_xform);
Transform2D get_custom_transform() const;
Transform2D get_cell_transform() const;
Vector2 get_cell_draw_offset() const;
Vector2 map_to_world(const Vector2 &p_pos, bool p_ignore_ofs = false) const;
Vector2 world_to_map(const Vector2 &p_pos) const;
void set_y_sort_mode(bool p_enable);
bool is_y_sort_mode_enabled() const;
void set_compatibility_mode(bool p_enable);
bool is_compatibility_mode_enabled() const;
void set_centered_textures(bool p_enable);
bool is_centered_textures_enabled() const;
Array get_used_cells() const;
Array get_used_cells_by_id(int p_id) const;
Rect2 get_used_rect(); // Not const because of cache
void set_occluder_light_mask(int p_mask);
int get_occluder_light_mask() const;
virtual void set_light_mask(int p_light_mask);
virtual void set_material(const Ref<Material> &p_material);
virtual void set_use_parent_material(bool p_use_parent_material);
void set_clip_uv(bool p_enable);
bool get_clip_uv() const;
String get_configuration_warning() const;
void fix_invalid_tiles();
void clear();
RTileMap();
~RTileMap();
};
VARIANT_ENUM_CAST(RTileMap::Mode);
VARIANT_ENUM_CAST(RTileMap::HalfOffset);
VARIANT_ENUM_CAST(RTileMap::TileOrigin);
#endif // TILE_MAP_H

2195
tile_map_editor_plugin.cpp Normal file

File diff suppressed because it is too large Load Diff

255
tile_map_editor_plugin.h Normal file
View File

@ -0,0 +1,255 @@
/*************************************************************************/
/* tile_map_editor_plugin.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef RTILE_MAP_EDITOR_PLUGIN_H
#define RTILE_MAP_EDITOR_PLUGIN_H
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "tile_map.h"
#include "scene/gui/check_box.h"
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/tool_button.h"
class RTileMapEditor : public VBoxContainer {
GDCLASS(RTileMapEditor, VBoxContainer);
enum Tool {
TOOL_NONE,
TOOL_PAINTING,
TOOL_ERASING,
TOOL_RECTANGLE_PAINT,
TOOL_RECTANGLE_ERASE,
TOOL_LINE_PAINT,
TOOL_LINE_ERASE,
TOOL_SELECTING,
TOOL_BUCKET,
TOOL_PICKING,
TOOL_PASTING
};
enum Options {
OPTION_COPY,
OPTION_ERASE_SELECTION,
OPTION_FIX_INVALID,
OPTION_CUT
};
RTileMap *node;
bool manual_autotile;
bool priority_atlastile;
Vector2 manual_position;
EditorNode *editor;
UndoRedo *undo_redo;
Control *canvas_item_editor_viewport;
LineEdit *search_box;
HSlider *size_slider;
ItemList *palette;
ItemList *manual_palette;
Label *info_message;
HBoxContainer *toolbar;
HBoxContainer *toolbar_right;
Label *tile_info;
MenuButton *options;
ToolButton *paint_button;
ToolButton *bucket_fill_button;
ToolButton *picker_button;
ToolButton *select_button;
ToolButton *flip_horizontal_button;
ToolButton *flip_vertical_button;
ToolButton *rotate_left_button;
ToolButton *rotate_right_button;
ToolButton *clear_transform_button;
CheckBox *manual_button;
CheckBox *priority_button;
Tool tool;
Tool last_tool;
bool selection_active;
bool mouse_over;
bool flip_h;
bool flip_v;
bool transpose;
Point2i autotile_coord;
Point2i rectangle_begin;
Rect2i rectangle;
Point2i over_tile;
bool refocus_over_tile;
bool *bucket_cache_visited;
Rect2i bucket_cache_rect;
int bucket_cache_tile;
PoolVector<Vector2> bucket_cache;
List<Point2i> bucket_queue;
struct CellOp {
int idx;
bool xf;
bool yf;
bool tr;
Vector2 ac;
CellOp() :
idx(RTileMap::INVALID_CELL),
xf(false),
yf(false),
tr(false) {}
};
Map<Point2i, CellOp> paint_undo;
struct TileData {
Point2i pos;
int cell;
bool flip_h;
bool flip_v;
bool transpose;
Point2i autotile_coord;
TileData() :
cell(RTileMap::INVALID_CELL),
flip_h(false),
flip_v(false),
transpose(false) {}
};
List<TileData> copydata;
Map<Point2i, CellOp> undo_data;
Vector<int> invalid_cell;
void _pick_tile(const Point2 &p_pos);
PoolVector<Vector2> _bucket_fill(const Point2i &p_start, bool erase = false, bool preview = false);
void _fill_points(const PoolVector<Vector2> &p_points, const Dictionary &p_op);
void _erase_points(const PoolVector<Vector2> &p_points);
void _select(const Point2i &p_from, const Point2i &p_to);
void _erase_selection();
void _draw_cell(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord, const Transform2D &p_xform);
void _draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord, const Transform2D &p_xform);
void _clear_bucket_cache();
void _update_copydata();
Vector<int> get_selected_tiles() const;
void set_selected_tiles(Vector<int> p_tile);
void _manual_toggled(bool p_enabled);
void _priority_toggled(bool p_enabled);
void _text_entered(const String &p_text);
void _text_changed(const String &p_text);
void _sbox_input(const Ref<InputEvent> &p_ie);
void _update_palette();
void _update_button_tool();
void _button_tool_select(int p_tool);
void _menu_option(int p_option);
void _palette_selected(int index);
void _palette_multi_selected(int index, bool selected);
void _palette_input(const Ref<InputEvent> &p_event);
Dictionary _create_cell_dictionary(int tile, bool flip_x, bool flip_y, bool transpose, Vector2 autotile_coord);
void _start_undo(const String &p_action);
void _finish_undo();
void _create_set_cell_undo_redo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new);
void _set_cell(const Point2i &p_pos, Vector<int> p_values, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false, const Point2i &p_autotile_coord = Point2());
void _canvas_mouse_enter();
void _canvas_mouse_exit();
void _tileset_settings_changed();
void _icon_size_changed(float p_value);
void _clear_transform();
void _flip_horizontal();
void _flip_vertical();
void _rotate(int steps);
protected:
void _notification(int p_what);
void _node_removed(Node *p_node);
static void _bind_methods();
CellOp _get_op_from_cell(const Point2i &p_pos);
public:
HBoxContainer *get_toolbar() const { return toolbar; }
HBoxContainer *get_toolbar_right() const { return toolbar_right; }
Label *get_tile_info() const { return tile_info; }
bool forward_gui_input(const Ref<InputEvent> &p_event);
void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(Node *p_tile_map);
RTileMapEditor(EditorNode *p_editor);
~RTileMapEditor();
};
class RTileMapEditorPlugin : public EditorPlugin {
GDCLASS(RTileMapEditorPlugin, EditorPlugin);
RTileMapEditor *tile_map_editor;
protected:
void _notification(int p_what);
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return tile_map_editor->forward_gui_input(p_event); }
virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { tile_map_editor->forward_canvas_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "RTileMap"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_object);
virtual bool handles(Object *p_object) const;
virtual void make_visible(bool p_visible);
RTileMapEditorPlugin(EditorNode *p_node);
~RTileMapEditorPlugin();
};
#endif // TILE_MAP_EDITOR_PLUGIN_H

1197
tile_set.cpp Normal file

File diff suppressed because it is too large Load Diff

269
tile_set.h Normal file
View File

@ -0,0 +1,269 @@
/*************************************************************************/
/* tile_set.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef RTILE_SET_H
#define RTILE_SET_H
#include "core/array.h"
#include "core/resource.h"
#include "scene/2d/light_occluder_2d.h"
#include "scene/2d/navigation_polygon.h"
#include "scene/resources/convex_polygon_shape_2d.h"
#include "scene/resources/shape_2d.h"
#include "scene/resources/texture.h"
class RTileSet : public Resource {
GDCLASS(RTileSet, Resource);
public:
struct ShapeData {
Ref<Shape2D> shape;
Transform2D shape_transform;
Vector2 autotile_coord;
bool one_way_collision;
float one_way_collision_margin;
ShapeData() {
one_way_collision = false;
one_way_collision_margin = 1.0;
}
};
enum BitmaskMode {
BITMASK_2X2,
BITMASK_3X3_MINIMAL,
BITMASK_3X3
};
enum AutotileBindings {
BIND_TOPLEFT = 1,
BIND_TOP = 2,
BIND_TOPRIGHT = 4,
BIND_LEFT = 8,
BIND_CENTER = 16,
BIND_RIGHT = 32,
BIND_BOTTOMLEFT = 64,
BIND_BOTTOM = 128,
BIND_BOTTOMRIGHT = 256,
BIND_IGNORE_TOPLEFT = 1 << 16,
BIND_IGNORE_TOP = 1 << 17,
BIND_IGNORE_TOPRIGHT = 1 << 18,
BIND_IGNORE_LEFT = 1 << 19,
BIND_IGNORE_CENTER = 1 << 20,
BIND_IGNORE_RIGHT = 1 << 21,
BIND_IGNORE_BOTTOMLEFT = 1 << 22,
BIND_IGNORE_BOTTOM = 1 << 23,
BIND_IGNORE_BOTTOMRIGHT = 1 << 24
};
enum TileMode {
SINGLE_TILE,
AUTO_TILE,
ATLAS_TILE
};
struct AutotileData {
BitmaskMode bitmask_mode;
Size2 size;
int spacing;
Vector2 icon_coord;
Map<Vector2, uint32_t> flags;
Map<Vector2, Ref<OccluderPolygon2D>> occluder_map;
Map<Vector2, Ref<NavigationPolygon>> navpoly_map;
Map<Vector2, int> priority_map;
Map<Vector2, int> z_index_map;
// Default size to prevent invalid value
explicit AutotileData() :
bitmask_mode(BITMASK_2X2),
size(64, 64),
spacing(0),
icon_coord(0, 0) {}
};
private:
struct TileData {
String name;
Ref<Texture> texture;
Ref<Texture> normal_map;
Vector2 offset;
Rect2i region;
Vector<ShapeData> shapes_data;
Vector2 occluder_offset;
Ref<OccluderPolygon2D> occluder;
Vector2 navigation_polygon_offset;
Ref<NavigationPolygon> navigation_polygon;
Ref<ShaderMaterial> material;
TileMode tile_mode;
Color modulate;
AutotileData autotile_data;
int z_index;
// Default modulate for back-compat
explicit TileData() :
tile_mode(SINGLE_TILE),
modulate(1, 1, 1),
z_index(0) {}
};
Map<int, TileData> tile_map;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
void _tile_set_shapes(int p_id, const Array &p_shapes);
Array _tile_get_shapes(int p_id) const;
Array _get_tiles_ids() const;
void _decompose_convex_shape(Ref<Shape2D> p_shape);
static void _bind_methods();
public:
void create_tile(int p_id);
void autotile_set_bitmask_mode(int p_id, BitmaskMode p_mode);
BitmaskMode autotile_get_bitmask_mode(int p_id) const;
void tile_set_name(int p_id, const String &p_name);
String tile_get_name(int p_id) const;
void tile_set_texture(int p_id, const Ref<Texture> &p_texture);
Ref<Texture> tile_get_texture(int p_id) const;
void tile_set_normal_map(int p_id, const Ref<Texture> &p_normal_map);
Ref<Texture> tile_get_normal_map(int p_id) const;
void tile_set_texture_offset(int p_id, const Vector2 &p_offset);
Vector2 tile_get_texture_offset(int p_id) const;
void tile_set_region(int p_id, const Rect2 &p_region);
Rect2 tile_get_region(int p_id) const;
void tile_set_tile_mode(int p_id, TileMode p_tile_mode);
TileMode tile_get_tile_mode(int p_id) const;
void autotile_set_icon_coordinate(int p_id, Vector2 coord);
Vector2 autotile_get_icon_coordinate(int p_id) const;
void autotile_set_spacing(int p_id, int p_spacing);
int autotile_get_spacing(int p_id) const;
void autotile_set_size(int p_id, Size2 p_size);
Size2 autotile_get_size(int p_id) const;
void autotile_clear_bitmask_map(int p_id);
void autotile_set_subtile_priority(int p_id, const Vector2 &p_coord, int p_priority);
int autotile_get_subtile_priority(int p_id, const Vector2 &p_coord);
const Map<Vector2, int> &autotile_get_priority_map(int p_id) const;
void autotile_set_z_index(int p_id, const Vector2 &p_coord, int p_z_index);
int autotile_get_z_index(int p_id, const Vector2 &p_coord);
const Map<Vector2, int> &autotile_get_z_index_map(int p_id) const;
void autotile_set_bitmask(int p_id, Vector2 p_coord, uint32_t p_flag);
uint32_t autotile_get_bitmask(int p_id, Vector2 p_coord);
const Map<Vector2, uint32_t> &autotile_get_bitmask_map(int p_id);
Vector2 autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node = nullptr, const Vector2 &p_tile_location = Vector2());
Vector2 atlastile_get_subtile_by_priority(int p_id, const Node *p_tilemap_node = nullptr, const Vector2 &p_tile_location = Vector2());
void tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_shape);
Ref<Shape2D> tile_get_shape(int p_id, int p_shape_id) const;
void tile_set_shape_transform(int p_id, int p_shape_id, const Transform2D &p_offset);
Transform2D tile_get_shape_transform(int p_id, int p_shape_id) const;
void tile_set_shape_offset(int p_id, int p_shape_id, const Vector2 &p_offset);
Vector2 tile_get_shape_offset(int p_id, int p_shape_id) const;
void tile_set_shape_one_way(int p_id, int p_shape_id, bool p_one_way);
bool tile_get_shape_one_way(int p_id, int p_shape_id) const;
void tile_set_shape_one_way_margin(int p_id, int p_shape_id, float p_margin);
float tile_get_shape_one_way_margin(int p_id, int p_shape_id) const;
void tile_clear_shapes(int p_id);
void tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transform2D &p_transform, bool p_one_way = false, const Vector2 &p_autotile_coord = Vector2());
int tile_get_shape_count(int p_id) const;
void tile_set_shapes(int p_id, const Vector<ShapeData> &p_shapes);
Vector<ShapeData> tile_get_shapes(int p_id) const;
void tile_set_material(int p_id, const Ref<ShaderMaterial> &p_material);
Ref<ShaderMaterial> tile_get_material(int p_id) const;
void tile_set_modulate(int p_id, const Color &p_modulate);
Color tile_get_modulate(int p_id) const;
void tile_set_occluder_offset(int p_id, const Vector2 &p_offset);
Vector2 tile_get_occluder_offset(int p_id) const;
void tile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder);
Ref<OccluderPolygon2D> tile_get_light_occluder(int p_id) const;
void autotile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder, const Vector2 &p_coord);
Ref<OccluderPolygon2D> autotile_get_light_occluder(int p_id, const Vector2 &p_coord) const;
const Map<Vector2, Ref<OccluderPolygon2D>> &autotile_get_light_oclusion_map(int p_id) const;
void tile_set_navigation_polygon_offset(int p_id, const Vector2 &p_offset);
Vector2 tile_get_navigation_polygon_offset(int p_id) const;
void tile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon);
Ref<NavigationPolygon> tile_get_navigation_polygon(int p_id) const;
void autotile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon, const Vector2 &p_coord);
Ref<NavigationPolygon> autotile_get_navigation_polygon(int p_id, const Vector2 &p_coord) const;
const Map<Vector2, Ref<NavigationPolygon>> &autotile_get_navigation_map(int p_id) const;
void tile_set_z_index(int p_id, int p_z_index);
int tile_get_z_index(int p_id) const;
void remove_tile(int p_id);
bool has_tile(int p_id) const;
bool is_tile_bound(int p_drawn_id, int p_neighbor_id);
int find_tile_by_name(const String &p_name) const;
void get_tile_list(List<int> *p_tiles) const;
void clear();
int get_last_unused_tile_id() const;
RTileSet();
};
VARIANT_ENUM_CAST(RTileSet::AutotileBindings);
VARIANT_ENUM_CAST(RTileSet::BitmaskMode);
VARIANT_ENUM_CAST(RTileSet::TileMode);
#endif // TILE_SET_H

3668
tile_set_editor_plugin.cpp Normal file

File diff suppressed because it is too large Load Diff

297
tile_set_editor_plugin.h Normal file
View File

@ -0,0 +1,297 @@
/*************************************************************************/
/* tile_set_editor_plugin.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef RTILE_SET_EDITOR_PLUGIN_H
#define RTILE_SET_EDITOR_PLUGIN_H
#include "editor/editor_node.h"
#include "scene/2d/sprite.h"
#include "scene/resources/concave_polygon_shape_2d.h"
#include "scene/resources/convex_polygon_shape_2d.h"
#include "tile_set.h"
#define WORKSPACE_MARGIN Vector2(10, 10)
class RTilesetEditorContext;
class RTileSetEditor : public HSplitContainer {
friend class RTileSetEditorPlugin;
friend class RTilesetEditorContext;
GDCLASS(RTileSetEditor, HSplitContainer);
enum TextureToolButtons {
TOOL_TILESET_ADD_TEXTURE,
TOOL_TILESET_REMOVE_TEXTURE,
TOOL_TILESET_CREATE_SCENE,
TOOL_TILESET_MERGE_SCENE,
TOOL_TILESET_MAX
};
enum WorkspaceMode {
WORKSPACE_EDIT,
WORKSPACE_CREATE_SINGLE,
WORKSPACE_CREATE_AUTOTILE,
WORKSPACE_CREATE_ATLAS,
WORKSPACE_MODE_MAX
};
enum EditMode {
EDITMODE_REGION,
EDITMODE_COLLISION,
EDITMODE_OCCLUSION,
EDITMODE_NAVIGATION,
EDITMODE_BITMASK,
EDITMODE_PRIORITY,
EDITMODE_ICON,
EDITMODE_Z_INDEX,
EDITMODE_MAX
};
enum TileSetTools {
SELECT_PREVIOUS,
SELECT_NEXT,
TOOL_SELECT,
BITMASK_COPY,
BITMASK_PASTE,
BITMASK_CLEAR,
SHAPE_NEW_POLYGON,
SHAPE_NEW_RECTANGLE,
SHAPE_TOGGLE_TYPE,
SHAPE_DELETE,
SHAPE_KEEP_INSIDE_TILE,
TOOL_GRID_SNAP,
ZOOM_OUT,
ZOOM_1,
ZOOM_IN,
VISIBLE_INFO,
TOOL_MAX
};
struct SubtileData {
Array collisions;
Ref<OccluderPolygon2D> occlusion_shape;
Ref<NavigationPolygon> navigation_shape;
};
Ref<RTileSet> tileset;
RTilesetEditorContext *helper;
EditorNode *editor;
UndoRedo *undo_redo;
ConfirmationDialog *cd;
AcceptDialog *err_dialog;
EditorFileDialog *texture_dialog;
ItemList *texture_list;
int option;
ToolButton *tileset_toolbar_buttons[TOOL_TILESET_MAX];
MenuButton *tileset_toolbar_tools;
Map<String, Ref<Texture>> texture_map;
bool creating_shape;
int dragging_point;
bool tile_names_visible;
Vector2 region_from;
Rect2 edited_region;
bool draw_edited_region;
Vector2 edited_shape_coord;
PoolVector2Array current_shape;
Map<Vector2i, SubtileData> current_tile_data;
Map<Vector2, uint32_t> bitmask_map_copy;
Vector2 snap_step;
Vector2 snap_offset;
Vector2 snap_separation;
Ref<Shape2D> edited_collision_shape;
Ref<OccluderPolygon2D> edited_occlusion_shape;
Ref<NavigationPolygon> edited_navigation_shape;
int current_item_index;
Sprite *preview;
ScrollContainer *scroll;
Label *empty_message;
Control *workspace_container;
bool draw_handles;
Control *workspace_overlay;
Control *workspace;
Button *tool_workspacemode[WORKSPACE_MODE_MAX];
Button *tool_editmode[EDITMODE_MAX];
HSeparator *separator_editmode;
HBoxContainer *toolbar;
ToolButton *tools[TOOL_MAX];
VSeparator *separator_shape_toggle;
VSeparator *separator_bitmask;
VSeparator *separator_delete;
VSeparator *separator_grid;
SpinBox *spin_priority;
SpinBox *spin_z_index;
WorkspaceMode workspace_mode;
EditMode edit_mode;
int current_tile;
float max_scale;
float min_scale;
float scale_ratio;
void update_texture_list();
void update_texture_list_icon();
void add_texture(Ref<Texture> p_texture);
void remove_texture(Ref<Texture> p_texture);
Ref<Texture> get_current_texture();
static void _import_node(Node *p_node, Ref<RTileSet> p_library);
static void _import_scene(Node *p_scene, Ref<RTileSet> p_library, bool p_merge);
void _undo_redo_import_scene(Node *p_scene, bool p_merge);
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
protected:
static void _bind_methods();
void _notification(int p_what);
public:
void edit(const Ref<RTileSet> &p_tileset);
static Error update_library_file(Node *p_base_scene, Ref<RTileSet> ml, bool p_merge = true);
RTileSetEditor(EditorNode *p_editor);
~RTileSetEditor();
private:
void _on_tileset_toolbar_button_pressed(int p_index);
void _on_tileset_toolbar_confirm();
void _on_texture_list_selected(int p_index);
void _on_textures_added(const PoolStringArray &p_paths);
void _on_edit_mode_changed(int p_edit_mode);
void _on_workspace_mode_changed(int p_workspace_mode);
void _on_workspace_overlay_draw();
void _on_workspace_draw();
void _on_workspace_process();
void _on_scroll_container_input(const Ref<InputEvent> &p_event);
void _on_workspace_input(const Ref<InputEvent> &p_ie);
void _on_tool_clicked(int p_tool);
void _on_priority_changed(float val);
void _on_z_index_changed(float val);
void _on_grid_snap_toggled(bool p_val);
Vector<Vector2> _get_collision_shape_points(const Ref<Shape2D> &p_shape);
Vector<Vector2> _get_edited_shape_points();
void _set_edited_shape_points(const Vector<Vector2> &points);
void _update_tile_data();
void _update_toggle_shape_button();
void _select_next_tile();
void _select_previous_tile();
Array _get_tiles_in_current_texture(bool sorted = false);
bool _sort_tiles(Variant p_a, Variant p_b);
Vector2 _get_subtiles_count(int p_tile_id);
void _select_next_subtile();
void _select_previous_subtile();
void _select_next_shape();
void _select_previous_shape();
void _set_edited_collision_shape(const Ref<Shape2D> &p_shape);
void _set_snap_step(Vector2 p_val);
void _set_snap_off(Vector2 p_val);
void _set_snap_sep(Vector2 p_val);
void _validate_current_tile_id();
void _select_edited_shape_coord();
void _undo_tile_removal(int p_id);
void _zoom_in();
void _zoom_out();
void _zoom_reset();
void draw_highlight_current_tile();
void draw_highlight_subtile(Vector2 coord, const Vector<Vector2> &other_highlighted = Vector<Vector2>());
void draw_tile_subdivision(int p_id, Color p_color) const;
void draw_edited_region_subdivision() const;
void draw_grid_snap();
void draw_polygon_shapes();
void close_shape(const Vector2 &shape_anchor);
void select_coord(const Vector2 &coord);
Vector2 snap_point(const Vector2 &point);
void update_workspace_tile_mode();
void update_workspace_minsize();
void update_edited_region(const Vector2 &end_point);
int get_grabbed_point(const Vector2 &p_mouse_pos, real_t grab_threshold);
bool is_within_grabbing_distance_of_first_point(const Vector2 &p_pos, real_t p_grab_threshold);
int get_current_tile() const;
void set_current_tile(int p_id);
};
class RTilesetEditorContext : public Object {
friend class RTileSetEditor;
GDCLASS(RTilesetEditorContext, Object);
Ref<RTileSet> tileset;
RTileSetEditor *tileset_editor;
bool snap_options_visible;
public:
bool _hide_script_from_inspector() { return true; }
void set_tileset(const Ref<RTileSet> &p_tileset);
private:
void set_snap_options_visible(bool p_visible);
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
static void _bind_methods();
public:
RTilesetEditorContext(RTileSetEditor *p_tileset_editor);
};
class RTileSetEditorPlugin : public EditorPlugin {
GDCLASS(RTileSetEditorPlugin, EditorPlugin);
RTileSetEditor *tileset_editor;
Button *tileset_editor_button;
EditorNode *editor;
public:
virtual String get_name() const { return "RTileSet"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
virtual bool handles(Object *p_node) const;
virtual void make_visible(bool p_visible);
void set_state(const Dictionary &p_state);
Dictionary get_state() const;
RTileSetEditorPlugin(EditorNode *p_node);
};
#endif // TILE_SET_EDITOR_PLUGIN_H