Compare commits
4 Commits
eee2a23231
...
xonkaede
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b4c9ef899 | ||
| 62cf438b0d | |||
| 81054b3572 | |||
| 1a29a449b0 |
@@ -1,9 +0,0 @@
|
|||||||
# MIT License
|
|
||||||
|
|
||||||
Copyright 2022 Gennady "Don Tnowe" Krupenyov
|
|
||||||
|
|
||||||
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.
|
|
||||||
38
README.md
@@ -1,38 +0,0 @@
|
|||||||
# Sprite Painter
|
|
||||||
|
|
||||||
Actually, it's not just sprites it paints.
|
|
||||||
|
|
||||||
Image editor right within Godot 4!
|
|
||||||
|
|
||||||
Just press the colorful button above the viewport to edit a Node's texture, or an image file in the project folder!
|
|
||||||
|
|
||||||
- **Box and Wand selections**, which mask effects of drawing tools. The underlying pixels can be dragged and dropped elsewhere;
|
|
||||||
- 1-pixel **pencil** - can erase if secondary color is transparent;
|
|
||||||
- Round **brush** with **eraser** and smooth option;
|
|
||||||
- A classic **bucket** tool with a **gradient** variant;
|
|
||||||
- **Line** drawing;
|
|
||||||
- A number of **shapes** to shape your graphics;
|
|
||||||
- And a bit of **scripting** support.
|
|
||||||
|
|
||||||
Other features:
|
|
||||||
- Quick operations on the image: flip, rotate, and resize;
|
|
||||||
- Press Alt to pick color from editor window;
|
|
||||||
- Grid overlay for Sprites with Frames and Maps with Tiles;
|
|
||||||
- Region overlays for Atlastextures and Spriteframes;
|
|
||||||
- Full Undo support.
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
Made by Don Tnowe in 2022.
|
|
||||||
|
|
||||||
[My Website](https://redbladegames.netlify.app)
|
|
||||||
|
|
||||||
[My Twitter](https://twitter.com/don_tnowe)
|
|
||||||
|
|
||||||
[My Itch](https://don-tnowe.itch.io)
|
|
||||||
|
|
||||||
Copying and Modification is allowed in accordance to the MIT license, full text is included.
|
|
||||||
|
|
||||||
Some shader code is from [https://iquilezles.org/articles](https://iquilezles.org/articles), released under the MIT License.
|
|
||||||
|
|
||||||
Icon made in Sprite Painter [*tm*]
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
extends CharacterBody2D
|
|
||||||
|
|
||||||
var speed = 300
|
|
||||||
var click_position = Vector2()
|
|
||||||
var target_position = Vector2()
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
click_position = position
|
|
||||||
func _physics_process(delta):
|
|
||||||
if Input.is_action_just_pressed("left_click"):
|
|
||||||
click_position = get_global_mouse_position()
|
|
||||||
|
|
||||||
if (position.distance_to(click_position)) >3:
|
|
||||||
target_position = (click_position - position).normalized()
|
|
||||||
velocity = target_position*speed
|
|
||||||
move_and_slide()
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://dtttpb73i7qt2"]
|
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://blmo4uqveqgtu" path="res://assets/Amogus.png" id="1_27e8i"]
|
|
||||||
[ext_resource type="Script" path="res://Scenes/player.gd" id="1_xdifv"]
|
|
||||||
|
|
||||||
[sub_resource type="CircleShape2D" id="CircleShape2D_ounmr"]
|
|
||||||
radius = 3.16228
|
|
||||||
|
|
||||||
[node name="Player" type="CharacterBody2D"]
|
|
||||||
script = ExtResource("1_xdifv")
|
|
||||||
|
|
||||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
|
||||||
texture = ExtResource("1_27e8i")
|
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
|
||||||
position = Vector2(0, 1)
|
|
||||||
shape = SubResource("CircleShape2D_ounmr")
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
# MIT License
|
|
||||||
|
|
||||||
Copyright 2022 Gennady "Don Tnowe" Krupenyov
|
|
||||||
|
|
||||||
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.
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends Button
|
|
||||||
|
|
||||||
@export var icon_name := "Node"
|
|
||||||
# set(v):
|
|
||||||
# _set_icon_name(v)
|
|
||||||
|
|
||||||
|
|
||||||
func _set_icon_name(v):
|
|
||||||
icon_name = v
|
|
||||||
if has_theme_icon(v, "EditorIcons"):
|
|
||||||
icon = get_theme_icon(v, "EditorIcons")
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
_set_icon_name(icon_name)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1038.4a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" fill="none" stroke="#5fb2ff" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 273 B |
@@ -1,37 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://cpxsxp2vr8kc6"
|
|
||||||
path="res://.godot/imported/circle_shape_2d.svg-82c4246092358c78c496ed3aeadc38e1.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://addons/sprite_painter/graphics/circle_shape_2d.svg"
|
|
||||||
dest_files=["res://.godot/imported/circle_shape_2d.svg-82c4246092358c78c496ed3aeadc38e1.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
svg/scale=1.0
|
|
||||||
editor/scale_with_editor_scale=false
|
|
||||||
editor/convert_colors_with_editor_theme=false
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://rvkxkfn8dol2"]
|
|
||||||
|
|
||||||
[sub_resource type="Image" id="Image_fmgcp"]
|
|
||||||
data = {
|
|
||||||
"data": PackedByteArray(255, 255, 255, 0, 225, 225, 225, 51, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 225, 225, 225, 51, 255, 255, 255, 0, 225, 225, 225, 51, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 50, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 112, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 112, 224, 224, 224, 254, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 17, 225, 225, 225, 34, 255, 255, 255, 0, 255, 255, 255, 4, 255, 255, 255, 4, 255, 255, 255, 4, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 160, 224, 224, 224, 194, 224, 224, 224, 32, 224, 224, 224, 8, 224, 224, 224, 104, 255, 255, 255, 6, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 224, 224, 224, 96, 224, 224, 224, 192, 224, 224, 224, 255, 224, 224, 224, 232, 227, 227, 227, 9, 224, 224, 224, 107, 224, 224, 224, 255, 226, 226, 226, 35, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 112, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 254, 225, 225, 225, 100, 255, 255, 255, 3, 224, 224, 224, 211, 224, 224, 224, 201, 255, 255, 255, 0, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 128, 225, 225, 225, 75, 255, 255, 255, 0, 225, 225, 225, 124, 224, 224, 224, 255, 226, 226, 226, 79, 255, 255, 255, 0, 231, 231, 231, 21, 225, 225, 225, 67, 238, 238, 238, 15, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 234, 234, 234, 12, 224, 224, 224, 139, 224, 224, 224, 255, 224, 224, 224, 153, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 51, 226, 226, 226, 77, 226, 226, 226, 86, 224, 224, 224, 123, 224, 224, 224, 178, 224, 224, 224, 238, 224, 224, 224, 254, 224, 224, 224, 140, 255, 255, 255, 2, 255, 255, 255, 0, 255, 255, 255, 0, 228, 228, 228, 37, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 253, 224, 224, 224, 211, 224, 224, 224, 153, 228, 228, 228, 47, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 42, 226, 226, 226, 52, 226, 226, 226, 44, 238, 238, 238, 15, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
|
||||||
"format": "RGBA8",
|
|
||||||
"height": 12,
|
|
||||||
"mipmaps": false,
|
|
||||||
"width": 12
|
|
||||||
}
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
image = SubResource("Image_fmgcp")
|
|
||||||
|
Before Width: | Height: | Size: 719 B |
@@ -1,34 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://c7nymhfcdr3hl"
|
|
||||||
path="res://.godot/imported/diags.png-8f1f755b2561632401e027e528c97db7.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://addons/sprite_painter/graphics/diags.png"
|
|
||||||
dest_files=["res://.godot/imported/diags.png-8f1f755b2561632401e027e528c97db7.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
height="16"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
width="16"
|
|
||||||
version="1.1"
|
|
||||||
id="svg4"
|
|
||||||
sodipodi:docname="DiamondShape2D.svg"
|
|
||||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
|
||||||
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="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="24.306796"
|
|
||||||
inkscape:cx="0.90509668"
|
|
||||||
inkscape:cy="4.8134687"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1057"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg4" />
|
|
||||||
<rect
|
|
||||||
fill="none"
|
|
||||||
height="8.3526468"
|
|
||||||
rx="1.1832915e-05"
|
|
||||||
stroke="#5fb2ff"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-miterlimit="10"
|
|
||||||
stroke-width="2.00051"
|
|
||||||
width="8.3526468"
|
|
||||||
x="-4.1989856"
|
|
||||||
y="7.0055852"
|
|
||||||
id="rect2"
|
|
||||||
transform="matrix(0.71834136,-0.6956908,0.71834136,0.6956908,0,0)" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,37 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://drjoeyt7e6kwg"
|
|
||||||
path="res://.godot/imported/diamond_shape_2d.svg-c7409b07122604b74671fded8f79cf9b.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://addons/sprite_painter/graphics/diamond_shape_2d.svg"
|
|
||||||
dest_files=["res://.godot/imported/diamond_shape_2d.svg-c7409b07122604b74671fded8f79cf9b.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
svg/scale=1.0
|
|
||||||
editor/scale_with_editor_scale=false
|
|
||||||
editor/convert_colors_with_editor_theme=false
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://b5v27x2n2je75"]
|
|
||||||
|
|
||||||
[sub_resource type="Image" id="Image_my53x"]
|
|
||||||
data = {
|
|
||||||
"data": PackedByteArray(225, 225, 225, 17, 225, 225, 225, 68, 225, 225, 225, 68, 225, 225, 225, 68, 224, 224, 224, 24, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 24, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 16, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 180, 255, 255, 255, 6, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 7, 224, 224, 224, 184, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 142, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 146, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 181, 225, 225, 225, 142, 224, 224, 224, 255, 224, 224, 224, 139, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 144, 224, 224, 224, 255, 224, 224, 224, 138, 224, 224, 224, 184, 224, 224, 224, 64, 233, 233, 233, 23, 255, 255, 255, 7, 255, 255, 255, 0, 224, 224, 224, 139, 224, 224, 224, 123, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 127, 225, 225, 225, 134, 255, 255, 255, 0, 255, 255, 255, 7, 233, 233, 233, 23, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 24, 255, 255, 255, 7, 255, 255, 255, 0, 224, 224, 224, 144, 225, 225, 225, 127, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 132, 224, 224, 224, 139, 255, 255, 255, 0, 224, 224, 224, 8, 224, 224, 224, 24, 224, 224, 224, 64, 224, 224, 224, 184, 224, 224, 224, 146, 224, 224, 224, 255, 225, 225, 225, 134, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 139, 224, 224, 224, 255, 225, 225, 225, 142, 224, 224, 224, 186, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 138, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 142, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 184, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 8, 224, 224, 224, 186, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 16, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 233, 233, 233, 23, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 24, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 16),
|
|
||||||
"format": "RGBA8",
|
|
||||||
"height": 12,
|
|
||||||
"mipmaps": false,
|
|
||||||
"width": 12
|
|
||||||
}
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
image = SubResource("Image_my53x")
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://diqj6upxhiiko"]
|
|
||||||
|
|
||||||
[sub_resource type="Image" id="Image_buorn"]
|
|
||||||
data = {
|
|
||||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 8, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 8, 224, 224, 224, 184, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 184, 255, 255, 255, 7, 255, 255, 255, 0, 224, 224, 224, 8, 224, 224, 224, 184, 224, 224, 224, 255, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 255, 224, 224, 224, 184, 255, 255, 255, 7, 255, 255, 255, 7, 224, 224, 224, 184, 224, 224, 224, 255, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 255, 225, 225, 225, 183, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 7, 224, 224, 224, 184, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 183, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
|
||||||
"format": "RGBA8",
|
|
||||||
"height": 12,
|
|
||||||
"mipmaps": false,
|
|
||||||
"width": 12
|
|
||||||
}
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
image = SubResource("Image_buorn")
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
height="16"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
width="16"
|
|
||||||
version="1.1"
|
|
||||||
id="svg4"
|
|
||||||
sodipodi:docname="HexShape2D.svg"
|
|
||||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
|
||||||
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="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="45.254834"
|
|
||||||
inkscape:cx="5.2149125"
|
|
||||||
inkscape:cy="8.9051261"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1057"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg4" />
|
|
||||||
<path
|
|
||||||
id="rect2"
|
|
||||||
style="fill:none;stroke:#5fb2ff;stroke-width:2.00051;stroke-linejoin:round;stroke-miterlimit:10"
|
|
||||||
transform="matrix(0.71834136,-0.6956908,0.71834136,0.6956908,0,0)"
|
|
||||||
d="m -1.5727512,5.4706195 5.7264006,1.5349657 1.19e-5,1.18e-5 1.5124976,5.703909 -4.4560086,4.456008 -5.409124,-1.807282 -1.19e-5,-1.2e-5 -1.8297623,-5.4316038 z"
|
|
||||||
sodipodi:nodetypes="ccccccccc" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,37 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://43n8i7bhg4he"
|
|
||||||
path="res://.godot/imported/hex_shape_2d.svg-33b4a57aed136855fbb5d791f29eb5bb.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://addons/sprite_painter/graphics/hex_shape_2d.svg"
|
|
||||||
dest_files=["res://.godot/imported/hex_shape_2d.svg-33b4a57aed136855fbb5d791f29eb5bb.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
svg/scale=1.0
|
|
||||||
editor/scale_with_editor_scale=false
|
|
||||||
editor/convert_colors_with_editor_theme=false
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://dnnjnka3gsci7"]
|
|
||||||
|
|
||||||
[sub_resource type="Image" id="Image_i608h"]
|
|
||||||
data = {
|
|
||||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 6, 224, 224, 224, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 42, 255, 255, 255, 6, 255, 255, 255, 0, 255, 255, 255, 6, 224, 224, 224, 226, 224, 224, 224, 255, 224, 224, 224, 164, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 168, 224, 224, 224, 255, 224, 224, 224, 225, 255, 255, 255, 6, 224, 224, 224, 41, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 40, 255, 255, 255, 0, 224, 224, 224, 165, 224, 224, 224, 254, 226, 226, 226, 35, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 229, 229, 229, 38, 224, 224, 224, 255, 224, 224, 224, 163, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 128, 224, 224, 224, 252, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 231, 231, 231, 31, 225, 225, 225, 17, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 128, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 128, 224, 224, 224, 252, 255, 255, 255, 0, 237, 237, 237, 14, 225, 225, 225, 68, 224, 224, 224, 224, 224, 224, 224, 180, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 128, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 128, 224, 224, 224, 252, 224, 224, 224, 24, 225, 225, 225, 182, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 245, 225, 225, 225, 84, 224, 224, 224, 255, 224, 224, 224, 128, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 128, 224, 224, 224, 252, 226, 226, 226, 35, 224, 224, 224, 80, 224, 224, 224, 80, 224, 224, 224, 80, 224, 224, 224, 80, 226, 226, 226, 35, 224, 224, 224, 255, 224, 224, 224, 128, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 166, 224, 224, 224, 255, 228, 228, 228, 37, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 229, 229, 229, 39, 224, 224, 224, 255, 224, 224, 224, 165, 255, 255, 255, 0, 225, 225, 225, 42, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 40, 255, 255, 255, 6, 224, 224, 224, 225, 224, 224, 224, 255, 224, 224, 224, 165, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 128, 225, 225, 225, 166, 224, 224, 224, 255, 224, 224, 224, 224, 255, 255, 255, 6, 255, 255, 255, 0, 255, 255, 255, 6, 224, 224, 224, 40, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 40, 255, 255, 255, 6, 255, 255, 255, 0),
|
|
||||||
"format": "RGBA8",
|
|
||||||
"height": 12,
|
|
||||||
"mipmaps": false,
|
|
||||||
"width": 12
|
|
||||||
}
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
image = SubResource("Image_i608h")
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><rect fill="none" height="8" rx=".000017" stroke="#5fb2ff" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2" width="12" x="2" y="4"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 237 B |
@@ -1,37 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://cfon2trqh4c3k"
|
|
||||||
path="res://.godot/imported/rect_shape_2d.svg-d16c8b9085065dfd954a4786aa34e9fe.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://addons/sprite_painter/graphics/rect_shape_2d.svg"
|
|
||||||
dest_files=["res://.godot/imported/rect_shape_2d.svg-d16c8b9085065dfd954a4786aa34e9fe.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
svg/scale=1.0
|
|
||||||
editor/scale_with_editor_scale=false
|
|
||||||
editor/convert_colors_with_editor_theme=false
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://jpxduo4o6vce"]
|
|
||||||
|
|
||||||
[sub_resource type="Image" id="Image_f5vrx"]
|
|
||||||
data = {
|
|
||||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 4, 224, 224, 224, 65, 224, 224, 224, 112, 224, 224, 224, 90, 230, 230, 230, 30, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 40, 224, 224, 224, 204, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 248, 224, 224, 224, 120, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 230, 230, 230, 10, 224, 224, 224, 220, 224, 224, 224, 230, 225, 225, 225, 83, 238, 238, 238, 15, 229, 229, 229, 38, 224, 224, 224, 164, 224, 224, 224, 255, 224, 224, 224, 98, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 113, 224, 224, 224, 254, 228, 228, 228, 55, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 184, 224, 224, 224, 236, 255, 255, 255, 1, 255, 255, 255, 1, 255, 255, 255, 4, 225, 225, 225, 169, 225, 225, 225, 216, 255, 255, 255, 4, 255, 255, 255, 2, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 89, 224, 224, 224, 255, 229, 229, 229, 38, 227, 227, 227, 9, 224, 224, 224, 209, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 214, 232, 232, 232, 11, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 91, 224, 224, 224, 255, 228, 228, 228, 37, 255, 255, 255, 0, 229, 229, 229, 39, 224, 224, 224, 244, 224, 224, 224, 246, 226, 226, 226, 44, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 187, 224, 224, 224, 235, 255, 255, 255, 1, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 90, 224, 224, 224, 97, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 1, 224, 224, 224, 40, 225, 225, 225, 167, 224, 224, 224, 255, 226, 226, 226, 95, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 247, 224, 224, 224, 115, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 230, 230, 230, 30, 224, 224, 224, 89, 228, 228, 228, 28, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
|
||||||
"format": "RGBA8",
|
|
||||||
"height": 12,
|
|
||||||
"mipmaps": false,
|
|
||||||
"width": 12
|
|
||||||
}
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
image = SubResource("Image_f5vrx")
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://hc35i3cvcupp"]
|
|
||||||
|
|
||||||
[sub_resource type="Image" id="Image_ts5bs"]
|
|
||||||
data = {
|
|
||||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 231, 231, 231, 31, 225, 225, 225, 91, 224, 224, 224, 113, 224, 224, 224, 66, 255, 255, 255, 5, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 1, 224, 224, 224, 121, 224, 224, 224, 250, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 205, 224, 224, 224, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 98, 224, 224, 224, 255, 224, 224, 224, 164, 224, 224, 224, 40, 224, 224, 224, 16, 225, 225, 225, 83, 224, 224, 224, 230, 224, 224, 224, 220, 232, 232, 232, 11, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 2, 224, 224, 224, 236, 224, 224, 224, 186, 255, 255, 255, 1, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 227, 227, 227, 53, 224, 224, 224, 254, 224, 224, 224, 115, 255, 255, 255, 0, 255, 255, 255, 0, 227, 227, 227, 36, 224, 224, 224, 255, 225, 225, 225, 93, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 1, 255, 255, 255, 4, 226, 226, 226, 214, 226, 226, 226, 171, 255, 255, 255, 4, 255, 255, 255, 0, 226, 226, 226, 35, 224, 224, 224, 255, 226, 226, 226, 94, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 232, 232, 232, 11, 224, 224, 224, 214, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 207, 224, 224, 224, 8, 255, 255, 255, 1, 224, 224, 224, 234, 224, 224, 224, 189, 255, 255, 255, 1, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 226, 226, 226, 43, 224, 224, 224, 245, 224, 224, 224, 242, 228, 228, 228, 37, 255, 255, 255, 0, 255, 255, 255, 0, 226, 226, 226, 95, 224, 224, 224, 255, 224, 224, 224, 168, 224, 224, 224, 41, 255, 255, 255, 2, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 97, 224, 224, 224, 88, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 1, 225, 225, 225, 116, 224, 224, 224, 248, 224, 224, 224, 255, 225, 225, 225, 68, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 228, 228, 228, 28, 224, 224, 224, 88, 224, 224, 224, 33, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
|
||||||
"format": "RGBA8",
|
|
||||||
"height": 12,
|
|
||||||
"mipmaps": false,
|
|
||||||
"width": 12
|
|
||||||
}
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
image = SubResource("Image_ts5bs")
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://ro5r4gstjow0"]
|
|
||||||
|
|
||||||
[sub_resource type="Image" id="Image_4da7w"]
|
|
||||||
data = {
|
|
||||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 226, 226, 226, 35, 224, 224, 224, 65, 224, 224, 224, 66, 225, 225, 225, 67, 227, 227, 227, 54, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 229, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 50, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 34, 224, 224, 224, 64, 224, 224, 224, 195, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 229, 229, 229, 19, 224, 224, 224, 224, 225, 225, 225, 191, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 1, 225, 225, 225, 75, 224, 224, 224, 74, 255, 255, 255, 1, 227, 227, 227, 18, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 76, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 72, 255, 255, 255, 0, 225, 225, 225, 34, 224, 224, 224, 226, 224, 224, 224, 33, 226, 226, 226, 35, 224, 224, 224, 229, 225, 225, 225, 34, 255, 255, 255, 0, 225, 225, 225, 75, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 72, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 229, 229, 229, 19, 255, 255, 255, 1, 224, 224, 224, 72, 224, 224, 224, 72, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 195, 224, 224, 224, 224, 227, 227, 227, 18, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 191, 224, 224, 224, 64, 225, 225, 225, 34, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 51, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 226, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 50, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 33, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
|
||||||
"format": "RGBA8",
|
|
||||||
"height": 12,
|
|
||||||
"mipmaps": false,
|
|
||||||
"width": 12
|
|
||||||
}
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
image = SubResource("Image_4da7w")
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
height="16"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
width="16"
|
|
||||||
version="1.1"
|
|
||||||
id="svg4"
|
|
||||||
sodipodi:docname="TriangleShape2D.svg"
|
|
||||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
|
||||||
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="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="24.306796"
|
|
||||||
inkscape:cx="0.90509668"
|
|
||||||
inkscape:cy="4.8134687"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1057"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg4" />
|
|
||||||
<path
|
|
||||||
id="rect2"
|
|
||||||
style="fill:none;stroke:#5fb2ff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:10"
|
|
||||||
d="m 2.000017,2 c 0,0 4.7752562,4.7752562 11.999983,11.999983 0,9e-6 -8e-6,1.7e-5 -1.7e-5,1.7e-5 H 2.000017 C 2.0000076,14 2,13.999992 2,13.999983 V 2.000017 c 0,-9.4e-6 8.305003,8.304969 1.7e-5,-1.7e-5 z"
|
|
||||||
sodipodi:nodetypes="ccssssc" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,37 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://yunqetk64l50"
|
|
||||||
path="res://.godot/imported/triangle_shape_2d.svg-215872cca079d243eb964f3debc05ac8.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://addons/sprite_painter/graphics/triangle_shape_2d.svg"
|
|
||||||
dest_files=["res://.godot/imported/triangle_shape_2d.svg-215872cca079d243eb964f3debc05ac8.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
svg/scale=1.0
|
|
||||||
editor/scale_with_editor_scale=false
|
|
||||||
editor/convert_colors_with_editor_theme=false
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
extends ImageScript
|
|
||||||
|
|
||||||
|
|
||||||
func _get_param_list():
|
|
||||||
return [
|
|
||||||
[
|
|
||||||
"Hue",
|
|
||||||
SCRIPT_PARAM_INT,
|
|
||||||
0,
|
|
||||||
[0, 360]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"Saturation",
|
|
||||||
SCRIPT_PARAM_INT,
|
|
||||||
0,
|
|
||||||
[-100, +100]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"Value",
|
|
||||||
SCRIPT_PARAM_INT,
|
|
||||||
0,
|
|
||||||
[-100, +100]
|
|
||||||
],
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
func _get_image(new_image, selection):
|
|
||||||
var pix : Color
|
|
||||||
for i in new_image.get_width():
|
|
||||||
for j in new_image.get_width():
|
|
||||||
if !selection.get_bit(i, j): continue
|
|
||||||
pix = new_image.get_pixel(i, j)
|
|
||||||
pix.h += get_param("Hue") / 360.0
|
|
||||||
pix.s *= 1.0 + get_param("Saturation") * 0.01
|
|
||||||
pix.v *= 1.0 + get_param("Value") * 0.01
|
|
||||||
new_image.set_pixel(i, j, pix)
|
|
||||||
|
|
||||||
return new_image
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
extends ImageScript
|
|
||||||
|
|
||||||
|
|
||||||
func _get_param_list():
|
|
||||||
var default_curve = Curve.new()
|
|
||||||
default_curve.add_point(Vector2.ZERO, 1, 1)
|
|
||||||
default_curve.add_point(Vector2.ONE, 1, 1)
|
|
||||||
return [
|
|
||||||
[
|
|
||||||
"Red",
|
|
||||||
SCRIPT_PARAM_RESOURCE,
|
|
||||||
default_curve.duplicate(),
|
|
||||||
"Curve",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"Green",
|
|
||||||
SCRIPT_PARAM_RESOURCE,
|
|
||||||
default_curve.duplicate(),
|
|
||||||
"Curve",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"Blue",
|
|
||||||
SCRIPT_PARAM_RESOURCE,
|
|
||||||
default_curve.duplicate(),
|
|
||||||
"Curve",
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"Alpha",
|
|
||||||
SCRIPT_PARAM_RESOURCE,
|
|
||||||
default_curve.duplicate(),
|
|
||||||
"Curve",
|
|
||||||
],
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
func _get_image(new_image, selection):
|
|
||||||
var r_curve = get_param("Red")
|
|
||||||
var g_curve = get_param("Green")
|
|
||||||
var b_curve = get_param("Blue")
|
|
||||||
var a_curve = get_param("Alpha")
|
|
||||||
var pix : Color
|
|
||||||
for i in new_image.get_width():
|
|
||||||
for j in new_image.get_width():
|
|
||||||
if !selection.get_bit(i, j): continue
|
|
||||||
pix = new_image.get_pixel(i, j)
|
|
||||||
pix.r = r_curve.sample(pix.r)
|
|
||||||
pix.g = g_curve.sample(pix.g)
|
|
||||||
pix.b = b_curve.sample(pix.b)
|
|
||||||
pix.a = a_curve.sample(pix.a)
|
|
||||||
new_image.set_pixel(i, j, pix)
|
|
||||||
|
|
||||||
return new_image
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
extends ImageScript
|
|
||||||
|
|
||||||
|
|
||||||
func _get_param_list():
|
|
||||||
return [
|
|
||||||
[
|
|
||||||
"Palette Texture",
|
|
||||||
SCRIPT_PARAM_RESOURCE,
|
|
||||||
# Does not work well on gradients: doesn't consider Interp Mode and Width
|
|
||||||
# so with no proper spatial partitioning takes an eternity
|
|
||||||
# GradientTexture1D.new(),
|
|
||||||
null,
|
|
||||||
"Texture2D"
|
|
||||||
],
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
func _get_image(new_image, selection):
|
|
||||||
if get_param("Palette Texture") == null:
|
|
||||||
return new_image
|
|
||||||
|
|
||||||
var palette_img = get_param("Palette Texture").get_image()
|
|
||||||
if palette_img == null:
|
|
||||||
return new_image
|
|
||||||
|
|
||||||
var palette = {}
|
|
||||||
var pix : Color
|
|
||||||
for i in palette_img.get_width():
|
|
||||||
for j in palette_img.get_height():
|
|
||||||
pix = palette_img.get_pixel(i, j)
|
|
||||||
if pix.a > 0.01:
|
|
||||||
palette[Color(pix, 1.0)] = true
|
|
||||||
|
|
||||||
var image_width = new_image.get_width()
|
|
||||||
var image_color_mapping = {}
|
|
||||||
var nearest_color : Color
|
|
||||||
for i in new_image.get_width():
|
|
||||||
for j in new_image.get_height():
|
|
||||||
pix = new_image.get_pixel(i, j)
|
|
||||||
if image_color_mapping.has(pix):
|
|
||||||
if selection.get_bit(i, j):
|
|
||||||
new_image.set_pixel(i, j, Color(image_color_mapping[pix], pix.a))
|
|
||||||
|
|
||||||
elif selection.get_bit(i, j):
|
|
||||||
# I'll rewrite this into a proper spatial algo access later,
|
|
||||||
# bruteforce will do for now
|
|
||||||
nearest_color = Color(pick_nearest(pix, palette), 1.0)
|
|
||||||
image_color_mapping[Color(pix, 1.0)] = nearest_color
|
|
||||||
new_image.set_pixel(i, j, Color(nearest_color, pix.a))
|
|
||||||
|
|
||||||
return new_image
|
|
||||||
|
|
||||||
|
|
||||||
func pick_nearest(to : Color, from : Dictionary):
|
|
||||||
var nearest_dist := INF
|
|
||||||
var nearest : Color
|
|
||||||
var cur_dist : float
|
|
||||||
for x in from:
|
|
||||||
cur_dist = (
|
|
||||||
(x.r - to.r) * (x.r - to.r)
|
|
||||||
+ (x.g - to.g) * (x.g - to.g)
|
|
||||||
+ (x.b - to.b) * (x.b - to.b)
|
|
||||||
)
|
|
||||||
if cur_dist < nearest_dist:
|
|
||||||
nearest = x
|
|
||||||
nearest_dist = cur_dist
|
|
||||||
|
|
||||||
return nearest
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
extends ImageScript
|
|
||||||
|
|
||||||
var sample_modes = [
|
|
||||||
[Vector2(0, 1), Vector2(1, 0), Vector2(-1, 0), Vector2(0, -1)],
|
|
||||||
range(8).map(func(i):return Vector2(cos(i * PI * 0.25), sin(i * PI * 0.25))),
|
|
||||||
range(16).map(func(i):return Vector2(cos(i * PI * 0.125), sin(i * PI * 0.125))),
|
|
||||||
# The following modes sample two rings around the pixel,
|
|
||||||
# resulting in a more precise thick outline around thin objects
|
|
||||||
range(16).map(func(i):return ceil((i + 1) * 0.125) * 0.5 * Vector2(cos(i * PI * 0.25), sin(i * PI * 0.25))),
|
|
||||||
range(32).map(func(i):return ceil((i + 1) * 0.0625) * 0.5 * Vector2(cos(i * PI * 0.125), sin(i * PI * 0.125))),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
func _get_param_list():
|
|
||||||
return [
|
|
||||||
[
|
|
||||||
"Width",
|
|
||||||
SCRIPT_PARAM_INT,
|
|
||||||
1,
|
|
||||||
[1, 150]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"Color",
|
|
||||||
SCRIPT_PARAM_COLOR,
|
|
||||||
Color.BLACK
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"Samples",
|
|
||||||
SCRIPT_PARAM_ENUM,
|
|
||||||
0,
|
|
||||||
["4 (Naive)", "8", "16", "4+4 (Wide Line)", "8+8 (Wide Line Ultra)"]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"Mode",
|
|
||||||
SCRIPT_PARAM_ENUM,
|
|
||||||
0,
|
|
||||||
["Outline + Image", "Just Outline"]
|
|
||||||
],
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
func _get_image(new_image, selection):
|
|
||||||
var line_color = get_param("Color")
|
|
||||||
var width = get_param("Width")
|
|
||||||
var line_only = get_param("Mode") == 1
|
|
||||||
var samples = sample_modes[get_param("Samples")]
|
|
||||||
var image_size = new_image.get_size()
|
|
||||||
var new_new_image = Image.create_from_data(
|
|
||||||
image_size.x,
|
|
||||||
image_size.y,
|
|
||||||
false,
|
|
||||||
new_image.get_format(),
|
|
||||||
new_image.get_data()
|
|
||||||
)
|
|
||||||
var pix : Color
|
|
||||||
var pix_outline_alpha := 0.0
|
|
||||||
for i in new_image.get_width():
|
|
||||||
for j in new_image.get_height():
|
|
||||||
if !selection.get_bit(i, j): continue
|
|
||||||
pix = new_image.get_pixel(i, j)
|
|
||||||
if pix.a == 1.0:
|
|
||||||
if line_only:
|
|
||||||
new_new_image.set_pixel(i, j, Color.TRANSPARENT)
|
|
||||||
|
|
||||||
continue
|
|
||||||
|
|
||||||
pix_outline_alpha = 0.0
|
|
||||||
for x in samples:
|
|
||||||
if pix_outline_alpha >= line_color.a: break
|
|
||||||
if ImageFillTools.is_out_of_bounds(Vector2(i, j) + x * width, image_size):
|
|
||||||
continue
|
|
||||||
|
|
||||||
pix_outline_alpha = max(pix_outline_alpha, min(
|
|
||||||
line_color.a,
|
|
||||||
new_image.get_pixelv(Vector2(i, j) + x * width).a
|
|
||||||
))
|
|
||||||
|
|
||||||
if pix_outline_alpha > 0.0:
|
|
||||||
if line_only:
|
|
||||||
pix = Color(line_color, pix_outline_alpha)
|
|
||||||
|
|
||||||
else:
|
|
||||||
pix = Color(line_color, pix_outline_alpha).blend(pix)
|
|
||||||
|
|
||||||
new_new_image.set_pixel(i, j, pix)
|
|
||||||
|
|
||||||
return new_new_image
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
extends ImageScript
|
|
||||||
|
|
||||||
const ROOT2DIV2 = 0.7071
|
|
||||||
|
|
||||||
|
|
||||||
func _get_param_list():
|
|
||||||
var default_curve = Curve.new()
|
|
||||||
default_curve.add_point(Vector2(0.0, 0.5), 1, 1, Curve.TANGENT_LINEAR, Curve.TANGENT_LINEAR)
|
|
||||||
default_curve.add_point(Vector2(1.0, 0.5), 1, 1, Curve.TANGENT_LINEAR, Curve.TANGENT_LINEAR)
|
|
||||||
return [
|
|
||||||
[
|
|
||||||
"Bevel",
|
|
||||||
SCRIPT_PARAM_INT,
|
|
||||||
1,
|
|
||||||
[1, 150]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"Bevel Distance",
|
|
||||||
SCRIPT_PARAM_ENUM,
|
|
||||||
0,
|
|
||||||
["Circle", "Square", "Diamond"]
|
|
||||||
],
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
func _get_image(new_image, selection):
|
|
||||||
var image_size : Vector2i = new_image.get_size()
|
|
||||||
var closest_edge : Array[Vector2] = []
|
|
||||||
var entropy := {}
|
|
||||||
closest_edge.resize(image_size.x * image_size.y)
|
|
||||||
|
|
||||||
var pix : Color
|
|
||||||
var vec : Vector2
|
|
||||||
for i in image_size.x:
|
|
||||||
for j in image_size.y:
|
|
||||||
pix = new_image.get_pixel(i, j)
|
|
||||||
if pix.a == 0.0:
|
|
||||||
closest_edge[i + j * image_size.x] = Vector2.ZERO
|
|
||||||
|
|
||||||
else:
|
|
||||||
vec = Vector2(0, 0)
|
|
||||||
if i == 0: vec.x -= 1
|
|
||||||
if j == 0: vec.y -= 1
|
|
||||||
if i == image_size.x - 1: vec.x += 1
|
|
||||||
if j == image_size.y - 1: vec.y += 1
|
|
||||||
|
|
||||||
if vec == Vector2.ZERO:
|
|
||||||
vec = Vector2(-INF, -INF)
|
|
||||||
entropy[Vector2(i, j)] = 5
|
|
||||||
|
|
||||||
closest_edge[i + j * image_size.x] = vec
|
|
||||||
|
|
||||||
var neighbors = []
|
|
||||||
var neighbor_pos = []
|
|
||||||
var iters = 0
|
|
||||||
var closest_edge_new : Array[Vector2]
|
|
||||||
while entropy.size() > 0:
|
|
||||||
iters += 1
|
|
||||||
closest_edge_new = closest_edge.duplicate()
|
|
||||||
for pos in entropy.keys():
|
|
||||||
neighbor_pos = [
|
|
||||||
pos + Vector2.RIGHT,
|
|
||||||
pos + Vector2.DOWN,
|
|
||||||
pos + Vector2.LEFT,
|
|
||||||
pos + Vector2.UP,
|
|
||||||
]
|
|
||||||
var any_neighbor_defined = false
|
|
||||||
for x in neighbor_pos:
|
|
||||||
if closest_edge[x.x + x.y * image_size.x] != Vector2(-INF, -INF):
|
|
||||||
any_neighbor_defined = true
|
|
||||||
break
|
|
||||||
|
|
||||||
if any_neighbor_defined:
|
|
||||||
entropy.erase(pos)
|
|
||||||
|
|
||||||
neighbors = [
|
|
||||||
closest_edge[pos.x + 1 + pos.y * image_size.x]
|
|
||||||
if !entropy.has(pos + Vector2.RIGHT) else Vector2(-INF, -INF),
|
|
||||||
closest_edge[pos.x + (pos.y + 1) * image_size.x]
|
|
||||||
if !entropy.has(pos + Vector2.DOWN) else Vector2(-INF, -INF),
|
|
||||||
closest_edge[pos.x - 1 + pos.y * image_size.x]
|
|
||||||
if !entropy.has(pos + Vector2.LEFT) else Vector2(-INF, -INF),
|
|
||||||
closest_edge[pos.x + (pos.y - 1) * image_size.x]
|
|
||||||
if !entropy.has(pos + Vector2.UP) else Vector2(-INF, -INF),
|
|
||||||
]
|
|
||||||
closest_edge_new[pos.x + pos.y * image_size.x] = get_closest_edge(neighbors)
|
|
||||||
|
|
||||||
closest_edge = closest_edge_new
|
|
||||||
|
|
||||||
var bevel = get_param("Bevel")
|
|
||||||
var dist_func = [
|
|
||||||
# Three different distance calculations have their own artifacts..
|
|
||||||
func (x): return x.length_squared() > bevel * 2.0, # Circle
|
|
||||||
func (x): return max(abs(x.x), abs(x.y)) > bevel, # Square
|
|
||||||
func (x): return abs(x.x) + abs(x.y) > bevel * 2.0, # Diamond
|
|
||||||
][get_param("Bevel Distance")]
|
|
||||||
|
|
||||||
var vec3 : Vector3
|
|
||||||
var vec_len : float
|
|
||||||
var vec_dir : Vector2
|
|
||||||
for i in image_size.x:
|
|
||||||
for j in image_size.y:
|
|
||||||
vec = closest_edge[i + j * image_size.x]
|
|
||||||
if vec == Vector2.ZERO || dist_func.call(vec):
|
|
||||||
new_image.set_pixel(i, j, Color(0.5, 0.5, 1.0))
|
|
||||||
continue
|
|
||||||
|
|
||||||
vec_len = vec.length()
|
|
||||||
vec_dir = vec / vec_len
|
|
||||||
vec3 = Vector3.BACK.rotated(
|
|
||||||
Vector3(-vec_dir.y, vec_dir.x, 0.0),
|
|
||||||
PI * 0.25
|
|
||||||
)
|
|
||||||
vec3 = vec3 * Vector3(0.5, -0.5, 1.0) + Vector3(0.5, 0.5, 0.0)
|
|
||||||
|
|
||||||
new_image.set_pixel(i, j, Color(vec3.x, vec3.y, vec3.z))
|
|
||||||
|
|
||||||
return new_image
|
|
||||||
|
|
||||||
|
|
||||||
func get_closest_edge(neighbor_vecs):
|
|
||||||
var lengths = [
|
|
||||||
neighbor_vecs[0].length_squared(),
|
|
||||||
neighbor_vecs[1].length_squared(),
|
|
||||||
neighbor_vecs[2].length_squared(),
|
|
||||||
neighbor_vecs[3].length_squared(),
|
|
||||||
]
|
|
||||||
var closest_length = INF
|
|
||||||
for i in 4:
|
|
||||||
if lengths[i] < closest_length:
|
|
||||||
closest_length = lengths[i]
|
|
||||||
|
|
||||||
var result = Vector2.ZERO
|
|
||||||
var neighbor_dirs = [Vector2.RIGHT, Vector2.DOWN, Vector2.LEFT, Vector2.UP]
|
|
||||||
var coeff = 1.0
|
|
||||||
for i in 4:
|
|
||||||
if lengths[i] == closest_length:
|
|
||||||
result += neighbor_vecs[i] + neighbor_dirs[i]
|
|
||||||
|
|
||||||
return result
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
[plugin]
|
|
||||||
|
|
||||||
name="Sprite Painter"
|
|
||||||
description="Paints Sprites.
|
|
||||||
|
|
||||||
An image editor built right into Godot 4."
|
|
||||||
author="Don Tnowe"
|
|
||||||
version="0.1"
|
|
||||||
script="plugin.gd"
|
|
||||||
@@ -1,181 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends EditorPlugin
|
|
||||||
|
|
||||||
const can_edit_properties := [
|
|
||||||
"texture",
|
|
||||||
"tile_set",
|
|
||||||
"frames", # AnimatedSprite
|
|
||||||
"texture_normal", # TextureButton
|
|
||||||
"texture_progress", # Self explanatory
|
|
||||||
]
|
|
||||||
|
|
||||||
const can_edit_types := [
|
|
||||||
"CompressedTexture2D",
|
|
||||||
"AtlasTexture",
|
|
||||||
"SpriteFrames",
|
|
||||||
"TileSet",
|
|
||||||
]
|
|
||||||
|
|
||||||
var editor_view : Control
|
|
||||||
var editor_2d_vp : Control
|
|
||||||
var editor_3d_vp : Control
|
|
||||||
var enable_buttons : Dictionary
|
|
||||||
var sploinky := Control.new()
|
|
||||||
var sploinky3 := Control.new()
|
|
||||||
var undo_redo : EditorUndoRedoManager
|
|
||||||
|
|
||||||
var overlay_enabled := false
|
|
||||||
|
|
||||||
|
|
||||||
func _enter_tree() -> void:
|
|
||||||
# Sometimes crashes on startup. Until I find why, let this be here
|
|
||||||
await get_tree().create_timer(2.0)
|
|
||||||
|
|
||||||
var ui := get_editor_interface()
|
|
||||||
|
|
||||||
undo_redo = get_undo_redo()
|
|
||||||
editor_view = load(get_script().resource_path.get_base_dir() + "/src/main.tscn").instantiate()
|
|
||||||
editor_view.editor_interface = ui
|
|
||||||
editor_view.editor_plugin = self
|
|
||||||
editor_view.undo_redo = undo_redo
|
|
||||||
|
|
||||||
_connect_editor_viewports()
|
|
||||||
_add_enable_button(EditorPlugin.CONTAINER_CANVAS_EDITOR_MENU)
|
|
||||||
_add_enable_button(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU)
|
|
||||||
|
|
||||||
main_screen_changed.connect(_on_main_screen_changed)
|
|
||||||
ui.get_selection().selection_changed.connect(_on_selection_changed)
|
|
||||||
|
|
||||||
ui.get_base_control().add_child(editor_view)
|
|
||||||
|
|
||||||
make_visible(false)
|
|
||||||
|
|
||||||
|
|
||||||
func _forward_canvas_gui_input(event):
|
|
||||||
if !overlay_enabled:
|
|
||||||
return false
|
|
||||||
|
|
||||||
return editor_view.handle_input(event)
|
|
||||||
|
|
||||||
|
|
||||||
func _connect_editor_viewports():
|
|
||||||
var mainscreen = get_editor_interface().get_editor_main_screen()
|
|
||||||
mainscreen.resized.connect(_on_editor_resized.bind(mainscreen))
|
|
||||||
for x in mainscreen.get_children():
|
|
||||||
if x.get_class() == "CanvasItemEditor":
|
|
||||||
editor_2d_vp = x
|
|
||||||
editor_view.editor_2d_vp = x
|
|
||||||
x.add_child(sploinky)
|
|
||||||
x.move_child(sploinky, 1)
|
|
||||||
|
|
||||||
if x.get_class() == "Node3DEditor":
|
|
||||||
editor_3d_vp = x
|
|
||||||
editor_view.editor_3d_vp = x
|
|
||||||
x.add_child(sploinky3)
|
|
||||||
x.move_child(sploinky3, 1)
|
|
||||||
|
|
||||||
call_deferred("_on_editor_resized", mainscreen)
|
|
||||||
|
|
||||||
|
|
||||||
func _add_enable_button(container_id):
|
|
||||||
var enable_button = Button.new()
|
|
||||||
add_control_to_container(container_id, enable_button)
|
|
||||||
|
|
||||||
enable_button.add_theme_stylebox_override("normal", StyleBoxEmpty.new())
|
|
||||||
enable_button.add_theme_stylebox_override("hover", StyleBoxEmpty.new())
|
|
||||||
enable_button.add_theme_stylebox_override("pressed", StyleBoxEmpty.new())
|
|
||||||
enable_button.add_theme_stylebox_override("focus", StyleBoxEmpty.new())
|
|
||||||
enable_button.icon = enable_button.get_theme_icon("StyleBoxTexture", "EditorIcons")
|
|
||||||
enable_button.text = "Edit Texture..."
|
|
||||||
enable_button.pressed.connect(_on_enable_pressed)
|
|
||||||
enable_button.hide()
|
|
||||||
|
|
||||||
enable_buttons[container_id] = enable_button
|
|
||||||
|
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
|
||||||
make_visible(false)
|
|
||||||
editor_view.queue_free()
|
|
||||||
sploinky.queue_free()
|
|
||||||
sploinky3.queue_free()
|
|
||||||
for x in enable_buttons.values():
|
|
||||||
x.queue_free()
|
|
||||||
|
|
||||||
|
|
||||||
func make_visible(visible):
|
|
||||||
if !is_instance_valid(editor_view): return
|
|
||||||
if editor_view.visible == visible: return
|
|
||||||
|
|
||||||
editor_view.visible = visible
|
|
||||||
editor_2d_vp.get_child(0).visible = !visible
|
|
||||||
editor_3d_vp.get_child(0).visible = !visible
|
|
||||||
sploinky.custom_minimum_size.y = editor_2d_vp.get_child(0).size.y
|
|
||||||
sploinky3.custom_minimum_size.y = editor_3d_vp.get_child(0).size.y
|
|
||||||
sploinky.visible = visible
|
|
||||||
sploinky3.visible = visible
|
|
||||||
if visible:
|
|
||||||
editor_view.edit_object(editor_view.edited_object)
|
|
||||||
|
|
||||||
else:
|
|
||||||
editor_view.save_changes()
|
|
||||||
if editor_view.unsaved_image_paths.size() == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
# print("Saved images: " + str(editor_view.unsaved_image_paths))
|
|
||||||
get_editor_interface()\
|
|
||||||
.get_resource_filesystem()\
|
|
||||||
# I am totally done with this thing freezing the editor forever,
|
|
||||||
# Yes it is more efficient, but stability matters more
|
|
||||||
# .reimport_files(editor_view.unsaved_image_paths)
|
|
||||||
.scan()
|
|
||||||
editor_view.unsaved_image_paths.clear()
|
|
||||||
|
|
||||||
|
|
||||||
func _edit(object):
|
|
||||||
editor_view.edit_object(object)
|
|
||||||
for x in enable_buttons.values():
|
|
||||||
x.show()
|
|
||||||
|
|
||||||
if overlay_enabled:
|
|
||||||
make_visible(true)
|
|
||||||
|
|
||||||
|
|
||||||
func _handles(object):
|
|
||||||
for x in can_edit_properties:
|
|
||||||
if x in object:
|
|
||||||
return true
|
|
||||||
|
|
||||||
for x in can_edit_types:
|
|
||||||
if ClassDB.is_parent_class(object.get_class(), x):
|
|
||||||
return true
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
func _on_enable_pressed():
|
|
||||||
overlay_enabled = !overlay_enabled
|
|
||||||
make_visible(overlay_enabled)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_main_screen_changed(screen):
|
|
||||||
overlay_enabled = false
|
|
||||||
make_visible(false)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_selection_changed():
|
|
||||||
var sel = get_editor_interface().get_selection().get_selected_nodes()
|
|
||||||
if sel.size() == 0 || !_handles(sel[-1]):
|
|
||||||
for x in enable_buttons.values():
|
|
||||||
x.hide()
|
|
||||||
|
|
||||||
overlay_enabled = false
|
|
||||||
make_visible(false)
|
|
||||||
|
|
||||||
else:
|
|
||||||
for x in enable_buttons.values():
|
|
||||||
x.show()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_editor_resized(mainscreen : Control):
|
|
||||||
editor_view.size = mainscreen.size
|
|
||||||
editor_view.global_position = mainscreen.global_position
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
[gd_resource type="Shader" format=3 uid="uid://bpswjmm8i01cg"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
render_mode blend_premul_alpha;
|
|
||||||
|
|
||||||
uniform sampler2D gradient;
|
|
||||||
uniform vec2 from;
|
|
||||||
uniform vec2 delta;
|
|
||||||
uniform int type;
|
|
||||||
|
|
||||||
float angle(vec2 dir) {
|
|
||||||
return atan(dir.x / dir.y) / PI * 0.5 + (dir.y < 0.0 ? 0.75 : 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
if (texture(TEXTURE, UV).r < 0.5) discard;
|
|
||||||
float pos;
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case 0: // Line
|
|
||||||
// Stolen again from:
|
|
||||||
// https://iquilezles.org/articles/forgot-the-exact-link
|
|
||||||
vec2 delta_rotated = vec2(-delta.y, delta.x);
|
|
||||||
vec2 diff = UV - from;
|
|
||||||
float h = dot(diff, delta_rotated) / dot(delta_rotated, delta_rotated);
|
|
||||||
if (dot(diff, delta) > 0.0)
|
|
||||||
pos = length(diff - h * delta_rotated) / length(delta);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // Line Mirrored
|
|
||||||
vec2 delta_rotated = vec2(-delta.y, delta.x);
|
|
||||||
float h = dot(UV - from, delta_rotated) / dot(delta_rotated, delta_rotated);
|
|
||||||
pos = length(UV - from - h * delta_rotated) / length(delta);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // Radial
|
|
||||||
pos = length(UV - from) / length(delta);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3: // Conic
|
|
||||||
vec2 dir = (UV - from);
|
|
||||||
pos = mod(angle(dir) - angle(delta), 1.0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4: // Bounds
|
|
||||||
vec2 abs_delta = abs(delta);
|
|
||||||
vec2 abs_from = from;
|
|
||||||
if (delta.x < 0.0) abs_from.x -= abs_delta.x;
|
|
||||||
if (delta.y < 0.0) abs_from.y -= abs_delta.y;
|
|
||||||
pos = min(
|
|
||||||
min(UV.x - abs_from.x, abs_delta.x - UV.x + abs_from.x),
|
|
||||||
min(UV.y - abs_from.y, abs_delta.y - UV.y + abs_from.y)
|
|
||||||
) / min(abs_delta.x, abs_delta.y) * 2.0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
COLOR = texture(gradient, vec2(clamp(pos, 0.0, 0.999999), 0.5));
|
|
||||||
}
|
|
||||||
"
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
[gd_resource type="Shader" format=3 uid="uid://c84r6o3a8gfo0"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
render_mode blend_premul_alpha;
|
|
||||||
|
|
||||||
uniform vec4 color;
|
|
||||||
uniform vec2 origin;
|
|
||||||
uniform vec2 delta;
|
|
||||||
uniform float width;
|
|
||||||
uniform bool enable_aa;
|
|
||||||
|
|
||||||
|
|
||||||
float get_sdf(vec2 pos) {
|
|
||||||
if (delta == vec2(0.0)) return float(-1.0);
|
|
||||||
|
|
||||||
float h = clamp(dot(pos, delta) / dot(delta, delta), 0.0, 1.0);
|
|
||||||
return length(pos - h * delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vec4 sdf_to_color(float sdf) {
|
|
||||||
if (enable_aa)
|
|
||||||
return vec4(color.rgb, mix(
|
|
||||||
0.0,
|
|
||||||
color.a,
|
|
||||||
(width * 0.5 - sdf) * 2.0
|
|
||||||
));
|
|
||||||
else
|
|
||||||
return vec4(color.rgb, 1.0 - floor(sdf / (width * 0.5)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
COLOR = sdf_to_color(get_sdf(
|
|
||||||
floor(UV / TEXTURE_PIXEL_SIZE) - origin
|
|
||||||
));
|
|
||||||
}
|
|
||||||
"
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
[gd_resource type="Shader" format=3 uid="uid://clpby1t4s1pvy"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
render_mode blend_premul_alpha;
|
|
||||||
|
|
||||||
uniform int shape_index;
|
|
||||||
// if you are reading this file and know
|
|
||||||
// what hint_color is called in 4.0
|
|
||||||
// please open an issue or pull request
|
|
||||||
uniform vec4 color_border;
|
|
||||||
uniform vec4 color_fill;
|
|
||||||
uniform vec2 origin;
|
|
||||||
uniform vec2 shape_size;
|
|
||||||
uniform float border_width;
|
|
||||||
uniform vec2 drag_delta;
|
|
||||||
uniform bool enable_aa;
|
|
||||||
|
|
||||||
|
|
||||||
float get_sdf(vec2 pos, vec2 size) {
|
|
||||||
size -= vec2(1.0);
|
|
||||||
if (size == vec2(0.0)) return -1.0;
|
|
||||||
switch(shape_index) {
|
|
||||||
case 0: // Rect
|
|
||||||
return min(
|
|
||||||
min(pos.x, size.x - pos.x),
|
|
||||||
min(pos.y, size.y - pos.y)
|
|
||||||
);
|
|
||||||
|
|
||||||
case 1: // Ellipse
|
|
||||||
// Stolen from:
|
|
||||||
// https://iquilezles.org/articles/ellipsedist/
|
|
||||||
vec2 extents = size * 0.5;
|
|
||||||
vec2 posf = abs(vec2(pos) - extents);
|
|
||||||
|
|
||||||
vec2 q = extents * (posf - extents);
|
|
||||||
vec2 cs = normalize(q.x < q.y ? vec2(0.01, 1) : vec2(1, 0.01));
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
vec2 u = extents * vec2(+cs.x, cs.y);
|
|
||||||
vec2 v = extents * vec2(-cs.y, cs.x);
|
|
||||||
float a = dot(posf - u, v);
|
|
||||||
float c = dot(posf - u, u) + dot(v, v);
|
|
||||||
float b = sqrt(c * c - a * a);
|
|
||||||
cs = vec2(cs.x * b - cs.y * a, cs.y * b + cs.x * a) / c;
|
|
||||||
}
|
|
||||||
|
|
||||||
float d = length(posf - extents * cs);
|
|
||||||
return dot(posf / extents, posf / extents) > 1.0 ? -d : d;
|
|
||||||
|
|
||||||
case 2: // RA Triangle
|
|
||||||
float aspect = size.x / size.y;
|
|
||||||
float distance_to_diag = 0.0;
|
|
||||||
if ((drag_delta.x < 0.0) == (drag_delta.y < 0.0))
|
|
||||||
// Main diag
|
|
||||||
if (drag_delta.x < drag_delta.y)
|
|
||||||
// Bottom filled
|
|
||||||
distance_to_diag = (pos.x - pos.y * aspect);
|
|
||||||
|
|
||||||
else
|
|
||||||
// Top filled
|
|
||||||
// !!! incorrest sdf
|
|
||||||
distance_to_diag = (pos.y * aspect - pos.x);
|
|
||||||
|
|
||||||
else
|
|
||||||
// Secondary diag
|
|
||||||
if (drag_delta.x < -drag_delta.y)
|
|
||||||
// Bottom filled
|
|
||||||
// !!! incorrest sdf
|
|
||||||
distance_to_diag = (pos.y * aspect - size.x + pos.x);
|
|
||||||
|
|
||||||
else
|
|
||||||
// Top filled
|
|
||||||
distance_to_diag = (size.x - pos.x - pos.y * aspect);
|
|
||||||
|
|
||||||
float rect_dist = min(
|
|
||||||
min(pos.x, size.x - pos.x),
|
|
||||||
min(pos.y, size.y - pos.y)
|
|
||||||
);
|
|
||||||
return min(distance_to_diag / aspect, rect_dist);
|
|
||||||
|
|
||||||
case 3: // Diamond
|
|
||||||
vec2 from_center = abs(vec2(pos * 2.0) - size) * 0.5;
|
|
||||||
from_center.y *= size.x / size.y;
|
|
||||||
return size.x * 0.5 - (from_center.x + from_center.y);
|
|
||||||
|
|
||||||
case 4: // Hex
|
|
||||||
if ((drag_delta.x < 0.0) == (drag_delta.y < 0.0)) {
|
|
||||||
pos = pos.yx;
|
|
||||||
size = size.yx;
|
|
||||||
}
|
|
||||||
vec2 diamond_from_center = abs(pos * 2.0 - size) * vec2(0.25, 0.5);
|
|
||||||
return size.x * 0.5 - max(
|
|
||||||
diamond_from_center.x + diamond_from_center.y * size.x / size.y,
|
|
||||||
abs(pos.x - size.x * 0.5)
|
|
||||||
);
|
|
||||||
|
|
||||||
return -1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vec4 sdf_to_color(float sdf) {
|
|
||||||
// Debug
|
|
||||||
// return vec4(sdf * 0.1, -sdf * 0.1, 0.0, 1.0);
|
|
||||||
if (sdf < -0.5) {
|
|
||||||
return vec4(color_border.rgb, 0.0);
|
|
||||||
}
|
|
||||||
if (sdf < 0.0 && enable_aa) {
|
|
||||||
sdf = (0.5 + sdf) * 2.0;
|
|
||||||
return mix(vec4(color_border.rgb, 0.0), color_border, sdf * sdf);
|
|
||||||
}
|
|
||||||
if (sdf <= border_width - 0.5) {
|
|
||||||
return color_border;
|
|
||||||
}
|
|
||||||
if (sdf < border_width && enable_aa) {
|
|
||||||
sdf = -(sdf - border_width + 0.5) * 2.0;
|
|
||||||
return mix(color_fill, color_border, 1.0 - sdf * sdf);
|
|
||||||
}
|
|
||||||
return color_fill;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
COLOR = sdf_to_color(get_sdf(
|
|
||||||
floor(UV / TEXTURE_PIXEL_SIZE) - origin,
|
|
||||||
shape_size
|
|
||||||
));
|
|
||||||
}
|
|
||||||
"
|
|
||||||
@@ -1,369 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name EditingTool
|
|
||||||
extends VBoxContainer
|
|
||||||
|
|
||||||
enum {
|
|
||||||
TOOL_PROP_BOOL,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
TOOL_PROP_FLOAT,
|
|
||||||
TOOL_PROP_ENUM,
|
|
||||||
TOOL_PROP_ICON_ENUM,
|
|
||||||
TOOL_PROP_ICON_FLAGS,
|
|
||||||
TOOL_PROP_RESOURCE,
|
|
||||||
TOOL_PROP_FOLDER_SCAN,
|
|
||||||
TOOL_PROP_COLOR,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
OPERATION_REPLACE,
|
|
||||||
OPERATION_ADD,
|
|
||||||
OPERATION_SUBTRACT,
|
|
||||||
OPERATION_INTERSECTION,
|
|
||||||
OPERATION_XOR,
|
|
||||||
}
|
|
||||||
|
|
||||||
@export var tool_name := "Box Selection"
|
|
||||||
@export_multiline var tool_desc := ""
|
|
||||||
@export var preview_shader : ShaderMaterial
|
|
||||||
@export_enum("None", "When Drawing", "When Active") var image_hide_mode := 0
|
|
||||||
|
|
||||||
var selection : BitMap
|
|
||||||
|
|
||||||
var _last_grid : GridContainer
|
|
||||||
var _hotkey_adjustment_hook : Callable
|
|
||||||
|
|
||||||
|
|
||||||
func _enter_tree():
|
|
||||||
if !visibility_changed.is_connected(_on_visibility_changed):
|
|
||||||
visibility_changed.connect(_on_visibility_changed)
|
|
||||||
|
|
||||||
set_process_shortcut_input(false)
|
|
||||||
|
|
||||||
|
|
||||||
func add_name():
|
|
||||||
var label = Label.new()
|
|
||||||
label.text = tool_name
|
|
||||||
label.size_flags_vertical = SIZE_SHRINK_CENTER | SIZE_FILL
|
|
||||||
add_child(label)
|
|
||||||
add_separator()
|
|
||||||
label = Label.new()
|
|
||||||
label.autowrap_mode = TextServer.AUTOWRAP_WORD
|
|
||||||
label.self_modulate.a = 0.75
|
|
||||||
label.text = tool_desc
|
|
||||||
label.size_flags_vertical = SIZE_SHRINK_CENTER | SIZE_FILL
|
|
||||||
if tool_desc == "": label.hide()
|
|
||||||
add_child(label)
|
|
||||||
|
|
||||||
_last_grid = null
|
|
||||||
|
|
||||||
|
|
||||||
func add_separator():
|
|
||||||
var sep = ColorRect.new()
|
|
||||||
sep.custom_minimum_size = Vector2(0, 2)
|
|
||||||
sep.color = get_theme_color("accent_color", "Editor")
|
|
||||||
sep.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
||||||
add_child(sep)
|
|
||||||
|
|
||||||
_last_grid = null
|
|
||||||
|
|
||||||
|
|
||||||
func start_property_grid():
|
|
||||||
var grid = GridContainer.new()
|
|
||||||
grid.columns = 2
|
|
||||||
_last_grid = grid
|
|
||||||
add_child(grid)
|
|
||||||
return grid
|
|
||||||
|
|
||||||
|
|
||||||
func add_property(
|
|
||||||
property_name,
|
|
||||||
default_value,
|
|
||||||
setter : Callable,
|
|
||||||
type : int,
|
|
||||||
hint : Variant = null,
|
|
||||||
hotkey_adjustment = false,
|
|
||||||
):
|
|
||||||
var parent = _last_grid
|
|
||||||
if _last_grid == null:
|
|
||||||
parent = HBoxContainer.new()
|
|
||||||
add_child(parent)
|
|
||||||
|
|
||||||
var label = Label.new()
|
|
||||||
label.size_flags_vertical = SIZE_SHRINK_CENTER | SIZE_FILL
|
|
||||||
label.text = property_name
|
|
||||||
parent.add_child(label)
|
|
||||||
|
|
||||||
var editor
|
|
||||||
match type:
|
|
||||||
TOOL_PROP_BOOL:
|
|
||||||
editor = CheckBox.new()
|
|
||||||
editor.button_pressed = default_value
|
|
||||||
editor.text = "On"
|
|
||||||
editor.toggled.connect(setter)
|
|
||||||
if hotkey_adjustment:
|
|
||||||
_hotkey_adjustment_hook = func(x):
|
|
||||||
editor.button_pressed = !editor.button_pressed
|
|
||||||
setter.call(editor.button_pressed)
|
|
||||||
|
|
||||||
TOOL_PROP_INT, TOOL_PROP_FLOAT:
|
|
||||||
editor = EditorSpinSlider.new()
|
|
||||||
if hint == null:
|
|
||||||
editor.max_value = INF
|
|
||||||
editor.min_value = -INF
|
|
||||||
|
|
||||||
else:
|
|
||||||
editor.min_value = hint[0]
|
|
||||||
editor.max_value = hint[1]
|
|
||||||
editor.hide_slider = false
|
|
||||||
|
|
||||||
editor.value = default_value
|
|
||||||
editor.step = 0.01 if type == TOOL_PROP_FLOAT else 1.0
|
|
||||||
editor.custom_minimum_size.x = 64.0
|
|
||||||
editor.value_changed.connect(setter)
|
|
||||||
if hotkey_adjustment:
|
|
||||||
_hotkey_adjustment_hook = func(x):
|
|
||||||
editor.value += editor.step * x
|
|
||||||
setter.call(editor.value)
|
|
||||||
|
|
||||||
TOOL_PROP_ENUM:
|
|
||||||
if hint.size() != 2:
|
|
||||||
editor = OptionButton.new()
|
|
||||||
for x in hint:
|
|
||||||
editor.add_item(x)
|
|
||||||
|
|
||||||
editor.item_selected.connect(setter)
|
|
||||||
editor.select(default_value)
|
|
||||||
if hotkey_adjustment:
|
|
||||||
_hotkey_adjustment_hook = func(x):
|
|
||||||
editor.select(posmod((editor.get_selected_id() + x), hint.size()))
|
|
||||||
setter.call(editor.get_selected_id())
|
|
||||||
|
|
||||||
else:
|
|
||||||
editor = Button.new()
|
|
||||||
editor.text = hint[default_value]
|
|
||||||
editor.pressed.connect(func():
|
|
||||||
var x = 1 if editor.text == hint[0] else 0
|
|
||||||
editor.text = hint[x]
|
|
||||||
setter.call(x)
|
|
||||||
)
|
|
||||||
if hotkey_adjustment:
|
|
||||||
_hotkey_adjustment_hook = func(x):
|
|
||||||
var new_value = 1 if editor.text == hint[0] else 0
|
|
||||||
editor.text = hint[new_value]
|
|
||||||
setter.call(new_value)
|
|
||||||
|
|
||||||
|
|
||||||
TOOL_PROP_ICON_ENUM, TOOL_PROP_ICON_FLAGS:
|
|
||||||
editor = HBoxContainer.new()
|
|
||||||
var icons = hint if hint is Array else hint.keys()
|
|
||||||
var tooltips = {} if hint is Array else hint
|
|
||||||
var button
|
|
||||||
|
|
||||||
var bgroup = ButtonGroup.new()
|
|
||||||
|
|
||||||
for x in icons:
|
|
||||||
button = load("res://addons/sprite_painter/editor_icon_button.gd").new()
|
|
||||||
button.tooltip_text = tooltips.get(x)
|
|
||||||
button.toggle_mode = true
|
|
||||||
button.add_theme_stylebox_override("pressed", button.get_theme_stylebox("focus", "Button"))
|
|
||||||
button.add_theme_stylebox_override("focus", StyleBoxEmpty.new())
|
|
||||||
|
|
||||||
if x is Texture:
|
|
||||||
button.set_deferred("icon", x)
|
|
||||||
|
|
||||||
else:
|
|
||||||
button._set_icon_name(x)
|
|
||||||
|
|
||||||
editor.add_child(button)
|
|
||||||
if type == TOOL_PROP_ICON_ENUM:
|
|
||||||
button.button_group = bgroup
|
|
||||||
button.toggled.connect(func(toggled):
|
|
||||||
if !toggled: return
|
|
||||||
setter.call(button.get_index())
|
|
||||||
)
|
|
||||||
button.button_pressed = default_value == button.get_index()
|
|
||||||
|
|
||||||
else:
|
|
||||||
button.toggled.connect(func(toggled):
|
|
||||||
default_value[button.get_index()] = toggled
|
|
||||||
setter.call(default_value)
|
|
||||||
)
|
|
||||||
button.button_pressed = default_value[button.get_index()]
|
|
||||||
|
|
||||||
if hotkey_adjustment:
|
|
||||||
_hotkey_adjustment_hook = func(x):
|
|
||||||
var new_value : int
|
|
||||||
for i in editor.get_child_count():
|
|
||||||
if editor.get_child(i).button_pressed:
|
|
||||||
new_value = posmod(i + x, hint.size())
|
|
||||||
editor.get_child(new_value).button_pressed = true
|
|
||||||
editor.get_child(i).button_pressed = false
|
|
||||||
break
|
|
||||||
|
|
||||||
# setter.call(new_value)
|
|
||||||
|
|
||||||
TOOL_PROP_RESOURCE:
|
|
||||||
editor = EditorResourcePicker.new()
|
|
||||||
editor.resource_changed.connect(func(x):
|
|
||||||
setter.call(x)
|
|
||||||
)
|
|
||||||
editor.edited_resource = default_value
|
|
||||||
if !hint is Array || hint.size() > 0:
|
|
||||||
editor.base_type = hint if hint is String else hint[0]
|
|
||||||
|
|
||||||
var plugin_root = get_parent()
|
|
||||||
while !plugin_root is Window:
|
|
||||||
plugin_root = plugin_root.get_parent()
|
|
||||||
if plugin_root is SpritePainterRoot:
|
|
||||||
editor.resource_selected.connect(func(x, inspected):
|
|
||||||
plugin_root.editor_interface.edit_resource(x)
|
|
||||||
)
|
|
||||||
break
|
|
||||||
|
|
||||||
TOOL_PROP_FOLDER_SCAN:
|
|
||||||
editor = OptionButton.new()
|
|
||||||
var folder = (hint if hint is String else hint[0]).trim_suffix("/") + "/"
|
|
||||||
var filenames = DirAccess.get_files_at(folder)
|
|
||||||
|
|
||||||
for x in filenames:
|
|
||||||
editor.add_item(x.get_basename())
|
|
||||||
|
|
||||||
editor.item_selected.connect(func(x):
|
|
||||||
setter.call(load(folder + filenames[x]))
|
|
||||||
)
|
|
||||||
if default_value is int:
|
|
||||||
editor.select(default_value)
|
|
||||||
|
|
||||||
elif default_value is String:
|
|
||||||
default_value = default_value.get_file()
|
|
||||||
|
|
||||||
var found_index = filenames.find(default_value)
|
|
||||||
editor.select(found_index)
|
|
||||||
|
|
||||||
if hotkey_adjustment:
|
|
||||||
_hotkey_adjustment_hook = func(x):
|
|
||||||
editor.select(posmod((editor.get_selected_id() + x), hint.size()))
|
|
||||||
setter.call(load(folder + filenames[editor.get_selected_id()]))
|
|
||||||
|
|
||||||
TOOL_PROP_COLOR:
|
|
||||||
editor = ColorPickerButton.new()
|
|
||||||
editor.color = default_value
|
|
||||||
editor.color_changed.connect(setter)
|
|
||||||
|
|
||||||
|
|
||||||
editor.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
||||||
parent.add_child(editor)
|
|
||||||
return editor
|
|
||||||
|
|
||||||
|
|
||||||
func add_text_display():
|
|
||||||
var textbox = LineEdit.new()
|
|
||||||
textbox.editable = false
|
|
||||||
textbox.size_flags_vertical = SIZE_FILL
|
|
||||||
textbox.expand_to_text_length = true
|
|
||||||
add_child(textbox)
|
|
||||||
|
|
||||||
_last_grid = null
|
|
||||||
return textbox
|
|
||||||
|
|
||||||
|
|
||||||
func add_button_panel(labels : Array[String]):
|
|
||||||
var container = HFlowContainer.new()
|
|
||||||
for x in labels:
|
|
||||||
var new_button = Button.new()
|
|
||||||
new_button.text = x
|
|
||||||
new_button.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
||||||
container.add_child(new_button)
|
|
||||||
|
|
||||||
add_child(container)
|
|
||||||
|
|
||||||
_last_grid = null
|
|
||||||
return container
|
|
||||||
|
|
||||||
|
|
||||||
func is_out_of_bounds(pos : Vector2i, rect_size : Vector2i):
|
|
||||||
return (
|
|
||||||
pos.x < 0 || pos.y < 0
|
|
||||||
|| pos.x >= rect_size.x || pos.y >= rect_size.y
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func get_rect_from_drag(start_pos, end_pos, squarify : bool = false):
|
|
||||||
var rect = Rect2i(start_pos, end_pos - start_pos)
|
|
||||||
if !squarify:
|
|
||||||
return rect.abs().grow_individual(0, 0, 1, 1)
|
|
||||||
|
|
||||||
var max_side = maxi(abs(rect.size.x), abs(rect.size.y))
|
|
||||||
var square = Rect2i(rect.position, Vector2i(max_side, max_side))
|
|
||||||
if rect.size.x < 0:
|
|
||||||
square.position.x -= square.size.x
|
|
||||||
|
|
||||||
if rect.size.y < 0:
|
|
||||||
square.position.y -= square.size.y
|
|
||||||
|
|
||||||
return square
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func is_selection_empty():
|
|
||||||
return selection.get_true_bit_count() == selection.get_size().x * selection.get_size().y
|
|
||||||
|
|
||||||
|
|
||||||
func set_image_pixel(image : Image, x : int, y : int, color : Color):
|
|
||||||
if !is_out_of_bounds(Vector2i(x, y), image.get_size()):
|
|
||||||
if selection.get_bit(x, y):
|
|
||||||
image.set_pixel(x, y, color)
|
|
||||||
|
|
||||||
|
|
||||||
func set_image_pixelv(image : Image, pos : Vector2i, color : Color):
|
|
||||||
if !is_out_of_bounds(pos, image.get_size()):
|
|
||||||
if selection.get_bitv(pos):
|
|
||||||
image.set_pixelv(pos, color)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
printerr("Not implemented: mouse_pressed! (" + get_script().resource_path.get_file() + ")")
|
|
||||||
|
|
||||||
|
|
||||||
func get_affected_rect() -> Rect2i:
|
|
||||||
printerr("Not implemented: get_affected_rect! (" + get_script().resource_path.get_file() + ")")
|
|
||||||
return Rect2i()
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
printerr("Not implemented: mouse_moved! (" + get_script().resource_path.get_file() + ")")
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
printerr("Not implemented: draw_preview! (" + get_script().resource_path.get_file() + ")")
|
|
||||||
|
|
||||||
|
|
||||||
func draw_shader_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func draw_crosshair(image_view : CanvasItem, mouse_position : Vector2i, line_length : int, color : Color):
|
|
||||||
image_view.draw_rect(Rect2i(mouse_position + Vector2i(0, 4), Vector2(1, +line_length)).abs(), color)
|
|
||||||
image_view.draw_rect(Rect2i(mouse_position - Vector2i(0, 3), Vector2(1, -line_length)).abs(), color)
|
|
||||||
image_view.draw_rect(Rect2i(mouse_position + Vector2i(4, 0), Vector2(+line_length, 1)).abs(), color)
|
|
||||||
image_view.draw_rect(Rect2i(mouse_position - Vector2i(3, 0), Vector2(-line_length, 1)).abs(), color)
|
|
||||||
|
|
||||||
|
|
||||||
func _shortcut_input(event : InputEvent):
|
|
||||||
if _hotkey_adjustment_hook.is_null(): return
|
|
||||||
if !event is InputEventKey: return
|
|
||||||
if !event.pressed: return
|
|
||||||
if event.keycode != KEY_BRACKETLEFT:
|
|
||||||
_hotkey_adjustment_hook.call(+1)
|
|
||||||
|
|
||||||
if event.keycode != KEY_BRACKETRIGHT:
|
|
||||||
_hotkey_adjustment_hook.call(-1)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_visibility_changed():
|
|
||||||
set_process_shortcut_input(visible)
|
|
||||||
@@ -1,264 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends EditingTool
|
|
||||||
|
|
||||||
enum {
|
|
||||||
BRUSH_DRAW,
|
|
||||||
BRUSH_ERASE,
|
|
||||||
BRUSH_CLONE,
|
|
||||||
BRUSH_SHADING,
|
|
||||||
BRUSH_NORMALMAP,
|
|
||||||
}
|
|
||||||
|
|
||||||
@export_enum("Draw", "Erase", "Clone", "Shading", "Normal Map") var brush_type := 0
|
|
||||||
@export var chunk_size := Vector2i(256, 256)
|
|
||||||
@export var max_brush_size := 150
|
|
||||||
@export var max_brush_min_size := 150
|
|
||||||
@export var crosshair_color := Color(0.5, 0.5, 0.5, 0.75)
|
|
||||||
|
|
||||||
var brushsize := 5
|
|
||||||
var brushminsize := 5
|
|
||||||
var brush_offset := Vector2(0.5, 0.5)
|
|
||||||
var hardness := 1.0
|
|
||||||
var opacity := 1.0
|
|
||||||
var pen_flags := [true, false, false]
|
|
||||||
|
|
||||||
var drawing := false
|
|
||||||
var drawing_color1 := Color()
|
|
||||||
var drawing_color2 := Color()
|
|
||||||
var last_edits_chunks := {}
|
|
||||||
var last_edits_textures := {}
|
|
||||||
var last_affected_rect := Rect2i()
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
add_name()
|
|
||||||
start_property_grid()
|
|
||||||
add_property("Size", brushsize,
|
|
||||||
func (x):
|
|
||||||
brushsize = x
|
|
||||||
brush_offset = Vector2(0.5, 0.5) * float(int(x) % 2),
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[1, max_brush_size],
|
|
||||||
true
|
|
||||||
)
|
|
||||||
add_property("Min Size", brushminsize,
|
|
||||||
func (x):
|
|
||||||
brushminsize = x,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[1, max_brush_min_size],
|
|
||||||
true
|
|
||||||
)
|
|
||||||
add_property("Hardness", hardness * 100,
|
|
||||||
func (x): hardness = x * 0.01,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[0, 100]
|
|
||||||
)
|
|
||||||
add_property("Strength", opacity * 100,
|
|
||||||
func (x): opacity = x * 0.01,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[0, 100]
|
|
||||||
)
|
|
||||||
|
|
||||||
var pressure_options := {
|
|
||||||
"ToolScale" : "Size",
|
|
||||||
"Gradient" : "Opacity",
|
|
||||||
}
|
|
||||||
if brush_type == BRUSH_DRAW:
|
|
||||||
pressure_options["CanvasItemMaterial"] = "Tint"
|
|
||||||
|
|
||||||
add_property("Pen Pressure", pen_flags,
|
|
||||||
func (x): pen_flags = x,
|
|
||||||
TOOL_PROP_ICON_FLAGS,
|
|
||||||
pressure_options
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
drawing = event.pressed
|
|
||||||
drawing_color1 = color1
|
|
||||||
drawing_color2 = color2
|
|
||||||
if drawing:
|
|
||||||
start_drawing(image, event.position)
|
|
||||||
|
|
||||||
else:
|
|
||||||
match brush_type:
|
|
||||||
BRUSH_ERASE:
|
|
||||||
apply_eraser(image)
|
|
||||||
|
|
||||||
_:
|
|
||||||
apply_brush(image)
|
|
||||||
|
|
||||||
|
|
||||||
func start_drawing(image, start_pos):
|
|
||||||
last_edits_chunks.clear()
|
|
||||||
# Break the image up into tiles - small images are faster to edit.
|
|
||||||
for i in ceil(float(image.get_width()) / chunk_size.x):
|
|
||||||
for j in ceil(float(image.get_height()) / chunk_size.y):
|
|
||||||
last_edits_chunks[Vector2i(i, j) * chunk_size] = Image.create(
|
|
||||||
chunk_size.x, chunk_size.y,
|
|
||||||
false, image.get_format()
|
|
||||||
)
|
|
||||||
for k in last_edits_chunks:
|
|
||||||
last_edits_textures[k] = ImageTexture.create_from_image(last_edits_chunks[k])
|
|
||||||
# Copy the image to the tiles. Worse opacity handling,
|
|
||||||
# but with more work can make eraser editing more performant and previewable.
|
|
||||||
# last_edits_chunks[k].blit_rect(image, Rect2i(k, chunk_size), Vector2i.ZERO)
|
|
||||||
|
|
||||||
last_affected_rect = Rect2i(start_pos, Vector2i.ZERO)
|
|
||||||
|
|
||||||
|
|
||||||
func apply_brush(image):
|
|
||||||
for k in last_edits_chunks:
|
|
||||||
image.blend_rect(
|
|
||||||
last_edits_chunks[k],
|
|
||||||
Rect2i(Vector2i.ZERO, chunk_size),
|
|
||||||
k
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func apply_eraser(image):
|
|
||||||
# Cutting off a smaller image does not increase performance.
|
|
||||||
# Must find another way - erasing is very slow.
|
|
||||||
# var new_image = Image.create(last_affected_rect.size.x + 1, last_affected_rect.size.y + 1, false, image.get_format())
|
|
||||||
# new_image.blit_rect(new_image, last_affected_rect, Vector2i.ZERO)
|
|
||||||
var pos : Vector2i
|
|
||||||
for k in last_edits_chunks:
|
|
||||||
var chunk = last_edits_chunks[k]
|
|
||||||
var height = mini(image.get_height() - k.y, chunk.get_height())
|
|
||||||
for i in mini(image.get_width() - k.x, chunk.get_width()):
|
|
||||||
for j in height:
|
|
||||||
# pos = k - last_affected_rect.position + Vector2i(i, j)
|
|
||||||
pos = Vector2i(i + k.x, j + k.y)
|
|
||||||
chunk.set_pixel(
|
|
||||||
i, j,
|
|
||||||
image.get_pixelv(pos) - chunk.get_pixel(i, j)
|
|
||||||
)
|
|
||||||
image.blit_rect(last_edits_chunks[k], Rect2i(Vector2i.ZERO, chunk_size), k)
|
|
||||||
|
|
||||||
|
|
||||||
func get_affected_rect():
|
|
||||||
return last_affected_rect.grow_individual(0, 0, 1, 1)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
if !drawing: return
|
|
||||||
if event.button_mask & MOUSE_BUTTON_MASK_LEFT != 0.0:
|
|
||||||
stroke(event.position, event.position - event.relative, event.pressure)
|
|
||||||
|
|
||||||
else:
|
|
||||||
stroke(event.position, event.position - event.relative, 1.0)
|
|
||||||
|
|
||||||
|
|
||||||
func stroke(stroke_start : Vector2, stroke_end : Vector2, pressure : float):
|
|
||||||
var rect = Rect2i(stroke_start, Vector2.ZERO)\
|
|
||||||
.expand(stroke_end)\
|
|
||||||
.grow(brushsize * 0.5 + 1)
|
|
||||||
rect = Rect2i(rect.position / chunk_size, rect.end / chunk_size)
|
|
||||||
var key : Vector2i
|
|
||||||
var keyf : Vector2
|
|
||||||
for i in rect.size.x + 1:
|
|
||||||
for j in rect.size.y + 1:
|
|
||||||
key = (rect.position + Vector2i(i, j)) * chunk_size
|
|
||||||
keyf = Vector2(key)
|
|
||||||
if !last_edits_chunks.has(key): continue
|
|
||||||
|
|
||||||
paint(
|
|
||||||
last_edits_chunks[key],
|
|
||||||
stroke_end - keyf,
|
|
||||||
stroke_start - keyf,
|
|
||||||
key,
|
|
||||||
pressure
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func paint(on_image : Image, stroke_start : Vector2, stroke_end : Vector2, chunk_position : Vector2i, pressure : float):
|
|
||||||
var unsolid_radius := (brushsize * 0.5) * (1.0 - hardness)
|
|
||||||
var radius := lerpf(brushminsize, brushsize, pressure if pen_flags[0] else 1.0) * 0.5
|
|
||||||
var solid_radius := radius - unsolid_radius
|
|
||||||
|
|
||||||
var color : Color
|
|
||||||
if brush_type == BRUSH_ERASE:
|
|
||||||
color = Color.BLACK
|
|
||||||
|
|
||||||
elif pen_flags[2]:
|
|
||||||
color = lerp(drawing_color2, drawing_color1, pressure)
|
|
||||||
|
|
||||||
else:
|
|
||||||
color = drawing_color1
|
|
||||||
|
|
||||||
color.a *= opacity
|
|
||||||
if pen_flags[1]:
|
|
||||||
color.a *= pressure
|
|
||||||
|
|
||||||
var new_rect := Rect2i(stroke_start, Vector2i.ZERO)\
|
|
||||||
.expand(stroke_end)\
|
|
||||||
.grow(radius + 2)\
|
|
||||||
.intersection(Rect2i(Vector2i.ZERO, on_image.get_size()))
|
|
||||||
|
|
||||||
if new_rect.size == Vector2i.ZERO:
|
|
||||||
return
|
|
||||||
|
|
||||||
last_affected_rect = last_affected_rect\
|
|
||||||
.expand(Vector2i(new_rect.position) + chunk_position)\
|
|
||||||
.expand(Vector2i(new_rect.end) + chunk_position)
|
|
||||||
|
|
||||||
stroke_start = stroke_start.floor() + Vector2(0.5, 0.5)
|
|
||||||
stroke_end = stroke_end.floor() + Vector2(0.5, 0.5)
|
|
||||||
var cur_pos
|
|
||||||
for i in new_rect.size.x:
|
|
||||||
for j in new_rect.size.y:
|
|
||||||
cur_pos = new_rect.position + Vector2i(i, j)
|
|
||||||
if is_out_of_bounds(cur_pos + chunk_position, selection.get_size()):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if !selection.get_bitv(cur_pos + chunk_position):
|
|
||||||
continue
|
|
||||||
|
|
||||||
on_image.set_pixelv(cur_pos, get_new_pixel(
|
|
||||||
on_image, color,
|
|
||||||
stroke_start, stroke_end, Vector2(cur_pos) + brush_offset,
|
|
||||||
radius, solid_radius
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
func get_new_pixel(on_image : Image, color : Color, stroke_start : Vector2, stroke_end : Vector2, cur_pos : Vector2, radius : float, solid_radius : float):
|
|
||||||
var old_color = on_image.get_pixelv(cur_pos)
|
|
||||||
var distance = Geometry2D.get_closest_point_to_segment(
|
|
||||||
cur_pos, stroke_start, stroke_end
|
|
||||||
).distance_to(cur_pos)
|
|
||||||
|
|
||||||
if distance <= solid_radius:
|
|
||||||
var blended = old_color.blend(color)
|
|
||||||
blended.a = max(old_color.a, color.a)
|
|
||||||
return blended
|
|
||||||
|
|
||||||
elif distance <= radius:
|
|
||||||
var blended := old_color.blend(color)
|
|
||||||
distance = (distance - solid_radius) / (radius - solid_radius)
|
|
||||||
# Possible better handling of variable pressure,
|
|
||||||
# but creates artifacts when zig-zagging
|
|
||||||
blended.a = max(old_color.a, color.a * (1.0 - distance * distance))
|
|
||||||
# This one also creates artifacts, but this is during normal brush usage.
|
|
||||||
# blended.a = lerp(old_color.a, color.a, (1.0 - distance * distance))
|
|
||||||
return blended
|
|
||||||
|
|
||||||
else:
|
|
||||||
return old_color
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
if drawing:
|
|
||||||
for k in last_edits_chunks:
|
|
||||||
last_edits_textures[k].update(last_edits_chunks[k])
|
|
||||||
image_view.draw_texture(last_edits_textures[k], k)
|
|
||||||
|
|
||||||
var circle_center = Vector2(mouse_position + Vector2i.ONE) - brush_offset
|
|
||||||
image_view.draw_arc(circle_center, brushsize * 0.5 + 0.5, PI * 0.1, PI * 0.9, 32, crosshair_color, 1.0)
|
|
||||||
image_view.draw_arc(circle_center, brushsize * 0.5 + 0.5, PI * 1.1, PI * 1.9, 32, crosshair_color, 1.0)
|
|
||||||
# With region set to (0, 0, 0, 0), hides the image.
|
|
||||||
# image_view.region_enabled = drawing
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends "res://addons/sprite_painter/src/editing_tools/tool_brush.gd"
|
|
||||||
|
|
||||||
@export var clone_preview_color := Color(0.5, 0.5, 0.5, 0.75)
|
|
||||||
|
|
||||||
var replace_alpha := false
|
|
||||||
|
|
||||||
var clone_offset := Vector2.ZERO
|
|
||||||
var clone_offset_editing := false
|
|
||||||
var source_image : Image
|
|
||||||
var clone_offset_view : Control
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
super._ready()
|
|
||||||
clone_offset_view = add_text_display()
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
source_image = image
|
|
||||||
if event.button_index == MOUSE_BUTTON_RIGHT:
|
|
||||||
clone_offset_editing = event.pressed
|
|
||||||
clone_offset = clone_offset.floor()
|
|
||||||
|
|
||||||
else:
|
|
||||||
super.mouse_pressed(event, image, color1, color2)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
if clone_offset_editing:
|
|
||||||
clone_offset -= event.relative
|
|
||||||
clone_offset_view.text = "Offset: " + str(clone_offset.floor())
|
|
||||||
|
|
||||||
super.mouse_moved(event)
|
|
||||||
|
|
||||||
|
|
||||||
func get_new_pixel(on_image : Image, color : Color, stroke_start : Vector2, stroke_end : Vector2, cur_pos : Vector2, radius : float, solid_radius : float):
|
|
||||||
var old_color := on_image.get_pixelv(cur_pos)
|
|
||||||
var cloned_color := source_image.get_pixel(
|
|
||||||
fposmod(cur_pos.x + clone_offset.x, source_image.get_width()),
|
|
||||||
fposmod(cur_pos.y + clone_offset.y, source_image.get_height())
|
|
||||||
)
|
|
||||||
var distance := Geometry2D.get_closest_point_to_segment(
|
|
||||||
cur_pos, stroke_start, stroke_end
|
|
||||||
).distance_to(cur_pos)
|
|
||||||
|
|
||||||
if distance <= solid_radius:
|
|
||||||
var blended = old_color.blend(cloned_color)
|
|
||||||
blended.a = max(old_color.a, cloned_color.a)
|
|
||||||
return blended
|
|
||||||
|
|
||||||
elif distance <= radius:
|
|
||||||
var blended = old_color.blend(cloned_color)
|
|
||||||
distance = (distance - solid_radius) / (radius - solid_radius)
|
|
||||||
# blended.a = max(old_color.a, cloned_color.a * (1.0 - distance * distance))
|
|
||||||
blended.a = lerp(old_color.a, cloned_color.a, (1.0 - distance * distance))
|
|
||||||
return blended
|
|
||||||
|
|
||||||
else:
|
|
||||||
return old_color
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
super.draw_preview(image_view, mouse_position)
|
|
||||||
|
|
||||||
if clone_offset == Vector2.ZERO:
|
|
||||||
image_view.draw_string(
|
|
||||||
get_theme_font("main", "EditorFonts"),
|
|
||||||
mouse_position,
|
|
||||||
"Hold Right Mouse and drag to change offset.",
|
|
||||||
HORIZONTAL_ALIGNMENT_CENTER
|
|
||||||
)
|
|
||||||
|
|
||||||
var circle_center := Vector2(mouse_position + Vector2i.ONE + Vector2i(clone_offset)) - brush_offset
|
|
||||||
image_view.draw_arc(circle_center, brushsize * 0.5 + 0.5, PI * 0.6, PI * 1.4, 32, clone_preview_color, 1.0)
|
|
||||||
image_view.draw_arc(circle_center, brushsize * 0.5 + 0.5, PI * 1.6, PI * 2.4, 32, clone_preview_color, 1.0)
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends "res://addons/sprite_painter/src/editing_tools/tool_brush.gd"
|
|
||||||
|
|
||||||
@export var tilt_preview_scale := 4.0
|
|
||||||
|
|
||||||
var shrink := 1.0
|
|
||||||
|
|
||||||
var mouse_tilt_editing := false
|
|
||||||
var mouse_tilt := Vector2.ZERO
|
|
||||||
|
|
||||||
var tilt : Vector2
|
|
||||||
var tilt_length : float
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
super._ready()
|
|
||||||
add_property("Edge Shrink", shrink * 100,
|
|
||||||
func (x): shrink = x * 0.01,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[0, 100]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
if event.button_index == MOUSE_BUTTON_RIGHT:
|
|
||||||
mouse_tilt_editing = event.pressed
|
|
||||||
mouse_tilt = mouse_tilt.limit_length(1.0)
|
|
||||||
|
|
||||||
else:
|
|
||||||
super.mouse_pressed(event, image, color1, color2)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
if mouse_tilt_editing:
|
|
||||||
mouse_tilt += event.relative / (brushsize * tilt_preview_scale)
|
|
||||||
tilt = mouse_tilt.limit_length(1.0)
|
|
||||||
return
|
|
||||||
|
|
||||||
if event.tilt != Vector2.ZERO:
|
|
||||||
tilt = Vector2(event.tilt.x, -event.tilt.y)
|
|
||||||
|
|
||||||
var joy_tilt = Vector2(Input.get_joy_axis(0, JOY_AXIS_LEFT_X), Input.get_joy_axis(0, JOY_AXIS_LEFT_Y))
|
|
||||||
if joy_tilt != Vector2.ZERO:
|
|
||||||
tilt = joy_tilt
|
|
||||||
|
|
||||||
tilt_length = tilt.length() * 0.707214
|
|
||||||
var tilt_basis = Basis.from_euler(Vector3(tilt.x * PI * 0.499, tilt.y * PI * 0.499, 0.0))
|
|
||||||
var normal = Vector3.BACK * tilt_basis
|
|
||||||
drawing_color1 = Color(normal.y * 0.5 + 0.5, normal.x * 0.5 + 0.5, normal.z, 1.0)
|
|
||||||
|
|
||||||
super.mouse_moved(event)
|
|
||||||
|
|
||||||
|
|
||||||
func get_new_pixel(on_image, color, stroke_start, stroke_end, cur_pos, radius, solid_radius):
|
|
||||||
return super.get_new_pixel(
|
|
||||||
on_image, on_image.get_pixelv(cur_pos).blend(Color(color, color.a)), stroke_start, stroke_end, cur_pos,
|
|
||||||
radius * (1.0 - tilt_length * shrink), solid_radius * (1.0 - tilt_length * shrink)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
var circle_center = Vector2(mouse_position + Vector2i.ONE) - brush_offset
|
|
||||||
image_view.draw_line(
|
|
||||||
circle_center,
|
|
||||||
circle_center + tilt * brushsize * tilt_preview_scale,
|
|
||||||
crosshair_color,
|
|
||||||
1.01
|
|
||||||
)
|
|
||||||
if mouse_tilt_editing:
|
|
||||||
image_view.draw_arc(circle_center - mouse_tilt * brushsize * tilt_preview_scale, brushsize * tilt_preview_scale + 0.5, PI * 0.6, PI * 1.4, 32, crosshair_color, 1.0)
|
|
||||||
image_view.draw_arc(circle_center - mouse_tilt * brushsize * tilt_preview_scale, brushsize * tilt_preview_scale + 0.5, PI * 1.6, PI * 2.4, 32, crosshair_color, 1.0)
|
|
||||||
|
|
||||||
super.draw_preview(image_view, mouse_position)
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends "res://addons/sprite_painter/src/editing_tools/tool_brush.gd"
|
|
||||||
|
|
||||||
var fill_mode := 0
|
|
||||||
var tolerance := 0.0
|
|
||||||
|
|
||||||
var allowed_pixels = BitMap.new()
|
|
||||||
var image_size := Vector2i()
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
super._ready()
|
|
||||||
add_property("Fill Mode", fill_mode,
|
|
||||||
func (x): fill_mode = x,
|
|
||||||
TOOL_PROP_ENUM,
|
|
||||||
[&"Contiguous", &"Global"]
|
|
||||||
)
|
|
||||||
add_property("Tolerance", tolerance * 100,
|
|
||||||
func (x): tolerance = x * 0.01,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[0, 100]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
image_size = image.get_size()
|
|
||||||
if event.pressed:
|
|
||||||
allowed_pixels.create(image.get_size())
|
|
||||||
ImageFillTools.fill_on_image(
|
|
||||||
image, allowed_pixels, event.position,
|
|
||||||
tolerance, fill_mode == 0, selection
|
|
||||||
)
|
|
||||||
|
|
||||||
super.mouse_pressed(event, image, color1, color2)
|
|
||||||
|
|
||||||
|
|
||||||
func get_new_pixel(on_image : Image, color : Color, stroke_start : Vector2, stroke_end : Vector2, cur_pos : Vector2, radius : float, solid_radius : float):
|
|
||||||
if !allowed_pixels.get_bitv(cur_pos):
|
|
||||||
return on_image.get_pixelv(cur_pos)
|
|
||||||
|
|
||||||
return super.get_new_pixel(on_image, color, stroke_start, stroke_end, cur_pos, radius, solid_radius)
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends EditingTool
|
|
||||||
|
|
||||||
var fill_mode := 0
|
|
||||||
var tolerance := 0.0
|
|
||||||
|
|
||||||
var drawing := false
|
|
||||||
var drawing_color := Color.BLACK
|
|
||||||
var image : Image
|
|
||||||
var start_color := Color.TRANSPARENT
|
|
||||||
var affected_pixels := BitMap.new()
|
|
||||||
var last_affected_rect := Rect2i()
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
add_name()
|
|
||||||
start_property_grid()
|
|
||||||
add_property("Fill Mode", fill_mode,
|
|
||||||
func (x): fill_mode = x,
|
|
||||||
TOOL_PROP_ENUM,
|
|
||||||
[&"Contiguous", &"Global"]
|
|
||||||
)
|
|
||||||
add_property("Tolerance", tolerance * 100,
|
|
||||||
func (x): tolerance = x * 0.01,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[0, 100],
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
drawing = event.pressed
|
|
||||||
drawing_color = Color.BLACK.blend(color1)
|
|
||||||
start_color = image.get_pixelv(event.position)
|
|
||||||
self.image = image
|
|
||||||
if drawing:
|
|
||||||
affected_pixels.create(image.get_size())
|
|
||||||
fill(event.position)
|
|
||||||
|
|
||||||
else:
|
|
||||||
for i in image.get_width():
|
|
||||||
for j in image.get_height():
|
|
||||||
if affected_pixels.get_bit(i, j):
|
|
||||||
set_image_pixel(image, i, j, color1)
|
|
||||||
|
|
||||||
|
|
||||||
func get_affected_rect():
|
|
||||||
return last_affected_rect.grow_individual(0, 0, 1, 1)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
if !drawing: return
|
|
||||||
if is_out_of_bounds(event.position, image.get_size()):
|
|
||||||
affected_pixels.create(affected_pixels.get_size())
|
|
||||||
return
|
|
||||||
|
|
||||||
var cur_color := image.get_pixelv(event.position)
|
|
||||||
if cur_color == start_color:
|
|
||||||
return
|
|
||||||
|
|
||||||
start_color = cur_color
|
|
||||||
fill(event.position)
|
|
||||||
|
|
||||||
|
|
||||||
func fill(start_pos : Vector2):
|
|
||||||
last_affected_rect = ImageFillTools.fill_on_image(
|
|
||||||
image,
|
|
||||||
affected_pixels,
|
|
||||||
start_pos,
|
|
||||||
tolerance,
|
|
||||||
(fill_mode == 0) != Input.is_key_pressed(KEY_SHIFT),
|
|
||||||
selection
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
if !drawing: return
|
|
||||||
|
|
||||||
image_view.draw_rect(Rect2(mouse_position, Vector2.ONE), Color.WHITE)
|
|
||||||
ImageFillTools.draw_bitmap(image_view, affected_pixels, drawing_color)
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends EditingTool
|
|
||||||
|
|
||||||
enum {
|
|
||||||
GRADIENT_LINEAR,
|
|
||||||
GRADIENT_LINEAR_MIRRORED,
|
|
||||||
GRADIENT_RADIAL,
|
|
||||||
GRADIENT_CONIC,
|
|
||||||
GRADIENT_BOUNDING_BOX,
|
|
||||||
}
|
|
||||||
|
|
||||||
@export var line_color = Color.GRAY
|
|
||||||
@export var line_aligned_color = Color.GREEN
|
|
||||||
@export var point_grab_area = Vector2(5, 5)
|
|
||||||
@export var point_grab_color = Color.GRAY
|
|
||||||
@export var shader_preview : NodePath
|
|
||||||
@export var shader_viewport_texture : Texture2D
|
|
||||||
|
|
||||||
var gradient_type := 0
|
|
||||||
var fill_mode := 0
|
|
||||||
var tolerance := 1.0
|
|
||||||
|
|
||||||
var drawing := false
|
|
||||||
var default_gradient := Gradient.new()
|
|
||||||
var custom_gradient : Gradient = null
|
|
||||||
var default_color2 := Color.TRANSPARENT
|
|
||||||
|
|
||||||
var affected_pixels := BitMap.new()
|
|
||||||
var affected_pixels_tex : ImageTexture
|
|
||||||
var points := [Vector2(-INF, -INF), Vector2(-INF, -INF)]
|
|
||||||
var point_grabbed := -1
|
|
||||||
var last_affected_rect := Rect2i()
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
default_gradient.add_point(1.0, Color.WHITE)
|
|
||||||
|
|
||||||
add_name()
|
|
||||||
start_property_grid()
|
|
||||||
add_property("Type", gradient_type,
|
|
||||||
func (x): gradient_type = x,
|
|
||||||
TOOL_PROP_ICON_ENUM,
|
|
||||||
{
|
|
||||||
"Line": "Linear",
|
|
||||||
"Hsize": "Linear Mirrored",
|
|
||||||
"Node": "Radial",
|
|
||||||
"ToolRotate": "Conic",
|
|
||||||
"Groups": "Bounding Box",
|
|
||||||
},
|
|
||||||
true
|
|
||||||
)
|
|
||||||
add_property("Gradient", custom_gradient,
|
|
||||||
func (x): custom_gradient = x,
|
|
||||||
TOOL_PROP_RESOURCE,
|
|
||||||
["Gradient"]
|
|
||||||
)
|
|
||||||
add_property("Fill Mode", fill_mode,
|
|
||||||
func (x): fill_mode = x,
|
|
||||||
TOOL_PROP_ENUM,
|
|
||||||
[&"Contiguous", &"Global"]
|
|
||||||
)
|
|
||||||
add_property("Tolerance", tolerance * 100,
|
|
||||||
func (x): tolerance = x * 0.01,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[0, 100]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
drawing = event.pressed
|
|
||||||
default_gradient.set_color(0, color1)
|
|
||||||
default_gradient.set_color(1, color2)
|
|
||||||
var cur_color := image.get_pixelv(event.position)
|
|
||||||
if drawing:
|
|
||||||
if try_grab_point(event):
|
|
||||||
return
|
|
||||||
|
|
||||||
if is_out_of_bounds(event.position, image.get_size()):
|
|
||||||
affected_pixels.create(affected_pixels.get_size())
|
|
||||||
return
|
|
||||||
|
|
||||||
points[0] = event.position.floor()
|
|
||||||
points[1] = event.position.floor()
|
|
||||||
affected_pixels.create(image.get_size())
|
|
||||||
fill(event.position, image)
|
|
||||||
var mask = affected_pixels.convert_to_image()
|
|
||||||
mask.clear_mipmaps()
|
|
||||||
affected_pixels_tex = ImageTexture.create_from_image(mask)
|
|
||||||
update_preview_shader()
|
|
||||||
point_grabbed = 1
|
|
||||||
|
|
||||||
else:
|
|
||||||
point_grabbed = -1
|
|
||||||
if points[0] == points[1]:
|
|
||||||
points[0] = Vector2(-INF, -INF)
|
|
||||||
points[1] = Vector2(-INF, -INF)
|
|
||||||
return
|
|
||||||
|
|
||||||
var result_image = shader_viewport_texture.get_image()
|
|
||||||
for i in result_image.get_width():
|
|
||||||
for j in result_image.get_height():
|
|
||||||
if affected_pixels.get_bit(i, j):
|
|
||||||
set_image_pixel(image, i, j, result_image.get_pixel(i, j))
|
|
||||||
|
|
||||||
|
|
||||||
func try_grab_point(event : InputEventMouse) -> bool:
|
|
||||||
for i in points.size():
|
|
||||||
if Rect2(points[i] - point_grab_area * 0.5, point_grab_area).has_point(event.position):
|
|
||||||
point_grabbed = i
|
|
||||||
return true
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
func get_affected_rect():
|
|
||||||
return last_affected_rect.grow_individual(0, 0, 1, 1)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
if point_grabbed == -1: return
|
|
||||||
|
|
||||||
if Input.is_key_pressed(KEY_SHIFT):
|
|
||||||
var origin = points[1 - point_grabbed]
|
|
||||||
var angle_rounded = snappedf(origin.angle_to_point(event.position), PI * 0.25)
|
|
||||||
var distance = (event.position - origin).length()
|
|
||||||
points[point_grabbed] = (origin + Vector2(
|
|
||||||
distance * cos(angle_rounded),
|
|
||||||
distance * sin(angle_rounded)
|
|
||||||
)).floor()
|
|
||||||
|
|
||||||
else:
|
|
||||||
points[point_grabbed] = event.position.floor()
|
|
||||||
|
|
||||||
update_preview_shader()
|
|
||||||
|
|
||||||
|
|
||||||
func update_preview_shader():
|
|
||||||
var preview_node = get_node(shader_preview)
|
|
||||||
var g_tex = preview_node.material.get_shader_parameter("gradient")
|
|
||||||
g_tex.gradient = default_gradient if custom_gradient == null else custom_gradient
|
|
||||||
preview_node.texture = affected_pixels_tex
|
|
||||||
preview_shader.set_shader_parameter("gradient", g_tex)
|
|
||||||
preview_shader.set_shader_parameter("type", gradient_type)
|
|
||||||
preview_shader.set_shader_parameter("from", points[0] / Vector2(affected_pixels.get_size()))
|
|
||||||
preview_shader.set_shader_parameter("delta", (points[1] - points[0]) / Vector2(affected_pixels.get_size()))
|
|
||||||
|
|
||||||
|
|
||||||
func fill(start_pos : Vector2, image : Image):
|
|
||||||
last_affected_rect = ImageFillTools.fill_on_image(
|
|
||||||
image,
|
|
||||||
affected_pixels,
|
|
||||||
start_pos,
|
|
||||||
tolerance,
|
|
||||||
(fill_mode == 0) != Input.is_key_pressed(KEY_SHIFT),
|
|
||||||
selection
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func draw_shader_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
if points[0] == Vector2(-INF, -INF):
|
|
||||||
image_view.hide()
|
|
||||||
return
|
|
||||||
|
|
||||||
image_view.texture = affected_pixels_tex
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
if points[0] == Vector2(-INF, -INF):
|
|
||||||
return
|
|
||||||
|
|
||||||
for i in points.size():
|
|
||||||
image_view.draw_line(points[0], points[1], line_color, 1.1)
|
|
||||||
image_view.draw_rect(
|
|
||||||
Rect2(points[i] - point_grab_area * 0.5, point_grab_area),
|
|
||||||
point_grab_color, false, 2
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_visibility_changed():
|
|
||||||
points = [Vector2(-INF, -INF), Vector2(-INF, -INF)]
|
|
||||||
super._on_visibility_changed()
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends "./tool_shape.gd"
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
add_name()
|
|
||||||
start_property_grid()
|
|
||||||
add_property("Width", line_width,
|
|
||||||
func (x): line_width = x,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[0, 250]
|
|
||||||
)
|
|
||||||
add_property("Flags", [erase_mode, aa],
|
|
||||||
func (x):
|
|
||||||
print(x)
|
|
||||||
erase_mode = x[0]
|
|
||||||
aa = x[1],
|
|
||||||
TOOL_PROP_ICON_FLAGS,
|
|
||||||
{"Eraser" : "Erase Mode", "CurveTexture" : "Anti-Aliasing"}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
if !drawing: return
|
|
||||||
if Input.is_key_pressed(KEY_SHIFT):
|
|
||||||
var angle_rounded = snappedf((Vector2(start_pos)).angle_to_point(event.position), PI * 0.25)
|
|
||||||
var distance = (event.position - Vector2(start_pos)).length()
|
|
||||||
end_pos = (Vector2(start_pos) + Vector2(
|
|
||||||
distance * cos(angle_rounded),
|
|
||||||
distance * sin(angle_rounded)
|
|
||||||
)).round()
|
|
||||||
|
|
||||||
else:
|
|
||||||
end_pos = event.position.floor()
|
|
||||||
|
|
||||||
|
|
||||||
func get_affected_rect():
|
|
||||||
return super.get_affected_rect().grow(line_width)
|
|
||||||
|
|
||||||
|
|
||||||
func update_preview_cheddar():
|
|
||||||
var rect = super.get_affected_rect()
|
|
||||||
preview_shader.set_shader_parameter("color", color_line if !erase_mode else Color.BLACK.blend(color_line));
|
|
||||||
preview_shader.set_shader_parameter("origin", Vector2(start_pos) + Vector2(0.5, 0.5));
|
|
||||||
preview_shader.set_shader_parameter("width", line_width);
|
|
||||||
preview_shader.set_shader_parameter("enable_aa", aa);
|
|
||||||
|
|
||||||
if end_pos == start_pos: return # The SDF for this case evaluates to being inside; abort
|
|
||||||
preview_shader.set_shader_parameter("delta", end_pos - start_pos);
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends EditingTool
|
|
||||||
|
|
||||||
@export var crosshair_color := Color(0.5, 0.5, 0.5, 0.75)
|
|
||||||
@export var crosshair_size := 3
|
|
||||||
@export var crosshair_size_ruler := 32
|
|
||||||
|
|
||||||
var ruler_mode := false
|
|
||||||
var jaggies_removal := true
|
|
||||||
|
|
||||||
var drawing := false
|
|
||||||
var drawing_color := Color()
|
|
||||||
var drawing_positions : Array[Vector2]
|
|
||||||
var image_size := Vector2()
|
|
||||||
var last_affected_rect := Rect2i()
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
add_name()
|
|
||||||
start_property_grid()
|
|
||||||
add_property("Guide Lines", ruler_mode,
|
|
||||||
func (x): ruler_mode = x,
|
|
||||||
TOOL_PROP_BOOL,
|
|
||||||
null,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
add_property("Remove Jaggies", jaggies_removal,
|
|
||||||
func (x): jaggies_removal = x,
|
|
||||||
TOOL_PROP_BOOL
|
|
||||||
)
|
|
||||||
drawing_positions = []
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
drawing = event.pressed
|
|
||||||
drawing_color = Color.BLACK.blend(color1)
|
|
||||||
image_size = image.get_size()
|
|
||||||
if drawing:
|
|
||||||
drawing_positions.clear()
|
|
||||||
last_affected_rect = Rect2i(event.position, Vector2i.ZERO)
|
|
||||||
_add_point(event.position)
|
|
||||||
|
|
||||||
else:
|
|
||||||
for x in drawing_positions:
|
|
||||||
set_image_pixelv(image, x, color1)
|
|
||||||
|
|
||||||
|
|
||||||
func get_affected_rect():
|
|
||||||
return last_affected_rect.grow_individual(0, 0, 1, 1)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
if !drawing: return
|
|
||||||
var pt_count = max(abs(event.relative.x), abs(event.relative.y))
|
|
||||||
var lerp_step = 1 / pt_count
|
|
||||||
for i in pt_count:
|
|
||||||
_add_point(event.position + Vector2.ONE - event.relative * i * lerp_step - Vector2.ONE)
|
|
||||||
|
|
||||||
|
|
||||||
func _add_point(pt : Vector2):
|
|
||||||
pt = pt.floor()
|
|
||||||
if drawing_positions.size() >= 1 && drawing_positions[-1] == pt:
|
|
||||||
return
|
|
||||||
|
|
||||||
if pt.x < 0 || pt.y < 0 || pt.x >= image_size.x || pt.y >= image_size.y:
|
|
||||||
return
|
|
||||||
|
|
||||||
if jaggies_removal && drawing_positions.size() > 2:
|
|
||||||
var diff1 = (drawing_positions[-1] - drawing_positions[-2]).abs()
|
|
||||||
var diff2 = (pt - drawing_positions[-1]).abs()
|
|
||||||
if diff1 != diff2 && diff1.x + diff1.y + diff2.x + diff2.y == 2:
|
|
||||||
drawing_positions.pop_back()
|
|
||||||
|
|
||||||
drawing_positions.append(pt)
|
|
||||||
last_affected_rect = last_affected_rect.expand(pt)
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
if drawing:
|
|
||||||
for x in drawing_positions:
|
|
||||||
image_view.draw_rect(Rect2(x, Vector2.ONE), drawing_color)
|
|
||||||
|
|
||||||
if !ruler_mode:
|
|
||||||
draw_crosshair(image_view, mouse_position, crosshair_size, crosshair_color)
|
|
||||||
|
|
||||||
else:
|
|
||||||
draw_crosshair(image_view, mouse_position, crosshair_size_ruler, crosshair_color)
|
|
||||||
var diag_distance := 8
|
|
||||||
var posf := Vector2(mouse_position) + Vector2(0.5, 0.5)
|
|
||||||
image_view.draw_line(posf + Vector2(-1, +1) * diag_distance, posf + Vector2(-1, +1) * (diag_distance + crosshair_size_ruler), crosshair_color, 1)
|
|
||||||
image_view.draw_line(posf + Vector2(+1, -1) * diag_distance, posf + Vector2(+1, -1) * (diag_distance + crosshair_size_ruler), crosshair_color, 1)
|
|
||||||
image_view.draw_line(posf + Vector2(+1, +1) * diag_distance, posf + Vector2(+1, +1) * (diag_distance + crosshair_size_ruler), crosshair_color, 1)
|
|
||||||
image_view.draw_line(posf + Vector2(-1, -1) * diag_distance, posf + Vector2(-1, -1) * (diag_distance + crosshair_size_ruler), crosshair_color, 1)
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends EditingTool
|
|
||||||
|
|
||||||
@export var workspace : NodePath
|
|
||||||
|
|
||||||
var live_update := true
|
|
||||||
|
|
||||||
var timer : Timer
|
|
||||||
var param_grid : Control
|
|
||||||
var script_instance : ImageScript
|
|
||||||
var original_image : Image
|
|
||||||
var result_image_tex : ImageTexture
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
add_name()
|
|
||||||
var button = add_property("Script",
|
|
||||||
"",
|
|
||||||
load_script,
|
|
||||||
TOOL_PROP_FOLDER_SCAN,
|
|
||||||
"res://addons/sprite_painter/image_scripts"
|
|
||||||
)
|
|
||||||
button.text = "Choose script... "
|
|
||||||
button.fit_to_longest_item = false
|
|
||||||
param_grid = start_property_grid()
|
|
||||||
add_separator()
|
|
||||||
add_property("Live Update",
|
|
||||||
live_update,
|
|
||||||
func(x):
|
|
||||||
live_update = x
|
|
||||||
if x: update_script(true),
|
|
||||||
TOOL_PROP_BOOL
|
|
||||||
)
|
|
||||||
|
|
||||||
var buttons = add_button_panel(["Apply", "Reset"]).get_children()
|
|
||||||
buttons[0].pressed.connect(func():
|
|
||||||
var ws = get_node(workspace)
|
|
||||||
var old_image = ws.edited_image
|
|
||||||
ws.replace_image(old_image, result_image_tex.get_image())
|
|
||||||
ws.image_replaced.emit(old_image, ws.edited_image)
|
|
||||||
)
|
|
||||||
buttons[1].pressed.connect(func(): load_script(script_instance.get_script()))
|
|
||||||
|
|
||||||
# Updates are expensive if images are changed on the CPU.
|
|
||||||
# Update only sometimes to reduce lag
|
|
||||||
timer = Timer.new()
|
|
||||||
timer.wait_time = 2.0
|
|
||||||
timer.one_shot = true
|
|
||||||
timer.timeout.connect(_on_timer_timeout)
|
|
||||||
add_child(timer)
|
|
||||||
|
|
||||||
|
|
||||||
func load_script(script : Script):
|
|
||||||
script_instance = script.new()
|
|
||||||
param_grid.free()
|
|
||||||
param_grid = start_property_grid()
|
|
||||||
param_grid.get_parent().move_child(param_grid, 3)
|
|
||||||
param_grid.get_parent().get_child(2).hide()
|
|
||||||
|
|
||||||
for x in script_instance._get_param_list():
|
|
||||||
add_property(
|
|
||||||
x[0], # Name
|
|
||||||
x[2], # Value
|
|
||||||
func(y):
|
|
||||||
script_instance._params[x[0]] = y
|
|
||||||
update_script()
|
|
||||||
if y is Resource && !y.changed.is_connected(update_script):
|
|
||||||
y.changed.connect(update_script),
|
|
||||||
x[1], # Type
|
|
||||||
x[3] if x.size() > 3 else null # Hint (if any)
|
|
||||||
)
|
|
||||||
script_instance._params[x[0]] = x[2]
|
|
||||||
if x[2] is Resource && !x[2].changed.is_connected(update_script):
|
|
||||||
x[2].changed.connect(update_script)
|
|
||||||
|
|
||||||
script_instance._ready(original_image)
|
|
||||||
update_script()
|
|
||||||
|
|
||||||
|
|
||||||
func update_script(automatic : bool = false):
|
|
||||||
if !live_update: return
|
|
||||||
if timer.time_left != 0.0: return
|
|
||||||
|
|
||||||
var new_image = Image.create_from_data(
|
|
||||||
original_image.get_width(),
|
|
||||||
original_image.get_height(),
|
|
||||||
false,
|
|
||||||
original_image.get_format(),
|
|
||||||
original_image.get_data()
|
|
||||||
)
|
|
||||||
result_image_tex = ImageTexture.create_from_image(
|
|
||||||
script_instance._get_image(new_image, selection)
|
|
||||||
)
|
|
||||||
if !automatic:
|
|
||||||
timer.start()
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
original_image = image
|
|
||||||
|
|
||||||
|
|
||||||
func get_affected_rect() -> Rect2i:
|
|
||||||
return Rect2i()
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
original_image = get_node(workspace).edited_image
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func draw_shader_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
image_view.texture = result_image_tex
|
|
||||||
|
|
||||||
|
|
||||||
func _on_visibility_changed():
|
|
||||||
super._on_visibility_changed()
|
|
||||||
if is_visible_in_tree() && script_instance != null:
|
|
||||||
script_instance._ready(original_image)
|
|
||||||
update_script(true)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_timer_timeout():
|
|
||||||
update_script(true)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_workspace_image_replaced(old_image, new_image):
|
|
||||||
original_image = new_image
|
|
||||||
if is_visible_in_tree() && script_instance != null:
|
|
||||||
script_instance._ready(original_image)
|
|
||||||
update_script(true)
|
|
||||||
@@ -1,219 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends EditingTool
|
|
||||||
|
|
||||||
@export var preview_color := Color("1e90ff7f")
|
|
||||||
@export var crosshair_size := 3
|
|
||||||
|
|
||||||
enum {
|
|
||||||
DRAG_LEAVE_TRANSPARENT,
|
|
||||||
DRAG_LEAVE_SECONDARY,
|
|
||||||
DRAG_SELECTION_ONLY,
|
|
||||||
DRAG_NONE,
|
|
||||||
}
|
|
||||||
|
|
||||||
var operation := 0
|
|
||||||
var dragging_mode := DRAG_LEAVE_TRANSPARENT
|
|
||||||
|
|
||||||
var mouse_down := false
|
|
||||||
var selection_dragging := false
|
|
||||||
var image : Image
|
|
||||||
var draw_start := Vector2i()
|
|
||||||
var draw_end := Vector2i()
|
|
||||||
var image_size := Vector2i()
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
add_name()
|
|
||||||
start_property_grid()
|
|
||||||
add_selection_common_properties()
|
|
||||||
add_selection_button_panel()
|
|
||||||
|
|
||||||
|
|
||||||
func add_selection_common_properties():
|
|
||||||
add_property("Operation", operation,
|
|
||||||
func (x): operation = x,
|
|
||||||
TOOL_PROP_ENUM,
|
|
||||||
["Replace", "Add (Ctrl)", "Subtract (Right-click)", "Intersection", "Invert"],
|
|
||||||
true
|
|
||||||
)
|
|
||||||
add_property("Drag Mode", dragging_mode,
|
|
||||||
func (x): dragging_mode = x,
|
|
||||||
TOOL_PROP_ENUM,
|
|
||||||
["Transparent BG", "Secondary Color BG", "Move Selection Only", "Never Drag"]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func add_selection_button_panel():
|
|
||||||
var selection_view = $"%SelectionView"
|
|
||||||
var workspace = $"%Workspace"
|
|
||||||
add_separator()
|
|
||||||
var buttons = add_button_panel(
|
|
||||||
["Deselect", "Erase", "Invert"]
|
|
||||||
).get_children()
|
|
||||||
buttons[0].pressed.connect(func():
|
|
||||||
selection.set_bit_rect(Rect2i(Vector2i.ZERO, selection.get_size()), true)
|
|
||||||
selection_view.queue_redraw()
|
|
||||||
)
|
|
||||||
|
|
||||||
# This fragment of code is worth framing IMO.
|
|
||||||
buttons[1].pressed.connect(func():
|
|
||||||
var bg_color = Color.TRANSPARENT
|
|
||||||
if dragging_mode == DRAG_LEAVE_SECONDARY:
|
|
||||||
bg_color = get_parent().current_color2
|
|
||||||
|
|
||||||
workspace.make_image_edit(
|
|
||||||
func():
|
|
||||||
for i in selection.get_size().x:
|
|
||||||
for j in selection.get_size().y:
|
|
||||||
if selection.get_bit(i, j):
|
|
||||||
image.set_pixel(i, j, bg_color),
|
|
||||||
Rect2i(Vector2i.ZERO, selection.get_size())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
buttons[2].pressed.connect(func():
|
|
||||||
for i in selection.get_size().x:
|
|
||||||
for j in selection.get_size().y:
|
|
||||||
selection.set_bit(i, j, !selection.get_bit(i, j))
|
|
||||||
|
|
||||||
selection_view.queue_redraw()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
var subtract = Input.is_key_pressed(KEY_ALT) || event.button_index == MOUSE_BUTTON_RIGHT
|
|
||||||
var add = Input.is_key_pressed(KEY_CTRL) || Input.is_key_pressed(KEY_META)
|
|
||||||
self.image = image
|
|
||||||
image_size = image.get_size()
|
|
||||||
mouse_down = event.pressed
|
|
||||||
if mouse_down:
|
|
||||||
draw_start = event.position
|
|
||||||
draw_end = draw_start
|
|
||||||
selection_dragging = (
|
|
||||||
dragging_mode != DRAG_NONE
|
|
||||||
&& !subtract && !add
|
|
||||||
&& selection.get_bitv(event.position)
|
|
||||||
&& !is_selection_empty()
|
|
||||||
)
|
|
||||||
|
|
||||||
elif selection_dragging:
|
|
||||||
move_selected_pixels(
|
|
||||||
image,
|
|
||||||
Vector2i(draw_end - draw_start),
|
|
||||||
add,
|
|
||||||
color2
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
apply_selection(add, subtract)
|
|
||||||
|
|
||||||
|
|
||||||
func apply_selection(add_modifier, subtract_modifier):
|
|
||||||
var rect = get_selection_rect()
|
|
||||||
if operation == OPERATION_REPLACE || is_selection_empty():
|
|
||||||
if !add_modifier && !subtract_modifier:
|
|
||||||
selection.set_bit_rect(Rect2i(Vector2i.ZERO, image_size), false)
|
|
||||||
|
|
||||||
selection.set_bit_rect(rect, !subtract_modifier)
|
|
||||||
|
|
||||||
match operation:
|
|
||||||
OPERATION_ADD:
|
|
||||||
selection.set_bit_rect(rect, !subtract_modifier)
|
|
||||||
|
|
||||||
OPERATION_SUBTRACT:
|
|
||||||
selection.set_bit_rect(rect, subtract_modifier)
|
|
||||||
|
|
||||||
OPERATION_INTERSECTION, OPERATION_XOR:
|
|
||||||
var intersect = operation == OPERATION_INTERSECTION
|
|
||||||
var result_bit
|
|
||||||
for i in image_size.x:
|
|
||||||
for j in image_size.y:
|
|
||||||
result_bit = (
|
|
||||||
selection.get_bit(i, j)
|
|
||||||
&& rect.has_point(Vector2i(i, j))
|
|
||||||
) if intersect else (
|
|
||||||
selection.get_bit(i, j)
|
|
||||||
!= rect.has_point(Vector2i(i, j))
|
|
||||||
)
|
|
||||||
selection.set_bit(i, j, result_bit != subtract_modifier)
|
|
||||||
|
|
||||||
|
|
||||||
func move_selected_pixels(image, drag_vec, copy, back_color):
|
|
||||||
var old_pixels = []
|
|
||||||
var old_sel = BitMap.new()
|
|
||||||
var move_image = dragging_mode != DRAG_SELECTION_ONLY
|
|
||||||
old_sel.create(image_size)
|
|
||||||
old_pixels.resize(image_size.x * image_size.y)
|
|
||||||
|
|
||||||
if dragging_mode == DRAG_LEAVE_TRANSPARENT:
|
|
||||||
back_color = Color.TRANSPARENT
|
|
||||||
|
|
||||||
# Go through source pixels
|
|
||||||
var source_selected := false
|
|
||||||
for i in image_size.x:
|
|
||||||
for j in image_size.y:
|
|
||||||
source_selected = selection.get_bit(i, j)
|
|
||||||
old_sel.set_bit(i, j, source_selected)
|
|
||||||
selection.set_bit(i, j, false)
|
|
||||||
old_pixels[i + j * image_size.x] = image.get_pixel(i, j)
|
|
||||||
if !copy && source_selected && move_image:
|
|
||||||
image.set_pixel(i, j, back_color)
|
|
||||||
|
|
||||||
# Paste into destination pixels
|
|
||||||
var dest_pixel : Color
|
|
||||||
var dest_pos : Vector2i
|
|
||||||
for i in image_size.x:
|
|
||||||
for j in image_size.y:
|
|
||||||
dest_pos = Vector2i(i, j) - drag_vec
|
|
||||||
if (is_out_of_bounds(dest_pos, image_size) || !old_sel.get_bitv(dest_pos)):
|
|
||||||
continue
|
|
||||||
|
|
||||||
selection.set_bit(i, j, true)
|
|
||||||
dest_pixel = old_pixels[dest_pos.x + dest_pos.y * image_size.x]
|
|
||||||
if move_image:
|
|
||||||
image.set_pixel(i, j, image.get_pixel(i, j).blend(dest_pixel))
|
|
||||||
|
|
||||||
|
|
||||||
func get_affected_rect():
|
|
||||||
if selection_dragging:
|
|
||||||
# Can be anything!
|
|
||||||
return Rect2i(Vector2i.ZERO, image_size)
|
|
||||||
|
|
||||||
else:
|
|
||||||
return Rect2()
|
|
||||||
|
|
||||||
|
|
||||||
func get_selection_rect():
|
|
||||||
if draw_start == draw_end: return Rect2i()
|
|
||||||
return get_rect_from_drag(draw_start, draw_end, Input.is_key_pressed(KEY_SHIFT))
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
draw_end = event.position
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
if mouse_down:
|
|
||||||
if selection_dragging:
|
|
||||||
ImageFillTools.draw_bitmap(
|
|
||||||
image_view,
|
|
||||||
selection,
|
|
||||||
preview_color,
|
|
||||||
mouse_position - draw_start
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
draw_selection_preview(image_view, mouse_position)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
draw_crosshair(image_view, mouse_position, crosshair_size, preview_color)
|
|
||||||
|
|
||||||
|
|
||||||
func draw_selection_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
image_view.draw_rect(get_selection_rect(), preview_color)
|
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends EditingTool
|
|
||||||
|
|
||||||
enum {
|
|
||||||
SHAPE_RECTANGLE,
|
|
||||||
SHAPE_ELLIPSE,
|
|
||||||
SHAPE_TRIANGLE,
|
|
||||||
SHAPE_DIAMOND,
|
|
||||||
SHAPE_HEXAGON,
|
|
||||||
}
|
|
||||||
|
|
||||||
const I_SIN120 = sin(PI * 0.66666) # Used for making hexagons have equal qdges
|
|
||||||
|
|
||||||
@export var crosshair_color := Color(0.5, 0.5, 0.5, 0.75)
|
|
||||||
@export var crosshair_size := 3
|
|
||||||
@export var shader_viewport_texture : Texture2D
|
|
||||||
|
|
||||||
var shape := 0
|
|
||||||
var fill_mode := 0
|
|
||||||
var line_width := 1
|
|
||||||
var erase_mode := false
|
|
||||||
var aa := false
|
|
||||||
|
|
||||||
var drawing := false
|
|
||||||
var color_line : Color = Color.BLACK
|
|
||||||
var color_fill : Color = Color.WHITE
|
|
||||||
var image_size := Vector2()
|
|
||||||
|
|
||||||
var start_pos := Vector2i()
|
|
||||||
var end_pos := Vector2i()
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
var icon_folder = "res://addons/sprite_painter/graphics/"
|
|
||||||
add_name()
|
|
||||||
start_property_grid()
|
|
||||||
add_property("Shape", shape,
|
|
||||||
func (x): shape = x,
|
|
||||||
TOOL_PROP_ICON_ENUM,
|
|
||||||
{
|
|
||||||
load(icon_folder + "rect_shape_2d.svg") : "Rectangle",
|
|
||||||
load(icon_folder + "circle_shape_2d.svg") : "Ellipse",
|
|
||||||
load(icon_folder + "triangle_shape_2d.svg") : "Triangle",
|
|
||||||
load(icon_folder + "diamond_shape_2d.svg") : "Diamond",
|
|
||||||
load(icon_folder + "hex_shape_2d.svg") : "Hexagon",
|
|
||||||
},
|
|
||||||
true
|
|
||||||
)
|
|
||||||
add_property("Fill Color", fill_mode,
|
|
||||||
func (x): fill_mode = x,
|
|
||||||
TOOL_PROP_ENUM,
|
|
||||||
["Primary", "Secondary", "None (outline only)"]
|
|
||||||
)
|
|
||||||
add_property("Border Width", line_width,
|
|
||||||
func (x): line_width = x,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[0, 20]
|
|
||||||
)
|
|
||||||
add_property("Flags", [erase_mode, aa],
|
|
||||||
func (x):
|
|
||||||
erase_mode = x[0]
|
|
||||||
aa = x[1],
|
|
||||||
TOOL_PROP_ICON_FLAGS,
|
|
||||||
{"Eraser" : "Erase Mode", "CurveTexture" : "Anti-Aliasing"}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_pressed(
|
|
||||||
event : InputEventMouseButton,
|
|
||||||
image : Image,
|
|
||||||
color1 : Color = Color.BLACK,
|
|
||||||
color2 : Color = Color.WHITE,
|
|
||||||
):
|
|
||||||
drawing = event.pressed
|
|
||||||
color_line = color1
|
|
||||||
color_fill = [color1, color2, Color.TRANSPARENT][fill_mode]
|
|
||||||
image_size = image.get_size()
|
|
||||||
if drawing:
|
|
||||||
start_pos = Vector2i(event.position)
|
|
||||||
end_pos = Vector2i(event.position)
|
|
||||||
|
|
||||||
else:
|
|
||||||
var rect = get_affected_rect()
|
|
||||||
var new_image = shader_viewport_texture.get_image()
|
|
||||||
var cur_pos : Vector2i
|
|
||||||
var cur_pixel : Color
|
|
||||||
for i in rect.size.x:
|
|
||||||
for j in rect.size.y:
|
|
||||||
cur_pos = rect.position + Vector2i(i, j)
|
|
||||||
if is_out_of_bounds(cur_pos, image_size):
|
|
||||||
continue
|
|
||||||
|
|
||||||
cur_pixel = image.get_pixelv(cur_pos)
|
|
||||||
if !erase_mode:
|
|
||||||
set_image_pixelv(image, cur_pos,
|
|
||||||
cur_pixel.blend(new_image.get_pixelv(cur_pos))
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
set_image_pixelv(image, cur_pos, Color(
|
|
||||||
cur_pixel,
|
|
||||||
(cur_pixel.a - new_image.get_pixelv(cur_pos).a)
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
func get_affected_rect():
|
|
||||||
var squarify = Input.is_key_pressed(KEY_SHIFT)
|
|
||||||
var rect = get_rect_from_drag(start_pos, end_pos, squarify)
|
|
||||||
if shape == SHAPE_HEXAGON && squarify:
|
|
||||||
if (start_pos.x < end_pos.x) == (start_pos.y < end_pos.y):
|
|
||||||
rect.size.y *= I_SIN120
|
|
||||||
|
|
||||||
else:
|
|
||||||
rect.size.x *= I_SIN120
|
|
||||||
|
|
||||||
return rect
|
|
||||||
|
|
||||||
|
|
||||||
func mouse_moved(event : InputEventMouseMotion):
|
|
||||||
if !drawing: return
|
|
||||||
end_pos = event.position
|
|
||||||
|
|
||||||
|
|
||||||
func update_preview_cheddar():
|
|
||||||
var rect = get_affected_rect()
|
|
||||||
preview_shader.set_shader_parameter("shape_index", shape);
|
|
||||||
preview_shader.set_shader_parameter("color_border", color_line if !erase_mode else Color.BLACK.blend(color_line));
|
|
||||||
preview_shader.set_shader_parameter("color_fill", color_fill);
|
|
||||||
preview_shader.set_shader_parameter("origin", rect.position);
|
|
||||||
preview_shader.set_shader_parameter("shape_size", rect.size);
|
|
||||||
preview_shader.set_shader_parameter("border_width", line_width);
|
|
||||||
preview_shader.set_shader_parameter("drag_delta", start_pos - end_pos);
|
|
||||||
preview_shader.set_shader_parameter("enable_aa", aa);
|
|
||||||
|
|
||||||
|
|
||||||
func draw_shader_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
image_view.texture = null
|
|
||||||
if !drawing:
|
|
||||||
image_view.hide()
|
|
||||||
|
|
||||||
else:
|
|
||||||
if image_view.texture == null || image_view.texture.get_size() != image_size:
|
|
||||||
image_view.texture = ImageTexture.create_from_image(Image.create(
|
|
||||||
image_size.x,
|
|
||||||
image_size.y,
|
|
||||||
false,
|
|
||||||
Image.FORMAT_L8 # Doesn't matter, won't read from it
|
|
||||||
))
|
|
||||||
|
|
||||||
update_preview_cheddar()
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
if !drawing:
|
|
||||||
draw_crosshair(image_view, mouse_position, crosshair_size, crosshair_color)
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends "./tool_select.gd"
|
|
||||||
|
|
||||||
var selection_operations = [
|
|
||||||
func(s, d): return d,
|
|
||||||
func(s, d): return s || d,
|
|
||||||
func(s, d): return s && !d,
|
|
||||||
func(s, d): return s && d,
|
|
||||||
func(s, d): return s != d,
|
|
||||||
]
|
|
||||||
|
|
||||||
var fill_mode := 0
|
|
||||||
var tolerance := 0.0
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
add_name()
|
|
||||||
start_property_grid()
|
|
||||||
add_selection_common_properties()
|
|
||||||
add_property("Fill Mode", fill_mode,
|
|
||||||
func (x): fill_mode = x,
|
|
||||||
TOOL_PROP_ENUM,
|
|
||||||
[&"Contiguous", &"Global"]
|
|
||||||
)
|
|
||||||
add_property("Tolerance", tolerance * 100,
|
|
||||||
func (x): tolerance = x * 0.01,
|
|
||||||
TOOL_PROP_INT,
|
|
||||||
[0, 100]
|
|
||||||
)
|
|
||||||
add_selection_button_panel()
|
|
||||||
|
|
||||||
|
|
||||||
func apply_selection(add_modifier, subtract_modifier):
|
|
||||||
var affected_pixels = BitMap.new()
|
|
||||||
affected_pixels.create(image_size)
|
|
||||||
var affected_rect = ImageFillTools.fill_on_image(
|
|
||||||
image,
|
|
||||||
affected_pixels,
|
|
||||||
draw_end,
|
|
||||||
tolerance,
|
|
||||||
(fill_mode == 0) != Input.is_key_pressed(KEY_SHIFT)
|
|
||||||
)
|
|
||||||
affected_rect.size += Vector2i.ONE
|
|
||||||
var used_op_index = operation
|
|
||||||
if operation == OPERATION_REPLACE || is_selection_empty():
|
|
||||||
if !add_modifier && !subtract_modifier:
|
|
||||||
selection.set_bit_rect(Rect2i(Vector2i.ZERO, image_size), false)
|
|
||||||
|
|
||||||
if add_modifier:
|
|
||||||
used_op_index = OPERATION_ADD
|
|
||||||
|
|
||||||
var used_op = selection_operations[used_op_index]
|
|
||||||
var cur_pos : Vector2i
|
|
||||||
for i in affected_rect.size.x:
|
|
||||||
for j in affected_rect.size.y:
|
|
||||||
cur_pos = Vector2i(i, j) + affected_rect.position
|
|
||||||
if !affected_pixels.get_bitv(cur_pos): continue
|
|
||||||
selection.set_bitv(cur_pos, used_op.call(
|
|
||||||
selection.get_bitv(cur_pos), true
|
|
||||||
) != subtract_modifier)
|
|
||||||
|
|
||||||
|
|
||||||
func draw_selection_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
var affected_pixels = BitMap.new()
|
|
||||||
affected_pixels.create(image_size)
|
|
||||||
var affected_rect = ImageFillTools.fill_on_image(
|
|
||||||
image,
|
|
||||||
affected_pixels,
|
|
||||||
draw_end,
|
|
||||||
tolerance,
|
|
||||||
(fill_mode == 0) != Input.is_key_pressed(KEY_SHIFT)
|
|
||||||
)
|
|
||||||
ImageFillTools.draw_bitmap(image_view, affected_pixels, preview_color)
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name ImageFillTools
|
|
||||||
|
|
||||||
|
|
||||||
static func fill_on_image(
|
|
||||||
image : Image,
|
|
||||||
result_into_mask : BitMap,
|
|
||||||
start_pos : Vector2i,
|
|
||||||
tolerance : float = 0.0,
|
|
||||||
fill_contiguous : bool = true,
|
|
||||||
selection : BitMap = null,
|
|
||||||
) -> Rect2i:
|
|
||||||
var affected_rect : Rect2i
|
|
||||||
result_into_mask.create(image.get_size())
|
|
||||||
if fill_contiguous:
|
|
||||||
affected_rect = flood_fill(image, result_into_mask, start_pos, tolerance, selection)
|
|
||||||
|
|
||||||
else:
|
|
||||||
affected_rect = global_fill(image, result_into_mask, start_pos, tolerance)
|
|
||||||
|
|
||||||
return affected_rect
|
|
||||||
|
|
||||||
|
|
||||||
static func flood_fill(
|
|
||||||
image : Image,
|
|
||||||
result_into_mask : BitMap,
|
|
||||||
start_pos : Vector2i,
|
|
||||||
tolerance : float = 0.0,
|
|
||||||
selection : BitMap = null
|
|
||||||
) -> Rect2i:
|
|
||||||
var start_color = image.get_pixelv(start_pos)
|
|
||||||
var affected_rect = Rect2i(start_pos, Vector2.ZERO)
|
|
||||||
var q = [start_pos]
|
|
||||||
while q.size() > 0:
|
|
||||||
var x = q.pop_front()
|
|
||||||
result_into_mask.set_bitv(x, true)
|
|
||||||
for pos in [x + Vector2i.RIGHT, x + Vector2i.DOWN, x + Vector2i.LEFT, x + Vector2i.UP]:
|
|
||||||
if (
|
|
||||||
is_out_of_bounds(pos, image.get_size())
|
|
||||||
|| result_into_mask.get_bitv(pos)
|
|
||||||
|| (selection != null && !selection.get_bitv(pos))
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if tolerance == 1.0 || get_color_distance_squared(start_color, image.get_pixelv(pos)) <= tolerance:
|
|
||||||
affected_rect = affected_rect.expand(pos)
|
|
||||||
result_into_mask.set_bitv(pos, true)
|
|
||||||
q.append(pos)
|
|
||||||
|
|
||||||
return affected_rect
|
|
||||||
|
|
||||||
|
|
||||||
static func global_fill(
|
|
||||||
image : Image,
|
|
||||||
result_into_mask : BitMap,
|
|
||||||
start_pos : Vector2i,
|
|
||||||
tolerance : float = 0.0
|
|
||||||
) -> Rect2i:
|
|
||||||
var start_color = image.get_pixelv(start_pos)
|
|
||||||
var affected_rect = Rect2i(start_pos, Vector2.ZERO)
|
|
||||||
for i in image.get_width():
|
|
||||||
for j in image.get_height():
|
|
||||||
if tolerance == 1.0 || get_color_distance_squared(start_color, image.get_pixel(i, j)) <= tolerance:
|
|
||||||
affected_rect = affected_rect.expand(Vector2i(i, j))
|
|
||||||
result_into_mask.set_bit(i, j, true)
|
|
||||||
|
|
||||||
return affected_rect
|
|
||||||
|
|
||||||
|
|
||||||
static func get_color_distance_squared(a : Color, b : Color) -> float:
|
|
||||||
if a.a + b.a == 0.0: return 0.0
|
|
||||||
return (
|
|
||||||
(a.r - b.r) * (a.r - b.r)
|
|
||||||
+ (a.g - b.g) * (a.g - b.g)
|
|
||||||
+ (a.b - b.b) * (a.b - b.b)
|
|
||||||
+ (a.a - b.a) * (a.a - b.a)
|
|
||||||
) * 0.33333
|
|
||||||
|
|
||||||
|
|
||||||
static func draw_bitmap(on_node : CanvasItem, bitmap : BitMap, color : Color, offset : Vector2 = Vector2(0, 0)):
|
|
||||||
var map_size = bitmap.get_size()
|
|
||||||
var draw_next = false
|
|
||||||
var rect_height = 0
|
|
||||||
var draw_pos : Vector2
|
|
||||||
for i in map_size.x:
|
|
||||||
for j in map_size.y:
|
|
||||||
if bitmap.get_bit(i, j) != draw_next || j == 0:
|
|
||||||
if rect_height >= 1 && draw_next:
|
|
||||||
draw_pos = Vector2(i, j - rect_height)
|
|
||||||
if j == 0:
|
|
||||||
draw_pos = Vector2(i - 1, map_size.y - rect_height)
|
|
||||||
|
|
||||||
on_node.draw_rect(Rect2(
|
|
||||||
draw_pos + offset,
|
|
||||||
Vector2(1, rect_height)
|
|
||||||
), color)
|
|
||||||
|
|
||||||
rect_height = 0
|
|
||||||
|
|
||||||
rect_height += 1
|
|
||||||
draw_next = bitmap.get_bit(i, j)
|
|
||||||
|
|
||||||
on_node.draw_rect(Rect2(
|
|
||||||
offset + Vector2(map_size.x - 1, map_size.y - rect_height),
|
|
||||||
Vector2(1, rect_height)
|
|
||||||
), color)
|
|
||||||
|
|
||||||
|
|
||||||
static func is_out_of_bounds(pos : Vector2i, rect_size : Vector2i) -> bool:
|
|
||||||
return (
|
|
||||||
pos.x < 0 || pos.y < 0
|
|
||||||
|| pos.x >= rect_size.x || pos.y >= rect_size.y
|
|
||||||
)
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends MarginContainer
|
|
||||||
|
|
||||||
signal color_changed(new_color, is_primary)
|
|
||||||
|
|
||||||
@export var workspace : NodePath
|
|
||||||
@export var picker_shortcut : Shortcut
|
|
||||||
|
|
||||||
@onready var color1_button = $Container/Box/Box/Box/Control/Color1
|
|
||||||
@onready var color2_button = $Container/Box/Box/Box/Control/Color2
|
|
||||||
@onready var palette = $Container/Box/Box/Palette
|
|
||||||
@onready var which_color_picked = $Container/Box/Box/WhichColor
|
|
||||||
@onready var color_picker_container = $Control/Picker
|
|
||||||
@onready var color_picker = $Control/Picker/Margins/Box/ColorPicker
|
|
||||||
@onready var color_picker_tool_button = $Container/Box/Box/Box/Control/Control.get_child(0)
|
|
||||||
|
|
||||||
var color1 := Color.WHITE
|
|
||||||
var color2 := Color.TRANSPARENT
|
|
||||||
|
|
||||||
var color_picker_primary := true
|
|
||||||
var color_picker_picking := false
|
|
||||||
var color_picker_picking_disable_with_click := false
|
|
||||||
var color_picker_pick_from_image := false
|
|
||||||
var screen_image : Image
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
if get_viewport() is SubViewport: return
|
|
||||||
|
|
||||||
hide()
|
|
||||||
size = Vector2.ZERO
|
|
||||||
show()
|
|
||||||
position = Vector2(0, get_parent().size.y - get_minimum_size().y)
|
|
||||||
|
|
||||||
set_picked_primary(true, false)
|
|
||||||
set_color(true, color1)
|
|
||||||
set_color(false, color2)
|
|
||||||
_on_visibility_changed()
|
|
||||||
_yoink_color_picker_tool_button()
|
|
||||||
hide()
|
|
||||||
show()
|
|
||||||
color_picker_container.hide()
|
|
||||||
color_picker_container.size = Vector2.ZERO
|
|
||||||
await get_tree().process_frame
|
|
||||||
color_picker_container.global_position = (
|
|
||||||
global_position
|
|
||||||
+ get_minimum_size()
|
|
||||||
+ Vector2(16, -color_picker_container.size.y)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func set_color(is_primary, color):
|
|
||||||
if is_primary:
|
|
||||||
color1 = color
|
|
||||||
color1_button.self_modulate = color
|
|
||||||
|
|
||||||
else:
|
|
||||||
color2 = color
|
|
||||||
color2_button.self_modulate = color
|
|
||||||
|
|
||||||
if color_picker_primary == is_primary:
|
|
||||||
color_picker.color = color
|
|
||||||
|
|
||||||
color_changed.emit(color, is_primary)
|
|
||||||
|
|
||||||
|
|
||||||
func set_picked_primary(is_primary, toggle_picker_shown = true):
|
|
||||||
if toggle_picker_shown:
|
|
||||||
color_picker_container.visible = !color_picker_container.visible
|
|
||||||
|
|
||||||
color_picker_primary = is_primary
|
|
||||||
color_picker.color = color1 if is_primary else color2
|
|
||||||
if !color_picker_container.visible:
|
|
||||||
which_color_picked.text = "Color"
|
|
||||||
|
|
||||||
elif is_primary:
|
|
||||||
which_color_picked.text = "Primary"
|
|
||||||
|
|
||||||
else:
|
|
||||||
which_color_picked.text = "Secondary"
|
|
||||||
|
|
||||||
|
|
||||||
func set_color_screen_picking(picking, hold):
|
|
||||||
color_picker_picking_disable_with_click = !hold
|
|
||||||
color_picker_picking = picking
|
|
||||||
get_node(workspace).input_disabled = picking
|
|
||||||
if picking:
|
|
||||||
screen_image = get_viewport().get_texture().get_image()
|
|
||||||
|
|
||||||
|
|
||||||
func _input(event):
|
|
||||||
if picker_shortcut.matches_event(event) && !event.is_echo():
|
|
||||||
# Only pick primary color (for consistent feel if picker not open)
|
|
||||||
set_color_screen_picking(event.is_pressed(), true)
|
|
||||||
return
|
|
||||||
|
|
||||||
if event is InputEventMouseButton && color_picker_picking:
|
|
||||||
if !event.pressed: return
|
|
||||||
if color_picker_picking_disable_with_click:
|
|
||||||
set_color_screen_picking(false, false)
|
|
||||||
|
|
||||||
if color_picker_pick_from_image:
|
|
||||||
var img_view = get_node(workspace).image_view
|
|
||||||
var imagespace_event = img_view.event_vp_to_image(event)
|
|
||||||
var color = get_node(workspace).edited_image.get_pixelv(imagespace_event.position)
|
|
||||||
set_color(event.button_index == MOUSE_BUTTON_LEFT, color)
|
|
||||||
|
|
||||||
else:
|
|
||||||
set_color(event.button_index == MOUSE_BUTTON_LEFT, screen_image.get_pixelv(event.position))
|
|
||||||
|
|
||||||
|
|
||||||
func _yoink_color_picker_tool_button():
|
|
||||||
var child = color_picker.get_child(1, true);
|
|
||||||
if child == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
for x in child.get_children(true):
|
|
||||||
if !x is Button:
|
|
||||||
continue
|
|
||||||
|
|
||||||
x.free()
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
func _on_color_picker_color_changed(color):
|
|
||||||
set_color(color_picker_primary, color)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_color_1_pressed():
|
|
||||||
set_picked_primary(true, !color_picker_container.visible || color_picker_primary)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_color_2_pressed():
|
|
||||||
set_picked_primary(false, !color_picker_container.visible || !color_picker_primary)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_swap_pressed():
|
|
||||||
var swap = color1
|
|
||||||
set_color(true, color2)
|
|
||||||
set_color(false, swap)
|
|
||||||
set_picked_primary(color_picker_primary, false)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_open_picker_toggled(button_pressed):
|
|
||||||
color_picker_container.visible = button_pressed
|
|
||||||
set_picked_primary(color_picker_primary)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_palette_toggled(button_pressed):
|
|
||||||
palette.visible = button_pressed
|
|
||||||
|
|
||||||
|
|
||||||
func _on_visibility_changed():
|
|
||||||
set_process_input(is_visible_in_tree())
|
|
||||||
|
|
||||||
|
|
||||||
func _on_picker_header_gui_input(event):
|
|
||||||
if event is InputEventMouseMotion:
|
|
||||||
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
|
|
||||||
color_picker_container.position += event.relative
|
|
||||||
|
|
||||||
|
|
||||||
func _on_color_pick_pressed():
|
|
||||||
set_color_screen_picking(!color_picker_picking, false)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_pick_from_image_toggled(button_pressed):
|
|
||||||
color_picker_pick_from_image = button_pressed
|
|
||||||
@@ -1,530 +0,0 @@
|
|||||||
[gd_scene load_steps=19 format=3 uid="uid://be21fmb246ubn"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/sprite_painter/src/floating/color_picker.gd" id="1_ae0lg"]
|
|
||||||
[ext_resource type="Script" path="res://addons/sprite_painter/editor_icon_button.gd" id="1_srmpw"]
|
|
||||||
|
|
||||||
[sub_resource type="InputEventKey" id="InputEventKey_l6hbd"]
|
|
||||||
resource_name = "Alt"
|
|
||||||
keycode = 4194328
|
|
||||||
|
|
||||||
[sub_resource type="InputEventKey" id="InputEventKey_wy4cg"]
|
|
||||||
resource_name = "I"
|
|
||||||
|
|
||||||
[sub_resource type="Shortcut" id="Shortcut_76p2c"]
|
|
||||||
events = [SubResource("InputEventKey_l6hbd"), SubResource("InputEventKey_wy4cg")]
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o2ioo"]
|
|
||||||
draw_center = false
|
|
||||||
border_width_left = 4
|
|
||||||
border_width_top = 4
|
|
||||||
border_width_right = 4
|
|
||||||
border_width_bottom = 4
|
|
||||||
corner_radius_top_left = 2
|
|
||||||
corner_radius_top_right = 2
|
|
||||||
corner_radius_bottom_right = 2
|
|
||||||
corner_radius_bottom_left = 2
|
|
||||||
shadow_color = Color(0.8, 0.8, 0.8, 1)
|
|
||||||
shadow_size = 4
|
|
||||||
anti_aliasing = false
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eeewi"]
|
|
||||||
bg_color = Color(1, 1, 1, 1)
|
|
||||||
border_width_left = 2
|
|
||||||
border_width_top = 2
|
|
||||||
border_width_right = 2
|
|
||||||
border_width_bottom = 2
|
|
||||||
border_color = Color(0.6, 0.6, 0.6, 1)
|
|
||||||
corner_radius_top_left = 4
|
|
||||||
corner_radius_top_right = 4
|
|
||||||
corner_radius_bottom_right = 4
|
|
||||||
corner_radius_bottom_left = 4
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_70jsv"]
|
|
||||||
bg_color = Color(1, 1, 1, 1)
|
|
||||||
border_width_left = 2
|
|
||||||
border_width_top = 2
|
|
||||||
border_width_right = 2
|
|
||||||
border_width_bottom = 2
|
|
||||||
border_color = Color(1.5, 1.5, 1.5, 1)
|
|
||||||
corner_radius_top_left = 4
|
|
||||||
corner_radius_top_right = 4
|
|
||||||
corner_radius_bottom_right = 4
|
|
||||||
corner_radius_bottom_left = 4
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_gjl5v"]
|
|
||||||
border_width_left = 2
|
|
||||||
border_width_top = 2
|
|
||||||
border_width_right = 2
|
|
||||||
border_width_bottom = 2
|
|
||||||
border_color = Color(0.6, 0.6, 0.6, 1)
|
|
||||||
corner_radius_top_left = 4
|
|
||||||
corner_radius_top_right = 4
|
|
||||||
corner_radius_bottom_right = 4
|
|
||||||
corner_radius_bottom_left = 4
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_cicb3"]
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5mbmh"]
|
|
||||||
bg_color = Color(1, 1, 1, 1)
|
|
||||||
draw_center = false
|
|
||||||
border_width_left = 2
|
|
||||||
border_width_top = 2
|
|
||||||
border_width_right = 2
|
|
||||||
border_width_bottom = 2
|
|
||||||
border_color = Color(0.6, 0.6, 0.6, 1)
|
|
||||||
corner_radius_top_left = 4
|
|
||||||
corner_radius_top_right = 4
|
|
||||||
corner_radius_bottom_right = 4
|
|
||||||
corner_radius_bottom_left = 4
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_qpcds"]
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_xa6r5"]
|
|
||||||
content_margin_left = 5.0
|
|
||||||
content_margin_top = 3.0
|
|
||||||
content_margin_right = 5.0
|
|
||||||
content_margin_bottom = 3.0
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_fjbou"]
|
|
||||||
|
|
||||||
[sub_resource type="InputEventKey" id="InputEventKey_0j7g6"]
|
|
||||||
keycode = 88
|
|
||||||
|
|
||||||
[sub_resource type="Shortcut" id="Shortcut_8hnrs"]
|
|
||||||
resource_name = "X"
|
|
||||||
events = [SubResource("InputEventKey_0j7g6")]
|
|
||||||
|
|
||||||
[sub_resource type="Image" id="Image_670mm"]
|
|
||||||
data = {
|
|
||||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 93, 93, 55, 255, 97, 97, 58, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 98, 98, 47, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 94, 94, 46, 255, 93, 93, 236, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
|
||||||
"format": "RGBA8",
|
|
||||||
"height": 16,
|
|
||||||
"mipmaps": false,
|
|
||||||
"width": 16
|
|
||||||
}
|
|
||||||
|
|
||||||
[sub_resource type="ImageTexture" id="ImageTexture_qaodq"]
|
|
||||||
image = SubResource("Image_670mm")
|
|
||||||
|
|
||||||
[node name="ColorSettings" type="MarginContainer"]
|
|
||||||
anchors_preset = 2
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_top = -110.0
|
|
||||||
offset_right = 80.0
|
|
||||||
grow_vertical = 0
|
|
||||||
mouse_filter = 0
|
|
||||||
script = ExtResource("1_ae0lg")
|
|
||||||
picker_shortcut = SubResource("Shortcut_76p2c")
|
|
||||||
|
|
||||||
[node name="Panel2" type="Panel" parent="."]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
theme_override_styles/panel = SubResource("StyleBoxFlat_o2ioo")
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Panel3" type="Panel" parent="."]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Container" type="MarginContainer" parent="."]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/margin_left = 8
|
|
||||||
theme_override_constants/margin_top = 8
|
|
||||||
theme_override_constants/margin_right = 8
|
|
||||||
theme_override_constants/margin_bottom = 8
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Box" type="HBoxContainer" parent="Container"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Box" type="VBoxContainer" parent="Container/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
alignment = 2
|
|
||||||
|
|
||||||
[node name="WhichColor" type="Label" parent="Container/Box/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Color"
|
|
||||||
|
|
||||||
[node name="Box" type="HBoxContainer" parent="Container/Box/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Control" type="Control" parent="Container/Box/Box/Box"]
|
|
||||||
custom_minimum_size = Vector2(64, 64)
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Color2" type="Button" parent="Container/Box/Box/Box/Control"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 3
|
|
||||||
anchor_left = 1.0
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = -37.0
|
|
||||||
offset_top = -37.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
grow_vertical = 0
|
|
||||||
tooltip_text = "(Right Click)
|
|
||||||
Secondary Color
|
|
||||||
|
|
||||||
Click to open the Color Picker."
|
|
||||||
theme_override_styles/normal = SubResource("StyleBoxFlat_eeewi")
|
|
||||||
theme_override_styles/hover = SubResource("StyleBoxFlat_70jsv")
|
|
||||||
theme_override_styles/pressed = SubResource("StyleBoxFlat_gjl5v")
|
|
||||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_cicb3")
|
|
||||||
|
|
||||||
[node name="Frame" type="Button" parent="Container/Box/Box/Box/Control/Color2"]
|
|
||||||
show_behind_parent = true
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
mouse_filter = 2
|
|
||||||
theme_override_styles/normal = SubResource("StyleBoxFlat_5mbmh")
|
|
||||||
theme_override_styles/hover = SubResource("StyleBoxFlat_5mbmh")
|
|
||||||
theme_override_styles/pressed = SubResource("StyleBoxFlat_5mbmh")
|
|
||||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_qpcds")
|
|
||||||
|
|
||||||
[node name="Color1" type="Button" parent="Container/Box/Box/Box/Control"]
|
|
||||||
self_modulate = Color(0.498039, 0.498039, 0.498039, 1)
|
|
||||||
layout_mode = 0
|
|
||||||
offset_right = 37.0
|
|
||||||
offset_bottom = 37.0
|
|
||||||
tooltip_text = "(Left Click)
|
|
||||||
Primary Color
|
|
||||||
|
|
||||||
Click to open the Color Picker."
|
|
||||||
theme_override_styles/normal = SubResource("StyleBoxFlat_eeewi")
|
|
||||||
theme_override_styles/hover = SubResource("StyleBoxFlat_70jsv")
|
|
||||||
theme_override_styles/pressed = SubResource("StyleBoxFlat_gjl5v")
|
|
||||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_cicb3")
|
|
||||||
|
|
||||||
[node name="Frame2" type="Button" parent="Container/Box/Box/Box/Control/Color1"]
|
|
||||||
show_behind_parent = true
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
mouse_filter = 2
|
|
||||||
theme_override_styles/normal = SubResource("StyleBoxFlat_5mbmh")
|
|
||||||
theme_override_styles/hover = SubResource("StyleBoxFlat_5mbmh")
|
|
||||||
theme_override_styles/pressed = SubResource("StyleBoxFlat_5mbmh")
|
|
||||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_qpcds")
|
|
||||||
|
|
||||||
[node name="Control2" type="CenterContainer" parent="Container/Box/Box/Box/Control"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = 38.0
|
|
||||||
offset_bottom = -37.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
||||||
[node name="Swap" type="Button" parent="Container/Box/Box/Box/Control/Control2"]
|
|
||||||
layout_mode = 2
|
|
||||||
tooltip_text = "(X)
|
|
||||||
Swap Primary/Secondary Colors
|
|
||||||
|
|
||||||
The Screen Color Picker (Alt) will always change the Primary (Left Mouse Button) color."
|
|
||||||
theme_override_styles/normal = SubResource("StyleBoxEmpty_xa6r5")
|
|
||||||
theme_override_styles/hover = SubResource("StyleBoxEmpty_xa6r5")
|
|
||||||
theme_override_styles/pressed = SubResource("StyleBoxEmpty_xa6r5")
|
|
||||||
theme_override_styles/disabled = SubResource("StyleBoxEmpty_xa6r5")
|
|
||||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_fjbou")
|
|
||||||
shortcut = SubResource("Shortcut_8hnrs")
|
|
||||||
shortcut_in_tooltip = false
|
|
||||||
icon = SubResource("ImageTexture_qaodq")
|
|
||||||
flat = true
|
|
||||||
icon_alignment = 1
|
|
||||||
script = ExtResource("1_srmpw")
|
|
||||||
icon_name = "Loop"
|
|
||||||
|
|
||||||
[node name="Control" type="CenterContainer" parent="Container/Box/Box/Box/Control"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_top = 38.0
|
|
||||||
offset_right = -38.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
||||||
[node name="Pick" type="Button" parent="Container/Box/Box/Box/Control/Control"]
|
|
||||||
layout_mode = 2
|
|
||||||
tooltip_text = "(Alt)
|
|
||||||
Color Sampler
|
|
||||||
|
|
||||||
Can pick color from the editor screen, or the image. Change this in the Color Picker accessed by clicking a color here."
|
|
||||||
theme_override_styles/normal = SubResource("StyleBoxEmpty_xa6r5")
|
|
||||||
theme_override_styles/hover = SubResource("StyleBoxEmpty_xa6r5")
|
|
||||||
theme_override_styles/pressed = SubResource("StyleBoxEmpty_xa6r5")
|
|
||||||
theme_override_styles/disabled = SubResource("StyleBoxEmpty_xa6r5")
|
|
||||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_fjbou")
|
|
||||||
icon = SubResource("ImageTexture_qaodq")
|
|
||||||
flat = true
|
|
||||||
icon_alignment = 1
|
|
||||||
script = ExtResource("1_srmpw")
|
|
||||||
icon_name = "ColorPick"
|
|
||||||
|
|
||||||
[node name="Palette" type="VBoxContainer" parent="Container/Box/Box"]
|
|
||||||
visible = false
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
|
|
||||||
[node name="Box" type="HBoxContainer" parent="Container/Box/Box/Palette"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="Container/Box/Box/Palette/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
text = "Palette"
|
|
||||||
|
|
||||||
[node name="FromImage" type="Button" parent="Container/Box/Box/Palette/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
tooltip_text = "Get from image / selection"
|
|
||||||
icon = SubResource("ImageTexture_qaodq")
|
|
||||||
script = ExtResource("1_srmpw")
|
|
||||||
icon_name = "CanvasLayer"
|
|
||||||
|
|
||||||
[node name="Palette" type="VFlowContainer" parent="Container/Box/Box/Palette"]
|
|
||||||
custom_minimum_size = Vector2(0, 96)
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="ColorRect" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect2" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect3" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect4" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect5" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect6" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect7" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect8" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect9" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect10" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect11" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect12" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect27" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect21" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect22" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect23" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect24" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect25" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect26" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect13" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect14" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect15" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect16" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect17" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect18" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect19" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ColorRect20" type="ColorRect" parent="Container/Box/Box/Palette/Palette"]
|
|
||||||
custom_minimum_size = Vector2(16, 16)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="Palette2" type="Button" parent="Container/Box/Box"]
|
|
||||||
visible = false
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
toggle_mode = true
|
|
||||||
icon = SubResource("ImageTexture_qaodq")
|
|
||||||
icon_alignment = 1
|
|
||||||
script = ExtResource("1_srmpw")
|
|
||||||
icon_name = "Grid"
|
|
||||||
|
|
||||||
[node name="Control" type="Control" parent="."]
|
|
||||||
layout_mode = 2
|
|
||||||
mouse_filter = 2
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Picker" type="MarginContainer" parent="Control"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 3
|
|
||||||
anchor_left = 1.0
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = 2.0
|
|
||||||
offset_top = -40.0
|
|
||||||
offset_right = 308.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
grow_vertical = 0
|
|
||||||
metadata/_edit_group_ = true
|
|
||||||
|
|
||||||
[node name="Panel4" type="Panel" parent="Control/Picker"]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
theme_override_styles/panel = SubResource("StyleBoxFlat_o2ioo")
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Panel5" type="Panel" parent="Control/Picker"]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Margins" type="MarginContainer" parent="Control/Picker"]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/margin_left = 8
|
|
||||||
theme_override_constants/margin_top = 8
|
|
||||||
theme_override_constants/margin_right = 8
|
|
||||||
theme_override_constants/margin_bottom = 8
|
|
||||||
|
|
||||||
[node name="Box" type="VBoxContainer" parent="Control/Picker/Margins"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Header" type="HBoxContainer" parent="Control/Picker/Margins/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Button" type="Button" parent="Control/Picker/Margins/Box/Header"]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
disabled = true
|
|
||||||
icon = SubResource("ImageTexture_qaodq")
|
|
||||||
icon_alignment = 1
|
|
||||||
script = ExtResource("1_srmpw")
|
|
||||||
icon_name = "ToolMove"
|
|
||||||
|
|
||||||
[node name="Button2" type="Button" parent="Control/Picker/Margins/Box/Header"]
|
|
||||||
layout_mode = 2
|
|
||||||
tooltip_text = "Toggle color picking from image
|
|
||||||
|
|
||||||
If off, the Picker Tool (Alt) will pick the color from the editor's viewport."
|
|
||||||
toggle_mode = true
|
|
||||||
icon = SubResource("ImageTexture_qaodq")
|
|
||||||
script = ExtResource("1_srmpw")
|
|
||||||
icon_name = "SubViewport"
|
|
||||||
|
|
||||||
[node name="Button3" type="Button" parent="Control/Picker/Margins/Box/Header"]
|
|
||||||
layout_mode = 2
|
|
||||||
icon = SubResource("ImageTexture_qaodq")
|
|
||||||
script = ExtResource("1_srmpw")
|
|
||||||
icon_name = "Close"
|
|
||||||
|
|
||||||
[node name="ColorPicker" type="ColorPicker" parent="Control/Picker/Margins/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
color = Color(0.498039, 0.498039, 0.498039, 1)
|
|
||||||
color_mode = 1
|
|
||||||
sampler_visible = false
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
|
|
||||||
[connection signal="pressed" from="Container/Box/Box/Box/Control/Color2" to="." method="_on_color_2_pressed"]
|
|
||||||
[connection signal="pressed" from="Container/Box/Box/Box/Control/Color2/Frame" to="." method="_on_color_2_pressed"]
|
|
||||||
[connection signal="pressed" from="Container/Box/Box/Box/Control/Color1" to="." method="_on_color_1_pressed"]
|
|
||||||
[connection signal="pressed" from="Container/Box/Box/Box/Control/Color1/Frame2" to="." method="_on_color_2_pressed"]
|
|
||||||
[connection signal="pressed" from="Container/Box/Box/Box/Control/Control2/Swap" to="." method="_on_swap_pressed"]
|
|
||||||
[connection signal="pressed" from="Container/Box/Box/Box/Control/Control/Pick" to="." method="_on_color_pick_pressed"]
|
|
||||||
[connection signal="toggled" from="Container/Box/Box/Palette2" to="." method="_on_palette_toggled"]
|
|
||||||
[connection signal="gui_input" from="Control/Picker/Margins/Box/Header/Button" to="." method="_on_picker_header_gui_input"]
|
|
||||||
[connection signal="toggled" from="Control/Picker/Margins/Box/Header/Button2" to="." method="_on_pick_from_image_toggled"]
|
|
||||||
[connection signal="pressed" from="Control/Picker/Margins/Box/Header/Button3" to="Control/Picker" method="hide"]
|
|
||||||
[connection signal="color_changed" from="Control/Picker/Margins/Box/ColorPicker" to="." method="_on_color_picker_color_changed"]
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends Control
|
|
||||||
|
|
||||||
signal tool_changed(tool_node)
|
|
||||||
|
|
||||||
@export var toolbar : NodePath
|
|
||||||
@export var toolbar_end : NodePath
|
|
||||||
@export var image_view : NodePath
|
|
||||||
|
|
||||||
var by_button := {}
|
|
||||||
var by_shortcut := {}
|
|
||||||
|
|
||||||
var current_tool : Control
|
|
||||||
var current_tool_shortcut_list := []
|
|
||||||
var current_color1 := Color.WHITE
|
|
||||||
var current_color2 := Color.WHITE
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
if get_viewport() is SubViewport: return
|
|
||||||
|
|
||||||
var end_at = get_node(toolbar_end)
|
|
||||||
for x in get_node(toolbar).get_children():
|
|
||||||
if x == end_at: break
|
|
||||||
if !x is BaseButton: continue
|
|
||||||
_setup_tool_button(x)
|
|
||||||
|
|
||||||
|
|
||||||
func _setup_tool_button(button : BaseButton):
|
|
||||||
var tool_node = get_node_or_null(NodePath(button.name))
|
|
||||||
by_button[button] = tool_node
|
|
||||||
button.disabled = false
|
|
||||||
if tool_node == null:
|
|
||||||
button.disabled = true
|
|
||||||
return
|
|
||||||
|
|
||||||
if button.shortcut != null:
|
|
||||||
var buttons_with_sc = by_shortcut.get(button.shortcut, [])
|
|
||||||
buttons_with_sc.append(button)
|
|
||||||
button.pressed.connect(_on_button_shortcut_pressed.bind(
|
|
||||||
button,
|
|
||||||
buttons_with_sc
|
|
||||||
))
|
|
||||||
if buttons_with_sc.size() >= 2:
|
|
||||||
button.set_deferred("shortcut", null)
|
|
||||||
|
|
||||||
by_shortcut[button.shortcut] = buttons_with_sc
|
|
||||||
if current_tool == null:
|
|
||||||
_on_button_shortcut_pressed(button, buttons_with_sc)
|
|
||||||
|
|
||||||
button.tooltip_text = "%s (%s)" % [
|
|
||||||
tool_node.tool_name,
|
|
||||||
(button.shortcut.get_as_text() + " + ")\
|
|
||||||
.repeat(by_shortcut[button.shortcut].size())\
|
|
||||||
.trim_suffix(" + "),
|
|
||||||
]
|
|
||||||
tool_node.hide()
|
|
||||||
button.toggled.connect(_on_tool_button_toggled.bind(tool_node))
|
|
||||||
if current_tool == null:
|
|
||||||
_on_tool_button_toggled(true, tool_node)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_button_shortcut_pressed(button : BaseButton, list : Array):
|
|
||||||
if button.shortcut == null: return
|
|
||||||
|
|
||||||
var pressed_in_list = list.find(button)
|
|
||||||
if current_tool_shortcut_list != list:
|
|
||||||
# Next time the shortcut is pressed, it will select the first from the list
|
|
||||||
if current_tool_shortcut_list.size() > 1:
|
|
||||||
var sc
|
|
||||||
for x in current_tool_shortcut_list:
|
|
||||||
if x.shortcut != null:
|
|
||||||
sc = x.shortcut
|
|
||||||
x.shortcut = null
|
|
||||||
|
|
||||||
current_tool_shortcut_list[0].shortcut = sc
|
|
||||||
|
|
||||||
list[(pressed_in_list + 1) % list.size()].shortcut = button.shortcut
|
|
||||||
if list.size() > 1:
|
|
||||||
button.shortcut = null
|
|
||||||
|
|
||||||
current_tool_shortcut_list = list
|
|
||||||
|
|
||||||
|
|
||||||
func _on_tool_button_toggled(toggled : bool, tool_node : EditingTool):
|
|
||||||
if !toggled: return
|
|
||||||
|
|
||||||
if current_tool != null:
|
|
||||||
current_tool.hide()
|
|
||||||
|
|
||||||
tool_node.show()
|
|
||||||
current_tool = tool_node
|
|
||||||
|
|
||||||
get_node(image_view).self_modulate.a = 1.0 if tool_node.image_hide_mode != 2 else 0.0
|
|
||||||
tool_changed.emit(tool_node)
|
|
||||||
|
|
||||||
|
|
||||||
func handle_image_input(event, image, selection) -> bool:
|
|
||||||
if current_tool == null: return false
|
|
||||||
if event is InputEventMouseMotion:
|
|
||||||
current_tool.selection = selection # Needed because Image Script tool does not normally use clicks
|
|
||||||
# I better just fetch it from the Workspace but also ehhhh incapsulation
|
|
||||||
current_tool.mouse_moved(event)
|
|
||||||
return true
|
|
||||||
|
|
||||||
elif event is InputEventMouseButton:
|
|
||||||
current_tool.selection = selection
|
|
||||||
current_tool.mouse_pressed(
|
|
||||||
event,
|
|
||||||
image,
|
|
||||||
current_color1 if event.button_index == MOUSE_BUTTON_LEFT else current_color2,
|
|
||||||
current_color1 if event.button_index != MOUSE_BUTTON_LEFT else current_color2
|
|
||||||
)
|
|
||||||
if current_tool.image_hide_mode != 2:
|
|
||||||
get_node(image_view).self_modulate.a = 1.0
|
|
||||||
|
|
||||||
if event.pressed && current_tool.image_hide_mode == 1:
|
|
||||||
get_node(image_view).self_modulate.a = 0.0
|
|
||||||
|
|
||||||
return true
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
func get_affected_rect() -> Rect2i:
|
|
||||||
return current_tool.get_affected_rect()
|
|
||||||
|
|
||||||
|
|
||||||
func draw_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
if current_tool == null: return
|
|
||||||
current_tool.draw_preview(image_view, mouse_position)
|
|
||||||
|
|
||||||
|
|
||||||
func draw_shader_preview(image_view : CanvasItem, mouse_position : Vector2i):
|
|
||||||
if current_tool == null: return
|
|
||||||
image_view.material = current_tool.preview_shader
|
|
||||||
current_tool.draw_shader_preview(image_view, mouse_position)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_color_settings_color_changed(new_color, is_primary):
|
|
||||||
if is_primary:
|
|
||||||
current_color1 = new_color
|
|
||||||
|
|
||||||
else:
|
|
||||||
current_color2 = new_color
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export var label : NodePath
|
|
||||||
@export var frame_data_textbox : NodePath
|
|
||||||
|
|
||||||
var plugin_root
|
|
||||||
var editor_dock
|
|
||||||
var anim_list
|
|
||||||
var frame_list
|
|
||||||
|
|
||||||
var edited_object
|
|
||||||
var current_anim
|
|
||||||
var current_frame
|
|
||||||
|
|
||||||
|
|
||||||
func connect_plugin(plugin_root_node):
|
|
||||||
plugin_root = plugin_root_node
|
|
||||||
|
|
||||||
|
|
||||||
func try_edit(object):
|
|
||||||
get_node(label).hide()
|
|
||||||
get_node(frame_data_textbox).hide()
|
|
||||||
if object is AnimatedSprite2D || object is AnimatedSprite3D:
|
|
||||||
try_edit(object.frames)
|
|
||||||
return
|
|
||||||
|
|
||||||
if object is SpriteFrames:
|
|
||||||
edited_object = object
|
|
||||||
call_deferred("update_spriteframes")
|
|
||||||
|
|
||||||
|
|
||||||
func try_connect_bottom_dock(dock : Control):
|
|
||||||
if dock.get_class() == "SpriteFramesEditor":
|
|
||||||
editor_dock = dock
|
|
||||||
anim_list = dock.get_child(0).get_child(1).get_child(0).get_child(1)
|
|
||||||
anim_list\
|
|
||||||
.item_selected.connect(_on_anim_selected)
|
|
||||||
frame_list = dock.get_child(1).get_child(1).get_child(0).get_child(1)
|
|
||||||
frame_list\
|
|
||||||
.item_clicked.connect(_on_frame_selected)
|
|
||||||
|
|
||||||
|
|
||||||
func update_spriteframes():
|
|
||||||
current_anim = anim_list.get_selected().get_text(0)
|
|
||||||
current_frame = frame_list.get_selected_items()[0]
|
|
||||||
get_node(label).show()
|
|
||||||
get_node(frame_data_textbox).show()
|
|
||||||
get_node(frame_data_textbox).text = "%s : frame %s" % [current_anim, current_frame]
|
|
||||||
|
|
||||||
var frame_tex = edited_object.get_frame(current_anim, current_frame)
|
|
||||||
if frame_tex is AtlasTexture:
|
|
||||||
plugin_root.edit_subresource(
|
|
||||||
frame_tex.atlas.resource_path,
|
|
||||||
frame_tex.region.size,
|
|
||||||
frame_tex.region.position,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
plugin_root.edit_file(frame_tex.resource_path)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_frame_selected(index, at_pos, mouse_button_index):
|
|
||||||
update_spriteframes()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_anim_selected():
|
|
||||||
update_spriteframes()
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
var plugin_root
|
|
||||||
var editor_dock
|
|
||||||
var source_list
|
|
||||||
|
|
||||||
var edited_object
|
|
||||||
|
|
||||||
|
|
||||||
func connect_plugin(plugin_root_node):
|
|
||||||
plugin_root = plugin_root_node
|
|
||||||
|
|
||||||
|
|
||||||
func try_edit(object):
|
|
||||||
if object is TileMap:
|
|
||||||
try_edit(object)
|
|
||||||
return
|
|
||||||
|
|
||||||
if object is TileSet:
|
|
||||||
edited_object = object
|
|
||||||
call_deferred("update_tileset")
|
|
||||||
|
|
||||||
|
|
||||||
func try_connect_bottom_dock(dock : Control):
|
|
||||||
if dock.get_class() == "TileSetEditor":
|
|
||||||
editor_dock = dock
|
|
||||||
source_list = dock.get_child(1).get_child(0).get_child(0)
|
|
||||||
source_list\
|
|
||||||
.item_clicked.connect(_on_source_selected)
|
|
||||||
|
|
||||||
|
|
||||||
func update_tileset():
|
|
||||||
var selected_id = source_list.get_selected_items()[0]
|
|
||||||
var sauce = edited_object.get_source(selected_id)
|
|
||||||
if !(sauce is TileSetAtlasSource):
|
|
||||||
return
|
|
||||||
|
|
||||||
plugin_root.edit_subresource(
|
|
||||||
sauce.get_texture().resource_path,
|
|
||||||
sauce.texture_region_size + sauce.separation,
|
|
||||||
sauce.margins,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_source_selected(index, at_pos, mouse_button_index):
|
|
||||||
update_tileset()
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends MarginContainer
|
|
||||||
|
|
||||||
@onready var type_handlers = $"TypeHandlers".get_children()
|
|
||||||
@onready var cursor_pos_info = $"Container/Box/CursorPos"
|
|
||||||
|
|
||||||
var editor_plugin : EditorPlugin
|
|
||||||
var plugin_root : Node
|
|
||||||
|
|
||||||
var input_start := Vector2()
|
|
||||||
var input_end := Vector2()
|
|
||||||
var input_pressed := false
|
|
||||||
|
|
||||||
var edited_object : Object
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
hide()
|
|
||||||
readjust_size()
|
|
||||||
show()
|
|
||||||
|
|
||||||
plugin_root = self
|
|
||||||
while !plugin_root is Window:
|
|
||||||
plugin_root = plugin_root.get_parent()
|
|
||||||
if !plugin_root is SpritePainterRoot:
|
|
||||||
continue
|
|
||||||
|
|
||||||
editor_plugin = plugin_root.editor_plugin
|
|
||||||
plugin_root.object_selected.connect(_on_plugin_object_selected)
|
|
||||||
for x in type_handlers:
|
|
||||||
x.connect_plugin(plugin_root)
|
|
||||||
break
|
|
||||||
|
|
||||||
var c = Control.new()
|
|
||||||
editor_plugin.add_control_to_bottom_panel(c, "AAA")
|
|
||||||
|
|
||||||
for x in c.get_parent().get_children():
|
|
||||||
for y in type_handlers:
|
|
||||||
y.try_connect_bottom_dock(x)
|
|
||||||
|
|
||||||
editor_plugin.remove_control_from_bottom_panel(c)
|
|
||||||
_on_plugin_object_selected(plugin_root.edited_object)
|
|
||||||
|
|
||||||
|
|
||||||
func handle_image_input(event):
|
|
||||||
if event is InputEventMouseMotion:
|
|
||||||
if input_pressed:
|
|
||||||
input_end = event.position.floor()
|
|
||||||
|
|
||||||
else:
|
|
||||||
input_start = event.position.floor()
|
|
||||||
|
|
||||||
elif event is InputEventMouseButton:
|
|
||||||
input_pressed = event.pressed
|
|
||||||
input_end = event.position.floor()
|
|
||||||
|
|
||||||
if input_pressed:
|
|
||||||
cursor_pos_info.text = "Cursor: %s -> %s (size %s)" % [
|
|
||||||
input_start,
|
|
||||||
input_end,
|
|
||||||
(input_end - input_start).abs() + Vector2.ONE
|
|
||||||
]
|
|
||||||
|
|
||||||
else:
|
|
||||||
cursor_pos_info.text = "Cursor: %s" % input_start
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
func _on_plugin_object_selected(obj):
|
|
||||||
if obj == null: return
|
|
||||||
for x in type_handlers:
|
|
||||||
x.try_edit(obj)
|
|
||||||
|
|
||||||
edited_object = obj
|
|
||||||
readjust_size()
|
|
||||||
|
|
||||||
|
|
||||||
func readjust_size():
|
|
||||||
size = Vector2.ZERO
|
|
||||||
position = Vector2(get_parent().size) - get_minimum_size() #get_parent().size can be a Vector2i
|
|
||||||
|
|
||||||
|
|
||||||
func _on_visibility_changed():
|
|
||||||
pass
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
[gd_scene load_steps=6 format=3 uid="uid://dcc6kewvuomhc"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/sprite_painter/src/floating/type_context_settings.gd" id="1_7q6dr"]
|
|
||||||
[ext_resource type="Script" path="res://addons/sprite_painter/editor_icon_button.gd" id="2_l84pr"]
|
|
||||||
[ext_resource type="Script" path="res://addons/sprite_painter/src/floating/type_context/context_spriteframes.gd" id="3_jtsht"]
|
|
||||||
[ext_resource type="Script" path="res://addons/sprite_painter/src/floating/type_context/context_tileset.gd" id="4_mhrcf"]
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o2ioo"]
|
|
||||||
draw_center = false
|
|
||||||
border_width_left = 4
|
|
||||||
border_width_top = 4
|
|
||||||
border_width_right = 4
|
|
||||||
border_width_bottom = 4
|
|
||||||
corner_radius_top_left = 2
|
|
||||||
corner_radius_top_right = 2
|
|
||||||
corner_radius_bottom_right = 2
|
|
||||||
corner_radius_bottom_left = 2
|
|
||||||
shadow_color = Color(0.8, 0.8, 0.8, 1)
|
|
||||||
shadow_size = 4
|
|
||||||
anti_aliasing = false
|
|
||||||
|
|
||||||
[node name="ContextSettings" type="MarginContainer"]
|
|
||||||
anchors_preset = 3
|
|
||||||
anchor_left = 1.0
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = -647.0
|
|
||||||
offset_top = -363.0
|
|
||||||
offset_right = -331.0
|
|
||||||
offset_bottom = -312.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
grow_vertical = 0
|
|
||||||
mouse_filter = 0
|
|
||||||
script = ExtResource("1_7q6dr")
|
|
||||||
|
|
||||||
[node name="Panel2" type="Panel" parent="."]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
theme_override_styles/panel = SubResource("StyleBoxFlat_o2ioo")
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Panel3" type="Panel" parent="."]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Container" type="MarginContainer" parent="."]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/margin_left = 8
|
|
||||||
theme_override_constants/margin_top = 8
|
|
||||||
theme_override_constants/margin_right = 8
|
|
||||||
theme_override_constants/margin_bottom = 8
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Box" type="VBoxContainer" parent="Container"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Grid" type="GridContainer" parent="Container/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
columns = 2
|
|
||||||
|
|
||||||
[node name="Anim" type="Label" parent="Container/Box/Grid"]
|
|
||||||
visible = false
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Animation"
|
|
||||||
|
|
||||||
[node name="FrameData" type="LineEdit" parent="Container/Box/Grid"]
|
|
||||||
visible = false
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
text = "Idle, Frame 8"
|
|
||||||
editable = false
|
|
||||||
expand_to_text_length = true
|
|
||||||
|
|
||||||
[node name="Label2" type="Label" parent="Container/Box/Grid"]
|
|
||||||
visible = false
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Helpers"
|
|
||||||
|
|
||||||
[node name="Box" type="HBoxContainer" parent="Container/Box/Grid"]
|
|
||||||
visible = false
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
||||||
[node name="ThemeIconButton" type="Button" parent="Container/Box/Grid/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
script = ExtResource("2_l84pr")
|
|
||||||
icon_name = "GuiVisibilityVisible"
|
|
||||||
|
|
||||||
[node name="Button" type="Button" parent="Container/Box/Grid/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
text = "Edit"
|
|
||||||
|
|
||||||
[node name="CursorPos" type="LineEdit" parent="Container/Box"]
|
|
||||||
custom_minimum_size = Vector2(300, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Cursor: (0, 0) -> (0, 0) (size (0, 0))"
|
|
||||||
editable = false
|
|
||||||
expand_to_text_length = true
|
|
||||||
|
|
||||||
[node name="Control" type="Control" parent="."]
|
|
||||||
layout_mode = 2
|
|
||||||
mouse_filter = 2
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Extra" type="MarginContainer" parent="Control"]
|
|
||||||
visible = false
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 3
|
|
||||||
anchor_left = 1.0
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = -704.0
|
|
||||||
offset_top = -143.0
|
|
||||||
offset_right = -398.0
|
|
||||||
offset_bottom = -103.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
grow_vertical = 0
|
|
||||||
metadata/_edit_group_ = true
|
|
||||||
|
|
||||||
[node name="Panel4" type="Panel" parent="Control/Extra"]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
theme_override_styles/panel = SubResource("StyleBoxFlat_o2ioo")
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Panel5" type="Panel" parent="Control/Extra"]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Margins" type="MarginContainer" parent="Control/Extra"]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/margin_left = 8
|
|
||||||
theme_override_constants/margin_top = 8
|
|
||||||
theme_override_constants/margin_right = 8
|
|
||||||
theme_override_constants/margin_bottom = 8
|
|
||||||
|
|
||||||
[node name="Box" type="VBoxContainer" parent="Control/Extra/Margins"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Header" type="HBoxContainer" parent="Control/Extra/Margins/Box"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Button" type="Button" parent="Control/Extra/Margins/Box/Header"]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
disabled = true
|
|
||||||
icon_alignment = 1
|
|
||||||
script = ExtResource("2_l84pr")
|
|
||||||
icon_name = "ToolMove"
|
|
||||||
|
|
||||||
[node name="Button2" type="Button" parent="Control/Extra/Margins/Box/Header"]
|
|
||||||
layout_mode = 2
|
|
||||||
script = ExtResource("2_l84pr")
|
|
||||||
icon_name = "Close"
|
|
||||||
|
|
||||||
[node name="TypeHandlers" type="Node" parent="."]
|
|
||||||
|
|
||||||
[node name="Spriteframes" type="Node" parent="TypeHandlers"]
|
|
||||||
script = ExtResource("3_jtsht")
|
|
||||||
label = NodePath("../../Container/Box/Grid/Anim")
|
|
||||||
frame_data_textbox = NodePath("../../Container/Box/Grid/FrameData")
|
|
||||||
|
|
||||||
[node name="Tileset" type="Node" parent="TypeHandlers"]
|
|
||||||
script = ExtResource("4_mhrcf")
|
|
||||||
|
|
||||||
[connection signal="gui_input" from="Control/Extra/Margins/Box/Header/Button" to="." method="_on_picker_header_gui_input"]
|
|
||||||
[connection signal="pressed" from="Control/Extra/Margins/Box/Header/Button2" to="Control/Extra" method="hide"]
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
class_name ImageScript
|
|
||||||
extends RefCounted
|
|
||||||
|
|
||||||
## Base class for scripts that process images through Sprite painter.
|
|
||||||
##
|
|
||||||
## Extend this script and add the new file to `res://addons/sprite_painter/image_scripts/`
|
|
||||||
## to make it usable in Sprite Painter.
|
|
||||||
|
|
||||||
enum {
|
|
||||||
SCRIPT_PARAM_BOOL, ## Checkbox property. No hints.
|
|
||||||
SCRIPT_PARAM_INT, ## Integer number property. Hints: [MINVALUE, MAXVALUE]
|
|
||||||
SCRIPT_PARAM_FLOAT, ## Floating-point number property. Hints: [MINVALUE, MAXVALUE]
|
|
||||||
SCRIPT_PARAM_ENUM, ## Enumeration property. Hint is an array of names for the created OptionButton.
|
|
||||||
SCRIPT_PARAM_ICON_ENUM, ## Enumeration property. Hint is an dictionary of {ICON : TOOLTIP} pairs. ICON can be a theme icon name or a loaded Texture.
|
|
||||||
SCRIPT_PARAM_ICON_FLAGS, ## Array of Bools property. Hint is an dictionary of {ICON : TOOLTIP} pairs. ICON can be a theme icon or a loaded Texture.
|
|
||||||
SCRIPT_PARAM_RESOURCE, ## Resource property. Hint is the base type of accepted Resources.
|
|
||||||
SCRIPT_PARAM_FILE, ## Resource property. Allows choosing a file from a folder set in a hint.
|
|
||||||
SCRIPT_PARAM_COLOR, ## Color property. No hints.
|
|
||||||
}
|
|
||||||
|
|
||||||
var _params = {}
|
|
||||||
|
|
||||||
## Returns a parameter set through the GUI.
|
|
||||||
##
|
|
||||||
## Key must be same as passed in `_get_param_list()`.
|
|
||||||
func get_param(key : String) -> Variant:
|
|
||||||
return _params[key]
|
|
||||||
|
|
||||||
## Called when the script is loaded: when switching scripts, opening an image, or resetting parameters.
|
|
||||||
func _ready(image : Image):
|
|
||||||
pass
|
|
||||||
|
|
||||||
## Called to preview or apply the script. Must return the result, which can be the same image object.
|
|
||||||
func _get_image(new_image : Image, selection : BitMap) -> Image:
|
|
||||||
return new_image
|
|
||||||
|
|
||||||
## Must return a list of parameters. Each parameter contains:
|
|
||||||
##
|
|
||||||
## - Name
|
|
||||||
##
|
|
||||||
## - Type
|
|
||||||
##
|
|
||||||
## - Default
|
|
||||||
##
|
|
||||||
## - Type Hint, for which refer to ImageScript's class.
|
|
||||||
func _get_param_list():
|
|
||||||
return [
|
|
||||||
[
|
|
||||||
"_get_param_list() Not overriden!",
|
|
||||||
SCRIPT_PARAM_ENUM,
|
|
||||||
0,
|
|
||||||
["Refer to the ImageScript class for more info."]
|
|
||||||
],
|
|
||||||
]
|
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends MenuButton
|
|
||||||
|
|
||||||
enum {
|
|
||||||
OPTION_ROTATE_CW,
|
|
||||||
OPTION_ROTATE_CCW,
|
|
||||||
OPTION_FLIP_H,
|
|
||||||
OPTION_FLIP_V,
|
|
||||||
OPTION_CROP,
|
|
||||||
OPTION_BORDER,
|
|
||||||
OPTION_RESIZE,
|
|
||||||
}
|
|
||||||
|
|
||||||
@export var workspace : NodePath
|
|
||||||
|
|
||||||
@onready var width_edit = $"Dialog/Grid/Width"
|
|
||||||
@onready var height_edit = $"Dialog/Grid/Height"
|
|
||||||
|
|
||||||
var original_size := Vector2i()
|
|
||||||
var expand_dir := Vector2i()
|
|
||||||
var percent_view := false
|
|
||||||
var stretch := false
|
|
||||||
var interp := 0
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
var dir_buttons = $"Dialog/Grid/Box/Grid".get_children()
|
|
||||||
$"Dialog/Grid/Box/Stretch".pressed.connect(_on_stretch_pressed)
|
|
||||||
for i in 9:
|
|
||||||
dir_buttons[i].pressed.connect(func():
|
|
||||||
_on_anchor_dir_pressed(Vector2i(1 - i % 3, 1 - i / 3))
|
|
||||||
)
|
|
||||||
|
|
||||||
var p = get_popup()
|
|
||||||
p.id_pressed.connect(_on_id_pressed)
|
|
||||||
p.hide_on_item_selection = false
|
|
||||||
|
|
||||||
if !get_viewport() is Window: return
|
|
||||||
p.set_item_icon(OPTION_ROTATE_CW, get_theme_icon("RotateRight", "EditorIcons"))
|
|
||||||
p.set_item_icon(OPTION_ROTATE_CCW, get_theme_icon("RotateLeft", "EditorIcons"))
|
|
||||||
p.set_item_icon(OPTION_FLIP_H, get_theme_icon("MoveRight", "EditorIcons"))
|
|
||||||
p.set_item_icon(OPTION_FLIP_V, get_theme_icon("MoveDown", "EditorIcons"))
|
|
||||||
# One of them is not real.
|
|
||||||
# p.set_item_icon(OPTION_FLIP_H, get_theme_icon("Hsize", "EditorIcons"))
|
|
||||||
# p.set_item_icon(OPTION_FLIP_V, get_theme_icon("VSize", "EditorIcons"))
|
|
||||||
p.set_item_icon(OPTION_CROP + 1, get_theme_icon("MeshTexture", "EditorIcons"))
|
|
||||||
p.set_item_icon(OPTION_BORDER + 1, get_theme_icon("ToolMove", "EditorIcons"))
|
|
||||||
p.set_item_icon(OPTION_RESIZE + 1, get_theme_icon("DistractionFree", "EditorIcons"))
|
|
||||||
|
|
||||||
|
|
||||||
func _on_id_pressed(id):
|
|
||||||
var old_image = get_node(workspace).edited_image
|
|
||||||
original_size = old_image.get_size()
|
|
||||||
if id == OPTION_CROP:
|
|
||||||
crop(old_image, get_node(workspace).edited_image_selection)
|
|
||||||
return
|
|
||||||
|
|
||||||
elif id == OPTION_RESIZE:
|
|
||||||
$"Dialog".popup_centered()
|
|
||||||
update_entered_size(original_size)
|
|
||||||
return
|
|
||||||
|
|
||||||
elif id == OPTION_BORDER:
|
|
||||||
var new_image = get_node(workspace).get_resized(
|
|
||||||
old_image,
|
|
||||||
original_size + Vector2i(2, 2),
|
|
||||||
Vector2i(0, 0),
|
|
||||||
-1
|
|
||||||
)
|
|
||||||
|
|
||||||
submit_changed_image(new_image)
|
|
||||||
return
|
|
||||||
|
|
||||||
var new_image = Image.create(original_size.x, original_size.y, false, old_image.get_format())
|
|
||||||
new_image.blit_rect(old_image, Rect2(Vector2i.ZERO, original_size), Vector2i.ZERO)
|
|
||||||
match id:
|
|
||||||
OPTION_ROTATE_CW:
|
|
||||||
new_image.rotate_90(CLOCKWISE)
|
|
||||||
|
|
||||||
OPTION_ROTATE_CCW:
|
|
||||||
new_image.rotate_90(COUNTERCLOCKWISE)
|
|
||||||
|
|
||||||
OPTION_FLIP_H:
|
|
||||||
new_image.flip_x()
|
|
||||||
|
|
||||||
OPTION_FLIP_V:
|
|
||||||
new_image.flip_y()
|
|
||||||
|
|
||||||
submit_changed_image(new_image)
|
|
||||||
|
|
||||||
|
|
||||||
func crop(old_image, selection):
|
|
||||||
var result_rect = Rect2i(0, 0, 0, 0)
|
|
||||||
var found_start = false
|
|
||||||
original_size = old_image.get_size()
|
|
||||||
var sel_bits = selection.get_true_bit_count()
|
|
||||||
var crop_selection = sel_bits > 2 && sel_bits < original_size.x * original_size.y
|
|
||||||
for i in original_size.x:
|
|
||||||
for j in original_size.y:
|
|
||||||
if crop_selection:
|
|
||||||
if !selection.get_bit(i, j):
|
|
||||||
continue
|
|
||||||
|
|
||||||
elif old_image.get_pixel(i, j).a < 0.02:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if !found_start:
|
|
||||||
found_start = true
|
|
||||||
result_rect.position = Vector2i(i, j)
|
|
||||||
|
|
||||||
else:
|
|
||||||
result_rect = result_rect.expand(Vector2i(i, j))
|
|
||||||
|
|
||||||
result_rect.size += Vector2i.ONE
|
|
||||||
if result_rect.size == Vector2i.ONE:
|
|
||||||
return
|
|
||||||
|
|
||||||
var new_image = Image.create(
|
|
||||||
result_rect.size.x,
|
|
||||||
result_rect.size.y,
|
|
||||||
false,
|
|
||||||
old_image.get_format()
|
|
||||||
)
|
|
||||||
new_image.blit_rect(old_image, result_rect, Vector2i.ZERO)
|
|
||||||
submit_changed_image(new_image)
|
|
||||||
|
|
||||||
|
|
||||||
func get_entered_size():
|
|
||||||
if percent_view:
|
|
||||||
return Vector2i(
|
|
||||||
original_size.x * width_edit.value * 0.01,
|
|
||||||
original_size.y * height_edit.value * 0.01
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
return Vector2i(
|
|
||||||
width_edit.value,
|
|
||||||
height_edit.value
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func update_entered_size(new_size):
|
|
||||||
if percent_view:
|
|
||||||
width_edit.prefix = ""
|
|
||||||
width_edit.value = new_size.x * 100.0 / original_size.x
|
|
||||||
width_edit.suffix = "%"
|
|
||||||
width_edit.step = 0.01
|
|
||||||
|
|
||||||
height_edit.prefix = ""
|
|
||||||
height_edit.value = new_size.y * 100.0 / original_size.y
|
|
||||||
height_edit.suffix = "%"
|
|
||||||
height_edit.step = 0.01
|
|
||||||
|
|
||||||
else:
|
|
||||||
width_edit.prefix = str(original_size.x) + " -> "
|
|
||||||
width_edit.value = new_size.x
|
|
||||||
width_edit.suffix = "px"
|
|
||||||
width_edit.step = 1
|
|
||||||
|
|
||||||
height_edit.prefix = str(original_size.y) + " -> "
|
|
||||||
height_edit.value = new_size.y
|
|
||||||
height_edit.suffix = "px"
|
|
||||||
height_edit.step = 1
|
|
||||||
|
|
||||||
|
|
||||||
func submit_changed_image(new_image):
|
|
||||||
var ws = get_node(workspace)
|
|
||||||
ws.image_replaced.emit(ws.edited_image, new_image)
|
|
||||||
ws.update_texture(new_image)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_dialog_confirmed():
|
|
||||||
var ws = get_node(workspace)
|
|
||||||
var new_image = ws.get_resized(
|
|
||||||
ws.edited_image,
|
|
||||||
get_entered_size(),
|
|
||||||
expand_dir,
|
|
||||||
interp if stretch else -1
|
|
||||||
)
|
|
||||||
|
|
||||||
submit_changed_image(new_image)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_anchor_dir_pressed(direction):
|
|
||||||
$"Dialog/Grid/Interpolation".disabled = true
|
|
||||||
stretch = false
|
|
||||||
expand_dir = direction
|
|
||||||
|
|
||||||
|
|
||||||
func _on_stretch_pressed():
|
|
||||||
$"Dialog/Grid/Interpolation".disabled = false
|
|
||||||
stretch = true
|
|
||||||
|
|
||||||
|
|
||||||
func _on_interpolation_item_selected(index):
|
|
||||||
interp = index
|
|
||||||
|
|
||||||
|
|
||||||
func _on_percent_toggled(v):
|
|
||||||
var old_entered_size = get_entered_size()
|
|
||||||
percent_view = v
|
|
||||||
update_entered_size(old_entered_size)
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends Node2D
|
|
||||||
|
|
||||||
@export var grid_color := Color.WHITE
|
|
||||||
@export var grid_line_width := 1.0
|
|
||||||
@export var region_color := Color.WHITE
|
|
||||||
@export var region_line_width := 1.0
|
|
||||||
@export var region_outer_color := Color.BLACK
|
|
||||||
|
|
||||||
var image_size := Vector2i()
|
|
||||||
var grid_size := Vector2i()
|
|
||||||
var grid_offset := Vector2i()
|
|
||||||
var is_region := false
|
|
||||||
|
|
||||||
|
|
||||||
func _draw():
|
|
||||||
if grid_size == Vector2i.ZERO: return
|
|
||||||
if is_region:
|
|
||||||
draw_rect(Rect2(
|
|
||||||
Vector2.ZERO,
|
|
||||||
Vector2(image_size.x, grid_offset.y)
|
|
||||||
), region_outer_color)
|
|
||||||
draw_rect(Rect2(
|
|
||||||
Vector2(0, grid_offset.y),
|
|
||||||
Vector2(grid_offset.x, grid_size.y)
|
|
||||||
), region_outer_color)
|
|
||||||
draw_rect(Rect2(
|
|
||||||
Vector2(grid_offset.x + grid_size.x, grid_offset.y),
|
|
||||||
Vector2(image_size.x - grid_offset.x - grid_size.x, grid_size.y)
|
|
||||||
), region_outer_color)
|
|
||||||
draw_rect(Rect2(
|
|
||||||
Vector2(0, grid_offset.y + grid_size.y),
|
|
||||||
Vector2(image_size.x, image_size.y - grid_offset.y - grid_size.y)
|
|
||||||
), region_outer_color)
|
|
||||||
|
|
||||||
draw_rect(Rect2(
|
|
||||||
grid_offset + Vector2i(-region_line_width, -region_line_width),
|
|
||||||
Vector2(grid_size.x + region_line_width * 2, region_line_width)
|
|
||||||
), region_color)
|
|
||||||
draw_rect(Rect2(
|
|
||||||
grid_offset + Vector2i(-region_line_width, 0),
|
|
||||||
Vector2(region_line_width, grid_size.y)
|
|
||||||
), region_color)
|
|
||||||
draw_rect(Rect2(
|
|
||||||
grid_offset + Vector2i(grid_size.x, 0),
|
|
||||||
Vector2(region_line_width, grid_size.y)
|
|
||||||
), region_color)
|
|
||||||
draw_rect(Rect2(
|
|
||||||
grid_offset + Vector2i(-region_line_width, grid_size.y),
|
|
||||||
Vector2(grid_size.x + region_line_width * 2, region_line_width)
|
|
||||||
), region_color)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
var lines = []
|
|
||||||
var line_count = Vector2i(
|
|
||||||
float(image_size.x - grid_offset.x % grid_size.x) / grid_size.x,
|
|
||||||
float(image_size.y - grid_offset.y % grid_size.y) / grid_size.y
|
|
||||||
)
|
|
||||||
lines.resize(line_count.x * 2)
|
|
||||||
for i in line_count.x:
|
|
||||||
lines[i * 2] = Vector2((i + 1) * grid_size.x + grid_offset.x, 0)
|
|
||||||
lines[i * 2 + 1] = lines[i * 2] + Vector2(0, image_size.y)
|
|
||||||
|
|
||||||
draw_multiline(lines, grid_color, grid_line_width)
|
|
||||||
|
|
||||||
lines.resize(line_count.y * 2)
|
|
||||||
for i in line_count.y:
|
|
||||||
lines[i * 2] = Vector2(0, (i + 1) * grid_size.y + grid_offset.y)
|
|
||||||
lines[i * 2 + 1] = lines[i * 2] + Vector2(image_size.x, 0)
|
|
||||||
|
|
||||||
draw_multiline(lines, grid_color, grid_line_width)
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends Node2D
|
|
||||||
|
|
||||||
@export var selection_color := Color(0.5, 0.5, 0.5, 0.5)
|
|
||||||
|
|
||||||
var selection : BitMap
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
get_node("../../..").image_changed.connect(_on_image_changed)
|
|
||||||
_on_visibility_changed()
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta):
|
|
||||||
if Engine.get_process_frames() % 10 != 0: return
|
|
||||||
self_modulate.a = abs(1.0 - fmod(Time.get_ticks_msec() * 0.0005, 2.0))
|
|
||||||
|
|
||||||
|
|
||||||
func _draw():
|
|
||||||
if selection == null: return
|
|
||||||
var sel_size = selection.get_size()
|
|
||||||
if selection.get_true_bit_count() == sel_size.x * sel_size.y:
|
|
||||||
return
|
|
||||||
|
|
||||||
ImageFillTools.draw_bitmap(self, selection, selection_color)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_visibility_changed():
|
|
||||||
if !get_viewport() is Window:
|
|
||||||
set_process(false)
|
|
||||||
self_modulate.a = 0.75
|
|
||||||
return
|
|
||||||
|
|
||||||
set_process(is_visible_in_tree())
|
|
||||||
|
|
||||||
|
|
||||||
func _on_image_changed(image, rect_changed):
|
|
||||||
if selection != null:
|
|
||||||
queue_redraw()
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends Sprite2D
|
|
||||||
|
|
||||||
@export var draw_handler : NodePath
|
|
||||||
@export var draw_method := "draw_preview"
|
|
||||||
|
|
||||||
var mouse_pos : Vector2
|
|
||||||
|
|
||||||
|
|
||||||
func _draw():
|
|
||||||
get_node(draw_handler).call(draw_method, self, mouse_pos)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_tool_switcher_tool_changed(tool_node):
|
|
||||||
texture = null
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends Sprite2D
|
|
||||||
|
|
||||||
@export var draw_handler : NodePath
|
|
||||||
|
|
||||||
@onready var border_rect = $"../ImageBorder"
|
|
||||||
@onready var resize_result = $"../ResizeResult"
|
|
||||||
@onready var preview = $"ToolView"
|
|
||||||
@onready var preview_shader = $"SubViewport/ShaderView"
|
|
||||||
@onready var resize_rect = border_rect.get_node("Resize")
|
|
||||||
|
|
||||||
var camera_pos := Vector2.ZERO
|
|
||||||
var mouse_pos := Vector2.ZERO
|
|
||||||
|
|
||||||
|
|
||||||
func zoom(by : Vector2):
|
|
||||||
scale *= by
|
|
||||||
camera_pos *= by
|
|
||||||
update_position()
|
|
||||||
|
|
||||||
|
|
||||||
func translate(by : Vector2):
|
|
||||||
camera_pos += by
|
|
||||||
update_position()
|
|
||||||
|
|
||||||
|
|
||||||
func update_position():
|
|
||||||
update_position_local()
|
|
||||||
resize_rect.rect_scale = global_scale
|
|
||||||
$"SubViewport".size = texture.get_size()
|
|
||||||
|
|
||||||
|
|
||||||
func reset_position():
|
|
||||||
camera_pos = Vector2.ZERO
|
|
||||||
scale = Vector2.ONE
|
|
||||||
update_position()
|
|
||||||
|
|
||||||
|
|
||||||
func update_position_local():
|
|
||||||
position = get_parent().size * 0.5 + camera_pos - texture.get_size() * 0.5
|
|
||||||
centered = false
|
|
||||||
update_texture_view_rect()
|
|
||||||
|
|
||||||
|
|
||||||
func update_position_overlay(edited_node):
|
|
||||||
position = edited_node.global_position - edited_node.get_viewport().get_visible_rect().position
|
|
||||||
centered = false
|
|
||||||
scale = edited_node.global_scale if edited_node is Node2D else edited_node.scale
|
|
||||||
# TODO: fetch source's actual on-screen position.
|
|
||||||
update_texture_view_rect()
|
|
||||||
|
|
||||||
|
|
||||||
func update_texture_view_rect():
|
|
||||||
border_rect.size = scale * (texture.get_size() if texture != null else Vector2.ZERO)
|
|
||||||
border_rect.position = position
|
|
||||||
if centered:
|
|
||||||
border_rect.position -= border_rect.size * 0.5
|
|
||||||
|
|
||||||
|
|
||||||
func _on_resize_preview_changed(current_delta, expand_direction):
|
|
||||||
resize_result.hide()
|
|
||||||
|
|
||||||
var old_size = texture.get_size()
|
|
||||||
var delta_one_axis = round(current_delta.x if expand_direction.x != 0 else current_delta.y)
|
|
||||||
var old_size_one_axis = old_size.x if expand_direction.x != 0 else old_size.y
|
|
||||||
resize_result.text = "%s%spx (%.1f%s)\n-> %s\n" % [
|
|
||||||
"+" if delta_one_axis >= 0.5 else "",
|
|
||||||
delta_one_axis,
|
|
||||||
(1.0 + delta_one_axis / float(old_size_one_axis)) * 100,
|
|
||||||
"%",
|
|
||||||
(old_size + current_delta).round(),
|
|
||||||
]
|
|
||||||
|
|
||||||
resize_result.visible = expand_direction != Vector2i(0, 0)
|
|
||||||
resize_result.global_position = get_global_mouse_position() - resize_result.size * 0.5
|
|
||||||
|
|
||||||
|
|
||||||
func event_vp_to_image(from_event : InputEventMouse, unsafe : bool = false) -> InputEventMouse:
|
|
||||||
if !unsafe:
|
|
||||||
from_event = from_event.duplicate()
|
|
||||||
|
|
||||||
from_event.position = (from_event.position - global_position) / scale
|
|
||||||
if from_event is InputEventMouseMotion:
|
|
||||||
from_event.relative /= scale
|
|
||||||
|
|
||||||
preview.mouse_pos = from_event.position
|
|
||||||
preview.show()
|
|
||||||
preview.queue_redraw()
|
|
||||||
preview_shader.mouse_pos = from_event.position
|
|
||||||
preview_shader.show()
|
|
||||||
preview_shader.queue_redraw()
|
|
||||||
return from_event
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends Control
|
|
||||||
|
|
||||||
signal preview_changed(current_delta, expand_direction)
|
|
||||||
signal value_changed(delta, expand_direction)
|
|
||||||
|
|
||||||
@export var delta_color := Color(1.0, 0.25, 0.0, 0.75)
|
|
||||||
@export var sensitivity := 1.0
|
|
||||||
|
|
||||||
var dragging := false
|
|
||||||
var size_delta := Vector2()
|
|
||||||
var rect_scale := Vector2.ONE
|
|
||||||
var resize_direction := Vector2()
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
$"X-".gui_input.connect(_on_child_gui_input.bind(Vector2.LEFT))
|
|
||||||
$"X+".gui_input.connect(_on_child_gui_input.bind(Vector2.RIGHT))
|
|
||||||
$"Y-".gui_input.connect(_on_child_gui_input.bind(Vector2.UP))
|
|
||||||
$"Y+".gui_input.connect(_on_child_gui_input.bind(Vector2.DOWN))
|
|
||||||
|
|
||||||
|
|
||||||
func _draw():
|
|
||||||
var anchor = (resize_direction + Vector2.ONE) * 0.5
|
|
||||||
|
|
||||||
draw_rect(Rect2(size * anchor.floor(), (
|
|
||||||
Vector2(resize_direction.x * round(size_delta.x) * rect_scale.x, size.y)
|
|
||||||
if size_delta.x != 0.0 else
|
|
||||||
Vector2(size.x, resize_direction.y * round(size_delta.y) * rect_scale.y)
|
|
||||||
)), delta_color)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_child_gui_input(event, direction):
|
|
||||||
if event is InputEventMouseMotion:
|
|
||||||
if !dragging: return
|
|
||||||
size_delta += event.relative * direction * sensitivity / rect_scale
|
|
||||||
preview_changed.emit(size_delta, Vector2i(direction))
|
|
||||||
|
|
||||||
if event is InputEventMouseButton && event.button_index == MOUSE_BUTTON_LEFT:
|
|
||||||
dragging = event.pressed
|
|
||||||
resize_direction = direction
|
|
||||||
if !event.pressed:
|
|
||||||
value_changed.emit(size_delta, Vector2i(direction))
|
|
||||||
preview_changed.emit(Vector2.ZERO, Vector2i.ZERO)
|
|
||||||
size_delta = Vector2.ZERO
|
|
||||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
|
||||||
|
|
||||||
else:
|
|
||||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
|
||||||
|
|
||||||
queue_redraw()
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
[gd_scene load_steps=3 format=3]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/sprite_painter/src/image_view/resize_rect.gd" id="1_eudu3"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://c7nymhfcdr3hl" path="res://addons/sprite_painter/graphics/diags.png" id="1_v44m5"]
|
|
||||||
|
|
||||||
[node name="Resize" type="Control"]
|
|
||||||
layout_mode = 3
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
mouse_filter = 2
|
|
||||||
script = ExtResource("1_eudu3")
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="X-" type="TextureRect" parent="."]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 4
|
|
||||||
anchor_top = 0.5
|
|
||||||
anchor_bottom = 0.5
|
|
||||||
offset_left = -48.0
|
|
||||||
offset_top = -16.0
|
|
||||||
offset_right = -16.0
|
|
||||||
offset_bottom = 16.0
|
|
||||||
grow_vertical = 2
|
|
||||||
mouse_filter = 0
|
|
||||||
mouse_default_cursor_shape = 10
|
|
||||||
texture = ExtResource("1_v44m5")
|
|
||||||
ignore_texture_size = true
|
|
||||||
stretch_mode = 1
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="X+" type="TextureRect" parent="."]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 6
|
|
||||||
anchor_left = 1.0
|
|
||||||
anchor_top = 0.5
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 0.5
|
|
||||||
offset_left = 16.0
|
|
||||||
offset_top = -16.0
|
|
||||||
offset_right = 48.0
|
|
||||||
offset_bottom = 16.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
grow_vertical = 2
|
|
||||||
mouse_filter = 0
|
|
||||||
mouse_default_cursor_shape = 10
|
|
||||||
texture = ExtResource("1_v44m5")
|
|
||||||
ignore_texture_size = true
|
|
||||||
stretch_mode = 1
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Y-" type="TextureRect" parent="."]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 5
|
|
||||||
anchor_left = 0.5
|
|
||||||
anchor_right = 0.5
|
|
||||||
offset_left = -16.0
|
|
||||||
offset_top = -48.0
|
|
||||||
offset_right = 16.0
|
|
||||||
offset_bottom = -16.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
mouse_filter = 0
|
|
||||||
mouse_default_cursor_shape = 9
|
|
||||||
texture = ExtResource("1_v44m5")
|
|
||||||
ignore_texture_size = true
|
|
||||||
stretch_mode = 1
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
|
|
||||||
[node name="Y+" type="TextureRect" parent="."]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 7
|
|
||||||
anchor_left = 0.5
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_right = 0.5
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = -16.0
|
|
||||||
offset_top = 16.0
|
|
||||||
offset_right = 16.0
|
|
||||||
offset_bottom = 48.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 0
|
|
||||||
mouse_filter = 0
|
|
||||||
mouse_default_cursor_shape = 9
|
|
||||||
texture = ExtResource("1_v44m5")
|
|
||||||
ignore_texture_size = true
|
|
||||||
stretch_mode = 1
|
|
||||||
metadata/_edit_lock_ = true
|
|
||||||
@@ -1,204 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name SpritePainterRoot
|
|
||||||
extends Control
|
|
||||||
|
|
||||||
signal object_selected(object)
|
|
||||||
|
|
||||||
@onready var workspace = $"%Workspace"
|
|
||||||
|
|
||||||
var editor_interface : EditorInterface
|
|
||||||
var editor_plugin : EditorPlugin
|
|
||||||
var editor_2d_vp : Control
|
|
||||||
var editor_3d_vp : Control
|
|
||||||
|
|
||||||
var viewport_ignored := true
|
|
||||||
var edited_object : Object
|
|
||||||
var unsaved_image_paths : Array[String] = []
|
|
||||||
var undo_redo : EditorUndoRedoManager
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
workspace.pre_image_changed.connect(_on_workspace_pre_image_changed)
|
|
||||||
workspace.image_changed.connect(_on_workspace_image_changed)
|
|
||||||
workspace.image_replaced.connect(_on_workspace_image_replaced)
|
|
||||||
|
|
||||||
# var plugin_undoredo = editor_plugin.get_undo_redo()
|
|
||||||
# var own_history_id = plugin_undoredo.get_object_history_id(self)
|
|
||||||
# undo_redo = plugin_undoredo.get_history_undo_redo(own_history_id)
|
|
||||||
# undo_redo = editor_plugin.get_undo_redo()
|
|
||||||
|
|
||||||
|
|
||||||
func edit_object(obj : Object):
|
|
||||||
if obj is Node:
|
|
||||||
edit_node(obj)
|
|
||||||
edited_object = obj
|
|
||||||
object_selected.emit(obj)
|
|
||||||
|
|
||||||
elif obj is CompressedTexture2D:
|
|
||||||
edit_file(obj.resource_path)
|
|
||||||
edited_object = obj
|
|
||||||
object_selected.emit(obj)
|
|
||||||
|
|
||||||
elif obj is AtlasTexture:
|
|
||||||
var region = obj.region
|
|
||||||
edit_subresource(obj.atlas.resource_path, region.size, region.position, true)
|
|
||||||
edited_object = obj
|
|
||||||
object_selected.emit(obj)
|
|
||||||
|
|
||||||
else:
|
|
||||||
object_selected.emit(obj)
|
|
||||||
|
|
||||||
|
|
||||||
func edit_node(node : Node):
|
|
||||||
if node == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
mouse_filter = MOUSE_FILTER_STOP if viewport_ignored else MOUSE_FILTER_IGNORE
|
|
||||||
if "texture" in node:
|
|
||||||
call_deferred("edit_subresource", node.texture.resource_path)
|
|
||||||
|
|
||||||
|
|
||||||
func edit_subresource(
|
|
||||||
filepath : String,
|
|
||||||
grid_size : Vector2i = Vector2i.ZERO,
|
|
||||||
grid_offset : Vector2i = Vector2i.ZERO,
|
|
||||||
is_region : bool = false
|
|
||||||
):
|
|
||||||
if unsaved_image_paths.find(StringName(filepath)) == -1:
|
|
||||||
unsaved_image_paths.append(StringName(filepath))
|
|
||||||
|
|
||||||
if !is_visible_in_tree(): return
|
|
||||||
|
|
||||||
workspace.edit_texture(filepath)
|
|
||||||
if edited_object is Sprite2D || edited_object is Sprite3D:
|
|
||||||
update_grid_from_sprite(edited_object)
|
|
||||||
|
|
||||||
else:
|
|
||||||
workspace.set_view_grid(grid_size, grid_offset, is_region)
|
|
||||||
|
|
||||||
|
|
||||||
func update_grid_from_sprite(node : CanvasItem):
|
|
||||||
var tex_size = Vector2(node.texture.get_size())
|
|
||||||
var frame_size = tex_size / Vector2(node.hframes, node.vframes)
|
|
||||||
var region_offset = Vector2i.ZERO
|
|
||||||
if node.region_enabled:
|
|
||||||
frame_size = node.region_rect.size
|
|
||||||
region_offset = node.region_rect.position
|
|
||||||
|
|
||||||
workspace.set_view_grid(frame_size, region_offset, node.region_enabled)
|
|
||||||
|
|
||||||
|
|
||||||
func edit_file(filepath : String):
|
|
||||||
unsaved_image_paths.append(filepath)
|
|
||||||
workspace.edit_texture(filepath)
|
|
||||||
workspace.set_view_grid(Vector2i.ZERO, Vector2i.ZERO, false)
|
|
||||||
|
|
||||||
|
|
||||||
func _gui_input(event):
|
|
||||||
handle_input(event)
|
|
||||||
|
|
||||||
|
|
||||||
func handle_input(event):
|
|
||||||
return workspace.handle_input(event)
|
|
||||||
|
|
||||||
|
|
||||||
static func print_hierarchy(root : Node, indent : String = ""):
|
|
||||||
for x in root.get_children(true):
|
|
||||||
print(x.name.indent(indent) + " : " + x.get_class())
|
|
||||||
print_hierarchy(x, indent + "- ")
|
|
||||||
|
|
||||||
|
|
||||||
static func save_scene(root : Node, filename = "saved_scn.tscn"):
|
|
||||||
for x in root.get_children(true):
|
|
||||||
pack_to_owner(root)
|
|
||||||
|
|
||||||
var packed = PackedScene.new()
|
|
||||||
packed.pack(root)
|
|
||||||
packed.resource_path = "res://" + filename
|
|
||||||
ResourceSaver.save(packed)
|
|
||||||
|
|
||||||
|
|
||||||
static func pack_to_owner(root : Node, keep_scene_nodes : bool = true, new_owner : Node = root):
|
|
||||||
for x in root.get_children(true):
|
|
||||||
# if keep_scene_nodes && root.file_path != "":
|
|
||||||
# new_owner = root
|
|
||||||
|
|
||||||
x.owner = new_owner
|
|
||||||
pack_to_owner(x, keep_scene_nodes, new_owner)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_close_pressed():
|
|
||||||
workspace.rollback_changes()
|
|
||||||
editor_plugin._on_enable_pressed()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_save_pressed():
|
|
||||||
editor_plugin._on_enable_pressed()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_workspace_pre_image_changed(image : Image, rect):
|
|
||||||
if rect.size.x == 0 || rect.size.y == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
undo_redo.create_action("Edit image (start: %s, end: %s)" % [rect.position, rect.end])
|
|
||||||
var saved_image = copy_image_rect(image, rect)
|
|
||||||
undo_redo.add_undo_method(self, "paste_image_rect", saved_image, image, rect.position)
|
|
||||||
# undo_redo.add_undo_method(func edit_undo():
|
|
||||||
# paste_image_rect(saved_image, image, rect.position)
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
func _on_workspace_image_changed(image : Image, rect):
|
|
||||||
if rect.size.x == 0 || rect.size.y == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
var saved_image = copy_image_rect(image, rect)
|
|
||||||
undo_redo.add_do_method(self, "paste_image_rect", saved_image, image, rect.position)
|
|
||||||
# undo_redo.add_do_method(func edit_do():
|
|
||||||
# paste_image_rect(saved_image, image, rect.position)
|
|
||||||
# )
|
|
||||||
undo_redo.commit_action()
|
|
||||||
|
|
||||||
|
|
||||||
func copy_image_rect(from, rect) -> Image:
|
|
||||||
var new_image = Image.create(rect.size.x, rect.size.y, false, from.get_format())
|
|
||||||
new_image.blit_rect(from, rect, Vector2.ZERO)
|
|
||||||
return new_image
|
|
||||||
|
|
||||||
|
|
||||||
func paste_image_rect(from, to, destination = Vector2.ZERO):
|
|
||||||
to.blit_rect(from, Rect2(Vector2.ZERO, from.get_size()), destination)
|
|
||||||
save_changes(to)
|
|
||||||
|
|
||||||
|
|
||||||
func save_changes(image = null):
|
|
||||||
if image == null:
|
|
||||||
image = workspace.edited_image
|
|
||||||
if image == null: return
|
|
||||||
|
|
||||||
var err = image.save_png(workspace.edited_image_path.get_basename() + ".png")
|
|
||||||
if err != OK: printerr(err)
|
|
||||||
workspace.update_texture(image)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_workspace_image_replaced(old_image, new_image):
|
|
||||||
undo_redo.create_action("Resize image (%s -> %s)" % [old_image.get_size(), new_image.get_size()])
|
|
||||||
undo_redo.add_undo_method(self, "save_changes",
|
|
||||||
copy_image_rect(old_image, Rect2i(Vector2i.ZERO, old_image.get_size()))
|
|
||||||
)
|
|
||||||
undo_redo.add_do_method(self, "save_changes",
|
|
||||||
copy_image_rect(new_image, Rect2i(Vector2i.ZERO, new_image.get_size()))
|
|
||||||
)
|
|
||||||
# undo_redo.add_undo_method(func edit_undo():
|
|
||||||
# workspace.edited_image = copy_image_rect(
|
|
||||||
# old_image,
|
|
||||||
# Rect2i(Vector2i.ZERO, old_image.get_size())
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
# undo_redo.add_do_method(func edit_do():
|
|
||||||
# workspace.edited_image = copy_image_rect(
|
|
||||||
# new_image,
|
|
||||||
# Rect2i(Vector2i.ZERO, new_image.get_size())
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
undo_redo.commit_action()
|
|
||||||
@@ -1,203 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends Control
|
|
||||||
|
|
||||||
signal pre_image_changed(image, rect_changed)
|
|
||||||
signal image_changed(image, rect_changed)
|
|
||||||
signal image_replaced(old_image, new_image)
|
|
||||||
|
|
||||||
@onready var image_view = $"%EditedImageView"
|
|
||||||
@onready var selection_view = $"%SelectionView"
|
|
||||||
@onready var grid_view = $"%GridView"
|
|
||||||
@onready var tool_manager = $"%ToolSwitcher"
|
|
||||||
@onready var context_settings = $"%ContextSettings"
|
|
||||||
|
|
||||||
var cur_scale := 1.0
|
|
||||||
var mouse_button := -1
|
|
||||||
var input_disabled := false
|
|
||||||
var dragging := false
|
|
||||||
var rollback_to_image : Image
|
|
||||||
var edited_image : Image
|
|
||||||
var edited_image_path : String
|
|
||||||
var edited_image_selection := BitMap.new()
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
if !get_viewport() is Window: return
|
|
||||||
|
|
||||||
# Recolor all floating panels to make buttons more visible
|
|
||||||
var style = get_theme_stylebox("panel", "Panel").duplicate()
|
|
||||||
style.bg_color = get_theme_color("base_color", "Editor")
|
|
||||||
theme = Theme.new()
|
|
||||||
theme.set_stylebox("panel", "Panel", style)
|
|
||||||
|
|
||||||
|
|
||||||
func handle_input(event) -> bool:
|
|
||||||
if input_disabled: return true
|
|
||||||
if event is InputEventMouseButton:
|
|
||||||
if event.button_index == MOUSE_BUTTON_RIGHT || event.button_index == MOUSE_BUTTON_LEFT:
|
|
||||||
if event.pressed:
|
|
||||||
dragging = true
|
|
||||||
mouse_button = event.button_index
|
|
||||||
return pass_event_to_tool(event)
|
|
||||||
|
|
||||||
elif mouse_button == event.button_index:
|
|
||||||
dragging = false
|
|
||||||
mouse_button = -1
|
|
||||||
var rect = tool_manager.get_affected_rect()
|
|
||||||
make_image_edit(func(): pass_event_to_tool(event), rect)
|
|
||||||
return true
|
|
||||||
|
|
||||||
if event.button_index == MOUSE_BUTTON_WHEEL_UP:
|
|
||||||
image_view.zoom(Vector2.ONE * 1.05)
|
|
||||||
return true
|
|
||||||
|
|
||||||
if event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
|
|
||||||
image_view.zoom(Vector2.ONE / 1.05)
|
|
||||||
return true
|
|
||||||
|
|
||||||
if event.button_index == MOUSE_BUTTON_MIDDLE:
|
|
||||||
return true
|
|
||||||
|
|
||||||
if event is InputEventMouseMotion:
|
|
||||||
if Input.is_mouse_button_pressed(MOUSE_BUTTON_MIDDLE) || Input.is_key_pressed(KEY_SPACE):
|
|
||||||
image_view.translate(event.relative)
|
|
||||||
|
|
||||||
grab_focus()
|
|
||||||
return pass_event_to_tool(event)
|
|
||||||
|
|
||||||
if event is InputEventKey:
|
|
||||||
var ctrl = (event.get_keycode_with_modifiers() & (KEY_MASK_CMD_OR_CTRL)) != 0
|
|
||||||
match event.keycode:
|
|
||||||
KEY_A, KEY_D:
|
|
||||||
if ctrl:
|
|
||||||
clear_selection()
|
|
||||||
|
|
||||||
return ctrl
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
func make_image_edit(edit : Callable, affected_rect : Rect2i):
|
|
||||||
pre_image_changed.emit(edited_image, affected_rect)
|
|
||||||
edit.call()
|
|
||||||
image_changed.emit(edited_image, affected_rect)
|
|
||||||
if edited_image_selection.get_true_bit_count() == 0:
|
|
||||||
clear_selection()
|
|
||||||
|
|
||||||
image_view.texture.update(edited_image)
|
|
||||||
|
|
||||||
|
|
||||||
func pass_event_to_tool(event) -> bool:
|
|
||||||
event.position = event.global_position
|
|
||||||
var image_space_event = image_view.event_vp_to_image(event)
|
|
||||||
if context_settings.handle_image_input(image_space_event):
|
|
||||||
return true
|
|
||||||
|
|
||||||
return tool_manager.handle_image_input(
|
|
||||||
image_space_event,
|
|
||||||
edited_image,
|
|
||||||
edited_image_selection
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func edit_texture(tex_path : String):
|
|
||||||
var new_image = Image.load_from_file(tex_path)
|
|
||||||
if new_image.get_format() == Image.FORMAT_RGB8:
|
|
||||||
# If no alpha, add alpha.
|
|
||||||
var image_bytes := new_image.get_data()
|
|
||||||
var new_image_bytes := PackedByteArray()
|
|
||||||
new_image_bytes.resize(image_bytes.size() / 3 * 4)
|
|
||||||
for i in image_bytes.size() / 3:
|
|
||||||
new_image_bytes[i * 4 + 0] = image_bytes[i * 3 + 0]
|
|
||||||
new_image_bytes[i * 4 + 1] = image_bytes[i * 3 + 1]
|
|
||||||
new_image_bytes[i * 4 + 2] = image_bytes[i * 3 + 2]
|
|
||||||
new_image_bytes[i * 4 + 3] = 255
|
|
||||||
|
|
||||||
new_image.set_data(new_image.get_width(), new_image.get_height(), new_image.has_mipmaps(), Image.FORMAT_RGBA8, new_image_bytes)
|
|
||||||
|
|
||||||
rollback_to_image = Image.create_from_data(new_image.get_width(), new_image.get_height(), new_image.has_mipmaps(), new_image.get_format(), new_image.get_data())
|
|
||||||
image_view.texture = ImageTexture.create_from_image(new_image)
|
|
||||||
image_view.reset_position()
|
|
||||||
replace_image(edited_image, new_image)
|
|
||||||
|
|
||||||
image_view.call_deferred("update_position")
|
|
||||||
edited_image_path = tex_path
|
|
||||||
|
|
||||||
|
|
||||||
func rollback_changes():
|
|
||||||
image_view.texture = ImageTexture.create_from_image(rollback_to_image)
|
|
||||||
replace_image(edited_image, rollback_to_image)
|
|
||||||
|
|
||||||
|
|
||||||
func set_view_grid(grid_size, grid_offset, is_region):
|
|
||||||
grid_view.image_size = edited_image.get_size()
|
|
||||||
grid_view.grid_size = grid_size
|
|
||||||
grid_view.grid_offset = grid_offset
|
|
||||||
grid_view.is_region = is_region
|
|
||||||
grid_view.queue_redraw()
|
|
||||||
|
|
||||||
|
|
||||||
func update_texture(new_image):
|
|
||||||
if new_image.get_size() != edited_image.get_size():
|
|
||||||
image_view.texture = ImageTexture.create_from_image(new_image)
|
|
||||||
image_view.update_position()
|
|
||||||
image_view.queue_redraw()
|
|
||||||
replace_image(edited_image, new_image)
|
|
||||||
|
|
||||||
image_view.texture.update(new_image)
|
|
||||||
edited_image = new_image
|
|
||||||
|
|
||||||
grid_view.image_size = new_image.get_size()
|
|
||||||
grid_view.queue_redraw()
|
|
||||||
|
|
||||||
|
|
||||||
func get_resized(old_image, new_size, expand_direction, stretch_format = -1) -> Image:
|
|
||||||
var old_size = old_image.get_size()
|
|
||||||
if stretch_format != -1:
|
|
||||||
var new_image = Image.create(old_size.x, old_size.y, false, old_image.get_format())
|
|
||||||
new_image.blit_rect(
|
|
||||||
old_image,
|
|
||||||
Rect2i(Vector2.ZERO, old_image.get_size()), Vector2i.ZERO
|
|
||||||
)
|
|
||||||
new_image.resize(new_size.x, new_size.y, stretch_format)
|
|
||||||
return new_image
|
|
||||||
|
|
||||||
else:
|
|
||||||
var new_image = Image.create(new_size.x, new_size.y, false, old_image.get_format())
|
|
||||||
var anchors = (Vector2i.ONE - expand_direction) * 0.5
|
|
||||||
new_image.blit_rect(
|
|
||||||
old_image,
|
|
||||||
Rect2i(Vector2i.ZERO, old_image.get_size()),
|
|
||||||
Vector2i(
|
|
||||||
(new_size.x - old_size.x) * anchors.x,
|
|
||||||
(new_size.y - old_size.y) * anchors.y,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return new_image
|
|
||||||
|
|
||||||
|
|
||||||
func replace_image(old_image, new_image):
|
|
||||||
var new_size = new_image.get_size()
|
|
||||||
edited_image = new_image
|
|
||||||
|
|
||||||
edited_image_selection.create(new_size)
|
|
||||||
clear_selection()
|
|
||||||
selection_view.selection = edited_image_selection
|
|
||||||
|
|
||||||
|
|
||||||
func clear_selection():
|
|
||||||
edited_image_selection.set_bit_rect(Rect2i(Vector2i.ZERO, edited_image_selection.get_size()), true)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_resize_value_changed(
|
|
||||||
delta, expand_direction,
|
|
||||||
stretch_format = Image.INTERPOLATE_NEAREST if Input.is_key_pressed(KEY_SHIFT) else -1
|
|
||||||
):
|
|
||||||
var old_size = edited_image.get_size()
|
|
||||||
var new_size = old_size + Vector2i(delta.round())
|
|
||||||
|
|
||||||
var new_image = get_resized(edited_image, new_size, expand_direction, stretch_format)
|
|
||||||
image_replaced.emit(edited_image, new_image)
|
|
||||||
update_texture(new_image)
|
|
||||||
BIN
amogus.kra
|
Before Width: | Height: | Size: 180 B |
@@ -1,34 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://blmo4uqveqgtu"
|
|
||||||
path="res://.godot/imported/Amogus.png-c83f0e9d5398aea3025fb80985b16828.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/Amogus.png"
|
|
||||||
dest_files=["res://.godot/imported/Amogus.png-c83f0e9d5398aea3025fb80985b16828.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 24 KiB |
@@ -1,34 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://b7n80wgfsnaml"
|
|
||||||
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://icon.png"
|
|
||||||
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 112 KiB |
30
npc/npc.gd
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
class_name NPC
|
||||||
|
extends Node2D
|
||||||
|
|
||||||
|
var id_path: Array[Vector2i]
|
||||||
|
|
||||||
|
func is_walking() -> bool:
|
||||||
|
return not id_path.is_empty()
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
randomize()
|
||||||
|
$Sprite2D.set_nation(randi()%$Sprite2D.Nations.max)
|
||||||
|
set_spacesuit(false)
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _physics_process(delta: float) -> void:
|
||||||
|
if id_path.is_empty(): return
|
||||||
|
|
||||||
|
var target_pos = Vector2(id_path.front()*World.tile_size)
|
||||||
|
|
||||||
|
global_position = global_position.move_toward(target_pos, 1)
|
||||||
|
|
||||||
|
if global_position == target_pos:
|
||||||
|
id_path.pop_front()
|
||||||
|
|
||||||
|
func set_spacesuit(suit: bool) -> void:
|
||||||
|
$Sprite2D.set_spacesuit(suit)
|
||||||
|
|
||||||
19
npc/npc.tscn
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[gd_scene load_steps=5 format=3 uid="uid://cxueg5xm4buqk"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://npc/npc.gd" id="1_m82ir"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bhpnk3olpquth" path="res://assets/moonnauts.png" id="1_vgeae"]
|
||||||
|
[ext_resource type="Script" path="res://npc/sprite_2d.gd" id="2_jtl2q"]
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_2v0ml"]
|
||||||
|
atlas = ExtResource("1_vgeae")
|
||||||
|
region = Rect2(0, 0, 16, 16)
|
||||||
|
|
||||||
|
[node name="npc" type="Node2D"]
|
||||||
|
z_index = 32
|
||||||
|
z_as_relative = false
|
||||||
|
script = ExtResource("1_m82ir")
|
||||||
|
|
||||||
|
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||||
|
texture = SubResource("AtlasTexture_2v0ml")
|
||||||
|
centered = false
|
||||||
|
script = ExtResource("2_jtl2q")
|
||||||
27
npc/sprite_2d.gd
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
extends Sprite2D
|
||||||
|
|
||||||
|
enum Nations {
|
||||||
|
ru = 0,
|
||||||
|
arab = 1,
|
||||||
|
chi = 2,
|
||||||
|
max,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
||||||
|
|
||||||
|
func set_spacesuit(suit: bool) -> void:
|
||||||
|
var atlas: AtlasTexture = texture
|
||||||
|
if suit: atlas.region.position.y = 0
|
||||||
|
else: atlas.region.position.y = 16
|
||||||
|
|
||||||
|
|
||||||
|
func set_nation(nation: Nations) -> void:
|
||||||
|
var atlas: AtlasTexture = texture
|
||||||
|
atlas.region.position.x = 16*nation
|
||||||
@@ -11,7 +11,7 @@ config_version=5
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="TestProject"
|
config/name="TestProject"
|
||||||
run/main_scene="res://world.tscn"
|
run/main_scene="res://world/world.tscn"
|
||||||
config/features=PackedStringArray("4.3", "GL Compatibility")
|
config/features=PackedStringArray("4.3", "GL Compatibility")
|
||||||
config/icon="res://assets/icon.svg"
|
config/icon="res://assets/icon.svg"
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ project/assembly_name="TestProject"
|
|||||||
|
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
enabled=PackedStringArray("res://addons/sprite_painter/plugin.cfg")
|
enabled=PackedStringArray()
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
|
|
||||||
@@ -37,7 +37,6 @@ left_click={
|
|||||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
left_mouse={
|
left_mouse={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(92, 19),"global_position":Vector2(101, 65),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
|
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(92, 19),"global_position":Vector2(101, 65),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
|
||||||
@@ -49,7 +48,6 @@ right_mouse={
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[rendering]
|
[rendering]
|
||||||
|
|
||||||
textures/canvas_textures/default_texture_filter=0
|
textures/canvas_textures/default_texture_filter=0
|
||||||
|
|||||||
BIN
test/diags2.png
|
Before Width: | Height: | Size: 719 B |
@@ -1,34 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://cejv38d7lmges"
|
|
||||||
path="res://.godot/imported/diags2.png-3ad0e4c68a2af359ead886b6bff1377e.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://test/diags2.png"
|
|
||||||
dest_files=["res://.godot/imported/diags2.png-3ad0e4c68a2af359ead886b6bff1377e.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><g transform="translate(32 32)"><path d="m-16-32c-8.86 0-16 7.13-16 15.99v95.98c0 8.86 7.13 15.99 16 15.99h96c8.86 0 16-7.13 16-15.99v-95.98c0-8.85-7.14-15.99-16-15.99z" fill="#363d52"/><path d="m-16-32c-8.86 0-16 7.13-16 15.99v95.98c0 8.86 7.13 15.99 16 15.99h96c8.86 0 16-7.13 16-15.99v-95.98c0-8.85-7.14-15.99-16-15.99zm0 4h96c6.64 0 12 5.35 12 11.99v95.98c0 6.64-5.35 11.99-12 11.99h-96c-6.64 0-12-5.35-12-11.99v-95.98c0-6.64 5.36-11.99 12-11.99z" fill-opacity=".4"/></g><g stroke-width="9.92746" transform="matrix(.10073078 0 0 .10073078 12.425923 2.256365)"><path d="m0 0s-.325 1.994-.515 1.976l-36.182-3.491c-2.879-.278-5.115-2.574-5.317-5.459l-.994-14.247-27.992-1.997-1.904 12.912c-.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-.994 14.247c-.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-.187.018-.324-1.978-.511-1.978l-.049-7.83 30.658-4.944 1.004-14.374c.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c.146-.01.29-.016.434-.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c.423-2.871 2.93-5.037 5.831-5.037.142 0 .284.005.423.015l38.556 2.75c2.911.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 919.24059 771.67186)"/><path d="m0 0v-47.514-6.035-5.492c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325c5.09692 6.4164715 9.92323 13.494208 13.621 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.4426579-6.973692 9.2079702-13.9828876 13.621-19.449z" fill="#478cbf" transform="matrix(4.162611 0 0 -4.162611 104.69892 525.90697)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.066.067c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(4.162611 0 0 -4.162611 784.07144 817.24284)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 389.21484 625.67104)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(4.162611 0 0 -4.162611 367.36686 631.05679)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 511.99336 724.73954)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 634.78706 625.67104)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(4.162611 0 0 -4.162611 656.64056 631.05679)"/></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1,37 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://bjmypnfjkbve6"
|
|
||||||
path="res://.godot/imported/icon.svg-9ffd99e4b8a55380f3055552bd81b639.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://test/icon.svg"
|
|
||||||
dest_files=["res://.godot/imported/icon.svg-9ffd99e4b8a55380f3055552bd81b639.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
svg/scale=1.0
|
|
||||||
editor/scale_with_editor_scale=false
|
|
||||||
editor/convert_colors_with_editor_theme=false
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://dq1nb7p2ts0ok"]
|
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://c7nymhfcdr3hl" path="res://addons/sprite_painter/graphics/diags.png" id="1_hgr16"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://b7n80wgfsnaml" path="res://icon.png" id="1_uj0gm"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://cejv38d7lmges" path="res://test/diags2.png" id="2_lxinl"]
|
|
||||||
|
|
||||||
[node name="Node2D" type="Node2D"]
|
|
||||||
|
|
||||||
[node name="Polygon2D2" type="Polygon2D" parent="."]
|
|
||||||
texture_repeat = 2
|
|
||||||
position = Vector2(-537, 434)
|
|
||||||
texture = ExtResource("1_hgr16")
|
|
||||||
polygon = PackedVector2Array(302, 105, -2, 293, 224, 391, 330, 537, 478, 327, 567, 292, 640, 199, 842, 581, 852, 669, 1112, 443, 904, 241, 868, 107, 665.661, 13.9704, 520, -53, 418, 52)
|
|
||||||
|
|
||||||
[node name="a" type="Sprite2D" parent="."]
|
|
||||||
position = Vector2(411, 128)
|
|
||||||
texture = ExtResource("2_lxinl")
|
|
||||||
centered = false
|
|
||||||
|
|
||||||
[node name="Icon2" type="Sprite2D" parent="."]
|
|
||||||
position = Vector2(43, 131)
|
|
||||||
texture = ExtResource("1_uj0gm")
|
|
||||||
centered = false
|
|
||||||
|
|
||||||
[node name="Icon4" type="Sprite2D" parent="."]
|
|
||||||
position = Vector2(281, 520)
|
|
||||||
texture = ExtResource("1_uj0gm")
|
|
||||||
centered = false
|
|
||||||
38
world/npcs.gd
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
extends Node2D
|
||||||
|
|
||||||
|
const NPC_SCENE = preload("res://npc/npc.tscn")
|
||||||
|
|
||||||
|
var npcs: Array[NPC]
|
||||||
|
|
||||||
|
|
||||||
|
func add_npc(pos: Vector2i):
|
||||||
|
var npc: NPC = NPC_SCENE.instantiate()
|
||||||
|
npc.translate(pos*World.tile_size)
|
||||||
|
npcs.append(npc)
|
||||||
|
add_child(npc)
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
randomize()
|
||||||
|
add_npc(Vector2i(11, 8))
|
||||||
|
add_npc(Vector2i(9, 9))
|
||||||
|
add_npc(Vector2i(12, 11))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func set_npc_target(npc: NPC, target: Vector2i):
|
||||||
|
var id_path = $"../TileMap".astar_grid.get_id_path(
|
||||||
|
$"../TileMap/ground".local_to_map(npc.global_position+$"../TileMap/ground".global_position),
|
||||||
|
target
|
||||||
|
).slice(1)
|
||||||
|
|
||||||
|
if not id_path.is_empty():
|
||||||
|
npc.id_path = id_path
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _physics_process(delta: float) -> void:
|
||||||
|
for npc in npcs:
|
||||||
|
if not npc.is_walking():
|
||||||
|
set_npc_target(npc, Vector2i(randi()%64,randi()%64))
|
||||||
|
pass
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
class_name MyTileMap
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
enum StructType {
|
enum StructType {
|
||||||
@@ -71,6 +72,7 @@ enum struct_fields {
|
|||||||
|
|
||||||
var layers: Array[TileMapLayer]
|
var layers: Array[TileMapLayer]
|
||||||
var layers_dict: Dictionary
|
var layers_dict: Dictionary
|
||||||
|
var astar_grid: AStarGrid2D
|
||||||
|
|
||||||
func _list_childrens(node: Node2D):
|
func _list_childrens(node: Node2D):
|
||||||
for child in node.get_children():
|
for child in node.get_children():
|
||||||
@@ -84,6 +86,18 @@ func _list_childrens(node: Node2D):
|
|||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
layers = []
|
layers = []
|
||||||
_list_childrens(self)
|
_list_childrens(self)
|
||||||
|
astar_grid = AStarGrid2D.new()
|
||||||
|
astar_grid.region = layers_dict["ground"].get_used_rect()
|
||||||
|
astar_grid.cell_size = Vector2i(16, 16)
|
||||||
|
astar_grid.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_NEVER
|
||||||
|
astar_grid.update()
|
||||||
|
|
||||||
|
for x in $ground.get_used_rect().size.x:
|
||||||
|
for y in $ground.get_used_rect().size.y:
|
||||||
|
var tile_pos = Vector2i(x,y)
|
||||||
|
update_astar_tile(tile_pos)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func get_maxZ(tile_pos: Vector2i) -> int:
|
func get_maxZ(tile_pos: Vector2i) -> int:
|
||||||
var max_z: int = -1024
|
var max_z: int = -1024
|
||||||
@@ -105,10 +119,12 @@ func place_road(pos: Vector2i) -> bool:
|
|||||||
if get_maxZ(pos) >= layer.z_index:
|
if get_maxZ(pos) >= layer.z_index:
|
||||||
return false
|
return false
|
||||||
layer.set_cells_terrain_connect([pos], 0, 2, true)
|
layer.set_cells_terrain_connect([pos], 0, 2, true)
|
||||||
|
update_astar_tile(pos)
|
||||||
return true
|
return true
|
||||||
func erase_road(pos: Vector2i) -> bool:
|
func erase_road(pos: Vector2i) -> bool:
|
||||||
var layer: TileMapLayer = layers_dict["roads"]
|
var layer: TileMapLayer = layers_dict["roads"]
|
||||||
layer.erase_cell(pos)
|
layer.erase_cell(pos)
|
||||||
|
update_astar_tile(pos)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
func place_way(pos1: Vector2i, pos2: Vector2i) -> bool:
|
func place_way(pos1: Vector2i, pos2: Vector2i) -> bool:
|
||||||
@@ -148,19 +164,6 @@ func place_way(pos1: Vector2i, pos2: Vector2i) -> bool:
|
|||||||
place_struct(Vector2i(pos1.x, y), StructType.V_WAY)
|
place_struct(Vector2i(pos1.x, y), StructType.V_WAY)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
func remove_struct(pos: Vector2i):
|
|
||||||
for layer in layers:
|
|
||||||
var tiledata: TileData = layer.get_cell_tile_data(pos)
|
|
||||||
if tiledata != null and tiledata.get_custom_data("is_center"):
|
|
||||||
var struct_size = tiledata.get_custom_data("struct_size")
|
|
||||||
var half_size = Vector2i(struct_size.x / 2, struct_size.y / 2)
|
|
||||||
for x in range(struct_size.x):
|
|
||||||
for y in range(struct_size.y):
|
|
||||||
var offset = Vector2i(x, y)
|
|
||||||
var tile_pos = pos+offset-half_size
|
|
||||||
layer.erase_cell(tile_pos)
|
|
||||||
return
|
|
||||||
|
|
||||||
func destroy_building(pos: Vector2i, only_ways: bool = false):
|
func destroy_building(pos: Vector2i, only_ways: bool = false):
|
||||||
for layer in layers:
|
for layer in layers:
|
||||||
var tiledata: TileData = layer.get_cell_tile_data(pos)
|
var tiledata: TileData = layer.get_cell_tile_data(pos)
|
||||||
@@ -183,6 +186,20 @@ func destroy_building(pos: Vector2i, only_ways: bool = false):
|
|||||||
remove_struct(pos)
|
remove_struct(pos)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
func remove_struct(pos: Vector2i):
|
||||||
|
for layer in layers:
|
||||||
|
var tiledata: TileData = layer.get_cell_tile_data(pos)
|
||||||
|
if tiledata != null and tiledata.get_custom_data("is_center"):
|
||||||
|
var struct_size = tiledata.get_custom_data("struct_size")
|
||||||
|
var half_size = Vector2i(struct_size.x / 2, struct_size.y / 2)
|
||||||
|
for x in range(struct_size.x):
|
||||||
|
for y in range(struct_size.y):
|
||||||
|
var offset = Vector2i(x, y)
|
||||||
|
var tile_pos = pos+offset-half_size
|
||||||
|
layer.erase_cell(tile_pos)
|
||||||
|
update_astar_tile(tile_pos)
|
||||||
|
return
|
||||||
|
|
||||||
func place_struct(pos: Vector2i, type: StructType) -> bool:
|
func place_struct(pos: Vector2i, type: StructType) -> bool:
|
||||||
if not structs.has(type):
|
if not structs.has(type):
|
||||||
return false
|
return false
|
||||||
@@ -206,4 +223,24 @@ func place_struct(pos: Vector2i, type: StructType) -> bool:
|
|||||||
var offset = Vector2i(x, y)
|
var offset = Vector2i(x, y)
|
||||||
var tile_pos = pos+offset-half_size
|
var tile_pos = pos+offset-half_size
|
||||||
layer.set_cell(tile_pos, source_id, Vector2i(x,y)+pos_atlas)
|
layer.set_cell(tile_pos, source_id, Vector2i(x,y)+pos_atlas)
|
||||||
|
update_astar_tile(tile_pos)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
func is_walkable(pos: Vector2i) -> bool:
|
||||||
|
var state: bool = true
|
||||||
|
for layer in layers:
|
||||||
|
var tiledata: TileData = layer.get_cell_tile_data(pos)
|
||||||
|
if tiledata != null and not tiledata.get_custom_data("walkable"):
|
||||||
|
state = false
|
||||||
|
break
|
||||||
|
return state
|
||||||
|
|
||||||
|
func weight(pos: Vector2i) -> int:
|
||||||
|
var layer = get_toplayer(pos)
|
||||||
|
var tiledata: TileData = layer.get_cell_tile_data(pos)
|
||||||
|
if tiledata != null: return tiledata.get_custom_data("astar_weight")
|
||||||
|
else: return 5
|
||||||
|
|
||||||
|
func update_astar_tile(pos: Vector2i):
|
||||||
|
astar_grid.set_point_solid(pos, not is_walkable(pos))
|
||||||
|
astar_grid.set_point_weight_scale(pos, weight(pos))
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
|
class_name World
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
|
const tile_size: int = 16
|
||||||
|
|
||||||
# Переменная для хранения ссылки на TileMap
|
# Переменная для хранения ссылки на TileMap
|
||||||
@onready var ground: TileMapLayer = $TileMap/ground
|
@onready var ground: TileMapLayer = $TileMap/ground
|
||||||
@onready var tileMap: Node2D = $TileMap
|
@onready var tileMap: Node2D = $TileMap
|
||||||
|
|
||||||
const SELECTION_SCENE = preload("res://selection.tscn")
|
const SELECTION_SCENE = preload("res://UI/selection/selection.tscn")
|
||||||
|
|
||||||
var selected_instrument: instruments
|
var selected_instrument: instruments
|
||||||
var selected_tile: Vector2i
|
var selected_tile: Vector2i
|
||||||
@@ -47,6 +50,7 @@ func _physics_process(delta: float) -> void:
|
|||||||
if(selected_tile==selected_tile2):
|
if(selected_tile==selected_tile2):
|
||||||
selected_tile2 = Vector2i(-128,-128)
|
selected_tile2 = Vector2i(-128,-128)
|
||||||
selected2 = false
|
selected2 = false
|
||||||
|
print(tileMap.is_walkable(selected_tile))
|
||||||
if Input.is_action_just_released("right_mouse") and rmb:
|
if Input.is_action_just_released("right_mouse") and rmb:
|
||||||
selected_tile2 = select_tile(ground.local_to_map(get_global_mouse_position()-tileMap.global_position))
|
selected_tile2 = select_tile(ground.local_to_map(get_global_mouse_position()-tileMap.global_position))
|
||||||
if(selected_tile!=selected_tile2): selected2 = true
|
if(selected_tile!=selected_tile2): selected2 = true
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
[gd_scene load_steps=9 format=4 uid="uid://d4e2mg6r7kt4m"]
|
[gd_scene load_steps=9 format=4 uid="uid://d4e2mg6r7kt4m"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://world.gd" id="1_336so"]
|
[ext_resource type="Script" path="res://world/world.gd" id="1_obe6v"]
|
||||||
[ext_resource type="Texture2D" uid="uid://hksnxmrpo2cp" path="res://assets/tileset.png" id="1_wepw1"]
|
[ext_resource type="Script" path="res://world/tile_map.gd" id="2_lm4q6"]
|
||||||
[ext_resource type="Script" path="res://tile_map.gd" id="2_wnvvd"]
|
[ext_resource type="Texture2D" uid="uid://hksnxmrpo2cp" path="res://assets/tileset.png" id="3_g3o52"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ws7nut2tt600" path="res://assets/moonbase.png" id="3_hky6b"]
|
[ext_resource type="Texture2D" uid="uid://ws7nut2tt600" path="res://assets/moonbase.png" id="4_xeinu"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dtttpb73i7qt2" path="res://Scenes/player.tscn" id="5_2xbni"]
|
[ext_resource type="Script" path="res://world/npcs.gd" id="5_et4gm"]
|
||||||
|
|
||||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_fyh4j"]
|
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_fyh4j"]
|
||||||
texture = ExtResource("1_wepw1")
|
texture = ExtResource("3_g3o52")
|
||||||
1:1/0 = 0
|
1:1/0 = 0
|
||||||
|
1:1/0/custom_data_5 = 5
|
||||||
0:0/0 = 0
|
0:0/0 = 0
|
||||||
0:0/0/terrain_set = 0
|
0:0/0/terrain_set = 0
|
||||||
0:0/0/terrain = 0
|
0:0/0/terrain = 0
|
||||||
@@ -20,14 +21,19 @@ texture = ExtResource("1_wepw1")
|
|||||||
0:0/0/terrains_peering_bit/top_left_corner = 0
|
0:0/0/terrains_peering_bit/top_left_corner = 0
|
||||||
0:0/0/terrains_peering_bit/top_side = 0
|
0:0/0/terrains_peering_bit/top_side = 0
|
||||||
0:0/0/terrains_peering_bit/top_right_corner = 0
|
0:0/0/terrains_peering_bit/top_right_corner = 0
|
||||||
|
0:0/0/custom_data_4 = true
|
||||||
|
0:0/0/custom_data_5 = 5
|
||||||
0:1/0 = 0
|
0:1/0 = 0
|
||||||
|
0:1/0/custom_data_5 = 5
|
||||||
1:0/0 = 0
|
1:0/0 = 0
|
||||||
|
1:0/0/custom_data_5 = 5
|
||||||
0:8/0 = 0
|
0:8/0 = 0
|
||||||
0:8/0/terrain_set = 0
|
0:8/0/terrain_set = 0
|
||||||
0:8/0/terrain = 1
|
0:8/0/terrain = 1
|
||||||
0:8/0/terrains_peering_bit/right_side = 1
|
0:8/0/terrains_peering_bit/right_side = 1
|
||||||
0:8/0/terrains_peering_bit/bottom_right_corner = 1
|
0:8/0/terrains_peering_bit/bottom_right_corner = 1
|
||||||
0:8/0/terrains_peering_bit/bottom_side = 1
|
0:8/0/terrains_peering_bit/bottom_side = 1
|
||||||
|
0:8/0/custom_data_5 = 5
|
||||||
1:8/0 = 0
|
1:8/0 = 0
|
||||||
1:8/0/terrain_set = 0
|
1:8/0/terrain_set = 0
|
||||||
1:8/0/terrain = 1
|
1:8/0/terrain = 1
|
||||||
@@ -36,21 +42,25 @@ texture = ExtResource("1_wepw1")
|
|||||||
1:8/0/terrains_peering_bit/bottom_side = 1
|
1:8/0/terrains_peering_bit/bottom_side = 1
|
||||||
1:8/0/terrains_peering_bit/bottom_left_corner = 1
|
1:8/0/terrains_peering_bit/bottom_left_corner = 1
|
||||||
1:8/0/terrains_peering_bit/left_side = 1
|
1:8/0/terrains_peering_bit/left_side = 1
|
||||||
|
1:8/0/custom_data_5 = 5
|
||||||
2:8/0 = 0
|
2:8/0 = 0
|
||||||
2:8/0/terrain_set = 0
|
2:8/0/terrain_set = 0
|
||||||
2:8/0/terrain = 1
|
2:8/0/terrain = 1
|
||||||
2:8/0/terrains_peering_bit/bottom_side = 1
|
2:8/0/terrains_peering_bit/bottom_side = 1
|
||||||
2:8/0/terrains_peering_bit/bottom_left_corner = 1
|
2:8/0/terrains_peering_bit/bottom_left_corner = 1
|
||||||
2:8/0/terrains_peering_bit/left_side = 1
|
2:8/0/terrains_peering_bit/left_side = 1
|
||||||
|
2:8/0/custom_data_5 = 5
|
||||||
3:8/0 = 0
|
3:8/0 = 0
|
||||||
3:8/0/terrain_set = 0
|
3:8/0/terrain_set = 0
|
||||||
3:8/0/terrain = 1
|
3:8/0/terrain = 1
|
||||||
3:8/0/terrains_peering_bit/bottom_side = 1
|
3:8/0/terrains_peering_bit/bottom_side = 1
|
||||||
|
3:8/0/custom_data_5 = 5
|
||||||
4:8/0 = 0
|
4:8/0 = 0
|
||||||
4:8/0/terrain_set = 0
|
4:8/0/terrain_set = 0
|
||||||
4:8/0/terrain = 1
|
4:8/0/terrain = 1
|
||||||
4:8/0/terrains_peering_bit/right_side = 1
|
4:8/0/terrains_peering_bit/right_side = 1
|
||||||
4:8/0/terrains_peering_bit/bottom_side = 1
|
4:8/0/terrains_peering_bit/bottom_side = 1
|
||||||
|
4:8/0/custom_data_5 = 5
|
||||||
5:8/0 = 0
|
5:8/0 = 0
|
||||||
5:8/0/terrain_set = 0
|
5:8/0/terrain_set = 0
|
||||||
5:8/0/terrain = 1
|
5:8/0/terrain = 1
|
||||||
@@ -58,6 +68,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
5:8/0/terrains_peering_bit/bottom_side = 1
|
5:8/0/terrains_peering_bit/bottom_side = 1
|
||||||
5:8/0/terrains_peering_bit/bottom_left_corner = 1
|
5:8/0/terrains_peering_bit/bottom_left_corner = 1
|
||||||
5:8/0/terrains_peering_bit/left_side = 1
|
5:8/0/terrains_peering_bit/left_side = 1
|
||||||
|
5:8/0/custom_data_5 = 5
|
||||||
6:8/0 = 0
|
6:8/0 = 0
|
||||||
6:8/0/terrain_set = 0
|
6:8/0/terrain_set = 0
|
||||||
6:8/0/terrain = 1
|
6:8/0/terrain = 1
|
||||||
@@ -65,17 +76,20 @@ texture = ExtResource("1_wepw1")
|
|||||||
6:8/0/terrains_peering_bit/bottom_right_corner = 1
|
6:8/0/terrains_peering_bit/bottom_right_corner = 1
|
||||||
6:8/0/terrains_peering_bit/bottom_side = 1
|
6:8/0/terrains_peering_bit/bottom_side = 1
|
||||||
6:8/0/terrains_peering_bit/left_side = 1
|
6:8/0/terrains_peering_bit/left_side = 1
|
||||||
|
6:8/0/custom_data_5 = 5
|
||||||
7:8/0 = 0
|
7:8/0 = 0
|
||||||
7:8/0/terrain_set = 0
|
7:8/0/terrain_set = 0
|
||||||
7:8/0/terrain = 1
|
7:8/0/terrain = 1
|
||||||
7:8/0/terrains_peering_bit/bottom_side = 1
|
7:8/0/terrains_peering_bit/bottom_side = 1
|
||||||
7:8/0/terrains_peering_bit/left_side = 1
|
7:8/0/terrains_peering_bit/left_side = 1
|
||||||
|
7:8/0/custom_data_5 = 5
|
||||||
8:8/0 = 0
|
8:8/0 = 0
|
||||||
8:8/0/terrain_set = 0
|
8:8/0/terrain_set = 0
|
||||||
8:8/0/terrain = 1
|
8:8/0/terrain = 1
|
||||||
8:8/0/terrains_peering_bit/right_side = 1
|
8:8/0/terrains_peering_bit/right_side = 1
|
||||||
8:8/0/terrains_peering_bit/bottom_side = 1
|
8:8/0/terrains_peering_bit/bottom_side = 1
|
||||||
8:8/0/terrains_peering_bit/left_side = 1
|
8:8/0/terrains_peering_bit/left_side = 1
|
||||||
|
8:8/0/custom_data_5 = 5
|
||||||
9:8/0 = 0
|
9:8/0 = 0
|
||||||
9:8/0/terrain_set = 0
|
9:8/0/terrain_set = 0
|
||||||
9:8/0/terrain = 1
|
9:8/0/terrain = 1
|
||||||
@@ -85,6 +99,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
9:8/0/terrains_peering_bit/left_side = 1
|
9:8/0/terrains_peering_bit/left_side = 1
|
||||||
9:8/0/terrains_peering_bit/top_left_corner = 1
|
9:8/0/terrains_peering_bit/top_left_corner = 1
|
||||||
9:8/0/terrains_peering_bit/top_side = 1
|
9:8/0/terrains_peering_bit/top_side = 1
|
||||||
|
9:8/0/custom_data_5 = 5
|
||||||
9:9/0 = 0
|
9:9/0 = 0
|
||||||
9:9/0/terrain_set = 0
|
9:9/0/terrain_set = 0
|
||||||
9:9/0/terrain = 1
|
9:9/0/terrain = 1
|
||||||
@@ -94,6 +109,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
9:9/0/terrains_peering_bit/left_side = 1
|
9:9/0/terrains_peering_bit/left_side = 1
|
||||||
9:9/0/terrains_peering_bit/top_side = 1
|
9:9/0/terrains_peering_bit/top_side = 1
|
||||||
9:9/0/terrains_peering_bit/top_right_corner = 1
|
9:9/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
9:9/0/custom_data_5 = 5
|
||||||
8:9/0 = 0
|
8:9/0 = 0
|
||||||
8:9/0/terrain_set = 0
|
8:9/0/terrain_set = 0
|
||||||
8:9/0/terrain = 1
|
8:9/0/terrain = 1
|
||||||
@@ -103,6 +119,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
8:9/0/terrains_peering_bit/top_left_corner = 1
|
8:9/0/terrains_peering_bit/top_left_corner = 1
|
||||||
8:9/0/terrains_peering_bit/top_side = 1
|
8:9/0/terrains_peering_bit/top_side = 1
|
||||||
8:9/0/terrains_peering_bit/top_right_corner = 1
|
8:9/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
8:9/0/custom_data_5 = 5
|
||||||
7:9/0 = 0
|
7:9/0 = 0
|
||||||
7:9/0/terrain_set = 0
|
7:9/0/terrain_set = 0
|
||||||
7:9/0/terrain = 1
|
7:9/0/terrain = 1
|
||||||
@@ -110,6 +127,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
7:9/0/terrains_peering_bit/left_side = 1
|
7:9/0/terrains_peering_bit/left_side = 1
|
||||||
7:9/0/terrains_peering_bit/top_left_corner = 1
|
7:9/0/terrains_peering_bit/top_left_corner = 1
|
||||||
7:9/0/terrains_peering_bit/top_side = 1
|
7:9/0/terrains_peering_bit/top_side = 1
|
||||||
|
7:9/0/custom_data_5 = 5
|
||||||
6:9/0 = 0
|
6:9/0 = 0
|
||||||
6:9/0/terrain_set = 0
|
6:9/0/terrain_set = 0
|
||||||
6:9/0/terrain = 1
|
6:9/0/terrain = 1
|
||||||
@@ -120,6 +138,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
6:9/0/terrains_peering_bit/top_left_corner = 1
|
6:9/0/terrains_peering_bit/top_left_corner = 1
|
||||||
6:9/0/terrains_peering_bit/top_side = 1
|
6:9/0/terrains_peering_bit/top_side = 1
|
||||||
6:9/0/terrains_peering_bit/top_right_corner = 1
|
6:9/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
6:9/0/custom_data_5 = 5
|
||||||
5:9/0 = 0
|
5:9/0 = 0
|
||||||
5:9/0/terrain_set = 0
|
5:9/0/terrain_set = 0
|
||||||
5:9/0/terrain = 1
|
5:9/0/terrain = 1
|
||||||
@@ -130,6 +149,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
5:9/0/terrains_peering_bit/top_left_corner = 1
|
5:9/0/terrains_peering_bit/top_left_corner = 1
|
||||||
5:9/0/terrains_peering_bit/top_side = 1
|
5:9/0/terrains_peering_bit/top_side = 1
|
||||||
5:9/0/terrains_peering_bit/top_right_corner = 1
|
5:9/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
5:9/0/custom_data_5 = 5
|
||||||
4:9/0 = 0
|
4:9/0 = 0
|
||||||
4:9/0/terrain_set = 0
|
4:9/0/terrain_set = 0
|
||||||
4:9/0/terrain = 1
|
4:9/0/terrain = 1
|
||||||
@@ -137,11 +157,13 @@ texture = ExtResource("1_wepw1")
|
|||||||
4:9/0/terrains_peering_bit/bottom_side = 1
|
4:9/0/terrains_peering_bit/bottom_side = 1
|
||||||
4:9/0/terrains_peering_bit/top_side = 1
|
4:9/0/terrains_peering_bit/top_side = 1
|
||||||
4:9/0/terrains_peering_bit/top_right_corner = 1
|
4:9/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
4:9/0/custom_data_5 = 5
|
||||||
3:9/0 = 0
|
3:9/0 = 0
|
||||||
3:9/0/terrain_set = 0
|
3:9/0/terrain_set = 0
|
||||||
3:9/0/terrain = 1
|
3:9/0/terrain = 1
|
||||||
3:9/0/terrains_peering_bit/bottom_side = 1
|
3:9/0/terrains_peering_bit/bottom_side = 1
|
||||||
3:9/0/terrains_peering_bit/top_side = 1
|
3:9/0/terrains_peering_bit/top_side = 1
|
||||||
|
3:9/0/custom_data_5 = 5
|
||||||
2:9/0 = 0
|
2:9/0 = 0
|
||||||
2:9/0/terrain_set = 0
|
2:9/0/terrain_set = 0
|
||||||
2:9/0/terrain = 1
|
2:9/0/terrain = 1
|
||||||
@@ -150,6 +172,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
2:9/0/terrains_peering_bit/left_side = 1
|
2:9/0/terrains_peering_bit/left_side = 1
|
||||||
2:9/0/terrains_peering_bit/top_left_corner = 1
|
2:9/0/terrains_peering_bit/top_left_corner = 1
|
||||||
2:9/0/terrains_peering_bit/top_side = 1
|
2:9/0/terrains_peering_bit/top_side = 1
|
||||||
|
2:9/0/custom_data_5 = 5
|
||||||
0:9/0 = 0
|
0:9/0 = 0
|
||||||
0:9/0/terrain_set = 0
|
0:9/0/terrain_set = 0
|
||||||
0:9/0/terrain = 1
|
0:9/0/terrain = 1
|
||||||
@@ -158,12 +181,14 @@ texture = ExtResource("1_wepw1")
|
|||||||
0:9/0/terrains_peering_bit/bottom_side = 1
|
0:9/0/terrains_peering_bit/bottom_side = 1
|
||||||
0:9/0/terrains_peering_bit/top_side = 1
|
0:9/0/terrains_peering_bit/top_side = 1
|
||||||
0:9/0/terrains_peering_bit/top_right_corner = 1
|
0:9/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
0:9/0/custom_data_5 = 5
|
||||||
0:10/0 = 0
|
0:10/0 = 0
|
||||||
0:10/0/terrain_set = 0
|
0:10/0/terrain_set = 0
|
||||||
0:10/0/terrain = 1
|
0:10/0/terrain = 1
|
||||||
0:10/0/terrains_peering_bit/right_side = 1
|
0:10/0/terrains_peering_bit/right_side = 1
|
||||||
0:10/0/terrains_peering_bit/top_side = 1
|
0:10/0/terrains_peering_bit/top_side = 1
|
||||||
0:10/0/terrains_peering_bit/top_right_corner = 1
|
0:10/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
0:10/0/custom_data_5 = 5
|
||||||
1:10/0 = 0
|
1:10/0 = 0
|
||||||
1:10/0/terrain_set = 0
|
1:10/0/terrain_set = 0
|
||||||
1:10/0/terrain = 1
|
1:10/0/terrain = 1
|
||||||
@@ -172,16 +197,19 @@ texture = ExtResource("1_wepw1")
|
|||||||
1:10/0/terrains_peering_bit/top_left_corner = 1
|
1:10/0/terrains_peering_bit/top_left_corner = 1
|
||||||
1:10/0/terrains_peering_bit/top_side = 1
|
1:10/0/terrains_peering_bit/top_side = 1
|
||||||
1:10/0/terrains_peering_bit/top_right_corner = 1
|
1:10/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
1:10/0/custom_data_5 = 5
|
||||||
2:10/0 = 0
|
2:10/0 = 0
|
||||||
2:10/0/terrain_set = 0
|
2:10/0/terrain_set = 0
|
||||||
2:10/0/terrain = 1
|
2:10/0/terrain = 1
|
||||||
2:10/0/terrains_peering_bit/left_side = 1
|
2:10/0/terrains_peering_bit/left_side = 1
|
||||||
2:10/0/terrains_peering_bit/top_left_corner = 1
|
2:10/0/terrains_peering_bit/top_left_corner = 1
|
||||||
2:10/0/terrains_peering_bit/top_side = 1
|
2:10/0/terrains_peering_bit/top_side = 1
|
||||||
|
2:10/0/custom_data_5 = 5
|
||||||
3:10/0 = 0
|
3:10/0 = 0
|
||||||
3:10/0/terrain_set = 0
|
3:10/0/terrain_set = 0
|
||||||
3:10/0/terrain = 1
|
3:10/0/terrain = 1
|
||||||
3:10/0/terrains_peering_bit/top_side = 1
|
3:10/0/terrains_peering_bit/top_side = 1
|
||||||
|
3:10/0/custom_data_5 = 5
|
||||||
4:10/0 = 0
|
4:10/0 = 0
|
||||||
4:10/0/terrain_set = 0
|
4:10/0/terrain_set = 0
|
||||||
4:10/0/terrain = 1
|
4:10/0/terrain = 1
|
||||||
@@ -189,6 +217,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
4:10/0/terrains_peering_bit/bottom_right_corner = 1
|
4:10/0/terrains_peering_bit/bottom_right_corner = 1
|
||||||
4:10/0/terrains_peering_bit/bottom_side = 1
|
4:10/0/terrains_peering_bit/bottom_side = 1
|
||||||
4:10/0/terrains_peering_bit/top_side = 1
|
4:10/0/terrains_peering_bit/top_side = 1
|
||||||
|
4:10/0/custom_data_5 = 5
|
||||||
5:10/0 = 0
|
5:10/0 = 0
|
||||||
5:10/0/terrain_set = 0
|
5:10/0/terrain_set = 0
|
||||||
5:10/0/terrain = 1
|
5:10/0/terrain = 1
|
||||||
@@ -199,6 +228,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
5:10/0/terrains_peering_bit/left_side = 1
|
5:10/0/terrains_peering_bit/left_side = 1
|
||||||
5:10/0/terrains_peering_bit/top_left_corner = 1
|
5:10/0/terrains_peering_bit/top_left_corner = 1
|
||||||
5:10/0/terrains_peering_bit/top_side = 1
|
5:10/0/terrains_peering_bit/top_side = 1
|
||||||
|
5:10/0/custom_data_5 = 5
|
||||||
6:10/0 = 0
|
6:10/0 = 0
|
||||||
6:10/0/terrain_set = 0
|
6:10/0/terrain_set = 0
|
||||||
6:10/0/terrain = 1
|
6:10/0/terrain = 1
|
||||||
@@ -209,6 +239,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
6:10/0/terrains_peering_bit/left_side = 1
|
6:10/0/terrains_peering_bit/left_side = 1
|
||||||
6:10/0/terrains_peering_bit/top_side = 1
|
6:10/0/terrains_peering_bit/top_side = 1
|
||||||
6:10/0/terrains_peering_bit/top_right_corner = 1
|
6:10/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
6:10/0/custom_data_5 = 5
|
||||||
7:10/0 = 0
|
7:10/0 = 0
|
||||||
7:10/0/terrain_set = 0
|
7:10/0/terrain_set = 0
|
||||||
7:10/0/terrain = 1
|
7:10/0/terrain = 1
|
||||||
@@ -216,6 +247,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
7:10/0/terrains_peering_bit/bottom_left_corner = 1
|
7:10/0/terrains_peering_bit/bottom_left_corner = 1
|
||||||
7:10/0/terrains_peering_bit/left_side = 1
|
7:10/0/terrains_peering_bit/left_side = 1
|
||||||
7:10/0/terrains_peering_bit/top_side = 1
|
7:10/0/terrains_peering_bit/top_side = 1
|
||||||
|
7:10/0/custom_data_5 = 5
|
||||||
8:10/0 = 0
|
8:10/0 = 0
|
||||||
8:10/0/terrain_set = 0
|
8:10/0/terrain_set = 0
|
||||||
8:10/0/terrain = 1
|
8:10/0/terrain = 1
|
||||||
@@ -225,6 +257,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
8:10/0/terrains_peering_bit/bottom_left_corner = 1
|
8:10/0/terrains_peering_bit/bottom_left_corner = 1
|
||||||
8:10/0/terrains_peering_bit/left_side = 1
|
8:10/0/terrains_peering_bit/left_side = 1
|
||||||
8:10/0/terrains_peering_bit/top_side = 1
|
8:10/0/terrains_peering_bit/top_side = 1
|
||||||
|
8:10/0/custom_data_5 = 5
|
||||||
9:10/0 = 0
|
9:10/0 = 0
|
||||||
9:10/0/terrain_set = 0
|
9:10/0/terrain_set = 0
|
||||||
9:10/0/terrain = 1
|
9:10/0/terrain = 1
|
||||||
@@ -233,6 +266,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
9:10/0/terrains_peering_bit/bottom_side = 1
|
9:10/0/terrains_peering_bit/bottom_side = 1
|
||||||
9:10/0/terrains_peering_bit/left_side = 1
|
9:10/0/terrains_peering_bit/left_side = 1
|
||||||
9:10/0/terrains_peering_bit/top_side = 1
|
9:10/0/terrains_peering_bit/top_side = 1
|
||||||
|
9:10/0/custom_data_5 = 5
|
||||||
10:10/0 = 0
|
10:10/0 = 0
|
||||||
10:10/0/terrain_set = 0
|
10:10/0/terrain_set = 0
|
||||||
10:10/0/terrain = 1
|
10:10/0/terrain = 1
|
||||||
@@ -241,6 +275,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
10:10/0/terrains_peering_bit/bottom_left_corner = 1
|
10:10/0/terrains_peering_bit/bottom_left_corner = 1
|
||||||
10:10/0/terrains_peering_bit/left_side = 1
|
10:10/0/terrains_peering_bit/left_side = 1
|
||||||
10:10/0/terrains_peering_bit/top_side = 1
|
10:10/0/terrains_peering_bit/top_side = 1
|
||||||
|
10:10/0/custom_data_5 = 5
|
||||||
10:11/0 = 0
|
10:11/0 = 0
|
||||||
10:11/0/terrain_set = 0
|
10:11/0/terrain_set = 0
|
||||||
10:11/0/terrain = 1
|
10:11/0/terrain = 1
|
||||||
@@ -249,6 +284,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
10:11/0/terrains_peering_bit/left_side = 1
|
10:11/0/terrains_peering_bit/left_side = 1
|
||||||
10:11/0/terrains_peering_bit/top_left_corner = 1
|
10:11/0/terrains_peering_bit/top_left_corner = 1
|
||||||
10:11/0/terrains_peering_bit/top_side = 1
|
10:11/0/terrains_peering_bit/top_side = 1
|
||||||
|
10:11/0/custom_data_5 = 5
|
||||||
9:11/0 = 0
|
9:11/0 = 0
|
||||||
9:11/0/terrain_set = 0
|
9:11/0/terrain_set = 0
|
||||||
9:11/0/terrain = 1
|
9:11/0/terrain = 1
|
||||||
@@ -257,17 +293,20 @@ texture = ExtResource("1_wepw1")
|
|||||||
9:11/0/terrains_peering_bit/left_side = 1
|
9:11/0/terrains_peering_bit/left_side = 1
|
||||||
9:11/0/terrains_peering_bit/top_side = 1
|
9:11/0/terrains_peering_bit/top_side = 1
|
||||||
9:11/0/terrains_peering_bit/top_right_corner = 1
|
9:11/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
9:11/0/custom_data_5 = 5
|
||||||
8:11/0 = 0
|
8:11/0 = 0
|
||||||
8:11/0/terrain_set = 0
|
8:11/0/terrain_set = 0
|
||||||
8:11/0/terrain = 1
|
8:11/0/terrain = 1
|
||||||
8:11/0/terrains_peering_bit/right_side = 1
|
8:11/0/terrains_peering_bit/right_side = 1
|
||||||
8:11/0/terrains_peering_bit/left_side = 1
|
8:11/0/terrains_peering_bit/left_side = 1
|
||||||
8:11/0/terrains_peering_bit/top_side = 1
|
8:11/0/terrains_peering_bit/top_side = 1
|
||||||
|
8:11/0/custom_data_5 = 5
|
||||||
7:11/0 = 0
|
7:11/0 = 0
|
||||||
7:11/0/terrain_set = 0
|
7:11/0/terrain_set = 0
|
||||||
7:11/0/terrain = 1
|
7:11/0/terrain = 1
|
||||||
7:11/0/terrains_peering_bit/left_side = 1
|
7:11/0/terrains_peering_bit/left_side = 1
|
||||||
7:11/0/terrains_peering_bit/top_side = 1
|
7:11/0/terrains_peering_bit/top_side = 1
|
||||||
|
7:11/0/custom_data_5 = 5
|
||||||
6:11/0 = 0
|
6:11/0 = 0
|
||||||
6:11/0/terrain_set = 0
|
6:11/0/terrain_set = 0
|
||||||
6:11/0/terrain = 1
|
6:11/0/terrain = 1
|
||||||
@@ -275,6 +314,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
6:11/0/terrains_peering_bit/left_side = 1
|
6:11/0/terrains_peering_bit/left_side = 1
|
||||||
6:11/0/terrains_peering_bit/top_side = 1
|
6:11/0/terrains_peering_bit/top_side = 1
|
||||||
6:11/0/terrains_peering_bit/top_right_corner = 1
|
6:11/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
6:11/0/custom_data_5 = 5
|
||||||
5:11/0 = 0
|
5:11/0 = 0
|
||||||
5:11/0/terrain_set = 0
|
5:11/0/terrain_set = 0
|
||||||
5:11/0/terrain = 1
|
5:11/0/terrain = 1
|
||||||
@@ -282,33 +322,40 @@ texture = ExtResource("1_wepw1")
|
|||||||
5:11/0/terrains_peering_bit/left_side = 1
|
5:11/0/terrains_peering_bit/left_side = 1
|
||||||
5:11/0/terrains_peering_bit/top_left_corner = 1
|
5:11/0/terrains_peering_bit/top_left_corner = 1
|
||||||
5:11/0/terrains_peering_bit/top_side = 1
|
5:11/0/terrains_peering_bit/top_side = 1
|
||||||
|
5:11/0/custom_data_5 = 5
|
||||||
4:11/0 = 0
|
4:11/0 = 0
|
||||||
4:11/0/terrain_set = 0
|
4:11/0/terrain_set = 0
|
||||||
4:11/0/terrain = 1
|
4:11/0/terrain = 1
|
||||||
4:11/0/terrains_peering_bit/right_side = 1
|
4:11/0/terrains_peering_bit/right_side = 1
|
||||||
4:11/0/terrains_peering_bit/top_side = 1
|
4:11/0/terrains_peering_bit/top_side = 1
|
||||||
|
4:11/0/custom_data_5 = 5
|
||||||
3:11/0 = 0
|
3:11/0 = 0
|
||||||
3:11/0/terrain_set = 0
|
3:11/0/terrain_set = 0
|
||||||
3:11/0/terrain = 1
|
3:11/0/terrain = 1
|
||||||
|
3:11/0/custom_data_5 = 5
|
||||||
2:11/0 = 0
|
2:11/0 = 0
|
||||||
2:11/0/terrain_set = 0
|
2:11/0/terrain_set = 0
|
||||||
2:11/0/terrain = 1
|
2:11/0/terrain = 1
|
||||||
2:11/0/terrains_peering_bit/left_side = 1
|
2:11/0/terrains_peering_bit/left_side = 1
|
||||||
|
2:11/0/custom_data_5 = 5
|
||||||
0:11/0 = 0
|
0:11/0 = 0
|
||||||
0:11/0/terrain_set = 0
|
0:11/0/terrain_set = 0
|
||||||
0:11/0/terrain = 1
|
0:11/0/terrain = 1
|
||||||
0:11/0/terrains_peering_bit/right_side = 1
|
0:11/0/terrains_peering_bit/right_side = 1
|
||||||
|
0:11/0/custom_data_5 = 5
|
||||||
1:11/0 = 0
|
1:11/0 = 0
|
||||||
1:11/0/terrain_set = 0
|
1:11/0/terrain_set = 0
|
||||||
1:11/0/terrain = 1
|
1:11/0/terrain = 1
|
||||||
1:11/0/terrains_peering_bit/right_side = 1
|
1:11/0/terrains_peering_bit/right_side = 1
|
||||||
1:11/0/terrains_peering_bit/left_side = 1
|
1:11/0/terrains_peering_bit/left_side = 1
|
||||||
|
1:11/0/custom_data_5 = 5
|
||||||
4:12/0 = 0
|
4:12/0 = 0
|
||||||
4:12/0/terrain_set = 0
|
4:12/0/terrain_set = 0
|
||||||
4:12/0/terrain = 1
|
4:12/0/terrain = 1
|
||||||
4:12/0/terrains_peering_bit/right_side = 1
|
4:12/0/terrains_peering_bit/right_side = 1
|
||||||
4:12/0/terrains_peering_bit/bottom_side = 1
|
4:12/0/terrains_peering_bit/bottom_side = 1
|
||||||
4:12/0/terrains_peering_bit/top_side = 1
|
4:12/0/terrains_peering_bit/top_side = 1
|
||||||
|
4:12/0/custom_data_5 = 5
|
||||||
5:12/0 = 0
|
5:12/0 = 0
|
||||||
5:12/0/terrain_set = 0
|
5:12/0/terrain_set = 0
|
||||||
5:12/0/terrain = 1
|
5:12/0/terrain = 1
|
||||||
@@ -318,6 +365,7 @@ texture = ExtResource("1_wepw1")
|
|||||||
5:12/0/terrains_peering_bit/left_side = 1
|
5:12/0/terrains_peering_bit/left_side = 1
|
||||||
5:12/0/terrains_peering_bit/top_left_corner = 1
|
5:12/0/terrains_peering_bit/top_left_corner = 1
|
||||||
5:12/0/terrains_peering_bit/top_side = 1
|
5:12/0/terrains_peering_bit/top_side = 1
|
||||||
|
5:12/0/custom_data_5 = 5
|
||||||
6:12/0 = 0
|
6:12/0 = 0
|
||||||
6:12/0/terrain_set = 0
|
6:12/0/terrain_set = 0
|
||||||
6:12/0/terrain = 1
|
6:12/0/terrain = 1
|
||||||
@@ -327,12 +375,14 @@ texture = ExtResource("1_wepw1")
|
|||||||
6:12/0/terrains_peering_bit/left_side = 1
|
6:12/0/terrains_peering_bit/left_side = 1
|
||||||
6:12/0/terrains_peering_bit/top_side = 1
|
6:12/0/terrains_peering_bit/top_side = 1
|
||||||
6:12/0/terrains_peering_bit/top_right_corner = 1
|
6:12/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
6:12/0/custom_data_5 = 5
|
||||||
7:12/0 = 0
|
7:12/0 = 0
|
||||||
7:12/0/terrain_set = 0
|
7:12/0/terrain_set = 0
|
||||||
7:12/0/terrain = 1
|
7:12/0/terrain = 1
|
||||||
7:12/0/terrains_peering_bit/bottom_side = 1
|
7:12/0/terrains_peering_bit/bottom_side = 1
|
||||||
7:12/0/terrains_peering_bit/left_side = 1
|
7:12/0/terrains_peering_bit/left_side = 1
|
||||||
7:12/0/terrains_peering_bit/top_side = 1
|
7:12/0/terrains_peering_bit/top_side = 1
|
||||||
|
7:12/0/custom_data_5 = 5
|
||||||
8:12/0 = 0
|
8:12/0 = 0
|
||||||
8:12/0/terrain_set = 0
|
8:12/0/terrain_set = 0
|
||||||
8:12/0/terrain = 1
|
8:12/0/terrain = 1
|
||||||
@@ -340,12 +390,15 @@ texture = ExtResource("1_wepw1")
|
|||||||
8:12/0/terrains_peering_bit/bottom_side = 1
|
8:12/0/terrains_peering_bit/bottom_side = 1
|
||||||
8:12/0/terrains_peering_bit/left_side = 1
|
8:12/0/terrains_peering_bit/left_side = 1
|
||||||
8:12/0/terrains_peering_bit/top_side = 1
|
8:12/0/terrains_peering_bit/top_side = 1
|
||||||
|
8:12/0/custom_data_5 = 5
|
||||||
0:3/0 = 0
|
0:3/0 = 0
|
||||||
0:3/0/terrain_set = 0
|
0:3/0/terrain_set = 0
|
||||||
0:3/0/terrain = 2
|
0:3/0/terrain = 2
|
||||||
0:3/0/terrains_peering_bit/right_side = 2
|
0:3/0/terrains_peering_bit/right_side = 2
|
||||||
0:3/0/terrains_peering_bit/bottom_right_corner = 2
|
0:3/0/terrains_peering_bit/bottom_right_corner = 2
|
||||||
0:3/0/terrains_peering_bit/bottom_side = 2
|
0:3/0/terrains_peering_bit/bottom_side = 2
|
||||||
|
0:3/0/custom_data_4 = true
|
||||||
|
0:3/0/custom_data_5 = 3
|
||||||
0:4/0 = 0
|
0:4/0 = 0
|
||||||
0:4/0/terrain_set = 0
|
0:4/0/terrain_set = 0
|
||||||
0:4/0/terrain = 2
|
0:4/0/terrain = 2
|
||||||
@@ -354,16 +407,22 @@ texture = ExtResource("1_wepw1")
|
|||||||
0:4/0/terrains_peering_bit/bottom_side = 2
|
0:4/0/terrains_peering_bit/bottom_side = 2
|
||||||
0:4/0/terrains_peering_bit/top_side = 2
|
0:4/0/terrains_peering_bit/top_side = 2
|
||||||
0:4/0/terrains_peering_bit/top_right_corner = 2
|
0:4/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
0:4/0/custom_data_4 = true
|
||||||
|
0:4/0/custom_data_5 = 3
|
||||||
0:5/0 = 0
|
0:5/0 = 0
|
||||||
0:5/0/terrain_set = 0
|
0:5/0/terrain_set = 0
|
||||||
0:5/0/terrain = 2
|
0:5/0/terrain = 2
|
||||||
0:5/0/terrains_peering_bit/right_side = 2
|
0:5/0/terrains_peering_bit/right_side = 2
|
||||||
0:5/0/terrains_peering_bit/top_side = 2
|
0:5/0/terrains_peering_bit/top_side = 2
|
||||||
0:5/0/terrains_peering_bit/top_right_corner = 2
|
0:5/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
0:5/0/custom_data_4 = true
|
||||||
|
0:5/0/custom_data_5 = 3
|
||||||
0:6/0 = 0
|
0:6/0 = 0
|
||||||
0:6/0/terrain_set = 0
|
0:6/0/terrain_set = 0
|
||||||
0:6/0/terrain = 2
|
0:6/0/terrain = 2
|
||||||
0:6/0/terrains_peering_bit/right_side = 2
|
0:6/0/terrains_peering_bit/right_side = 2
|
||||||
|
0:6/0/custom_data_4 = true
|
||||||
|
0:6/0/custom_data_5 = 3
|
||||||
1:3/0 = 0
|
1:3/0 = 0
|
||||||
1:3/0/terrain_set = 0
|
1:3/0/terrain_set = 0
|
||||||
1:3/0/terrain = 2
|
1:3/0/terrain = 2
|
||||||
@@ -372,6 +431,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
1:3/0/terrains_peering_bit/bottom_side = 2
|
1:3/0/terrains_peering_bit/bottom_side = 2
|
||||||
1:3/0/terrains_peering_bit/bottom_left_corner = 2
|
1:3/0/terrains_peering_bit/bottom_left_corner = 2
|
||||||
1:3/0/terrains_peering_bit/left_side = 2
|
1:3/0/terrains_peering_bit/left_side = 2
|
||||||
|
1:3/0/custom_data_4 = true
|
||||||
|
1:3/0/custom_data_5 = 3
|
||||||
1:4/0 = 0
|
1:4/0 = 0
|
||||||
1:4/0/terrain_set = 0
|
1:4/0/terrain_set = 0
|
||||||
1:4/0/terrain = 2
|
1:4/0/terrain = 2
|
||||||
@@ -383,6 +444,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
1:4/0/terrains_peering_bit/top_left_corner = 2
|
1:4/0/terrains_peering_bit/top_left_corner = 2
|
||||||
1:4/0/terrains_peering_bit/top_side = 2
|
1:4/0/terrains_peering_bit/top_side = 2
|
||||||
1:4/0/terrains_peering_bit/top_right_corner = 2
|
1:4/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
1:4/0/custom_data_4 = true
|
||||||
|
1:4/0/custom_data_5 = 3
|
||||||
1:5/0 = 0
|
1:5/0 = 0
|
||||||
1:5/0/terrain_set = 0
|
1:5/0/terrain_set = 0
|
||||||
1:5/0/terrain = 2
|
1:5/0/terrain = 2
|
||||||
@@ -391,17 +454,23 @@ texture = ExtResource("1_wepw1")
|
|||||||
1:5/0/terrains_peering_bit/top_left_corner = 2
|
1:5/0/terrains_peering_bit/top_left_corner = 2
|
||||||
1:5/0/terrains_peering_bit/top_side = 2
|
1:5/0/terrains_peering_bit/top_side = 2
|
||||||
1:5/0/terrains_peering_bit/top_right_corner = 2
|
1:5/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
1:5/0/custom_data_4 = true
|
||||||
|
1:5/0/custom_data_5 = 3
|
||||||
1:6/0 = 0
|
1:6/0 = 0
|
||||||
1:6/0/terrain_set = 0
|
1:6/0/terrain_set = 0
|
||||||
1:6/0/terrain = 2
|
1:6/0/terrain = 2
|
||||||
1:6/0/terrains_peering_bit/right_side = 2
|
1:6/0/terrains_peering_bit/right_side = 2
|
||||||
1:6/0/terrains_peering_bit/left_side = 2
|
1:6/0/terrains_peering_bit/left_side = 2
|
||||||
|
1:6/0/custom_data_4 = true
|
||||||
|
1:6/0/custom_data_5 = 3
|
||||||
2:3/0 = 0
|
2:3/0 = 0
|
||||||
2:3/0/terrain_set = 0
|
2:3/0/terrain_set = 0
|
||||||
2:3/0/terrain = 2
|
2:3/0/terrain = 2
|
||||||
2:3/0/terrains_peering_bit/bottom_side = 2
|
2:3/0/terrains_peering_bit/bottom_side = 2
|
||||||
2:3/0/terrains_peering_bit/bottom_left_corner = 2
|
2:3/0/terrains_peering_bit/bottom_left_corner = 2
|
||||||
2:3/0/terrains_peering_bit/left_side = 2
|
2:3/0/terrains_peering_bit/left_side = 2
|
||||||
|
2:3/0/custom_data_4 = true
|
||||||
|
2:3/0/custom_data_5 = 3
|
||||||
2:4/0 = 0
|
2:4/0 = 0
|
||||||
2:4/0/terrain_set = 0
|
2:4/0/terrain_set = 0
|
||||||
2:4/0/terrain = 2
|
2:4/0/terrain = 2
|
||||||
@@ -410,37 +479,53 @@ texture = ExtResource("1_wepw1")
|
|||||||
2:4/0/terrains_peering_bit/left_side = 2
|
2:4/0/terrains_peering_bit/left_side = 2
|
||||||
2:4/0/terrains_peering_bit/top_left_corner = 2
|
2:4/0/terrains_peering_bit/top_left_corner = 2
|
||||||
2:4/0/terrains_peering_bit/top_side = 2
|
2:4/0/terrains_peering_bit/top_side = 2
|
||||||
|
2:4/0/custom_data_4 = true
|
||||||
|
2:4/0/custom_data_5 = 3
|
||||||
2:5/0 = 0
|
2:5/0 = 0
|
||||||
2:5/0/terrain_set = 0
|
2:5/0/terrain_set = 0
|
||||||
2:5/0/terrain = 2
|
2:5/0/terrain = 2
|
||||||
2:5/0/terrains_peering_bit/left_side = 2
|
2:5/0/terrains_peering_bit/left_side = 2
|
||||||
2:5/0/terrains_peering_bit/top_left_corner = 2
|
2:5/0/terrains_peering_bit/top_left_corner = 2
|
||||||
2:5/0/terrains_peering_bit/top_side = 2
|
2:5/0/terrains_peering_bit/top_side = 2
|
||||||
|
2:5/0/custom_data_4 = true
|
||||||
|
2:5/0/custom_data_5 = 3
|
||||||
2:6/0 = 0
|
2:6/0 = 0
|
||||||
2:6/0/terrain_set = 0
|
2:6/0/terrain_set = 0
|
||||||
2:6/0/terrain = 2
|
2:6/0/terrain = 2
|
||||||
2:6/0/terrains_peering_bit/left_side = 2
|
2:6/0/terrains_peering_bit/left_side = 2
|
||||||
|
2:6/0/custom_data_4 = true
|
||||||
|
2:6/0/custom_data_5 = 3
|
||||||
3:3/0 = 0
|
3:3/0 = 0
|
||||||
3:3/0/terrain_set = 0
|
3:3/0/terrain_set = 0
|
||||||
3:3/0/terrain = 2
|
3:3/0/terrain = 2
|
||||||
3:3/0/terrains_peering_bit/bottom_side = 2
|
3:3/0/terrains_peering_bit/bottom_side = 2
|
||||||
|
3:3/0/custom_data_4 = true
|
||||||
|
3:3/0/custom_data_5 = 3
|
||||||
3:4/0 = 0
|
3:4/0 = 0
|
||||||
3:4/0/terrain_set = 0
|
3:4/0/terrain_set = 0
|
||||||
3:4/0/terrain = 2
|
3:4/0/terrain = 2
|
||||||
3:4/0/terrains_peering_bit/bottom_side = 2
|
3:4/0/terrains_peering_bit/bottom_side = 2
|
||||||
3:4/0/terrains_peering_bit/top_side = 2
|
3:4/0/terrains_peering_bit/top_side = 2
|
||||||
|
3:4/0/custom_data_4 = true
|
||||||
|
3:4/0/custom_data_5 = 3
|
||||||
3:5/0 = 0
|
3:5/0 = 0
|
||||||
3:5/0/terrain_set = 0
|
3:5/0/terrain_set = 0
|
||||||
3:5/0/terrain = 2
|
3:5/0/terrain = 2
|
||||||
3:5/0/terrains_peering_bit/top_side = 2
|
3:5/0/terrains_peering_bit/top_side = 2
|
||||||
|
3:5/0/custom_data_4 = true
|
||||||
|
3:5/0/custom_data_5 = 3
|
||||||
3:6/0 = 0
|
3:6/0 = 0
|
||||||
3:6/0/terrain_set = 0
|
3:6/0/terrain_set = 0
|
||||||
3:6/0/terrain = 2
|
3:6/0/terrain = 2
|
||||||
|
3:6/0/custom_data_4 = true
|
||||||
|
3:6/0/custom_data_5 = 3
|
||||||
4:3/0 = 0
|
4:3/0 = 0
|
||||||
4:3/0/terrain_set = 0
|
4:3/0/terrain_set = 0
|
||||||
4:3/0/terrain = 2
|
4:3/0/terrain = 2
|
||||||
4:3/0/terrains_peering_bit/right_side = 2
|
4:3/0/terrains_peering_bit/right_side = 2
|
||||||
4:3/0/terrains_peering_bit/bottom_side = 2
|
4:3/0/terrains_peering_bit/bottom_side = 2
|
||||||
|
4:3/0/custom_data_4 = true
|
||||||
|
4:3/0/custom_data_5 = 3
|
||||||
4:4/0 = 0
|
4:4/0 = 0
|
||||||
4:4/0/terrain_set = 0
|
4:4/0/terrain_set = 0
|
||||||
4:4/0/terrain = 2
|
4:4/0/terrain = 2
|
||||||
@@ -448,6 +533,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
4:4/0/terrains_peering_bit/bottom_side = 2
|
4:4/0/terrains_peering_bit/bottom_side = 2
|
||||||
4:4/0/terrains_peering_bit/top_side = 2
|
4:4/0/terrains_peering_bit/top_side = 2
|
||||||
4:4/0/terrains_peering_bit/top_right_corner = 2
|
4:4/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
4:4/0/custom_data_4 = true
|
||||||
|
4:4/0/custom_data_5 = 3
|
||||||
4:5/0 = 0
|
4:5/0 = 0
|
||||||
4:5/0/terrain_set = 0
|
4:5/0/terrain_set = 0
|
||||||
4:5/0/terrain = 2
|
4:5/0/terrain = 2
|
||||||
@@ -455,11 +542,15 @@ texture = ExtResource("1_wepw1")
|
|||||||
4:5/0/terrains_peering_bit/bottom_right_corner = 2
|
4:5/0/terrains_peering_bit/bottom_right_corner = 2
|
||||||
4:5/0/terrains_peering_bit/bottom_side = 2
|
4:5/0/terrains_peering_bit/bottom_side = 2
|
||||||
4:5/0/terrains_peering_bit/top_side = 2
|
4:5/0/terrains_peering_bit/top_side = 2
|
||||||
|
4:5/0/custom_data_4 = true
|
||||||
|
4:5/0/custom_data_5 = 3
|
||||||
4:6/0 = 0
|
4:6/0 = 0
|
||||||
4:6/0/terrain_set = 0
|
4:6/0/terrain_set = 0
|
||||||
4:6/0/terrain = 2
|
4:6/0/terrain = 2
|
||||||
4:6/0/terrains_peering_bit/right_side = 2
|
4:6/0/terrains_peering_bit/right_side = 2
|
||||||
4:6/0/terrains_peering_bit/top_side = 2
|
4:6/0/terrains_peering_bit/top_side = 2
|
||||||
|
4:6/0/custom_data_4 = true
|
||||||
|
4:6/0/custom_data_5 = 3
|
||||||
5:3/0 = 0
|
5:3/0 = 0
|
||||||
5:3/0/terrain_set = 0
|
5:3/0/terrain_set = 0
|
||||||
5:3/0/terrain = 2
|
5:3/0/terrain = 2
|
||||||
@@ -467,6 +558,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
5:3/0/terrains_peering_bit/bottom_side = 2
|
5:3/0/terrains_peering_bit/bottom_side = 2
|
||||||
5:3/0/terrains_peering_bit/bottom_left_corner = 2
|
5:3/0/terrains_peering_bit/bottom_left_corner = 2
|
||||||
5:3/0/terrains_peering_bit/left_side = 2
|
5:3/0/terrains_peering_bit/left_side = 2
|
||||||
|
5:3/0/custom_data_4 = true
|
||||||
|
5:3/0/custom_data_5 = 3
|
||||||
5:4/0 = 0
|
5:4/0 = 0
|
||||||
5:4/0/terrain_set = 0
|
5:4/0/terrain_set = 0
|
||||||
5:4/0/terrain = 2
|
5:4/0/terrain = 2
|
||||||
@@ -477,6 +570,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
5:4/0/terrains_peering_bit/top_left_corner = 2
|
5:4/0/terrains_peering_bit/top_left_corner = 2
|
||||||
5:4/0/terrains_peering_bit/top_side = 2
|
5:4/0/terrains_peering_bit/top_side = 2
|
||||||
5:4/0/terrains_peering_bit/top_right_corner = 2
|
5:4/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
5:4/0/custom_data_4 = true
|
||||||
|
5:4/0/custom_data_5 = 3
|
||||||
5:5/0 = 0
|
5:5/0 = 0
|
||||||
5:5/0/terrain_set = 0
|
5:5/0/terrain_set = 0
|
||||||
5:5/0/terrain = 2
|
5:5/0/terrain = 2
|
||||||
@@ -487,6 +582,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
5:5/0/terrains_peering_bit/left_side = 2
|
5:5/0/terrains_peering_bit/left_side = 2
|
||||||
5:5/0/terrains_peering_bit/top_left_corner = 2
|
5:5/0/terrains_peering_bit/top_left_corner = 2
|
||||||
5:5/0/terrains_peering_bit/top_side = 2
|
5:5/0/terrains_peering_bit/top_side = 2
|
||||||
|
5:5/0/custom_data_4 = true
|
||||||
|
5:5/0/custom_data_5 = 3
|
||||||
5:6/0 = 0
|
5:6/0 = 0
|
||||||
5:6/0/terrain_set = 0
|
5:6/0/terrain_set = 0
|
||||||
5:6/0/terrain = 2
|
5:6/0/terrain = 2
|
||||||
@@ -494,6 +591,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
5:6/0/terrains_peering_bit/left_side = 2
|
5:6/0/terrains_peering_bit/left_side = 2
|
||||||
5:6/0/terrains_peering_bit/top_left_corner = 2
|
5:6/0/terrains_peering_bit/top_left_corner = 2
|
||||||
5:6/0/terrains_peering_bit/top_side = 2
|
5:6/0/terrains_peering_bit/top_side = 2
|
||||||
|
5:6/0/custom_data_4 = true
|
||||||
|
5:6/0/custom_data_5 = 3
|
||||||
6:3/0 = 0
|
6:3/0 = 0
|
||||||
6:3/0/terrain_set = 0
|
6:3/0/terrain_set = 0
|
||||||
6:3/0/terrain = 2
|
6:3/0/terrain = 2
|
||||||
@@ -501,6 +600,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
6:3/0/terrains_peering_bit/bottom_right_corner = 2
|
6:3/0/terrains_peering_bit/bottom_right_corner = 2
|
||||||
6:3/0/terrains_peering_bit/bottom_side = 2
|
6:3/0/terrains_peering_bit/bottom_side = 2
|
||||||
6:3/0/terrains_peering_bit/left_side = 2
|
6:3/0/terrains_peering_bit/left_side = 2
|
||||||
|
6:3/0/custom_data_4 = true
|
||||||
|
6:3/0/custom_data_5 = 3
|
||||||
6:4/0 = 0
|
6:4/0 = 0
|
||||||
6:4/0/terrain_set = 0
|
6:4/0/terrain_set = 0
|
||||||
6:4/0/terrain = 2
|
6:4/0/terrain = 2
|
||||||
@@ -511,6 +612,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
6:4/0/terrains_peering_bit/top_left_corner = 2
|
6:4/0/terrains_peering_bit/top_left_corner = 2
|
||||||
6:4/0/terrains_peering_bit/top_side = 2
|
6:4/0/terrains_peering_bit/top_side = 2
|
||||||
6:4/0/terrains_peering_bit/top_right_corner = 2
|
6:4/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
6:4/0/custom_data_4 = true
|
||||||
|
6:4/0/custom_data_5 = 3
|
||||||
6:5/0 = 0
|
6:5/0 = 0
|
||||||
6:5/0/terrain_set = 0
|
6:5/0/terrain_set = 0
|
||||||
6:5/0/terrain = 2
|
6:5/0/terrain = 2
|
||||||
@@ -521,6 +624,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
6:5/0/terrains_peering_bit/left_side = 2
|
6:5/0/terrains_peering_bit/left_side = 2
|
||||||
6:5/0/terrains_peering_bit/top_side = 2
|
6:5/0/terrains_peering_bit/top_side = 2
|
||||||
6:5/0/terrains_peering_bit/top_right_corner = 2
|
6:5/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
6:5/0/custom_data_4 = true
|
||||||
|
6:5/0/custom_data_5 = 3
|
||||||
6:6/0 = 0
|
6:6/0 = 0
|
||||||
6:6/0/terrain_set = 0
|
6:6/0/terrain_set = 0
|
||||||
6:6/0/terrain = 2
|
6:6/0/terrain = 2
|
||||||
@@ -528,11 +633,15 @@ texture = ExtResource("1_wepw1")
|
|||||||
6:6/0/terrains_peering_bit/left_side = 2
|
6:6/0/terrains_peering_bit/left_side = 2
|
||||||
6:6/0/terrains_peering_bit/top_side = 2
|
6:6/0/terrains_peering_bit/top_side = 2
|
||||||
6:6/0/terrains_peering_bit/top_right_corner = 2
|
6:6/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
6:6/0/custom_data_4 = true
|
||||||
|
6:6/0/custom_data_5 = 3
|
||||||
7:3/0 = 0
|
7:3/0 = 0
|
||||||
7:3/0/terrain_set = 0
|
7:3/0/terrain_set = 0
|
||||||
7:3/0/terrain = 2
|
7:3/0/terrain = 2
|
||||||
7:3/0/terrains_peering_bit/bottom_side = 2
|
7:3/0/terrains_peering_bit/bottom_side = 2
|
||||||
7:3/0/terrains_peering_bit/left_side = 2
|
7:3/0/terrains_peering_bit/left_side = 2
|
||||||
|
7:3/0/custom_data_4 = true
|
||||||
|
7:3/0/custom_data_5 = 3
|
||||||
7:4/0 = 0
|
7:4/0 = 0
|
||||||
7:4/0/terrain_set = 0
|
7:4/0/terrain_set = 0
|
||||||
7:4/0/terrain = 2
|
7:4/0/terrain = 2
|
||||||
@@ -540,6 +649,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
7:4/0/terrains_peering_bit/left_side = 2
|
7:4/0/terrains_peering_bit/left_side = 2
|
||||||
7:4/0/terrains_peering_bit/top_left_corner = 2
|
7:4/0/terrains_peering_bit/top_left_corner = 2
|
||||||
7:4/0/terrains_peering_bit/top_side = 2
|
7:4/0/terrains_peering_bit/top_side = 2
|
||||||
|
7:4/0/custom_data_4 = true
|
||||||
|
7:4/0/custom_data_5 = 3
|
||||||
7:5/0 = 0
|
7:5/0 = 0
|
||||||
7:5/0/terrain_set = 0
|
7:5/0/terrain_set = 0
|
||||||
7:5/0/terrain = 2
|
7:5/0/terrain = 2
|
||||||
@@ -547,17 +658,23 @@ texture = ExtResource("1_wepw1")
|
|||||||
7:5/0/terrains_peering_bit/bottom_left_corner = 2
|
7:5/0/terrains_peering_bit/bottom_left_corner = 2
|
||||||
7:5/0/terrains_peering_bit/left_side = 2
|
7:5/0/terrains_peering_bit/left_side = 2
|
||||||
7:5/0/terrains_peering_bit/top_side = 2
|
7:5/0/terrains_peering_bit/top_side = 2
|
||||||
|
7:5/0/custom_data_4 = true
|
||||||
|
7:5/0/custom_data_5 = 3
|
||||||
7:6/0 = 0
|
7:6/0 = 0
|
||||||
7:6/0/terrain_set = 0
|
7:6/0/terrain_set = 0
|
||||||
7:6/0/terrain = 2
|
7:6/0/terrain = 2
|
||||||
7:6/0/terrains_peering_bit/left_side = 2
|
7:6/0/terrains_peering_bit/left_side = 2
|
||||||
7:6/0/terrains_peering_bit/top_side = 2
|
7:6/0/terrains_peering_bit/top_side = 2
|
||||||
|
7:6/0/custom_data_4 = true
|
||||||
|
7:6/0/custom_data_5 = 3
|
||||||
8:3/0 = 0
|
8:3/0 = 0
|
||||||
8:3/0/terrain_set = 0
|
8:3/0/terrain_set = 0
|
||||||
8:3/0/terrain = 2
|
8:3/0/terrain = 2
|
||||||
8:3/0/terrains_peering_bit/right_side = 2
|
8:3/0/terrains_peering_bit/right_side = 2
|
||||||
8:3/0/terrains_peering_bit/bottom_side = 2
|
8:3/0/terrains_peering_bit/bottom_side = 2
|
||||||
8:3/0/terrains_peering_bit/left_side = 2
|
8:3/0/terrains_peering_bit/left_side = 2
|
||||||
|
8:3/0/custom_data_4 = true
|
||||||
|
8:3/0/custom_data_5 = 3
|
||||||
8:4/0 = 0
|
8:4/0 = 0
|
||||||
8:4/0/terrain_set = 0
|
8:4/0/terrain_set = 0
|
||||||
8:4/0/terrain = 2
|
8:4/0/terrain = 2
|
||||||
@@ -567,6 +684,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
8:4/0/terrains_peering_bit/top_left_corner = 2
|
8:4/0/terrains_peering_bit/top_left_corner = 2
|
||||||
8:4/0/terrains_peering_bit/top_side = 2
|
8:4/0/terrains_peering_bit/top_side = 2
|
||||||
8:4/0/terrains_peering_bit/top_right_corner = 2
|
8:4/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
8:4/0/custom_data_4 = true
|
||||||
|
8:4/0/custom_data_5 = 3
|
||||||
8:5/0 = 0
|
8:5/0 = 0
|
||||||
8:5/0/terrain_set = 0
|
8:5/0/terrain_set = 0
|
||||||
8:5/0/terrain = 2
|
8:5/0/terrain = 2
|
||||||
@@ -576,12 +695,16 @@ texture = ExtResource("1_wepw1")
|
|||||||
8:5/0/terrains_peering_bit/bottom_left_corner = 2
|
8:5/0/terrains_peering_bit/bottom_left_corner = 2
|
||||||
8:5/0/terrains_peering_bit/left_side = 2
|
8:5/0/terrains_peering_bit/left_side = 2
|
||||||
8:5/0/terrains_peering_bit/top_side = 2
|
8:5/0/terrains_peering_bit/top_side = 2
|
||||||
|
8:5/0/custom_data_4 = true
|
||||||
|
8:5/0/custom_data_5 = 3
|
||||||
8:6/0 = 0
|
8:6/0 = 0
|
||||||
8:6/0/terrain_set = 0
|
8:6/0/terrain_set = 0
|
||||||
8:6/0/terrain = 2
|
8:6/0/terrain = 2
|
||||||
8:6/0/terrains_peering_bit/right_side = 2
|
8:6/0/terrains_peering_bit/right_side = 2
|
||||||
8:6/0/terrains_peering_bit/left_side = 2
|
8:6/0/terrains_peering_bit/left_side = 2
|
||||||
8:6/0/terrains_peering_bit/top_side = 2
|
8:6/0/terrains_peering_bit/top_side = 2
|
||||||
|
8:6/0/custom_data_4 = true
|
||||||
|
8:6/0/custom_data_5 = 3
|
||||||
9:3/0 = 0
|
9:3/0 = 0
|
||||||
9:3/0/terrain_set = 0
|
9:3/0/terrain_set = 0
|
||||||
9:3/0/terrain = 2
|
9:3/0/terrain = 2
|
||||||
@@ -591,6 +714,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
9:3/0/terrains_peering_bit/left_side = 2
|
9:3/0/terrains_peering_bit/left_side = 2
|
||||||
9:3/0/terrains_peering_bit/top_left_corner = 2
|
9:3/0/terrains_peering_bit/top_left_corner = 2
|
||||||
9:3/0/terrains_peering_bit/top_side = 2
|
9:3/0/terrains_peering_bit/top_side = 2
|
||||||
|
9:3/0/custom_data_4 = true
|
||||||
|
9:3/0/custom_data_5 = 3
|
||||||
9:4/0 = 0
|
9:4/0 = 0
|
||||||
9:4/0/terrain_set = 0
|
9:4/0/terrain_set = 0
|
||||||
9:4/0/terrain = 2
|
9:4/0/terrain = 2
|
||||||
@@ -600,6 +725,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
9:4/0/terrains_peering_bit/left_side = 2
|
9:4/0/terrains_peering_bit/left_side = 2
|
||||||
9:4/0/terrains_peering_bit/top_side = 2
|
9:4/0/terrains_peering_bit/top_side = 2
|
||||||
9:4/0/terrains_peering_bit/top_right_corner = 2
|
9:4/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
9:4/0/custom_data_4 = true
|
||||||
|
9:4/0/custom_data_5 = 3
|
||||||
9:5/0 = 0
|
9:5/0 = 0
|
||||||
9:5/0/terrain_set = 0
|
9:5/0/terrain_set = 0
|
||||||
9:5/0/terrain = 2
|
9:5/0/terrain = 2
|
||||||
@@ -608,6 +735,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
9:5/0/terrains_peering_bit/bottom_side = 2
|
9:5/0/terrains_peering_bit/bottom_side = 2
|
||||||
9:5/0/terrains_peering_bit/left_side = 2
|
9:5/0/terrains_peering_bit/left_side = 2
|
||||||
9:5/0/terrains_peering_bit/top_side = 2
|
9:5/0/terrains_peering_bit/top_side = 2
|
||||||
|
9:5/0/custom_data_4 = true
|
||||||
|
9:5/0/custom_data_5 = 3
|
||||||
9:6/0 = 0
|
9:6/0 = 0
|
||||||
9:6/0/terrain_set = 0
|
9:6/0/terrain_set = 0
|
||||||
9:6/0/terrain = 2
|
9:6/0/terrain = 2
|
||||||
@@ -616,6 +745,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
9:6/0/terrains_peering_bit/left_side = 2
|
9:6/0/terrains_peering_bit/left_side = 2
|
||||||
9:6/0/terrains_peering_bit/top_side = 2
|
9:6/0/terrains_peering_bit/top_side = 2
|
||||||
9:6/0/terrains_peering_bit/top_right_corner = 2
|
9:6/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
9:6/0/custom_data_4 = true
|
||||||
|
9:6/0/custom_data_5 = 3
|
||||||
10:5/0 = 0
|
10:5/0 = 0
|
||||||
10:5/0/terrain_set = 0
|
10:5/0/terrain_set = 0
|
||||||
10:5/0/terrain = 2
|
10:5/0/terrain = 2
|
||||||
@@ -624,6 +755,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
10:5/0/terrains_peering_bit/bottom_left_corner = 2
|
10:5/0/terrains_peering_bit/bottom_left_corner = 2
|
||||||
10:5/0/terrains_peering_bit/left_side = 2
|
10:5/0/terrains_peering_bit/left_side = 2
|
||||||
10:5/0/terrains_peering_bit/top_side = 2
|
10:5/0/terrains_peering_bit/top_side = 2
|
||||||
|
10:5/0/custom_data_4 = true
|
||||||
|
10:5/0/custom_data_5 = 3
|
||||||
10:6/0 = 0
|
10:6/0 = 0
|
||||||
10:6/0/terrain_set = 0
|
10:6/0/terrain_set = 0
|
||||||
10:6/0/terrain = 2
|
10:6/0/terrain = 2
|
||||||
@@ -632,12 +765,16 @@ texture = ExtResource("1_wepw1")
|
|||||||
10:6/0/terrains_peering_bit/left_side = 2
|
10:6/0/terrains_peering_bit/left_side = 2
|
||||||
10:6/0/terrains_peering_bit/top_left_corner = 2
|
10:6/0/terrains_peering_bit/top_left_corner = 2
|
||||||
10:6/0/terrains_peering_bit/top_side = 2
|
10:6/0/terrains_peering_bit/top_side = 2
|
||||||
|
10:6/0/custom_data_4 = true
|
||||||
|
10:6/0/custom_data_5 = 3
|
||||||
4:7/0 = 0
|
4:7/0 = 0
|
||||||
4:7/0/terrain_set = 0
|
4:7/0/terrain_set = 0
|
||||||
4:7/0/terrain = 2
|
4:7/0/terrain = 2
|
||||||
4:7/0/terrains_peering_bit/right_side = 2
|
4:7/0/terrains_peering_bit/right_side = 2
|
||||||
4:7/0/terrains_peering_bit/bottom_side = 2
|
4:7/0/terrains_peering_bit/bottom_side = 2
|
||||||
4:7/0/terrains_peering_bit/top_side = 2
|
4:7/0/terrains_peering_bit/top_side = 2
|
||||||
|
4:7/0/custom_data_4 = true
|
||||||
|
4:7/0/custom_data_5 = 3
|
||||||
5:7/0 = 0
|
5:7/0 = 0
|
||||||
5:7/0/terrain_set = 0
|
5:7/0/terrain_set = 0
|
||||||
5:7/0/terrain = 2
|
5:7/0/terrain = 2
|
||||||
@@ -647,6 +784,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
5:7/0/terrains_peering_bit/left_side = 2
|
5:7/0/terrains_peering_bit/left_side = 2
|
||||||
5:7/0/terrains_peering_bit/top_left_corner = 2
|
5:7/0/terrains_peering_bit/top_left_corner = 2
|
||||||
5:7/0/terrains_peering_bit/top_side = 2
|
5:7/0/terrains_peering_bit/top_side = 2
|
||||||
|
5:7/0/custom_data_4 = true
|
||||||
|
5:7/0/custom_data_5 = 3
|
||||||
6:7/0 = 0
|
6:7/0 = 0
|
||||||
6:7/0/terrain_set = 0
|
6:7/0/terrain_set = 0
|
||||||
6:7/0/terrain = 2
|
6:7/0/terrain = 2
|
||||||
@@ -656,12 +795,16 @@ texture = ExtResource("1_wepw1")
|
|||||||
6:7/0/terrains_peering_bit/left_side = 2
|
6:7/0/terrains_peering_bit/left_side = 2
|
||||||
6:7/0/terrains_peering_bit/top_side = 2
|
6:7/0/terrains_peering_bit/top_side = 2
|
||||||
6:7/0/terrains_peering_bit/top_right_corner = 2
|
6:7/0/terrains_peering_bit/top_right_corner = 2
|
||||||
|
6:7/0/custom_data_4 = true
|
||||||
|
6:7/0/custom_data_5 = 3
|
||||||
7:7/0 = 0
|
7:7/0 = 0
|
||||||
7:7/0/terrain_set = 0
|
7:7/0/terrain_set = 0
|
||||||
7:7/0/terrain = 2
|
7:7/0/terrain = 2
|
||||||
7:7/0/terrains_peering_bit/bottom_side = 2
|
7:7/0/terrains_peering_bit/bottom_side = 2
|
||||||
7:7/0/terrains_peering_bit/left_side = 2
|
7:7/0/terrains_peering_bit/left_side = 2
|
||||||
7:7/0/terrains_peering_bit/top_side = 2
|
7:7/0/terrains_peering_bit/top_side = 2
|
||||||
|
7:7/0/custom_data_4 = true
|
||||||
|
7:7/0/custom_data_5 = 3
|
||||||
8:7/0 = 0
|
8:7/0 = 0
|
||||||
8:7/0/terrain_set = 0
|
8:7/0/terrain_set = 0
|
||||||
8:7/0/terrain = 2
|
8:7/0/terrain = 2
|
||||||
@@ -669,6 +812,8 @@ texture = ExtResource("1_wepw1")
|
|||||||
8:7/0/terrains_peering_bit/bottom_side = 2
|
8:7/0/terrains_peering_bit/bottom_side = 2
|
||||||
8:7/0/terrains_peering_bit/left_side = 2
|
8:7/0/terrains_peering_bit/left_side = 2
|
||||||
8:7/0/terrains_peering_bit/top_side = 2
|
8:7/0/terrains_peering_bit/top_side = 2
|
||||||
|
8:7/0/custom_data_4 = true
|
||||||
|
8:7/0/custom_data_5 = 3
|
||||||
1:9/0 = 0
|
1:9/0 = 0
|
||||||
1:9/0/terrain_set = 0
|
1:9/0/terrain_set = 0
|
||||||
1:9/0/terrain = 1
|
1:9/0/terrain = 1
|
||||||
@@ -680,109 +825,172 @@ texture = ExtResource("1_wepw1")
|
|||||||
1:9/0/terrains_peering_bit/top_left_corner = 1
|
1:9/0/terrains_peering_bit/top_left_corner = 1
|
||||||
1:9/0/terrains_peering_bit/top_side = 1
|
1:9/0/terrains_peering_bit/top_side = 1
|
||||||
1:9/0/terrains_peering_bit/top_right_corner = 1
|
1:9/0/terrains_peering_bit/top_right_corner = 1
|
||||||
|
1:9/0/custom_data_5 = 5
|
||||||
|
|
||||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_mv7cw"]
|
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_mv7cw"]
|
||||||
texture = ExtResource("3_hky6b")
|
texture = ExtResource("4_xeinu")
|
||||||
0:0/0 = 0
|
0:0/0 = 0
|
||||||
0:0/0/custom_data_3 = Vector2i(1, 1)
|
0:0/0/custom_data_3 = Vector2i(1, 1)
|
||||||
|
0:0/0/custom_data_5 = 255
|
||||||
1:0/0 = 0
|
1:0/0 = 0
|
||||||
1:0/0/custom_data_3 = Vector2i(1, 1)
|
1:0/0/custom_data_3 = Vector2i(1, 1)
|
||||||
|
1:0/0/custom_data_5 = 1
|
||||||
2:0/0 = 0
|
2:0/0 = 0
|
||||||
2:0/0/custom_data_3 = Vector2i(0, 1)
|
2:0/0/custom_data_3 = Vector2i(0, 1)
|
||||||
|
2:0/0/custom_data_4 = true
|
||||||
|
2:0/0/custom_data_5 = 2
|
||||||
3:0/0 = 0
|
3:0/0 = 0
|
||||||
3:0/0/custom_data_3 = Vector2i(-1, 1)
|
3:0/0/custom_data_3 = Vector2i(-1, 1)
|
||||||
|
3:0/0/custom_data_5 = 255
|
||||||
4:0/0 = 0
|
4:0/0 = 0
|
||||||
4:0/0/custom_data_3 = Vector2i(-1, 1)
|
4:0/0/custom_data_3 = Vector2i(-1, 1)
|
||||||
|
4:0/0/custom_data_5 = 255
|
||||||
0:1/0 = 0
|
0:1/0 = 0
|
||||||
0:1/0/custom_data_3 = Vector2i(1, 1)
|
0:1/0/custom_data_3 = Vector2i(1, 1)
|
||||||
|
0:1/0/custom_data_5 = 255
|
||||||
1:1/0 = 0
|
1:1/0 = 0
|
||||||
1:1/0/custom_data_3 = Vector2i(1, 1)
|
1:1/0/custom_data_3 = Vector2i(1, 1)
|
||||||
|
1:1/0/custom_data_4 = true
|
||||||
|
1:1/0/custom_data_5 = 1
|
||||||
2:1/0 = 0
|
2:1/0 = 0
|
||||||
2:1/0/custom_data_3 = Vector2i(0, 1)
|
2:1/0/custom_data_3 = Vector2i(0, 1)
|
||||||
|
2:1/0/custom_data_4 = true
|
||||||
|
2:1/0/custom_data_5 = 1
|
||||||
3:1/0 = 0
|
3:1/0 = 0
|
||||||
3:1/0/custom_data_3 = Vector2i(-1, 1)
|
3:1/0/custom_data_3 = Vector2i(-1, 1)
|
||||||
|
3:1/0/custom_data_4 = true
|
||||||
|
3:1/0/custom_data_5 = 1
|
||||||
4:1/0 = 0
|
4:1/0 = 0
|
||||||
4:1/0/custom_data_3 = Vector2i(-1, 1)
|
4:1/0/custom_data_3 = Vector2i(-1, 1)
|
||||||
|
4:1/0/custom_data_5 = 255
|
||||||
0:2/0 = 0
|
0:2/0 = 0
|
||||||
0:2/0/custom_data_3 = Vector2i(1, 0)
|
0:2/0/custom_data_3 = Vector2i(1, 0)
|
||||||
|
0:2/0/custom_data_4 = true
|
||||||
|
0:2/0/custom_data_5 = 2
|
||||||
1:2/0 = 0
|
1:2/0 = 0
|
||||||
1:2/0/custom_data_3 = Vector2i(1, 0)
|
1:2/0/custom_data_3 = Vector2i(1, 0)
|
||||||
|
1:2/0/custom_data_4 = true
|
||||||
|
1:2/0/custom_data_5 = 1
|
||||||
2:2/0 = 0
|
2:2/0 = 0
|
||||||
2:2/0/custom_data_0 = true
|
2:2/0/custom_data_0 = true
|
||||||
2:2/0/custom_data_1 = Vector2i(5, 5)
|
2:2/0/custom_data_1 = Vector2i(5, 5)
|
||||||
2:2/0/custom_data_2 = "EMPTY_ROOM"
|
2:2/0/custom_data_2 = "EMPTY_ROOM"
|
||||||
|
2:2/0/custom_data_4 = true
|
||||||
|
2:2/0/custom_data_5 = 1
|
||||||
3:2/0 = 0
|
3:2/0 = 0
|
||||||
3:2/0/custom_data_3 = Vector2i(-1, 0)
|
3:2/0/custom_data_3 = Vector2i(-1, 0)
|
||||||
|
3:2/0/custom_data_4 = true
|
||||||
|
3:2/0/custom_data_5 = 1
|
||||||
4:2/0 = 0
|
4:2/0 = 0
|
||||||
4:2/0/custom_data_3 = Vector2i(-1, 0)
|
4:2/0/custom_data_3 = Vector2i(-1, 0)
|
||||||
|
4:2/0/custom_data_4 = true
|
||||||
|
4:2/0/custom_data_5 = 2
|
||||||
0:3/0 = 0
|
0:3/0 = 0
|
||||||
0:3/0/custom_data_3 = Vector2i(1, -1)
|
0:3/0/custom_data_3 = Vector2i(1, -1)
|
||||||
|
0:3/0/custom_data_5 = 255
|
||||||
1:3/0 = 0
|
1:3/0 = 0
|
||||||
1:3/0/custom_data_3 = Vector2i(1, -1)
|
1:3/0/custom_data_3 = Vector2i(1, -1)
|
||||||
|
1:3/0/custom_data_4 = true
|
||||||
|
1:3/0/custom_data_5 = 1
|
||||||
2:3/0 = 0
|
2:3/0 = 0
|
||||||
2:3/0/custom_data_3 = Vector2i(0, -1)
|
2:3/0/custom_data_3 = Vector2i(0, -1)
|
||||||
|
2:3/0/custom_data_4 = true
|
||||||
|
2:3/0/custom_data_5 = 1
|
||||||
3:3/0 = 0
|
3:3/0 = 0
|
||||||
3:3/0/custom_data_3 = Vector2i(-1, -1)
|
3:3/0/custom_data_3 = Vector2i(-1, -1)
|
||||||
|
3:3/0/custom_data_4 = true
|
||||||
|
3:3/0/custom_data_5 = 1
|
||||||
4:3/0 = 0
|
4:3/0 = 0
|
||||||
4:3/0/custom_data_3 = Vector2i(-1, -1)
|
4:3/0/custom_data_3 = Vector2i(-1, -1)
|
||||||
|
4:3/0/custom_data_5 = 255
|
||||||
0:4/0 = 0
|
0:4/0 = 0
|
||||||
0:4/0/custom_data_3 = Vector2i(1, -1)
|
0:4/0/custom_data_3 = Vector2i(1, -1)
|
||||||
|
0:4/0/custom_data_5 = 255
|
||||||
1:4/0 = 0
|
1:4/0 = 0
|
||||||
1:4/0/custom_data_3 = Vector2i(1, -1)
|
1:4/0/custom_data_3 = Vector2i(1, -1)
|
||||||
|
1:4/0/custom_data_5 = 255
|
||||||
2:4/0 = 0
|
2:4/0 = 0
|
||||||
2:4/0/custom_data_3 = Vector2i(0, -1)
|
2:4/0/custom_data_3 = Vector2i(0, -1)
|
||||||
|
2:4/0/custom_data_4 = true
|
||||||
|
2:4/0/custom_data_5 = 2
|
||||||
3:4/0 = 0
|
3:4/0 = 0
|
||||||
3:4/0/custom_data_3 = Vector2i(-1, -1)
|
3:4/0/custom_data_3 = Vector2i(-1, -1)
|
||||||
|
3:4/0/custom_data_5 = 255
|
||||||
4:4/0 = 0
|
4:4/0 = 0
|
||||||
4:4/0/custom_data_3 = Vector2i(-1, -1)
|
4:4/0/custom_data_3 = Vector2i(-1, -1)
|
||||||
|
4:4/0/custom_data_5 = 255
|
||||||
1:5/0 = 0
|
1:5/0 = 0
|
||||||
1:5/0/custom_data_0 = true
|
1:5/0/custom_data_0 = true
|
||||||
1:5/0/custom_data_1 = Vector2i(3, 1)
|
1:5/0/custom_data_1 = Vector2i(3, 1)
|
||||||
1:5/0/custom_data_3 = Vector2i(0, 1)
|
1:5/0/custom_data_3 = Vector2i(0, 1)
|
||||||
|
1:5/0/custom_data_4 = true
|
||||||
|
1:5/0/custom_data_5 = 1
|
||||||
2:5/0 = 0
|
2:5/0 = 0
|
||||||
2:5/0/custom_data_3 = Vector2i(-1, 1)
|
2:5/0/custom_data_3 = Vector2i(-1, 1)
|
||||||
|
2:5/0/custom_data_5 = 255
|
||||||
3:5/0 = 0
|
3:5/0 = 0
|
||||||
3:5/0/custom_data_3 = Vector2i(1, 1)
|
3:5/0/custom_data_3 = Vector2i(1, 1)
|
||||||
|
3:5/0/custom_data_5 = 255
|
||||||
1:6/0 = 0
|
1:6/0 = 0
|
||||||
1:6/0/custom_data_0 = true
|
1:6/0/custom_data_0 = true
|
||||||
1:6/0/custom_data_1 = Vector2i(3, 1)
|
1:6/0/custom_data_1 = Vector2i(3, 1)
|
||||||
1:6/0/custom_data_2 = "V_WAY"
|
1:6/0/custom_data_2 = "V_WAY"
|
||||||
|
1:6/0/custom_data_4 = true
|
||||||
|
1:6/0/custom_data_5 = 1
|
||||||
2:6/0 = 0
|
2:6/0 = 0
|
||||||
2:6/0/custom_data_3 = Vector2i(-1, 0)
|
2:6/0/custom_data_3 = Vector2i(-1, 0)
|
||||||
|
2:6/0/custom_data_5 = 255
|
||||||
3:6/0 = 0
|
3:6/0 = 0
|
||||||
3:6/0/custom_data_0 = true
|
3:6/0/custom_data_0 = true
|
||||||
3:6/0/custom_data_1 = Vector2i(1, 3)
|
3:6/0/custom_data_1 = Vector2i(1, 3)
|
||||||
3:6/0/custom_data_3 = Vector2i(1, 0)
|
3:6/0/custom_data_3 = Vector2i(1, 0)
|
||||||
|
3:6/0/custom_data_4 = true
|
||||||
|
3:6/0/custom_data_5 = 1
|
||||||
1:7/0 = 0
|
1:7/0 = 0
|
||||||
1:7/0/custom_data_0 = true
|
1:7/0/custom_data_0 = true
|
||||||
1:7/0/custom_data_1 = Vector2i(3, 1)
|
1:7/0/custom_data_1 = Vector2i(3, 1)
|
||||||
1:7/0/custom_data_3 = Vector2i(0, -1)
|
1:7/0/custom_data_3 = Vector2i(0, -1)
|
||||||
|
1:7/0/custom_data_4 = true
|
||||||
|
1:7/0/custom_data_5 = 1
|
||||||
2:7/0 = 0
|
2:7/0 = 0
|
||||||
2:7/0/custom_data_3 = Vector2i(-1, -1)
|
2:7/0/custom_data_3 = Vector2i(-1, -1)
|
||||||
|
2:7/0/custom_data_5 = 255
|
||||||
3:7/0 = 0
|
3:7/0 = 0
|
||||||
3:7/0/custom_data_3 = Vector2i(1, -1)
|
3:7/0/custom_data_3 = Vector2i(1, -1)
|
||||||
|
3:7/0/custom_data_5 = 255
|
||||||
0:5/0 = 0
|
0:5/0 = 0
|
||||||
0:5/0/custom_data_3 = Vector2i(1, 1)
|
0:5/0/custom_data_3 = Vector2i(1, 1)
|
||||||
|
0:5/0/custom_data_5 = 255
|
||||||
0:6/0 = 0
|
0:6/0 = 0
|
||||||
0:6/0/custom_data_3 = Vector2i(1, 0)
|
0:6/0/custom_data_3 = Vector2i(1, 0)
|
||||||
|
0:6/0/custom_data_5 = 255
|
||||||
0:7/0 = 0
|
0:7/0 = 0
|
||||||
0:7/0/custom_data_3 = Vector2i(1, -1)
|
0:7/0/custom_data_3 = Vector2i(1, -1)
|
||||||
|
0:7/0/custom_data_5 = 255
|
||||||
4:7/0 = 0
|
4:7/0 = 0
|
||||||
4:7/0/custom_data_3 = Vector2i(0, -1)
|
4:7/0/custom_data_3 = Vector2i(0, -1)
|
||||||
|
4:7/0/custom_data_5 = 255
|
||||||
4:6/0 = 0
|
4:6/0 = 0
|
||||||
4:6/0/custom_data_0 = true
|
4:6/0/custom_data_0 = true
|
||||||
4:6/0/custom_data_1 = Vector2i(1, 3)
|
4:6/0/custom_data_1 = Vector2i(1, 3)
|
||||||
4:6/0/custom_data_2 = "H_WAY"
|
4:6/0/custom_data_2 = "H_WAY"
|
||||||
|
4:6/0/custom_data_4 = true
|
||||||
|
4:6/0/custom_data_5 = 1
|
||||||
4:5/0 = 0
|
4:5/0 = 0
|
||||||
4:5/0/custom_data_3 = Vector2i(0, 1)
|
4:5/0/custom_data_3 = Vector2i(0, 1)
|
||||||
|
4:5/0/custom_data_5 = 255
|
||||||
5:5/0 = 0
|
5:5/0 = 0
|
||||||
5:5/0/custom_data_3 = Vector2i(-1, 1)
|
5:5/0/custom_data_3 = Vector2i(-1, 1)
|
||||||
|
5:5/0/custom_data_5 = 255
|
||||||
5:6/0 = 0
|
5:6/0 = 0
|
||||||
5:6/0/custom_data_0 = true
|
5:6/0/custom_data_0 = true
|
||||||
5:6/0/custom_data_1 = Vector2i(1, 3)
|
5:6/0/custom_data_1 = Vector2i(1, 3)
|
||||||
5:6/0/custom_data_3 = Vector2i(-1, 0)
|
5:6/0/custom_data_3 = Vector2i(-1, 0)
|
||||||
|
5:6/0/custom_data_4 = true
|
||||||
|
5:6/0/custom_data_5 = 1
|
||||||
5:7/0 = 0
|
5:7/0 = 0
|
||||||
5:7/0/custom_data_3 = Vector2i(-1, -1)
|
5:7/0/custom_data_3 = Vector2i(-1, -1)
|
||||||
|
5:7/0/custom_data_5 = 255
|
||||||
|
|
||||||
[sub_resource type="TileSet" id="TileSet_twrk0"]
|
[sub_resource type="TileSet" id="TileSet_twrk0"]
|
||||||
terrain_set_0/mode = 0
|
terrain_set_0/mode = 0
|
||||||
@@ -800,15 +1008,19 @@ custom_data_layer_2/name = "struct_name"
|
|||||||
custom_data_layer_2/type = 4
|
custom_data_layer_2/type = 4
|
||||||
custom_data_layer_3/name = "center_direction"
|
custom_data_layer_3/name = "center_direction"
|
||||||
custom_data_layer_3/type = 6
|
custom_data_layer_3/type = 6
|
||||||
|
custom_data_layer_4/name = "walkable"
|
||||||
|
custom_data_layer_4/type = 1
|
||||||
|
custom_data_layer_5/name = "astar_weight"
|
||||||
|
custom_data_layer_5/type = 2
|
||||||
sources/0 = SubResource("TileSetAtlasSource_fyh4j")
|
sources/0 = SubResource("TileSetAtlasSource_fyh4j")
|
||||||
sources/1 = SubResource("TileSetAtlasSource_mv7cw")
|
sources/1 = SubResource("TileSetAtlasSource_mv7cw")
|
||||||
|
|
||||||
[node name="World" type="Node2D"]
|
[node name="World" type="Node2D"]
|
||||||
script = ExtResource("1_336so")
|
script = ExtResource("1_obe6v")
|
||||||
metadata/_edit_horizontal_guides_ = [830.0]
|
metadata/_edit_horizontal_guides_ = [830.0]
|
||||||
|
|
||||||
[node name="TileMap" type="Node2D" parent="."]
|
[node name="TileMap" type="Node2D" parent="."]
|
||||||
script = ExtResource("2_wnvvd")
|
script = ExtResource("2_lm4q6")
|
||||||
|
|
||||||
[node name="mountians" type="TileMapLayer" parent="TileMap"]
|
[node name="mountians" type="TileMapLayer" parent="TileMap"]
|
||||||
z_index = 32
|
z_index = 32
|
||||||
@@ -820,9 +1032,6 @@ tile_set = SubResource("TileSet_twrk0")
|
|||||||
[node name="buildings" type="Node2D" parent="TileMap"]
|
[node name="buildings" type="Node2D" parent="TileMap"]
|
||||||
z_index = 2
|
z_index = 2
|
||||||
|
|
||||||
[node name="Player" parent="TileMap/buildings" instance=ExtResource("5_2xbni")]
|
|
||||||
position = Vector2(603, 507)
|
|
||||||
|
|
||||||
[node name="buildings1" type="TileMapLayer" parent="TileMap/buildings"]
|
[node name="buildings1" type="TileMapLayer" parent="TileMap/buildings"]
|
||||||
z_index = 3
|
z_index = 3
|
||||||
z_as_relative = false
|
z_as_relative = false
|
||||||
@@ -851,3 +1060,6 @@ tile_set = SubResource("TileSet_twrk0")
|
|||||||
|
|
||||||
[node name="Camera2D" type="Camera2D" parent="."]
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
anchor_mode = 0
|
anchor_mode = 0
|
||||||
|
|
||||||
|
[node name="NPCs" type="Node2D" parent="."]
|
||||||
|
script = ExtResource("5_et4gm")
|
||||||