Major clean up and reorganization
- Upgraded to Godot 4 - Just remembered the basic principles are based on a tile editor, and dramatically simplified from there. Derp. - New state machine and license display add-ons. - Re-licensed under the GPL because Micropolis' assets aren't under a separate one.
|
@ -1,24 +0,0 @@
|
|||
extends Reference
|
||||
|
||||
var blackboard = {}
|
||||
|
||||
func set(key, value, blackboard_name = 'default'):
|
||||
if not blackboard.has(blackboard_name):
|
||||
blackboard[blackboard_name] = {}
|
||||
|
||||
blackboard[blackboard_name][key] = value
|
||||
|
||||
|
||||
func get(key, default_value = null, blackboard_name = 'default'):
|
||||
if has(key, blackboard_name):
|
||||
return blackboard[blackboard_name].get(key, default_value)
|
||||
return default_value
|
||||
|
||||
|
||||
func has(key, blackboard_name = 'default'):
|
||||
return blackboard.has(blackboard_name) and blackboard[blackboard_name].has(key) and blackboard[blackboard_name][key] != null
|
||||
|
||||
|
||||
func erase(key, blackboard_name = 'default'):
|
||||
if blackboard.has(blackboard_name):
|
||||
blackboard[blackboard_name][key] = null
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg14360"
|
||||
sodipodi:docname="action.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata14366">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs14364" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
id="namedview14362"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="12"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg14360" />
|
||||
<path
|
||||
d="M 8,4 C 5.792,4 4,5.792 4,8 c 0,2.208 1.792,4 4,4 2.208,0 4,-1.792 4,-4 C 12,5.792 10.208,4 8,4 Z M 8,0 C 3.584,0 0,3.584 0,8 c 0,4.416 3.584,8 8,8 4.416,0 8,-3.584 8,-8 C 16,3.584 12.416,0 8,0 Z M 8,14.4 C 4.464,14.4 1.6,11.536 1.6,8 1.6,4.464 4.464,1.6 8,1.6 c 3.536,0 6.4,2.864 6.4,6.4 0,3.536 -2.864,6.4 -6.4,6.4 z"
|
||||
id="path14356"
|
||||
style="fill:#efd7a5;fill-opacity:1;stroke-width:0.80000001"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path14358"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/action.svg-e8a91246d0ba9ba3cf84290d65648f06.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/action.svg"
|
||||
dest_files=[ "res://.import/action.svg-e8a91246d0ba9ba3cf84290d65648f06.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg893"
|
||||
sodipodi:docname="blackboard.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata899">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs897" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
id="namedview895"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="12"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg893" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path889"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
<path
|
||||
d="M 0,8.888889 H 7.111111 V 0 H 0 Z M 0,16 H 7.111111 V 10.666667 H 0 Z m 8.888889,0 H 16 V 7.111111 H 8.888889 Z m 0,-16 V 5.333333 H 16 V 0 Z"
|
||||
id="path891"
|
||||
style="fill:#b2a5ef;fill-opacity:1;stroke-width:0.8888889"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.8 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/blackboard.svg-18d4dfd4f6de558de250b67251ff1e69.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/blackboard.svg"
|
||||
dest_files=[ "res://.import/blackboard.svg-18d4dfd4f6de558de250b67251ff1e69.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg14360"
|
||||
sodipodi:docname="category_bt.svg"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
|
||||
<metadata
|
||||
id="metadata14366">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs14364" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1051"
|
||||
id="namedview14362"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="-6.0508475"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="29"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg14360" />
|
||||
<path
|
||||
d="M 8,4 C 5.792,4 4,5.792 4,8 c 0,2.208 1.792,4 4,4 2.208,0 4,-1.792 4,-4 C 12,5.792 10.208,4 8,4 Z M 8,0 C 3.584,0 0,3.584 0,8 c 0,4.416 3.584,8 8,8 4.416,0 8,-3.584 8,-8 C 16,3.584 12.416,0 8,0 Z M 8,14.4 C 4.464,14.4 1.6,11.536 1.6,8 1.6,4.464 4.464,1.6 8,1.6 c 3.536,0 6.4,2.864 6.4,6.4 0,3.536 -2.864,6.4 -6.4,6.4 z"
|
||||
id="path14356"
|
||||
style="fill:#b2a5ef;fill-opacity:1;stroke-width:0.80000001"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path14358"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/category_bt.svg-8537bebd1c5f62dca3d7ee7f17efeed4.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/category_bt.svg"
|
||||
dest_files=[ "res://.import/category_bt.svg-8537bebd1c5f62dca3d7ee7f17efeed4.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg14360"
|
||||
sodipodi:docname="category_composite.svg"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
|
||||
<metadata
|
||||
id="metadata14366">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs14364" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1051"
|
||||
id="namedview14362"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="-6.0508475"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="29"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg14360" />
|
||||
<path
|
||||
d="M 8,4 C 5.792,4 4,5.792 4,8 c 0,2.208 1.792,4 4,4 2.208,0 4,-1.792 4,-4 C 12,5.792 10.208,4 8,4 Z M 8,0 C 3.584,0 0,3.584 0,8 c 0,4.416 3.584,8 8,8 4.416,0 8,-3.584 8,-8 C 16,3.584 12.416,0 8,0 Z M 8,14.4 C 4.464,14.4 1.6,11.536 1.6,8 1.6,4.464 4.464,1.6 8,1.6 c 3.536,0 6.4,2.864 6.4,6.4 0,3.536 -2.864,6.4 -6.4,6.4 z"
|
||||
id="path14356"
|
||||
style="fill:#a5efac;fill-opacity:1;stroke-width:0.80000001"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path14358"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/category_composite.svg-43f66e63a7ccfa5ac8ec6da0583b3246.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/category_composite.svg"
|
||||
dest_files=[ "res://.import/category_composite.svg-43f66e63a7ccfa5ac8ec6da0583b3246.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg14360"
|
||||
sodipodi:docname="category_decorator.svg"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
|
||||
<metadata
|
||||
id="metadata14366">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs14364" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1051"
|
||||
id="namedview14362"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="-6.0508475"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="29"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg14360" />
|
||||
<path
|
||||
d="M 8,4 C 5.792,4 4,5.792 4,8 c 0,2.208 1.792,4 4,4 2.208,0 4,-1.792 4,-4 C 12,5.792 10.208,4 8,4 Z M 8,0 C 3.584,0 0,3.584 0,8 c 0,4.416 3.584,8 8,8 4.416,0 8,-3.584 8,-8 C 16,3.584 12.416,0 8,0 Z M 8,14.4 C 4.464,14.4 1.6,11.536 1.6,8 1.6,4.464 4.464,1.6 8,1.6 c 3.536,0 6.4,2.864 6.4,6.4 0,3.536 -2.864,6.4 -6.4,6.4 z"
|
||||
id="path14356"
|
||||
style="fill:#fc9c9c;fill-opacity:1;stroke-width:0.80000001"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path14358"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/category_decorator.svg-79d598d6456f32724156248e09d6eaf3.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/category_decorator.svg"
|
||||
dest_files=[ "res://.import/category_decorator.svg-79d598d6456f32724156248e09d6eaf3.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg13771"
|
||||
sodipodi:docname="condition.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata13777">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs13775" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
id="namedview13773"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="12"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg13771" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path13767"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
<path
|
||||
d="M 14.222222,0 H 1.7777778 C 0.7911111,0 0,0.8 0,1.7777778 V 14.222222 C 0,15.2 0.7911111,16 1.7777778,16 H 14.222222 C 15.208889,16 16,15.2 16,14.222222 V 1.7777778 C 16,0.8 15.208889,0 14.222222,0 Z M 6.2222222,12.444444 1.7777778,8 3.0311111,6.7466667 6.2222222,9.9288889 12.968889,3.1822222 14.222222,4.4444444 Z"
|
||||
id="path13769"
|
||||
style="fill:#efd7a5;fill-opacity:1;stroke-width:0.8888889"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/condition.svg-57892684b10a64086f68c09c388b17e5.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/condition.svg"
|
||||
dest_files=[ "res://.import/condition.svg-57892684b10a64086f68c09c388b17e5.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,66 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg5952"
|
||||
sodipodi:docname="fail.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata5958">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs5956" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
id="namedview5954"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="-23.186441"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg5952"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
scale-x="1" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path5948"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
<path
|
||||
d="m 8.1694915,0.0338983 c -4.416,0 -7.99999997,3.584 -7.99999997,8 0,4.4159997 3.58399997,7.9999997 7.99999997,7.9999997 4.4160005,0 8.0000005,-3.584 8.0000005,-7.9999997 0,-4.416 -3.584,-8 -8.0000005,-8 z m 0.8,11.9999997 h -1.6 v -1.6 h 1.6 z m 0,-3.1999997 h -1.6 v -4.8 h 1.6 z"
|
||||
id="path5950"
|
||||
style="fill:#fc9c9c;fill-opacity:1;stroke-width:0.80000001"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2.1 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/fail.svg-85247bd8065819a11b971d222d3d43bb.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/fail.svg"
|
||||
dest_files=[ "res://.import/fail.svg-85247bd8065819a11b971d222d3d43bb.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg6553"
|
||||
sodipodi:docname="inverter.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata6559">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs6557" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
id="namedview6555"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="-22.881356"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg6553" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z m 0,0 H 24 V 16 H 0 Z m 0,0 H 24 V 16 H 0 Z"
|
||||
id="path6549"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
<path
|
||||
d="M 14.222222,0 H 1.7777778 C 0.8,0 0,0.8 0,1.7777778 V 14.222222 C 0,15.2 0.8,16 1.7777778,16 H 14.222222 C 15.2,16 16,15.2 16,14.222222 V 1.7777778 C 16,0.8 15.2,0 14.222222,0 Z M 2.6666667,3.5555556 H 7.111111 V 4.8888889 H 2.6666667 Z M 14.222222,14.222222 H 1.7777778 L 14.222222,1.7777778 Z m -4,-2.666666 v 1.777777 h 1.333334 v -1.777777 h 1.777777 V 10.222222 H 11.555556 V 8.444444 h -1.333334 v 1.777778 H 8.444444 v 1.333334 z"
|
||||
id="path6551"
|
||||
style="fill:#fc9c9c;fill-opacity:1;stroke-width:0.8888889"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2.2 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/inverter.svg-1f1b976d95de42c4ad99a92fa9a6c5d0.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/inverter.svg"
|
||||
dest_files=[ "res://.import/inverter.svg-1f1b976d95de42c4ad99a92fa9a6c5d0.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg7154"
|
||||
sodipodi:docname="limiter.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata7160">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs7158" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
id="namedview7156"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="12"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg7154" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path7150"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
<path
|
||||
d="M 8.0685714,4.541598 10.79619,7.2768364 H 0 v 1.523809 H 10.79619 L 8.0609524,11.535884 9.142857,12.61017 13.714286,8.0387404 9.142857,3.4673123 Z M 14.47619,3.4673123 V 12.61017 H 16 V 3.4673123 Z"
|
||||
id="path7152"
|
||||
style="fill:#fc9c9c;fill-opacity:1;stroke-width:0.76190478"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.9 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/limiter.svg-b4c7646605c46f53c5e403fe21d8f584.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/limiter.svg"
|
||||
dest_files=[ "res://.import/limiter.svg-b4c7646605c46f53c5e403fe21d8f584.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg12569"
|
||||
sodipodi:docname="selector.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata12575">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs12573" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
id="namedview12571"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="12"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg12569" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path12565"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
<path
|
||||
d="M 3.8101694,4 H 11.81017 v 2.4 l 3.2,-3.2 -3.2,-3.2 V 2.4 H 2.2101694 v 4.8 h 1.6 z M 11.81017,12 H 3.8101694 V 9.6 L 0.61016952,12.8 3.8101694,16 V 13.6 H 13.41017 V 8.8 h -1.6 z"
|
||||
id="path12567"
|
||||
style="fill:#a5efac;fill-opacity:1;stroke-width:0.80000001"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.9 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/selector.svg-78bccfc448bd1676b5a29bfde4b08e5b.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/selector.svg"
|
||||
dest_files=[ "res://.import/selector.svg-78bccfc448bd1676b5a29bfde4b08e5b.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<rect id="path12565" x="0" y="-8" width="24" height="24" style="fill:none;fill-rule:nonzero;"/>
|
||||
<g transform="matrix(0.571429,0,0,0.571429,7.42857,-585.2)">
|
||||
<path d="M8,1038.1L5.626,1042.2L1,1043.3L4.236,1046.7L3.877,1051.38L8.016,1049.4L12.174,1051.34L11.778,1046.69L15,1043.3L10.374,1042.2L8,1038.1Z" style="fill:rgb(165,239,172);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<path id="path12567" d="M8.76,13.6L8.784,13.315L7.405,12L3.81,12L3.81,9.6L0.61,12.8L3.81,16L3.81,13.6L8.76,13.6ZM13.41,8.855L13.375,8.8L13.41,8.8L13.41,8.855ZM3.81,4L11.81,4L11.81,6.4L15.01,3.2L11.81,0L11.81,2.4L2.21,2.4L2.21,7.2L3.81,7.2L3.81,4Z" style="fill:rgb(165,239,172);fill-rule:nonzero;"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/selector_star.svg-368af7abfb9842c3f4258786871d1f03.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/selector_star.svg"
|
||||
dest_files=[ "res://.import/selector_star.svg-368af7abfb9842c3f4258786871d1f03.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=false
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg13170"
|
||||
sodipodi:docname="sequence.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata13176">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs13174" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
id="namedview13172"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="12"
|
||||
inkscape:cy="17.186441"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg13170" />
|
||||
<path
|
||||
d="M 0,9.0376644 H 1.7777778 V 7.2598874 H 0 Z M 0,12.59322 H 1.7777778 V 10.815442 H 0 Z M 0,5.4821093 H 1.7777778 V 3.7043315 H 0 Z M 3.5555556,9.0376644 H 16 V 7.2598874 H 3.5555556 Z m 0,3.5555556 H 16 V 10.815442 H 3.5555556 Z m 0,-8.8888885 V 5.4821093 H 16 V 3.7043315 Z"
|
||||
id="path13166"
|
||||
style="fill:#a5efac;fill-opacity:1;stroke-width:0.8888889"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path13168"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/sequencer.svg-a7b0e1cc6b00c0067836f9a81d0b2f9b.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/sequencer.svg"
|
||||
dest_files=[ "res://.import/sequencer.svg-a7b0e1cc6b00c0067836f9a81d0b2f9b.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<rect id="path13168" x="0" y="-8" width="24" height="24" style="fill:none;fill-rule:nonzero;"/>
|
||||
<g transform="matrix(0.571429,0,0,0.571429,7.42857,-585.2)">
|
||||
<path d="M8,1038.1L5.626,1042.2L1,1043.3L4.236,1046.7L3.877,1051.38L8.016,1049.4L12.174,1051.34L11.778,1046.69L15,1043.3L10.374,1042.2L8,1038.1Z" style="fill:rgb(165,239,172);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<path id="path13166" d="M0,12.593L1.778,12.593L1.778,10.815L0,10.815L0,12.593ZM5.728,10.815L3.556,10.815L3.556,12.593L7.416,12.593L5.728,10.815ZM0,9.038L1.778,9.038L1.778,7.26L0,7.26L0,9.038ZM10.976,7.26L3.556,7.26L3.556,9.038L9.946,9.038L10.976,7.26ZM13.024,7.26L14.054,9.038L16,9.038L16,7.26L13.024,7.26ZM0,5.482L1.778,5.482L1.778,3.704L0,3.704L0,5.482ZM3.556,3.704L3.556,5.482L16,5.482L16,3.704L3.556,3.704Z" style="fill:rgb(165,239,172);fill-rule:nonzero;"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.3 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/sequencer_star.svg-2385cbba0c38b4d4ec43e0996f8a3493.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/sequencer_star.svg"
|
||||
dest_files=[ "res://.import/sequencer_star.svg-2385cbba0c38b4d4ec43e0996f8a3493.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=false
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg5317"
|
||||
sodipodi:docname="succeed.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata5323">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs5321" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
id="namedview5319"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="-40.576272"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg5317" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path5313"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
<path
|
||||
d="M 8,0 C 3.584,0 0,3.584 0,8 c 0,4.416 3.584,8 8,8 4.416,0 8,-3.584 8,-8 C 16,3.584 12.416,0 8,0 Z M 6.4,12 2.4,8 3.528,6.872 6.4,9.736 12.472,3.664 13.6,4.8 Z"
|
||||
id="path5315"
|
||||
style="fill:#fc9c9c;fill-opacity:1;stroke-width:0.80000001"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.9 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/succeed.svg-c70f0a6f3d9b2864e4771942f0762307.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/succeed.svg"
|
||||
dest_files=[ "res://.import/succeed.svg-c70f0a6f3d9b2864e4771942f0762307.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg61"
|
||||
sodipodi:docname="tree.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata67">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs65" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
id="namedview63"
|
||||
showgrid="false"
|
||||
inkscape:zoom="36.041667"
|
||||
inkscape:cx="-2.3445086"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg61" />
|
||||
<path
|
||||
d="M 0,-8 H 24 V 16 H 0 Z"
|
||||
id="path57"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none" />
|
||||
<path
|
||||
d="m 16,8.0000002 v -6.4 h -5.6 v 2.4 H 5.6 v -2.4 H 0 v 6.4 h 5.6 v -2.4 H 7.2 V 13.6 h 3.2 V 16 H 16 V 9.6000002 H 10.4 V 12 H 8.7999998 V 5.6000002 H 10.4 v 2.4 z"
|
||||
id="path59"
|
||||
style="fill:#b2a5ef;fill-opacity:1;stroke-width:0.80000001"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.9 KiB |
|
@ -1,35 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/tree.svg-c0b20ed88b2fe300c0296f7236049076.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/beehave/icons/tree.svg"
|
||||
dest_files=[ "res://.import/tree.svg-c0b20ed88b2fe300c0296f7236049076.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,8 +0,0 @@
|
|||
extends BeehaveTree
|
||||
|
||||
class_name BeehaveNode, "../icons/action.svg"
|
||||
|
||||
enum { SUCCESS, FAILURE, RUNNING }
|
||||
|
||||
func tick(actor, blackboard):
|
||||
pass
|
|
@ -1,84 +0,0 @@
|
|||
extends BeehaveTree
|
||||
|
||||
class_name BeehaveRoot, "../icons/tree.svg"
|
||||
|
||||
const Blackboard = preload("../blackboard.gd")
|
||||
const SUCCESS = 0
|
||||
const FAILURE = 1
|
||||
const RUNNING = 2
|
||||
|
||||
enum ProcessMode {
|
||||
PHYSICS_PROCESS,
|
||||
IDLE,
|
||||
MANUAL
|
||||
}
|
||||
|
||||
export (ProcessMode) var process_mode = ProcessMode.PHYSICS_PROCESS setget set_process_mode
|
||||
export (bool) var enabled = true
|
||||
|
||||
export (NodePath) var actor_node_path
|
||||
|
||||
var actor : Node
|
||||
|
||||
onready var blackboard = Blackboard.new()
|
||||
|
||||
func _ready():
|
||||
if self.get_child_count() != 1:
|
||||
push_error("Beehave error: Root %s should have one child (NodePath: %s)" % [self.name, self.get_path()])
|
||||
disable()
|
||||
return
|
||||
|
||||
actor = get_parent()
|
||||
if actor_node_path:
|
||||
actor = get_node(actor_node_path)
|
||||
|
||||
set_process_mode(self.process_mode)
|
||||
|
||||
func _process(delta):
|
||||
tick(delta)
|
||||
|
||||
func _physics_process(delta):
|
||||
tick(delta)
|
||||
|
||||
func tick(delta):
|
||||
blackboard.set("delta", delta)
|
||||
|
||||
var status = self.get_child(0).tick(actor, blackboard)
|
||||
|
||||
if status != RUNNING:
|
||||
blackboard.set("running_action", null)
|
||||
|
||||
func get_running_action():
|
||||
if blackboard.has("running_action"):
|
||||
return blackboard.get("running_action")
|
||||
return null
|
||||
|
||||
func get_last_condition():
|
||||
if blackboard.has("last_condition"):
|
||||
return blackboard.get("last_condition")
|
||||
return null
|
||||
|
||||
func get_last_condition_status():
|
||||
if blackboard.has("last_condition_status"):
|
||||
var status = blackboard.get("last_condition_status")
|
||||
if status == SUCCESS:
|
||||
return "SUCCESS"
|
||||
elif status == FAILURE:
|
||||
return "FAILURE"
|
||||
else:
|
||||
return "RUNNING"
|
||||
return ""
|
||||
|
||||
func enable():
|
||||
self.enabled = true
|
||||
set_process_mode(self.process_mode)
|
||||
|
||||
func disable():
|
||||
self.enabled = false
|
||||
set_process(self.enabled)
|
||||
set_physics_process(self.enabled)
|
||||
|
||||
func set_process_mode(value):
|
||||
process_mode = value
|
||||
set_process(process_mode == ProcessMode.IDLE)
|
||||
set_physics_process(process_mode == ProcessMode.PHYSICS_PROCESS)
|
|
@ -1,3 +0,0 @@
|
|||
extends Node
|
||||
|
||||
class_name BeehaveTree
|
|
@ -1,8 +0,0 @@
|
|||
extends BeehaveNode
|
||||
|
||||
class_name Composite, "../../icons/category_composite.svg"
|
||||
|
||||
|
||||
func _ready():
|
||||
if self.get_child_count() < 1:
|
||||
push_error("BehaviorTree Error: Composite %s should have at least one child (NodePath: %s)" % [self.name, self.get_path()])
|
|
@ -1,18 +0,0 @@
|
|||
extends Composite
|
||||
|
||||
class_name SelectorComposite, "../../icons/selector.svg"
|
||||
|
||||
func tick(actor, blackboard):
|
||||
for c in get_children():
|
||||
var response = c.tick(actor, blackboard)
|
||||
|
||||
if c is ConditionLeaf:
|
||||
blackboard.set("last_condition", c)
|
||||
blackboard.set("last_condition_status", response)
|
||||
|
||||
if response != FAILURE:
|
||||
if c is ActionLeaf and response == RUNNING:
|
||||
blackboard.set("running_action", c)
|
||||
return response
|
||||
|
||||
return FAILURE
|
|
@ -1,33 +0,0 @@
|
|||
# Special implementation of a selector that will
|
||||
# "wait" for running nodes and will not re-attempt
|
||||
# to execute previous nodes until that node is either
|
||||
# FAILED or SUCCEEDED
|
||||
extends Composite
|
||||
|
||||
class_name SelectorStarComposite, "../../icons/selector_star.svg"
|
||||
|
||||
|
||||
var last_execution_index = 0
|
||||
|
||||
func tick(actor, blackboard):
|
||||
for c in get_children():
|
||||
if c.get_index() < last_execution_index:
|
||||
continue
|
||||
|
||||
var response = c.tick(actor, blackboard)
|
||||
|
||||
if c is ConditionLeaf:
|
||||
blackboard.set("last_condition", c)
|
||||
blackboard.set("last_condition_status", response)
|
||||
|
||||
if response != FAILURE:
|
||||
if c is ActionLeaf and response == RUNNING:
|
||||
blackboard.set("running_action", c)
|
||||
if response == SUCCESS:
|
||||
last_execution_index = 0
|
||||
return response
|
||||
else:
|
||||
last_execution_index += 1
|
||||
|
||||
last_execution_index = 0
|
||||
return FAILURE
|
|
@ -1,18 +0,0 @@
|
|||
extends Composite
|
||||
|
||||
class_name SequenceComposite, "../../icons/sequencer.svg"
|
||||
|
||||
func tick(actor, blackboard):
|
||||
for c in get_children():
|
||||
var response = c.tick(actor, blackboard)
|
||||
|
||||
if c is ConditionLeaf:
|
||||
blackboard.set("last_condition", c)
|
||||
blackboard.set("last_condition_status", response)
|
||||
|
||||
if response != SUCCESS:
|
||||
if c is ActionLeaf and response == RUNNING:
|
||||
blackboard.set("running_action", c)
|
||||
return response
|
||||
|
||||
return SUCCESS
|
|
@ -1,35 +0,0 @@
|
|||
# Special implementation of sequencer who will execute
|
||||
# successful nodes only once until all nodes were successful
|
||||
|
||||
extends Composite
|
||||
|
||||
class_name SequenceStarComposite, "../../icons/sequencer_star.svg"
|
||||
|
||||
var successful_index = 0
|
||||
|
||||
func tick(actor, blackboard):
|
||||
for c in get_children():
|
||||
if c.get_index() < successful_index:
|
||||
continue
|
||||
|
||||
var response = c.tick(actor, blackboard)
|
||||
|
||||
if c is ConditionLeaf:
|
||||
blackboard.set("last_condition", c)
|
||||
blackboard.set("last_condition_status", response)
|
||||
|
||||
if response != SUCCESS:
|
||||
if response == FAILURE:
|
||||
successful_index = 0
|
||||
if c is ActionLeaf and response == RUNNING:
|
||||
blackboard.set("running_action", c)
|
||||
return response
|
||||
else:
|
||||
successful_index += 1
|
||||
|
||||
if successful_index == get_child_count():
|
||||
successful_index = 0
|
||||
return SUCCESS
|
||||
else:
|
||||
successful_index = 0
|
||||
return FAILURE
|
|
@ -1,8 +0,0 @@
|
|||
extends BeehaveNode
|
||||
|
||||
class_name Decorator, "../../icons/category_decorator.svg"
|
||||
|
||||
|
||||
func _ready():
|
||||
if self.get_child_count() != 1:
|
||||
push_error("Beehave Error: Decorator %s should have only one child (NodePath: %s)" % [self.name, self.get_path()])
|
|
@ -1,11 +0,0 @@
|
|||
extends Decorator
|
||||
|
||||
class_name AlwaysFailDecorator, "../../icons/fail.svg"
|
||||
|
||||
|
||||
func tick(action, blackboard):
|
||||
for c in get_children():
|
||||
var response = c.tick(action, blackboard)
|
||||
if response == RUNNING:
|
||||
return RUNNING
|
||||
return FAILURE
|
|
@ -1,17 +0,0 @@
|
|||
extends Decorator
|
||||
|
||||
class_name InverterDecorator, "../../icons/inverter.svg"
|
||||
|
||||
|
||||
func tick(action, blackboard):
|
||||
for c in get_children():
|
||||
var response = c.tick(action, blackboard)
|
||||
|
||||
if response == SUCCESS:
|
||||
return FAILURE
|
||||
if response == FAILURE:
|
||||
return SUCCESS
|
||||
|
||||
if c is Leaf and response == RUNNING:
|
||||
blackboard.set("running_action", c)
|
||||
return RUNNING
|
|
@ -1,19 +0,0 @@
|
|||
extends Decorator
|
||||
|
||||
class_name LimiterDecorator, "../../icons/limiter.svg"
|
||||
|
||||
onready var cache_key = 'limiter_%s' % self.get_instance_id()
|
||||
|
||||
export (float) var max_count = 0
|
||||
|
||||
func tick(actor, blackboard):
|
||||
var current_count = blackboard.get(cache_key)
|
||||
|
||||
if current_count == null:
|
||||
current_count = 0
|
||||
|
||||
if current_count <= max_count:
|
||||
blackboard.set(cache_key, current_count + 1)
|
||||
return self.get_child(0).tick(actor, blackboard)
|
||||
else:
|
||||
return FAILED
|
|
@ -1,11 +0,0 @@
|
|||
extends Decorator
|
||||
|
||||
class_name AlwaysSucceedDecorator, "../../icons/succeed.svg"
|
||||
|
||||
|
||||
func tick(action, blackboard):
|
||||
for c in get_children():
|
||||
var response = c.tick(action, blackboard)
|
||||
if response == RUNNING:
|
||||
return RUNNING
|
||||
return SUCCESS
|
|
@ -1,3 +0,0 @@
|
|||
extends Leaf
|
||||
|
||||
class_name ActionLeaf, "../../icons/action.svg"
|
|
@ -1,3 +0,0 @@
|
|||
extends Leaf
|
||||
|
||||
class_name ConditionLeaf, "../../icons/condition.svg"
|
|
@ -1,3 +0,0 @@
|
|||
extends BeehaveNode
|
||||
|
||||
class_name Leaf, "../../icons/action.svg"
|
|
@ -1,7 +0,0 @@
|
|||
[plugin]
|
||||
|
||||
name="Beehave"
|
||||
description="🐝 Behaviour Tree addon for Godot Engine"
|
||||
author="bitbrain"
|
||||
version="1.2.0"
|
||||
script="plugin.gd"
|
|
@ -1,5 +0,0 @@
|
|||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
func _init():
|
||||
print("Beehave initialized!")
|
|
@ -1,70 +0,0 @@
|
|||
# Godot Version Manager
|
||||
|
||||
<img src="https://raw.githubusercontent.com/fcazalet/godot-version-management/main/icon.png" width="64" height="64">
|
||||
|
||||
This addon is for developpers that want a centralized place for version naming / build number and then display it in game.
|
||||
|
||||
It allow you to configure version and build in project settings.
|
||||
|
||||
These configurations are synchronized to all existing export of your project.
|
||||
|
||||
Moreover configurations can be loaded for in game display.
|
||||
|
||||
## How to install it
|
||||
|
||||
You can find this addon in Godot AssetLibrary
|
||||
See the Godot Addon install section : https://docs.godotengine.org/en/stable/tutorials/plugins/editor/installing_plugins.html
|
||||
|
||||
## How to use it for exports
|
||||
|
||||
Once the addon activated it add two entry in your project configuration:
|
||||
|
||||
- Application / Config / Version as String (application/config/version default to 0.0.1)
|
||||
- Application / Config / Build as Integer (application/config/build default to 1)
|
||||
|
||||
You can change the version and the build numbers.
|
||||
It will update all your exports versions value to the project config value.
|
||||
Then you need to reload the project (Project / Reload current project).
|
||||
|
||||
See below section to know why you need to reload project.
|
||||
|
||||
For Android exports:
|
||||
* version is version/name
|
||||
* build is version/code
|
||||
|
||||
For iOS and MacOS exports:
|
||||
* version is application/short_version
|
||||
* build is application/version
|
||||
|
||||
For Windows Desktop exports:
|
||||
* version is application/file_version and application/product_version
|
||||
|
||||
For HTML5 and UWP exports no versions specified.
|
||||
|
||||
## How to use it for in game display
|
||||
|
||||
The version and build numbers can be accessed for in game use like that:
|
||||
|
||||
|
||||
```GDScript
|
||||
# To get version string
|
||||
var version = ProjectSettings.get_setting("application/config/version")
|
||||
# To get build number
|
||||
var build = ProjectSettings.get_setting("application/config/build")
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Why I need to reload project ?
|
||||
|
||||
The GodotVersionManager addon update the export-presets.cfg file.
|
||||
|
||||
Because of Godot keep in memory ExportsSettings and do not reload it from export-presets.cfg file you will need to reload your project.
|
||||
|
||||
When project is loaded Godot load in memory the export-presets.cfg .
|
||||
|
||||
## Support Me
|
||||
|
||||
You to buy me a coffee ?
|
||||
<a href='https://ko-fi.com/J3J2COV54' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi3.png?v=3' border='0' alt='Buy Me a Coffee' /></a>
|
|
@ -1,78 +0,0 @@
|
|||
# By Erasor
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
const PLUGIN_NAME = "Godot-Version-Manager"
|
||||
const DEBUG = true
|
||||
# Use same name as https://github.com/godotengine/godot/pull/35555
|
||||
const PROJECT_VERSION_SETTING = "application/config/version"
|
||||
const PROJECT_BUILD_SETTING = "application/config/build"
|
||||
const EXPORT_PRESETS_FILE = "res://export_presets.cfg"
|
||||
var current_version
|
||||
var current_build
|
||||
|
||||
func _enter_tree():
|
||||
if not ProjectSettings.has_setting(PROJECT_VERSION_SETTING):
|
||||
ProjectSettings.set_setting(PROJECT_VERSION_SETTING, "0.0.1")
|
||||
if not ProjectSettings.has_setting(PROJECT_BUILD_SETTING):
|
||||
ProjectSettings.set_setting(PROJECT_BUILD_SETTING, 1)
|
||||
current_version = ProjectSettings.get_setting(PROJECT_VERSION_SETTING)
|
||||
current_build = ProjectSettings.get_setting(PROJECT_BUILD_SETTING)
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
# Do not remove the verson config, may conflict with https://github.com/godotengine/godot/pull/35555
|
||||
pass
|
||||
|
||||
|
||||
func apply_changes():
|
||||
_update_export_presets()
|
||||
|
||||
|
||||
func save_external_data():
|
||||
_update_export_presets()
|
||||
|
||||
|
||||
func _update_export_presets():
|
||||
# If config version changed, update all exports
|
||||
if ProjectSettings.get_setting(PROJECT_VERSION_SETTING) != current_version:
|
||||
var export_config: ConfigFile = ConfigFile.new()
|
||||
var err = export_config.load(EXPORT_PRESETS_FILE)
|
||||
if err == OK:
|
||||
# Loop limited to 100 exports
|
||||
for i in range(0, 100):
|
||||
var section = "preset." + str(i)
|
||||
if export_config.has_section(section):
|
||||
plugin_log("Update Export " + export_config.get_value(section, "platform"))
|
||||
# Update Android exports configs
|
||||
if export_config.get_value(section, "platform") == "Android":
|
||||
export_config.set_value(section + ".options", 'version/name', ProjectSettings.get_setting(PROJECT_VERSION_SETTING))
|
||||
export_config.set_value(section + ".options", 'version/code', ProjectSettings.get_setting(PROJECT_BUILD_SETTING))
|
||||
if export_config.get_value(section, "platform") == "iOS" or export_config.get_value(section, "platform") == "Mac OSX":
|
||||
export_config.set_value(section + ".options", 'application/short_version', ProjectSettings.get_setting(PROJECT_VERSION_SETTING))
|
||||
export_config.set_value(section + ".options", 'application/version', ProjectSettings.get_setting(PROJECT_BUILD_SETTING))
|
||||
if export_config.get_value(section, "platform") == "UWP":
|
||||
# TODO parsing of version to minor/major
|
||||
pass
|
||||
if export_config.get_value(section, "platform") == "Windows Desktop":
|
||||
export_config.set_value(section + ".options", 'application/file_version', ProjectSettings.get_setting(PROJECT_VERSION_SETTING))
|
||||
export_config.set_value(section + ".options", 'application/product_version', ProjectSettings.get_setting(PROJECT_VERSION_SETTING))
|
||||
else:
|
||||
break
|
||||
err = export_config.save(EXPORT_PRESETS_FILE)
|
||||
ProjectSettings.save()
|
||||
if err == OK:
|
||||
plugin_log("All exports updated")
|
||||
else:
|
||||
plugin_log("Error saving " + EXPORT_PRESETS_FILE + ", exports not updated")
|
||||
else:
|
||||
plugin_log('Error open ' + EXPORT_PRESETS_FILE)
|
||||
|
||||
|
||||
func plugin_log(message):
|
||||
if (DEBUG):
|
||||
var time : Dictionary = OS.get_datetime()
|
||||
var date_string : String = "%02d:%02d" % [time.hour, time.minute]
|
||||
print(date_string, " - ", PLUGIN_NAME, " - ", message)
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[plugin]
|
||||
|
||||
name="Godot-Version-Manager"
|
||||
description="Godot plugin to manage versions for exports.
|
||||
It centralize the version number in project."
|
||||
author="Erasor"
|
||||
version="1.0.0"
|
||||
script="godot_version_manager.gd"
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 Tomek
|
||||
Copyright (c) 2022 Addons By Aura
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -18,4 +18,4 @@ 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.
|
||||
SOFTWARE.
|
47
addons/simple-state/classes/animation_state.gd
Normal file
|
@ -0,0 +1,47 @@
|
|||
@icon("../icons/animation_state.png")
|
||||
class_name AnimationState
|
||||
extends State
|
||||
|
||||
## Plays an animation from the linked [member animation_player].
|
||||
## The name of the animation to be played comes from the name of the node.
|
||||
|
||||
## Emitted when the animation started by this state has finished playing.
|
||||
signal animation_finished
|
||||
|
||||
|
||||
@export_range(0, 20, 1, "or_greater")
|
||||
## How many times to play before emitting [signal State.choose_new_substate_requested].
|
||||
## [b]If set to zero, it will go forever.[/b]
|
||||
var loops := 0
|
||||
|
||||
|
||||
var _loops_left := 0
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
set_meta(&"description", "Plays the named animation from the linked AnimationPlayer.")
|
||||
|
||||
|
||||
func _on_animation_finished(animation_name: StringName) -> void:
|
||||
if animation_name != name: return
|
||||
if loops == 0:
|
||||
animation_player.play(name)
|
||||
elif _loops_left <= 0:
|
||||
choose_new_substate_requested.emit()
|
||||
else:
|
||||
_loops_left -= 1
|
||||
animation_player.play(name)
|
||||
|
||||
|
||||
func enter(set_target: Node, set_animation_player: AnimationPlayer, set_debug_mode := false) -> void:
|
||||
super(set_target, set_animation_player, set_debug_mode)
|
||||
assert(animation_player != null, "AnimationPlayer must be set, either directly or by an ancestor.")
|
||||
animation_player.animation_finished.connect(_on_animation_finished)
|
||||
_loops_left = loops - 1
|
||||
animation_player.play(name)
|
||||
|
||||
|
||||
func exit() -> void:
|
||||
super()
|
||||
animation_player.animation_finished.disconnect(_on_animation_finished)
|
||||
animation_player.stop()
|
139
addons/simple-state/classes/debugger.gd
Normal file
|
@ -0,0 +1,139 @@
|
|||
@icon("../icons/state_machine_debugger.png")
|
||||
class_name StateMachineDebugger
|
||||
extends Tree
|
||||
|
||||
|
||||
## Displays an interactive state tree.
|
||||
# This source code is a mess, I'm trying to make it less so.
|
||||
|
||||
|
||||
@export
|
||||
## Root state machine to reference.
|
||||
var state_machine_root : State:
|
||||
set(value):
|
||||
state_machine_root = value
|
||||
_setup_tree()
|
||||
|
||||
@export
|
||||
## What color to make the item when a state is active.
|
||||
var active_color := Color.FOREST_GREEN
|
||||
|
||||
@export
|
||||
## Forcefully switch states by double-clicking them.
|
||||
## Due to its nature, it has the potential to be destructive
|
||||
## and/ or not behave completely how one might expect.
|
||||
var allow_state_switching := false:
|
||||
set(value):
|
||||
allow_state_switching = value
|
||||
if allow_state_switching:
|
||||
item_activated.connect(_on_item_activated)
|
||||
else:
|
||||
item_activated.disconnect(_on_item_activated)
|
||||
|
||||
|
||||
@export_group("Signals", "signal_")
|
||||
@export
|
||||
## Show when a state emits a relevant signal.
|
||||
var signal_show := false:
|
||||
set(value):
|
||||
signal_show = value
|
||||
|
||||
if state_machine_root == null:
|
||||
return
|
||||
|
||||
if signal_show:
|
||||
connect_signals()
|
||||
else:
|
||||
disconnect_signals()
|
||||
|
||||
@export
|
||||
## Which signals to connect to on each state, as long as they exist.
|
||||
var signal_connections : Array[StringName] = [
|
||||
&"entered",
|
||||
&"exited",
|
||||
&"choose_new_substate_requested",
|
||||
&"animation_finished",
|
||||
]
|
||||
|
||||
@export
|
||||
## Delay before hiding signal.
|
||||
var signal_hide_delay := 1.0
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
columns = 2
|
||||
|
||||
|
||||
func change_state_by_path(path: NodePath) -> void:
|
||||
if not state_machine_root.has_node(path):
|
||||
return
|
||||
var state := state_machine_root
|
||||
for i in path.get_name_count():
|
||||
var part := path.get_name(i)
|
||||
state = await state.change_state_name(part)
|
||||
|
||||
|
||||
func connect_signals(state := state_machine_root) -> void:
|
||||
if not state.has_meta(&"tree_item"):
|
||||
return
|
||||
for signal_name in signal_connections:
|
||||
if state.has_signal(signal_name) and not \
|
||||
state.is_connected(signal_name, _on_state_signal):
|
||||
state.connect(signal_name, _on_state_signal.bind(signal_name, state.get_meta(&"tree_item")))
|
||||
for child in(state.get_children() as Array[State]):
|
||||
connect_signals(child)
|
||||
|
||||
|
||||
func disconnect_signals(state := state_machine_root) -> void:
|
||||
for signal_name in signal_connections:
|
||||
if state.has_signal(signal_name) and \
|
||||
state.is_connected(signal_name, _on_state_signal):
|
||||
state.disconnect(signal_name, _on_state_signal)
|
||||
for child in (state.get_children() as Array[State]):
|
||||
disconnect_signals(child)
|
||||
|
||||
|
||||
func _setup_tree(state := state_machine_root, parent_item: TreeItem = null) -> void:
|
||||
if state == state_machine_root:
|
||||
if get_root() != null:
|
||||
disconnect_signals()
|
||||
clear()
|
||||
if state_machine_root == null:
|
||||
return
|
||||
# state.print_tree_pretty()
|
||||
|
||||
# TODO: add icons
|
||||
var item := create_item(parent_item)
|
||||
item.set_text(0, state.name)
|
||||
item.set_metadata(0, state)
|
||||
state.set_meta(&"tree_item", item)
|
||||
connect_signals(state)
|
||||
|
||||
for child in (state.get_children() as Array[State]):
|
||||
_setup_tree(child, item)
|
||||
|
||||
|
||||
func _on_item_activated() -> void:
|
||||
change_state_by_path(state_machine_root.get_path_to(
|
||||
get_selected().get_metadata(0) as State))
|
||||
|
||||
|
||||
func _on_state_signal(signal_name: StringName, state_item: TreeItem) -> void:
|
||||
match signal_name:
|
||||
&"entered":
|
||||
for i in columns:
|
||||
state_item.set_custom_color(i, active_color)
|
||||
&"exited":
|
||||
for i in columns:
|
||||
state_item.clear_custom_color(i)
|
||||
|
||||
if not signal_show:
|
||||
return
|
||||
|
||||
state_item.set_text(1, signal_name)
|
||||
var timer := state_item.get_metadata(1) as SceneTreeTimer
|
||||
if timer != null:
|
||||
timer.timeout.disconnect(state_item.set_text)
|
||||
timer = get_tree().create_timer(signal_hide_delay)
|
||||
timer.timeout.connect(state_item.set_text.bind(1, ""))
|
||||
state_item.set_metadata(1, timer)
|
34
addons/simple-state/classes/random_state.gd
Normal file
|
@ -0,0 +1,34 @@
|
|||
@icon("../icons/random_state.png")
|
||||
class_name RandomState
|
||||
extends State
|
||||
|
||||
## Activates a random one of its substates.
|
||||
## Useful in conjuction with [AnimationState] for random idles.
|
||||
|
||||
|
||||
@export
|
||||
## When one of its children asks for a state change,
|
||||
## instead of picking another one itself, it defers that choice to its parent.
|
||||
## Allows for nested random states for finer control over flow and probability.
|
||||
var defer_choice := false
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
set_meta(&"description", "Pseudo-randomly picks a state to start.")
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
randomize()
|
||||
super()
|
||||
|
||||
|
||||
# You can define which state is picked automatically (like on enter).
|
||||
# If you would like to call it yourself, use the public version (choose_substate).
|
||||
func _choose_substate() -> State:
|
||||
if get_child_count() == 0:
|
||||
return null
|
||||
if defer_choice and _active_substate != null:
|
||||
choose_new_substate_requested.emit()
|
||||
return null
|
||||
return get_child(randi() % get_child_count()) as State
|
||||
|
43
addons/simple-state/classes/sequence_state.gd
Normal file
|
@ -0,0 +1,43 @@
|
|||
@icon("../icons/sequence_state.png")
|
||||
class_name SequenceState
|
||||
extends State
|
||||
|
||||
|
||||
## Executes its children in order, one after the other. Like an [Array] in [State] form!
|
||||
|
||||
|
||||
@export_range(0, 20, 1, "or_greater")
|
||||
## How many times the sequence should be looped through before emitting [signal State.choose_new_substate_requested].
|
||||
## [b]If set to zero, it will go forever.[/b]
|
||||
var loops := 1
|
||||
|
||||
|
||||
var _loops_left := 0
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
set_meta(&"description", "Starts its children one after the other in order, \
|
||||
waiting for each one to be done before starting the next.")
|
||||
|
||||
|
||||
# You can define which state is picked automatically (like on [method enter]).
|
||||
# If you would like to call it yourself, use the public version ([method choose_substate]).
|
||||
func _choose_substate() -> State:
|
||||
if _active_substate == null:
|
||||
return get_child(0) as State if get_child_count() > 0 else null
|
||||
|
||||
if _active_substate.get_index() == get_child_count() - 1:
|
||||
if loops == 0:
|
||||
return get_child(0) as State
|
||||
elif _loops_left == 0:
|
||||
choose_new_substate_requested.emit()
|
||||
return null
|
||||
else:
|
||||
_loops_left -= 1
|
||||
return get_child(0) as State
|
||||
return get_child(_active_substate.get_index() + 1) as State
|
||||
|
||||
|
||||
func enter(set_target: Node, set_animation_player: AnimationPlayer, set_debug := false) -> void:
|
||||
super(set_target, set_animation_player, set_debug)
|
||||
_loops_left = loops - 1
|
291
addons/simple-state/classes/state.gd
Normal file
|
@ -0,0 +1,291 @@
|
|||
@icon("../icons/state.png")
|
||||
class_name State
|
||||
extends Node
|
||||
|
||||
## The bare, basic state. Use it if you want total control over the state-flow.
|
||||
##
|
||||
## Properties marked as [b](inherited)[/b] are passed to substates,
|
||||
## meaning you don't have to set it on each individual state, only the root.
|
||||
## You can override it of course, and that will be passed to all of [i]its[/i] children.
|
||||
|
||||
|
||||
## Emitted between [method _enter] and [method _after_enter].
|
||||
signal entered
|
||||
|
||||
## Emitted after [method _exit].
|
||||
signal exited
|
||||
|
||||
## Emitted between [method _update] and [method _after_update]
|
||||
signal updated
|
||||
|
||||
## Switched active substates.
|
||||
signal active_substate_changed(new: State, old: State)
|
||||
|
||||
## A request for the parent to pick a new substate to activate.
|
||||
## Mainly used by children of [RandomState], such as an [AnimationState].
|
||||
signal choose_new_substate_requested
|
||||
|
||||
|
||||
## Active or not.
|
||||
enum Status {
|
||||
INACTIVE, ## Inactive
|
||||
ACTIVE, ## Active
|
||||
}
|
||||
|
||||
|
||||
@export
|
||||
## The node that the states will act upon. [b](inherited)[/b]
|
||||
## Doesn't actually get used in the addon scripts, it's just
|
||||
## included for your convenience when scripting your own behaviour.
|
||||
var target: Node:
|
||||
set(value):
|
||||
target = value
|
||||
if _active_substate != null:
|
||||
_active_substate.target = target
|
||||
|
||||
@export
|
||||
## Where to play animations from. [b](inherited)[/b]
|
||||
var animation_player: AnimationPlayer
|
||||
|
||||
@export_range(0, 120, 1, "or_greater")
|
||||
## How many seconds the state should be active before emitting [signal choose_new_substate_requested].
|
||||
## [b]If set to zero, it will go forever.[/b]
|
||||
var timer := 0.0
|
||||
|
||||
@export
|
||||
## Whether to force-restart the chosen substate in the callback for [signal choose_new_substate_requested] if it was already active.
|
||||
var force := true
|
||||
|
||||
@export
|
||||
## The state will not be activated under any circumstances.
|
||||
var disabled := false:
|
||||
set(value):
|
||||
disabled = value
|
||||
var root := is_root()
|
||||
if root and not disabled:
|
||||
enter(target, animation_player, debug_mode)
|
||||
elif status == Status.ACTIVE:
|
||||
exit()
|
||||
|
||||
@export
|
||||
## Print a message avery time there is a state change. [b](inherited)[/b]
|
||||
var debug_mode := false:
|
||||
set(value):
|
||||
debug_mode = value
|
||||
if _active_substate != null:
|
||||
_active_substate.debug_mode = debug_mode
|
||||
|
||||
## The status of this state, ie. whether it's running or not.
|
||||
var status := Status.INACTIVE
|
||||
|
||||
|
||||
# The substate that is currently active, if any.
|
||||
var _active_substate: State:
|
||||
set(value):
|
||||
if _active_substate != null:
|
||||
_active_substate.choose_new_substate_requested.disconnect(_on_choose_new_substate_requested)
|
||||
active_substate_changed.emit(value, _active_substate)
|
||||
_active_substate = value
|
||||
if _active_substate != null:
|
||||
_active_substate.choose_new_substate_requested.connect(_on_choose_new_substate_requested)
|
||||
|
||||
# If a timer is set, the object will be stored here.
|
||||
var _timer_object: SceneTreeTimer
|
||||
|
||||
|
||||
#########################
|
||||
### VIRTUAL METHODS ###
|
||||
#########################
|
||||
func _init() -> void:
|
||||
set_physics_process(false)
|
||||
set_meta(&"description", "A bare, basic state - will only ever automatically start its first child.")
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
for child in get_children():
|
||||
assert(child is State, "A State should not have any children that are not other States.")
|
||||
if is_root() and not disabled:
|
||||
enter(target, animation_player, debug_mode)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if status == Status.INACTIVE:
|
||||
set_physics_process(false)
|
||||
return
|
||||
update(delta)
|
||||
|
||||
|
||||
## [b][parents, then children][/b] Called when the state is activated.
|
||||
func _enter() -> void:
|
||||
pass
|
||||
|
||||
|
||||
## [b][children, then parents][/b] Called after the state is activated.
|
||||
func _after_enter() -> void:
|
||||
pass
|
||||
|
||||
|
||||
## [b][parents, then children][/b] Called every physics frame (only when the state is active, of course).
|
||||
func _update(delta: float) -> void:
|
||||
pass
|
||||
|
||||
|
||||
## [b][children, then parents][/b] Called at the end of every physics frame.
|
||||
func _after_update(delta: float) -> void:
|
||||
pass
|
||||
|
||||
|
||||
## [b][parents, then children][/b] Called before the state is deactivated.
|
||||
func _before_exit() -> void:
|
||||
pass
|
||||
|
||||
|
||||
## [b][children, then parents][/b] Called when the state is deactivated.
|
||||
func _exit() -> void:
|
||||
pass
|
||||
|
||||
|
||||
## You can define which state is picked automatically (like on [method enter]).
|
||||
## Return `null` to not change substate at all.
|
||||
## If you would like to call it yourself, use the public version ([method choose_substate]).
|
||||
func _choose_substate() -> State:
|
||||
return get_child(0) as State if get_child_count() > 0 else null
|
||||
|
||||
|
||||
########################
|
||||
### PUBLIC METHODS ###
|
||||
########################
|
||||
|
||||
## Switch to the specified substate by name. It is just a shortcut to [method change_state_node].
|
||||
func change_state_name(name: String, force := false) -> State:
|
||||
return await change_state_node(get_node_or_null(name) as State, force)
|
||||
|
||||
|
||||
## Switch to the specified substate by node. If it is not a direct child, nothing will happen.
|
||||
## If `force`, it will start a state again even if it's already running.
|
||||
## It waits for the next [signal updated] to make sure it's not
|
||||
## switching all over the place in one tick.
|
||||
func change_state_node(node: State, force := false) -> State:
|
||||
await updated
|
||||
if (
|
||||
node == null
|
||||
or node.disabled
|
||||
or (node.status != Status.INACTIVE and not force)
|
||||
or node.get_parent() != self
|
||||
):
|
||||
return node
|
||||
|
||||
var old := _active_substate
|
||||
_active_substate = node
|
||||
if old != null:
|
||||
old.exit()
|
||||
_active_substate.enter(target, animation_player, debug_mode)
|
||||
|
||||
if debug_mode:
|
||||
print(
|
||||
("FORCE " if force else "") +
|
||||
"STATE: " +
|
||||
str(get_root().get_parent().get_path_to(_active_substate))
|
||||
)
|
||||
return _active_substate
|
||||
|
||||
|
||||
## Return the currently active substate, if any.
|
||||
func get_active_substate() -> State:
|
||||
return _active_substate
|
||||
|
||||
|
||||
## Public [method _choose_substate].
|
||||
func choose_substate() -> State:
|
||||
return _choose_substate()
|
||||
|
||||
|
||||
## Shortcut for `change_state_node(choose_substate())`.
|
||||
func change_to_next_substate(force := false) -> void:
|
||||
await change_state_node(choose_substate(), force)
|
||||
|
||||
|
||||
## Whether this state is the root of the state tree,
|
||||
## ie. it is the common ancestor of all the others.
|
||||
func is_root() -> bool:
|
||||
# If your parent is not a state, then you are the root.
|
||||
return not get_parent() is State
|
||||
|
||||
|
||||
## Get the root state.
|
||||
func get_root() -> State:
|
||||
var node: State = self
|
||||
while not node.is_root():
|
||||
node = node.get_parent() as State
|
||||
return node
|
||||
|
||||
|
||||
## Runs [method _enter] and [method _after_enter],
|
||||
## not a good idea to call it yourself unless you really know what you're doing.
|
||||
func enter(set_target: Node, set_animation_player: AnimationPlayer, set_debug_mode: bool) -> void:
|
||||
for child in get_children():
|
||||
assert(child is State, "A State should not have any children that are not other States.")
|
||||
|
||||
_enter()
|
||||
entered.emit()
|
||||
status = Status.ACTIVE
|
||||
if timer != 0:
|
||||
_timer_object = get_tree().create_timer(timer)
|
||||
_timer_object.timeout.connect(_on_timer_timeout)
|
||||
set_physics_process(is_root())
|
||||
|
||||
# Only set them if they're not being overridden
|
||||
if target == null:
|
||||
target = set_target
|
||||
if animation_player == null:
|
||||
animation_player = set_animation_player
|
||||
if debug_mode == false:
|
||||
debug_mode = set_debug_mode
|
||||
|
||||
change_to_next_substate()
|
||||
_after_enter()
|
||||
|
||||
|
||||
## Runs [method _update] and [method _after_update],
|
||||
## not a good idea to call it yourself unless you really know what you're doing.
|
||||
func update(delta: float) -> void:
|
||||
_update(delta)
|
||||
updated.emit()
|
||||
if _active_substate != null:
|
||||
_active_substate.update(delta)
|
||||
_after_update(delta)
|
||||
|
||||
|
||||
## Runs [method _exit] and [method _before_exit],
|
||||
## not a good idea to call it yourself unless you really know what you're doing.
|
||||
func exit() -> void:
|
||||
_before_exit()
|
||||
status = Status.INACTIVE
|
||||
if _active_substate != null:
|
||||
_active_substate.exit()
|
||||
_active_substate = null
|
||||
|
||||
if is_instance_valid(_timer_object):
|
||||
_timer_object.timeout.disconnect(_on_timer_timeout)
|
||||
_timer_object = null
|
||||
|
||||
_exit()
|
||||
exited.emit()
|
||||
set_physics_process(false)
|
||||
|
||||
|
||||
#########################
|
||||
### PRIVATE METHODS ###
|
||||
#########################
|
||||
|
||||
|
||||
#################
|
||||
### CALLBACKS ###
|
||||
#################
|
||||
|
||||
func _on_choose_new_substate_requested() -> void:
|
||||
change_to_next_substate(force)
|
||||
|
||||
|
||||
func _on_timer_timeout() -> void:
|
||||
choose_new_substate_requested.emit()
|
14
addons/simple-state/demo/demo.gd
Normal file
|
@ -0,0 +1,14 @@
|
|||
extends State
|
||||
|
||||
|
||||
const NEXT_STATE_ACTION = "demo_next_state"
|
||||
|
||||
|
||||
func _enter() -> void:
|
||||
if InputMap.has_action(NEXT_STATE_ACTION):
|
||||
return
|
||||
var input_event := InputEventKey.new()
|
||||
input_event.keycode = KEY_TAB
|
||||
|
||||
InputMap.add_action(NEXT_STATE_ACTION)
|
||||
InputMap.action_add_event(NEXT_STATE_ACTION, input_event)
|
218
addons/simple-state/demo/demo.tscn
Normal file
|
@ -0,0 +1,218 @@
|
|||
[gd_scene load_steps=17 format=3 uid="uid://clnliyc6fmqy6"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/simple-state/classes/debugger.gd" id="1_rqf1w"]
|
||||
[ext_resource type="Script" path="res://addons/simple-state/demo/description_box.gd" id="2_gktik"]
|
||||
[ext_resource type="Script" path="res://addons/simple-state/classes/sequence_state.gd" id="3_4afa7"]
|
||||
[ext_resource type="Script" path="res://addons/simple-state/demo/demo.gd" id="3_x0hcs"]
|
||||
[ext_resource type="Script" path="res://addons/simple-state/classes/random_state.gd" id="4_wxjoe"]
|
||||
[ext_resource type="Script" path="res://addons/simple-state/demo/emit_next.gd" id="6_kxcgl"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ysqm7"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_wxupu"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7gdgn"]
|
||||
draw_center = false
|
||||
border_width_left = 1
|
||||
border_width_top = 1
|
||||
border_width_right = 1
|
||||
border_width_bottom = 1
|
||||
|
||||
[sub_resource type="Animation" id="Animation_5pgem"]
|
||||
resource_name = "RESET"
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("ColorRect:color")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(1, 1, 1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_mwhj1"]
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("ColorRect:color")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(0, 0, 0, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_yyph0"]
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("ColorRect:color")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(0, 0, 1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_xmkhy"]
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("ColorRect:color")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(0, 1, 0, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_4pwkk"]
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("ColorRect:color")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(1, 0, 0, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_gt7hj"]
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("ColorRect:color")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(1, 1, 0, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_01hf1"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_5pgem"),
|
||||
"black": SubResource("Animation_mwhj1"),
|
||||
"blue": SubResource("Animation_yyph0"),
|
||||
"green": SubResource("Animation_xmkhy"),
|
||||
"red": SubResource("Animation_4pwkk"),
|
||||
"yellow": SubResource("Animation_gt7hj")
|
||||
}
|
||||
|
||||
[node name="SimpleStateDemo" type="Panel"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_constants/margin_left = 10
|
||||
theme_override_constants/margin_top = 10
|
||||
theme_override_constants/margin_right = 10
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="StateMachineDebugger" type="Tree" parent="MarginContainer/HBoxContainer" node_paths=PackedStringArray("state_machine_root")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/relationship_line_width = 2
|
||||
theme_override_constants/draw_guides = 0
|
||||
theme_override_styles/panel = SubResource("StyleBoxEmpty_ysqm7")
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_wxupu")
|
||||
theme_override_styles/selected = SubResource("StyleBoxFlat_7gdgn")
|
||||
theme_override_styles/selected_focus = SubResource("StyleBoxFlat_7gdgn")
|
||||
select_mode = 1
|
||||
script = ExtResource("1_rqf1w")
|
||||
state_machine_root = NodePath("../../Root")
|
||||
allow_state_switching = true
|
||||
signal_show = true
|
||||
|
||||
[node name="DescriptionBox" type="Label" parent="MarginContainer/HBoxContainer" node_paths=PackedStringArray("tree")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
autowrap_mode = 3
|
||||
script = ExtResource("2_gktik")
|
||||
tree = NodePath("../StateMachineDebugger")
|
||||
show_descriptions = 2
|
||||
|
||||
[node name="InputInfo" type="Label" parent="MarginContainer/HBoxContainer/DescriptionBox"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 3
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -349.0
|
||||
offset_top = -78.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 0
|
||||
text = "MOUSE CLICK on state: select
|
||||
DOUBLE MOUSE CLICK on state: start
|
||||
TAB: next substate (only has effect on leaves)"
|
||||
horizontal_alignment = 2
|
||||
vertical_alignment = 2
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="MarginContainer"]
|
||||
custom_minimum_size = Vector2(50, 50)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 8
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="MarginContainer"]
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_01hf1")
|
||||
}
|
||||
|
||||
[node name="Root" type="Node" parent="MarginContainer" node_paths=PackedStringArray("target", "animation_player")]
|
||||
script = ExtResource("3_x0hcs")
|
||||
target = NodePath("")
|
||||
animation_player = NodePath("../AnimationPlayer")
|
||||
|
||||
[node name="SequenceState" type="Node" parent="MarginContainer/Root"]
|
||||
script = ExtResource("3_4afa7")
|
||||
|
||||
[node name="RandomState" type="Node" parent="MarginContainer/Root/SequenceState"]
|
||||
script = ExtResource("4_wxjoe")
|
||||
defer_choice = true
|
||||
|
||||
[node name="red" type="Node" parent="MarginContainer/Root/SequenceState/RandomState"]
|
||||
script = ExtResource("6_kxcgl")
|
||||
|
||||
[node name="yellow" type="Node" parent="MarginContainer/Root/SequenceState/RandomState"]
|
||||
script = ExtResource("6_kxcgl")
|
||||
|
||||
[node name="green" type="Node" parent="MarginContainer/Root/SequenceState"]
|
||||
script = ExtResource("6_kxcgl")
|
||||
|
||||
[node name="blue" type="Node" parent="MarginContainer/Root/SequenceState"]
|
||||
script = ExtResource("6_kxcgl")
|
||||
|
||||
[node name="black" type="Node" parent="MarginContainer/Root"]
|
||||
script = ExtResource("6_kxcgl")
|
||||
timer = 1.0
|
||||
metadata/description = "Will never start automatically, due to its parent being only a normal state."
|
98
addons/simple-state/demo/description_box.gd
Normal file
|
@ -0,0 +1,98 @@
|
|||
extends Label
|
||||
|
||||
|
||||
## Mode of description box rendering.
|
||||
enum DisplayModes {
|
||||
NONE, ## Description box completely hidden.
|
||||
ACTIVE, ## Show descriptions of all active states.
|
||||
SELECTION, ## Show description of last selected state (also includes manual switches).
|
||||
}
|
||||
|
||||
|
||||
@export
|
||||
## [StateMachineDebugger] to reference.
|
||||
var tree : StateMachineDebugger:
|
||||
set(value):
|
||||
tree = value
|
||||
if show_descriptions == DisplayModes.SELECTION and \
|
||||
not tree.item_selected.is_connected(_on_tree_item_selected):
|
||||
tree.item_selected.connect(_on_tree_item_selected)
|
||||
|
||||
|
||||
@export
|
||||
## Show a description of a state.
|
||||
## Looks for a string metadata value by the name of [code]description[/code] on each state.
|
||||
var show_descriptions := DisplayModes.NONE:
|
||||
set(value):
|
||||
show_descriptions = value
|
||||
|
||||
match show_descriptions:
|
||||
DisplayModes.NONE:
|
||||
visible = false
|
||||
DisplayModes.ACTIVE:
|
||||
visible = true
|
||||
if not is_instance_valid(tree):
|
||||
return
|
||||
if tree.item_selected.is_connected(_on_tree_item_selected):
|
||||
tree.item_selected.disconnect(_on_tree_item_selected)
|
||||
DisplayModes.SELECTION:
|
||||
visible = true
|
||||
if not is_instance_valid(tree):
|
||||
return
|
||||
if not tree.item_selected.is_connected(_on_tree_item_selected):
|
||||
tree.item_selected.connect(_on_tree_item_selected)
|
||||
|
||||
|
||||
var _active_states : Array[State] = []
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
visible = show_descriptions != DisplayModes.NONE
|
||||
connect_signals()
|
||||
|
||||
|
||||
func connect_signals(state := tree.state_machine_root) -> void:
|
||||
if not state.has_meta(&"tree_item"):
|
||||
return
|
||||
for signal_name in tree.signal_connections:
|
||||
if state.has_signal(signal_name) and not \
|
||||
state.is_connected(signal_name, _on_state_signal):
|
||||
state.connect(signal_name, _on_state_signal.bind(signal_name, state))
|
||||
for child in(state.get_children() as Array[State]):
|
||||
connect_signals(child)
|
||||
|
||||
|
||||
func disconnect_signals(state := tree.state_machine_root) -> void:
|
||||
for signal_name in tree.signal_connections:
|
||||
if state.has_signal(signal_name) and \
|
||||
state.is_connected(signal_name, _on_state_signal):
|
||||
state.disconnect(signal_name, _on_state_signal)
|
||||
for child in (state.get_children() as Array[State]):
|
||||
disconnect_signals(child)
|
||||
|
||||
|
||||
func _set_description_from_active_states() -> void:
|
||||
text = ""
|
||||
for state in _active_states:
|
||||
text += ("" if state.is_root() else "\n\n") + \
|
||||
state.name as String + \
|
||||
": " + \
|
||||
state.get_meta(&"description", "") as String
|
||||
|
||||
|
||||
func _on_tree_item_selected() -> void:
|
||||
text = tree.get_selected() \
|
||||
.get_metadata(0).get_meta(&"description", "")
|
||||
|
||||
|
||||
func _on_state_signal(signal_name: StringName, state: State) -> void:
|
||||
match signal_name:
|
||||
&"entered":
|
||||
if show_descriptions == DisplayModes.ACTIVE:
|
||||
_active_states.push_back(state)
|
||||
_set_description_from_active_states()
|
||||
&"exited":
|
||||
if show_descriptions == DisplayModes.ACTIVE:
|
||||
_active_states.pop_back()
|
||||
_set_description_from_active_states()
|
6
addons/simple-state/demo/emit_next.gd
Normal file
|
@ -0,0 +1,6 @@
|
|||
extends AnimationState
|
||||
|
||||
|
||||
func _update(_delta: float) -> void:
|
||||
if Input.is_action_just_pressed(get_root().NEXT_STATE_ACTION):
|
||||
choose_new_substate_requested.emit()
|
BIN
addons/simple-state/icons/animation_state.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
34
addons/simple-state/icons/animation_state.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cna1s8hi8xc58"
|
||||
path="res://.godot/imported/animation_state.png-5f10255295e45d80e555d2885de83e22.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/simple-state/icons/animation_state.png"
|
||||
dest_files=["res://.godot/imported/animation_state.png-5f10255295e45d80e555d2885de83e22.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
|
2
addons/simple-state/icons/licenses/Visit Kenney.url
Normal file
|
@ -0,0 +1,2 @@
|
|||
[InternetShortcut]
|
||||
URL=http://www.kenney.nl/
|
2
addons/simple-state/icons/licenses/Visit Patreon.url
Normal file
|
@ -0,0 +1,2 @@
|
|||
[InternetShortcut]
|
||||
URL=https://www.patreon.com/kenney/
|
22
addons/simple-state/icons/licenses/board_game_icons.txt
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
|
||||
Board Game Icons (1.0)
|
||||
|
||||
Created/distributed by Kenney (www.kenney.nl)
|
||||
Creation date: 10-01-2022
|
||||
|
||||
------------------------------
|
||||
|
||||
License: (Creative Commons Zero, CC0)
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
This content is free to use in personal, educational and commercial projects.
|
||||
Support us by crediting Kenney or www.kenney.nl (this is not mandatory)
|
||||
|
||||
------------------------------
|
||||
|
||||
Donate: http://support.kenney.nl
|
||||
Patreon: http://patreon.com/kenney/
|
||||
|
||||
Follow on Twitter for updates:
|
||||
http://twitter.com/KenneyNL
|
14
addons/simple-state/icons/licenses/game_icons+expansion.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
###############################################################################
|
||||
|
||||
Game icon pack by Kenney Vleugels (www.kenney.nl)
|
||||
|
||||
------------------------------
|
||||
|
||||
License (CC0)
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
You may use these graphics in personal and commercial projects.
|
||||
Credit (Kenney or www.kenney.nl) would be nice but is not mandatory.
|
||||
|
||||
###############################################################################
|
20
addons/simple-state/icons/licenses/pictogrammers.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
Pictogrammers Free License
|
||||
--------------------------
|
||||
|
||||
This icon collection is released as free, open source, and GPL friendly by
|
||||
the [Pictogrammers](http://pictogrammers.com/). You may use it
|
||||
for commercial projects, open source projects, or anything really.
|
||||
|
||||
# Icons: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
||||
Some of the icons are redistributed under the Apache 2.0 license. All other
|
||||
icons are either redistributed under their respective licenses or are
|
||||
distributed under the Apache 2.0 license.
|
||||
|
||||
# Fonts: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
||||
All web and desktop fonts are distributed under the Apache 2.0 license. Web
|
||||
and desktop fonts contain some icons that are redistributed under the Apache
|
||||
2.0 license. All other icons are either redistributed under their respective
|
||||
licenses or are distributed under the Apache 2.0 license.
|
||||
|
||||
# Code: MIT (https://opensource.org/licenses/MIT)
|
||||
The MIT license applies to all non-font and non-icon files.
|
BIN
addons/simple-state/icons/random_state.png
Normal file
After Width: | Height: | Size: 551 B |
34
addons/simple-state/icons/random_state.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cgoc214akn2d6"
|
||||
path="res://.godot/imported/random_state.png-0878745fbdc123f3f0d51012c73a7024.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/simple-state/icons/random_state.png"
|
||||
dest_files=["res://.godot/imported/random_state.png-0878745fbdc123f3f0d51012c73a7024.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
|
BIN
addons/simple-state/icons/sequence_state.png
Normal file
After Width: | Height: | Size: 424 B |
34
addons/simple-state/icons/sequence_state.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bcviu3dccvvm2"
|
||||
path="res://.godot/imported/sequence_state.png-4718f2c926301319d99a0ccd15ff62fb.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/simple-state/icons/sequence_state.png"
|
||||
dest_files=["res://.godot/imported/sequence_state.png-4718f2c926301319d99a0ccd15ff62fb.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
|
12
addons/simple-state/icons/sources.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
Icon Sources
|
||||
-----------
|
||||
[0] Board Game Icons: https://kenney.nl/assets/board-game-icons
|
||||
- state.png
|
||||
- random_state.png
|
||||
- sequence_state.png
|
||||
|
||||
[1] Game Icons: https://kenney.nl/assets/game-icons
|
||||
- animation_state.png
|
||||
|
||||
[2] Pictogrammers: <https://pictogrammers.com/library/mdi/>
|
||||
- state_machine_debugger.png (tinted)
|
BIN
addons/simple-state/icons/state.png
Normal file
After Width: | Height: | Size: 572 B |
34
addons/simple-state/icons/state.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://msu07hn5ewo5"
|
||||
path="res://.godot/imported/state.png-fa3dd722682a28f890f138dcc6e162af.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/simple-state/icons/state.png"
|
||||
dest_files=["res://.godot/imported/state.png-fa3dd722682a28f890f138dcc6e162af.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
|
BIN
addons/simple-state/icons/state_fullsize.png
Normal file
After Width: | Height: | Size: 767 B |
34
addons/simple-state/icons/state_fullsize.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b32u1sa3robj0"
|
||||
path="res://.godot/imported/state_fullsize.png-41a4827bc36d7745ba55c17c0bc213e9.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/simple-state/icons/state_fullsize.png"
|
||||
dest_files=["res://.godot/imported/state_fullsize.png-41a4827bc36d7745ba55c17c0bc213e9.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
|
BIN
addons/simple-state/icons/state_machine_debugger.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
34
addons/simple-state/icons/state_machine_debugger.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dsglk01amsawf"
|
||||
path="res://.godot/imported/state_machine_debugger.png-4af22f2c577f0756aa0b1d50ce679700.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/simple-state/icons/state_machine_debugger.png"
|
||||
dest_files=["res://.godot/imported/state_machine_debugger.png-4af22f2c577f0756aa0b1d50ce679700.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
|
7
addons/simple-state/plugin.cfg
Normal file
|
@ -0,0 +1,7 @@
|
|||
[plugin]
|
||||
|
||||
name="SimpleState"
|
||||
description="A super-simple state machine. Lightweight and (hopefully) reliable."
|
||||
author="AuraTheEnby"
|
||||
version="1.3.2"
|
||||
script="plugin.gd"
|
25
addons/simple-state/plugin.gd
Normal file
|
@ -0,0 +1,25 @@
|
|||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
## It uses the icons provided by the scripts anyway, so
|
||||
## we don't really need to specify the real ones here.
|
||||
## Plus, it might help with enabling it before the project
|
||||
## has been reloaded for the first time.
|
||||
var placeholder_texture := PlaceholderTexture2D.new()
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
add_custom_type("State", "Node", State, placeholder_texture)
|
||||
add_custom_type("RandomState", "Node", RandomState, placeholder_texture)
|
||||
add_custom_type("AnimationState", "Node", AnimationState, placeholder_texture)
|
||||
add_custom_type("SequenceState", "Node", SequenceState, placeholder_texture)
|
||||
add_custom_type("StateMachineDebugger", "Tree", StateMachineDebugger, placeholder_texture)
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
remove_custom_type("State")
|
||||
remove_custom_type("RandomState")
|
||||
remove_custom_type("AnimationState")
|
||||
remove_custom_type("SequenceState")
|
||||
remove_custom_type("StateMachineDebugger")
|
33
addons/simple-state/templates/State/empty_state.gd
Normal file
|
@ -0,0 +1,33 @@
|
|||
# meta-default: true
|
||||
extends _BASE_
|
||||
|
||||
|
||||
# Called when the state is activated. (parents, then children)
|
||||
func _enter() -> void:
|
||||
pass
|
||||
|
||||
|
||||
# Called after the state is activated. (children, then parents)
|
||||
func _after_enter() -> void:
|
||||
pass
|
||||
|
||||
|
||||
# Called every physics frame (only when the state is active, of course). (parents, then children)
|
||||
func _update(delta: float) -> void:
|
||||
pass
|
||||
|
||||
|
||||
# Called at the end of every physics frame. (children, then parents)
|
||||
func _after_update(delta: float) -> void:
|
||||
pass
|
||||
|
||||
|
||||
# Called before the state is deactivated. (parents, then children)
|
||||
func _before_exit() -> void:
|
||||
pass
|
||||
|
||||
|
||||
# Called when the state is deactivated. (children, then parents)
|
||||
func _exit() -> void:
|
||||
pass
|
||||
|
111
addons/simplelicense/GUI/LicenseGUI.tscn
Normal file
|
@ -0,0 +1,111 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://bbhv8iqdbkqbt"]
|
||||
|
||||
[ext_resource type="Script" path="res://scripts/license_gui.gd" id="1_esldu"]
|
||||
[ext_resource type="Script" path="res://addons/simplelicense/api/LicenseManager.gd" id="2_cpb2k"]
|
||||
|
||||
[node name="LicenseGUI" type="Control"]
|
||||
custom_minimum_size = Vector2(256, 256)
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_esldu")
|
||||
load_locations = Array[String](["res://licenses", "res://addons/simplelicense/mod_example/licenses/"])
|
||||
export_locations = Array[String](["user://licenses/game/", "user://licenses/mods/mod_1/"])
|
||||
|
||||
[node name="LicenseManager" type="Node" parent="."]
|
||||
script = ExtResource("2_cpb2k")
|
||||
|
||||
[node name="background" type="Panel" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.381076
|
||||
anchor_right = 0.461806
|
||||
anchor_bottom = 0.0401235
|
||||
offset_left = 3.05176e-05
|
||||
grow_horizontal = 2
|
||||
text = "License Info"
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="Tree" type="Tree" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.00694444
|
||||
anchor_top = 0.0462963
|
||||
anchor_right = 0.404514
|
||||
anchor_bottom = 0.987654
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 2
|
||||
hide_root = true
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="Text" type="TextEdit" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.434028
|
||||
anchor_top = 0.0462963
|
||||
anchor_right = 0.993056
|
||||
anchor_bottom = 0.987654
|
||||
offset_left = -8.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
editable = false
|
||||
scroll_smooth = true
|
||||
minimap_draw = true
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="btn_open_data_dir" type="Button" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.585069
|
||||
anchor_top = 0.00308642
|
||||
anchor_right = 0.696181
|
||||
anchor_bottom = 0.0416667
|
||||
grow_horizontal = 2
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "Open Data Directory"
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="btn_save_licenses" type="Button" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.491319
|
||||
anchor_top = 0.00308642
|
||||
anchor_right = 0.56684
|
||||
anchor_bottom = 0.0416667
|
||||
grow_horizontal = 2
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "Save Licenses"
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="op_locations" type="OptionButton" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.00694444
|
||||
anchor_top = 0.00308642
|
||||
anchor_right = 0.172743
|
||||
anchor_bottom = 0.0416667
|
||||
theme_override_font_sizes/font_size = 12
|
||||
item_count = 2
|
||||
popup/item_0/text = "a"
|
||||
popup/item_0/id = 0
|
||||
popup/item_1/text = "b"
|
||||
popup/item_1/id = 1
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[connection signal="item_activated" from="Tree" to="." method="_on_tree_item_activated"]
|
||||
[connection signal="item_selected" from="Tree" to="." method="_on_tree_item_selected"]
|
||||
[connection signal="pressed" from="btn_open_data_dir" to="." method="_on_btn_open_data_dir_pressed"]
|
||||
[connection signal="pressed" from="btn_save_licenses" to="." method="_on_button_pressed"]
|
||||
[connection signal="item_selected" from="op_locations" to="." method="_on_op_locations_item_selected"]
|
BIN
addons/simplelicense/Icon.png
Normal file
After Width: | Height: | Size: 45 KiB |
34
addons/simplelicense/Icon.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://duvmbh55cyvev"
|
||||
path="res://.godot/imported/Icon.png-451064bd72ea26ed7eb00aedd926556f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/simplelicense/Icon.png"
|
||||
dest_files=["res://.godot/imported/Icon.png-451064bd72ea26ed7eb00aedd926556f.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
|
163
addons/simplelicense/Icon.svg
Normal file
After Width: | Height: | Size: 51 KiB |
37
addons/simplelicense/Icon.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dnr20t153it5i"
|
||||
path="res://.godot/imported/Icon.svg-62b5bc5b7872f9c089f3b98f0084a03c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/simplelicense/Icon.svg"
|
||||
dest_files=["res://.godot/imported/Icon.svg-62b5bc5b7872f9c089f3b98f0084a03c.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
|
121
addons/simplelicense/LICENSE.txt
Normal file
|
@ -0,0 +1,121 @@
|
|||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
37
addons/simplelicense/README.txt
Normal file
|
@ -0,0 +1,37 @@
|
|||
A simple plugin, to make dealing with licensing simple.
|
||||
Files: ./addons/simplelicense/*
|
||||
License: CC0-1.0
|
||||
|
||||
Developed in Godot version: v4.0.beta.custom_build [166df0896]
|
||||
|
||||
Quick Example: (A License Viewer Scene, that you can also drop into one of your game scenes)
|
||||
Run the Scene at
|
||||
res://addons/simplelicense/GUI/LicenseGUI.tscn
|
||||
|
||||
look around, then
|
||||
click on the "open data directory" button
|
||||
then click on the "save licenses" button
|
||||
and watch the data directory populate with license files
|
||||
|
||||
|
||||
Quick Start:
|
||||
1. Create a "LicenseLink" Resource file inside the
|
||||
res://licenses/license_links/
|
||||
|
||||
2. Click on the the new Resource file, and try it out
|
||||
There are docs on how to use it, so just F1 + LicenseLink, to find out more
|
||||
|
||||
3. Load license information
|
||||
Create an instance of "LicenseManager" either in code or by adding the node to the scene
|
||||
then call "load_license_information" on the LicenseManager
|
||||
|
||||
4. Export License information
|
||||
call "export" function on the LicenseManager
|
||||
it will populate the "user://" directory with your license files
|
||||
one combined "COPYRIGHT.txt" file
|
||||
and individual copyright files into "user://licenses/<license_identifier>.txt".
|
||||
The license text will be formatted in the SPDX standard.
|
||||
It's the way the Godot Engine does it.
|
||||
in the Godot Editor: Help -> About Godot -> Third-party Licenses
|
||||
There is more you can do, just visit the docs!
|
||||
(Like support for loading mod's license information!)
|
78
addons/simplelicense/api/License.gd
Normal file
|
@ -0,0 +1,78 @@
|
|||
class_name License
|
||||
extends Resource
|
||||
## Holds AUTO GENERATED License information
|
||||
|
||||
## SPDX-License-Identifier or similar to it. CASE SENSITIVE[br]
|
||||
## Like "CC0-1.0"[br]
|
||||
## See [url=https://spdx.org/licenses/]SPDX Identifier List[/url]
|
||||
var identifier: String = ""
|
||||
|
||||
## The License's Name. [br]
|
||||
## Like "CC0 1.0 Universal"
|
||||
var name: String = ""
|
||||
|
||||
## License Terms; The text of a license file
|
||||
var terms: String = ""
|
||||
|
||||
## Returns a string containing this license's information, formatted to [url=https://spdx.dev/resources/use/]SPDX Standards[/url]
|
||||
func to_formatted_string() -> String:
|
||||
return "License: {identifier}\n{terms}".format({
|
||||
'identifier': identifier,
|
||||
'terms': _add_line_padding(terms)
|
||||
})
|
||||
|
||||
|
||||
# wouldn't recomend using this, unless you know what your doing
|
||||
# but if you do, this loads and parses all licenses (.txt files) in a directory,
|
||||
# plus Godot's built-in Licenses
|
||||
static func _load_licenses_in(dir: String):
|
||||
var dict = {}
|
||||
|
||||
# get game licenses
|
||||
var names = DirAccess.get_files_at(dir)
|
||||
if names.size() == 0:
|
||||
print_verbose("\nSimple License: No License files found in dir\n", dir, "\nif you have no license files there, then this can be ignored\n")
|
||||
for _name in names:
|
||||
var ext = _name.rsplit('.', false, 1)
|
||||
if ext.size() == 0 or ext[-1] != 'txt':
|
||||
continue
|
||||
|
||||
var l = new()
|
||||
l.identifier = _name.split('.', false, 1)[0]
|
||||
l.name = l.identifier
|
||||
l.terms = FileAccess.open(dir.path_join(_name), FileAccess.READ).get_as_text()
|
||||
dict[l.identifier] = l
|
||||
|
||||
# get licenses built into the Godot Engine
|
||||
var tmp = Engine.get_license_info()
|
||||
for id in tmp:
|
||||
if dict.has(id):
|
||||
continue
|
||||
|
||||
var l = new()
|
||||
l.identifier = id
|
||||
l.terms = tmp[id]
|
||||
dict[id] = l
|
||||
|
||||
return dict
|
||||
|
||||
|
||||
# this is for formatting individual lines accoring to SPDX standards
|
||||
static func _add_line_padding(combined_lines: String, padding: String = " ") -> String:
|
||||
if combined_lines.is_empty():
|
||||
return combined_lines
|
||||
|
||||
var lines = combined_lines.split("\n")
|
||||
|
||||
var s = ""
|
||||
for i in len(lines):
|
||||
if lines[i].is_empty() or lines[i] == "\n":
|
||||
if i+1 < len(lines):
|
||||
s += padding + "." + "\n"
|
||||
else:
|
||||
s += '\n'
|
||||
else:
|
||||
s += padding + lines[i] + "\n"
|
||||
s = s.strip_edges(false)
|
||||
s += '\n'
|
||||
return s
|
178
addons/simplelicense/api/LicenseLink.gd
Normal file
|
@ -0,0 +1,178 @@
|
|||
class_name LicenseLink
|
||||
extends Resource
|
||||
|
||||
## Files that are under this license [br]
|
||||
## [color=red]WARNING[/color] DO NOT put in any file that Godot Cannot load, via Resource.load() [br]
|
||||
## or it will prevent the game from launching. files like .txt .csg etc
|
||||
@export var link_files: Array[Resource]
|
||||
|
||||
## Directories that are under this license [br]
|
||||
## The given file's Parent Directory will be tracked [br]
|
||||
## [color=red]WARNING[/color] DO NOT put in any file that Godot Cannot load, via Resource.load() [br]
|
||||
## or it will prevent the game from launching. files like .txt .csg etc
|
||||
@export var link_dirs: Array[Resource]
|
||||
|
||||
## Files that are under this license [br]
|
||||
## Note: These paths are [b]NOT[/b] automatically tracked, [br]
|
||||
## you will have to, manually keep these paths up to date
|
||||
@export var link_paths: Array
|
||||
|
||||
## Example: Godot_Icon, Custom Font Name, Your Games Name, etc
|
||||
@export var componet_name: String = ""
|
||||
|
||||
## Gets included in [method to_formatted_string] right after [member componet_name] [br]
|
||||
## as part of the "Comment:" Section of the SPDX format
|
||||
@export var extra: String = ""
|
||||
|
||||
## SPDX-License-Identifier or similar to it. CASE SENSITIVE[br]
|
||||
## Like "CC0-1.0" or more complex entries like [br]
|
||||
## "CC0-1.0 or MIT" [br]
|
||||
## "CC0-1.0 and MIT" [br]
|
||||
## See [url=https://spdx.org/licenses/]SPDX Identifier List[/url]
|
||||
@export var license_identifier: String = "" : set = _set_identifier
|
||||
|
||||
## who and when was the copyright was created [br]
|
||||
## example [br]
|
||||
## 2022, John Doe [br]
|
||||
## (next entry) [br]
|
||||
## 2022-2023, Jim Stirling, Corp xyz [br]
|
||||
@export var copyright: Array[String]
|
||||
|
||||
var license: License
|
||||
|
||||
## Unlike [member license_identifier] this contains [b]ONLY[/b] the identifiers [br]
|
||||
var license_identifiers: Array[String]
|
||||
|
||||
## Either "Godot Engine" or "Game" [br]
|
||||
## This value is AUTO GENERATED [br]
|
||||
## [b]DON'T SET THIS VALUE MANUALLY[/b], IT CAN BREAK THINGS
|
||||
var component_of: String = ""
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
_set_identifier(license_identifier)
|
||||
|
||||
|
||||
func _set_identifier(v: String):
|
||||
license_identifier = v
|
||||
|
||||
var tmp = v.replace(' and ', '!break!').replace(' or ', '!break!').split('!break!', false)
|
||||
for x in tmp:
|
||||
license_identifiers.append(x)
|
||||
|
||||
|
||||
func _to_string() -> String:
|
||||
return self.to_formatted_string()
|
||||
|
||||
## Returns a string containing this link's information, formatted to [url=https://spdx.dev/resources/use/]SPDX Standards[/url]
|
||||
func to_formatted_string(hide_files: bool = false):
|
||||
var _files = ""
|
||||
if not hide_files:
|
||||
for x in link_files:
|
||||
_files += x.resource_path.replace("res://", " ./").strip_edges() + "\n"
|
||||
for x in link_dirs:
|
||||
_files += (
|
||||
x.resource_path.replace("res://", " ./").rsplit("/", false, 1)[0].strip_edges()
|
||||
+ "/*\n"
|
||||
)
|
||||
for x in link_paths:
|
||||
_files += x.replace("res://", " ./").strip_edges() + "\n"
|
||||
_files = _files.strip_edges()
|
||||
|
||||
var _comment = ""
|
||||
if not componet_name.is_empty():
|
||||
_comment += componet_name
|
||||
if not extra.is_empty():
|
||||
_comment += "\n"
|
||||
if not extra.is_empty():
|
||||
_comment += extra
|
||||
|
||||
return "Files:{files}\nComment:{comment}\nCopyright:{copyright}\nLicense:{identifier}\n".format(
|
||||
{
|
||||
"files": _add_line_padding(_files, " "),
|
||||
"comment": _add_line_padding(_comment, " "),
|
||||
"copyright": _add_line_padding("\n".join(copyright), " "),
|
||||
"identifier": _add_line_padding(license_identifier, " "),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
# wouldn't recomend using this, unless you know what your doing
|
||||
# but if you do, this loads and parses all links (LicenseLink Resource files) in a directory,
|
||||
# plus Godot's built-in Licenses
|
||||
#
|
||||
# exclude engine: excludes loading Godot's built-in license information
|
||||
# this is for mods, in which the main game will have already shown the Godot Engine's Licensing
|
||||
static func _load_links_in(dir: String, exclude_engine: bool = false):
|
||||
var dict = {
|
||||
'array': [],
|
||||
'by_identifier': {},
|
||||
'by_parent': {},
|
||||
}
|
||||
|
||||
if not DirAccess.dir_exists_absolute(dir):
|
||||
printerr('Simple License: LicenseLinks directory is missing! ', dir)
|
||||
return dict
|
||||
|
||||
|
||||
# get Game license links
|
||||
var names = DirAccess.get_files_at(dir)
|
||||
if len(names) == 0:
|
||||
print_verbose("\nSimple License: No LicenseLinks found in dir\n", dir, "\nif you have no LicenseLinks there, then this can be ignored\n")
|
||||
for name in names:
|
||||
name = name.replace('.remap', '')
|
||||
var path = dir.path_join(name)
|
||||
var res = ResourceLoader.load(path)
|
||||
if res is Resource and res.get("copyright") != null:
|
||||
if res.component_of.is_empty():
|
||||
res.component_of = "Game"
|
||||
|
||||
dict.array.append(res)
|
||||
|
||||
dict.by_identifier[res.license_identifier] = res
|
||||
|
||||
if not dict.by_parent.has(res.component_of):
|
||||
dict.by_parent[res.component_of] = {}
|
||||
dict.by_parent[res.component_of][res.license_identifier] = res
|
||||
|
||||
# Get Engine license links
|
||||
if not exclude_engine:
|
||||
for a in Engine.get_copyright_info():
|
||||
var l = new()
|
||||
l.componet_name = a.name
|
||||
l.component_of = "Godot Engine"
|
||||
l.link_paths = a.parts[0].files
|
||||
|
||||
l.license_identifier = a.parts[0].license
|
||||
l.copyright.append_array(a.parts[0].copyright)
|
||||
|
||||
dict.array.append(l)
|
||||
|
||||
dict.by_identifier[l.license_identifier] = l
|
||||
|
||||
if not dict.by_parent.has(l.component_of):
|
||||
dict.by_parent[l.component_of] = {}
|
||||
|
||||
if not dict.by_parent[l.component_of].has(l.license_identifier):
|
||||
dict.by_parent[l.component_of][l.license_identifier] = l
|
||||
|
||||
return dict
|
||||
|
||||
# this is for formatting individual lines accoring to SPDX standards
|
||||
static func _add_line_padding(combined_lines: String, padding: String) -> String:
|
||||
if combined_lines.is_empty():
|
||||
return combined_lines
|
||||
|
||||
var lines = combined_lines.split("\n")
|
||||
|
||||
var s = ""
|
||||
for i in len(lines):
|
||||
if lines[i].is_empty() or lines[i] == "\n":
|
||||
if i+1 < len(lines):
|
||||
s += padding + "." + "\n"
|
||||
else:
|
||||
s += '\n'
|
||||
else:
|
||||
s += padding + lines[i] + "\n"
|
||||
s = s.strip_edges(false)
|
||||
return s
|
121
addons/simplelicense/api/LicenseManager.gd
Normal file
|
@ -0,0 +1,121 @@
|
|||
class_name LicenseManager
|
||||
extends Node
|
||||
|
||||
## loads license information from this directory and the sub-directory "license_links"
|
||||
@export var load_dir: String = "res://licenses"
|
||||
|
||||
## export license information to this directory and the sub-directory "licenses"
|
||||
@export var export_dir: String = "user://"
|
||||
|
||||
## This disables loading Godot's built-in license information [br]
|
||||
## this is for mods, in which the main game will have already shown the Godot's built-in Licensing
|
||||
@export var exclude_engine: bool = false
|
||||
|
||||
## contains all loaded [License]s [br]
|
||||
## key = identifier [br]
|
||||
## value = [License]
|
||||
var licenses := {}
|
||||
|
||||
## contains all loaded [LicenseLink]s [br]
|
||||
## with searching in mind [br]
|
||||
## "array" [] [br]
|
||||
## "by_identifier" {} license identifier [br]
|
||||
## "by_parent" {} parent component name [br]
|
||||
var license_links := {
|
||||
'array': [],
|
||||
'by_identifier': {},
|
||||
'by_parent': {},
|
||||
}
|
||||
|
||||
|
||||
## Loads license information from [member load_dir] [br]
|
||||
func load_license_information():
|
||||
licenses.clear()
|
||||
license_links.array.clear()
|
||||
license_links.by_identifier.clear()
|
||||
license_links.by_parent.clear()
|
||||
|
||||
if not DirAccess.dir_exists_absolute(load_dir):
|
||||
printerr("Failed to find license directory ", load_dir)
|
||||
return
|
||||
|
||||
licenses = License._load_licenses_in(load_dir)
|
||||
if licenses.has('Expat') and not licenses.has('MIT'):
|
||||
var l = licenses['Expat'].duplicate() as License
|
||||
l.identifier = 'MIT'
|
||||
licenses['MIT'] = l
|
||||
|
||||
license_links = LicenseLink._load_links_in(load_dir.path_join('license_links'), exclude_engine)
|
||||
|
||||
|
||||
## Returns a single string "file", that is formatted in the SPDX Standard [br]
|
||||
## that contains all licensing information, contained in this instance, [br]
|
||||
## if only_links, then the returned data will omit the licensing term files
|
||||
func get_combined_copyright(only_links: bool = false) -> String:
|
||||
var lines = ""
|
||||
|
||||
var used_licenses = {}
|
||||
|
||||
# Links
|
||||
for link in license_links.array:
|
||||
if link is LicenseLink:
|
||||
lines += link.to_formatted_string(link.component_of == 'Godot Engine')
|
||||
lines += '\n'
|
||||
used_licenses.merge(get_all_valid_licenses(link))
|
||||
|
||||
lines += '\n\n'
|
||||
|
||||
if only_links:
|
||||
return lines
|
||||
|
||||
# License Terms
|
||||
var values = used_licenses.values()
|
||||
for i in len(values):
|
||||
if i+1 < len(values):
|
||||
lines += values[i].to_formatted_string() + '\n'
|
||||
else:
|
||||
lines += values[i].to_formatted_string()
|
||||
|
||||
return lines
|
||||
|
||||
## Returns all licenses that are "valid"/exist [br]
|
||||
## Sometimes license files are missing, or Identifiers are incorrectly spelled, this helps with that.
|
||||
func get_all_valid_licenses(link: LicenseLink) -> Dictionary:
|
||||
var d = {}
|
||||
for x in link.license_identifiers:
|
||||
if licenses.has(x):
|
||||
d[x] = licenses[x]
|
||||
return d
|
||||
|
||||
## export all license information to [member export_dir] and the sub-directory "licenses"
|
||||
func export(directory: String = ""):
|
||||
if directory.is_empty():
|
||||
directory = export_dir
|
||||
|
||||
var licenses_path = directory.path_join('licenses')
|
||||
if not DirAccess.dir_exists_absolute(licenses_path):
|
||||
DirAccess.make_dir_recursive_absolute(licenses_path)
|
||||
|
||||
# Export the combined license file
|
||||
var f = FileAccess.open(directory.path_join('COPYRIGHT.txt'), FileAccess.WRITE)
|
||||
if f is FileAccess:
|
||||
f.store_string(self.get_combined_copyright())
|
||||
|
||||
# Export the slim license file
|
||||
f = FileAccess.open(directory.path_join('COPYRIGHT_SLIM.txt'), FileAccess.WRITE)
|
||||
if f is FileAccess:
|
||||
f.store_string(self.get_combined_copyright(true))
|
||||
|
||||
|
||||
# Export the individual license files
|
||||
|
||||
var used = {}
|
||||
for i in license_links.array.size():
|
||||
var license = license_links.array[i] as LicenseLink
|
||||
var ids = self.get_all_valid_licenses(license)
|
||||
used.merge(ids)
|
||||
|
||||
for id in ids:
|
||||
var license_path = licenses_path.path_join(id)+'.txt'
|
||||
f = FileAccess.open(license_path, FileAccess.WRITE)
|
||||
f.store_string(licenses[id].to_formatted_string())
|
|
@ -0,0 +1,14 @@
|
|||
[gd_resource type="Resource" script_class="LicenseLink" load_steps=3 format=3 uid="uid://ch5muqo430mw"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/simplelicense/mod_example/mod_1.gd" id="1_3n7mw"]
|
||||
[ext_resource type="Script" path="res://addons/simplelicense/api/LicenseLink.gd" id="1_gufc2"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_gufc2")
|
||||
link_files = Array[Resource]([])
|
||||
link_dirs = Array[Resource]([ExtResource("1_3n7mw")])
|
||||
link_paths = []
|
||||
componet_name = "Mod 1"
|
||||
extra = "extra info shown in the comment section of the link text"
|
||||
license_identifier = "mod_1_license_identifier"
|
||||
copyright = Array[String](["copyright year, (comma) name, (comma) company name"])
|
|
@ -0,0 +1,15 @@
|
|||
This is an example of the custom license terms for Mod_1
|
||||
|
||||
So like
|
||||
|
||||
MIT LICENSE TERMS
|
||||
...
|
||||
..
|
||||
.
|
||||
|
||||
or
|
||||
|
||||
CC0 1.0 LICENSE TERMS
|
||||
...
|
||||
..
|
||||
.
|
1
addons/simplelicense/mod_example/mod_1.gd
Normal file
|
@ -0,0 +1 @@
|
|||
extends Node
|
9
addons/simplelicense/plugin.cfg
Normal file
|
@ -0,0 +1,9 @@
|
|||
[plugin]
|
||||
|
||||
name="SimpleLicense"
|
||||
description="A simple license managment plugin.
|
||||
|
||||
Licensed under: CC0-1.0"
|
||||
author="GradyTheDev"
|
||||
version="1.1.2"
|
||||
script="plugin.gd"
|
12
addons/simplelicense/plugin.gd
Normal file
|
@ -0,0 +1,12 @@
|
|||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
# Initialization of the plugin goes here
|
||||
pass
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
# Clean-up of the plugin goes here.
|
||||
pass
|
0
addons/simplelicense/screenshots/.gdignore
Normal file
BIN
addons/simplelicense/screenshots/Example.png
Normal file
After Width: | Height: | Size: 140 KiB |