Added my rtile_map module.

This commit is contained in:
Relintai 2022-03-16 01:37:06 +01:00
parent aaf91df4c1
commit 24e5d5cb34
15 changed files with 10432 additions and 0 deletions

8
modules/rtile_map/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
.import
*.d
*.o
*.meta
*.pyc
*.obj
*.bc

19
modules/rtile_map/LICENSE Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2019-2021 Péter Magyar
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.

View File

@ -0,0 +1,25 @@
# RTileMap
Godot's TileMap but as an engine module, with a few smaller features added.
The tilemap classes will be prefixed with R, so it compiles cleanly with the built in TileMap class.
# Building
1. Get the source code for the engine.
```git clone -b 3.x https://github.com/godotengine/godot.git godot```
2. Go into Godot's modules directory.
```
cd ./godot/modules/
```
3. Clone this repository
```
git clone https://github.com/Relintai/rtile_map.git rtile_map
```
4. Build Godot. [Tutorial](https://docs.godotengine.org/en/latest/development/compiling/index.html)

10
modules/rtile_map/SCsub Normal file
View File

@ -0,0 +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_map_editor_plugin.cpp")
env.add_source_files(env.modules_sources, "tile_set_editor_plugin.cpp")

View File

@ -0,0 +1,13 @@
def can_build(env, platform):
return True
def configure(env):
pass
def get_doc_classes():
return [
]
def get_doc_path():
return "doc_classes"

View File

@ -0,0 +1,44 @@
/*
Copyright (c) 2021 Péter Magyar
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.
*/
#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() {
}

View File

@ -0,0 +1,24 @@
/*
Copyright (c) 2021 Péter Magyar
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.
*/
void register_rtile_map_types();
void unregister_rtile_map_types();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,378 @@
/*************************************************************************/
/* 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"
#include "core/version.h"
#include "../fastnoise/noise.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;
Ref<FastNoise> noise;
bool _use_rao;
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;
}
};
struct Cell {
int32_t id;
bool flip_h;
bool flip_v;
bool transpose;
int16_t autotile_coord_x;
int16_t autotile_coord_y;
uint8_t rao;
Cell() {
id = 0;
flip_h = false;
flip_v = false;
transpose = false;
autotile_coord_x = 0;
autotile_coord_y = 0;
rao = 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 {
#if VERSION_MINOR < 5
int id;
#else
RID region;
#endif
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_use_rao(bool p_rao);
bool get_use_rao() 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

File diff suppressed because it is too large Load Diff

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,277 @@
/*************************************************************************/
/* 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"
#include "../fastnoise/noise.h"
#include "../fastnoise/fastnoise_noise_params.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;
Ref<FastnoiseNoiseParams> _noise_params;
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;
void set_noise_params(const Ref<FastnoiseNoiseParams> &noise);
Ref<FastnoiseNoiseParams> get_noise_params();
void setup_noise(Ref<FastNoise> noise);
RTileSet();
};
VARIANT_ENUM_CAST(RTileSet::AutotileBindings);
VARIANT_ENUM_CAST(RTileSet::BitmaskMode);
VARIANT_ENUM_CAST(RTileSet::TileMode);
#endif // TILE_SET_H

File diff suppressed because it is too large Load Diff

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