Reflection-driven target dropdowns (SelectNode3D, HasCondition), Brain activeNode generalization with auto-restart, TweenMaterial slot-ownership fix, Behavior/ file reorg into Core/Movements/Receptors, LockOn/CameraLocker updates
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e2a1171e5e
commit
ba487e326c
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="BehaviorBranch.svg"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#505050"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="10.363534"
|
||||||
|
inkscape:cx="4.728117"
|
||||||
|
inkscape:cy="5.789531"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="rect401"
|
||||||
|
style="color:#000000;fill:#1de3ab;fill-opacity:1;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:markers stroke fill"
|
||||||
|
d="m 1.319336,0.0888674 c -0.674094,0 -1.248047,0.571999 -1.248047,1.246093 v 2.511719 h 2 V 2.0888674 H 3.81543 v -2 z m 10.84375,0 v 2 h 1.765625 v 1.757812 h 2 v -2.511719 c 0,-0.674094 -0.573952,-1.246093 -1.248047,-1.246093 z M 0.071289,12.194336 v 2.46875 c 0,0.674094 0.573953,1.248047 1.248047,1.248047 H 3.81543 v -2 H 2.071289 v -1.716797 z m 13.857422,0 v 1.716797 h -1.765625 v 2 h 2.517578 c 0.674095,0 1.248047,-0.573953 1.248047,-1.248047 v -2.46875 z" />
|
||||||
|
<path
|
||||||
|
id="path1539"
|
||||||
|
style="font-weight:bold;font-size:15.624px;line-height:1;font-family:'MS Outlook';-inkscape-font-specification:'MS Outlook Bold';fill:#1de3ab;fill-opacity:1;stroke-width:0.29295;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
|
||||||
|
d="m 51.913678,-11.337595 c -0.708287,0 -1.359413,0.08855 -1.953125,0.265625 -0.593711,0.177072 -1.145866,0.406268 -1.65625,0.6875 l 0.828125,1.671875 c 0.447888,-0.229152 0.885445,-0.411467 1.3125,-0.546875 0.427056,-0.135408 0.859404,-0.203125 1.296875,-0.203125 0.437472,0 0.776058,0.088553 1.015625,0.265625 0.249984,0.177072 0.373047,0.427104 0.373047,0.75 0,0.333312 -0.10418,0.625016 -0.3125,0.875 -0.197904,0.239568 -0.529327,0.526063 -0.998047,0.859375 -0.531215,0.385392 -0.906264,0.76044 -1.125,1.125 -0.218735,0.354144 -0.328125,0.786492 -0.328125,1.296875 v 0.5625002 h 2.015625 V -4.181345 c 0,-0.20832 0.02605,-0.385426 0.07813,-0.53125 0.0625,-0.15624 0.171885,-0.307301 0.328125,-0.453125 0.166656,-0.15624 0.404318,-0.348973 0.716797,-0.578125 0.406224,-0.291648 0.744809,-0.572934 1.015625,-0.84375 0.270816,-0.270816 0.473967,-0.56252 0.609375,-0.875 0.135408,-0.31248 0.203125,-0.682319 0.203125,-1.109375 0,-0.802031 -0.302122,-1.463576 -0.90625,-1.984375 -0.593711,-0.520799 -1.430409,-0.78125 -2.513672,-0.78125 z m -0.453125,8.9218752 c -0.374975,0 -0.692725,0.09897 -0.953125,0.296875 -0.260399,0.187488 -0.390625,0.520864 -0.390625,1 0,0.45830298 0.130226,0.79167998 0.390625,0.99999998 0.2604,0.197904 0.57815,0.296875 0.953125,0.296875 0.36456,0 0.677101,-0.09897 0.9375,-0.296875 0.2604,-0.20832 0.390625,-0.541697 0.390625,-0.99999998 0,-0.479136 -0.130225,-0.812512 -0.390625,-1 -0.260399,-0.197904 -0.57294,-0.296875 -0.9375,-0.296875 z" />
|
||||||
|
<g
|
||||||
|
id="g96554"
|
||||||
|
transform="matrix(0.75262015,0,0,0.75262015,1.9507002,2.0121453)">
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ff82db;fill-opacity:1;stroke:none;stroke-width:7.27012;stroke-linecap:square;stroke-linejoin:round;paint-order:stroke fill markers"
|
||||||
|
id="path92548"
|
||||||
|
cx="5.1813359"
|
||||||
|
cy="8.1338291"
|
||||||
|
rx="4.3999071"
|
||||||
|
ry="5.1538987" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ff82db;fill-opacity:1;stroke:none;stroke-width:7.27012;stroke-linecap:square;stroke-linejoin:round;paint-order:stroke fill markers"
|
||||||
|
id="circle92550"
|
||||||
|
cx="10.589555"
|
||||||
|
cy="8.1338291"
|
||||||
|
rx="4.3999071"
|
||||||
|
ry="5.1538987" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.0 KiB |
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://whc152vj4786"
|
||||||
|
path="res://.godot/imported/BehaviorBranch.svg-2479d9ece5118d365ff6adf5a4a78745.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/rokojori_action_library/Icons/BehaviorBranch.svg"
|
||||||
|
dest_files=["res://.godot/imported/BehaviorBranch.svg-2479d9ece5118d365ff6adf5a4a78745.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
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/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="BehaviorSequence.svg"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#505050"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="20.727068"
|
||||||
|
inkscape:cx="-0.38596872"
|
||||||
|
inkscape:cy="6.0307613"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path1539"
|
||||||
|
style="font-weight:bold;font-size:15.624px;line-height:1;font-family:'MS Outlook';-inkscape-font-specification:'MS Outlook Bold';fill:#1de3ab;fill-opacity:1;stroke-width:0.29295;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
|
||||||
|
d="m 51.913678,-11.337595 c -0.708287,0 -1.359413,0.08855 -1.953125,0.265625 -0.593711,0.177072 -1.145866,0.406268 -1.65625,0.6875 l 0.828125,1.671875 c 0.447888,-0.229152 0.885445,-0.411467 1.3125,-0.546875 0.427056,-0.135408 0.859404,-0.203125 1.296875,-0.203125 0.437472,0 0.776058,0.088553 1.015625,0.265625 0.249984,0.177072 0.373047,0.427104 0.373047,0.75 0,0.333312 -0.10418,0.625016 -0.3125,0.875 -0.197904,0.239568 -0.529327,0.526063 -0.998047,0.859375 -0.531215,0.385392 -0.906264,0.76044 -1.125,1.125 -0.218735,0.354144 -0.328125,0.786492 -0.328125,1.296875 v 0.5625002 h 2.015625 V -4.181345 c 0,-0.20832 0.02605,-0.385426 0.07813,-0.53125 0.0625,-0.15624 0.171885,-0.307301 0.328125,-0.453125 0.166656,-0.15624 0.404318,-0.348973 0.716797,-0.578125 0.406224,-0.291648 0.744809,-0.572934 1.015625,-0.84375 0.270816,-0.270816 0.473967,-0.56252 0.609375,-0.875 0.135408,-0.31248 0.203125,-0.682319 0.203125,-1.109375 0,-0.802031 -0.302122,-1.463576 -0.90625,-1.984375 -0.593711,-0.520799 -1.430409,-0.78125 -2.513672,-0.78125 z m -0.453125,8.9218752 c -0.374975,0 -0.692725,0.09897 -0.953125,0.296875 -0.260399,0.187488 -0.390625,0.520864 -0.390625,1 0,0.45830298 0.130226,0.79167998 0.390625,0.99999998 0.2604,0.197904 0.57815,0.296875 0.953125,0.296875 0.36456,0 0.677101,-0.09897 0.9375,-0.296875 0.2604,-0.20832 0.390625,-0.541697 0.390625,-0.99999998 0,-0.479136 -0.130225,-0.812512 -0.390625,-1 -0.260399,-0.197904 -0.57294,-0.296875 -0.9375,-0.296875 z" />
|
||||||
|
<g
|
||||||
|
id="g102401"
|
||||||
|
transform="translate(0.15792213,0.18000243)">
|
||||||
|
<g
|
||||||
|
id="g96554"
|
||||||
|
transform="matrix(0.59356973,0,0,0.59356973,6.7183722,-1.2770906)">
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ff82db;fill-opacity:1;stroke:none;stroke-width:7.27012;stroke-linecap:square;stroke-linejoin:round;paint-order:stroke fill markers"
|
||||||
|
id="path92548"
|
||||||
|
cx="5.1813359"
|
||||||
|
cy="8.1338291"
|
||||||
|
rx="4.3999071"
|
||||||
|
ry="5.1538987" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ff82db;fill-opacity:1;stroke:none;stroke-width:7.27012;stroke-linecap:square;stroke-linejoin:round;paint-order:stroke fill markers"
|
||||||
|
id="circle92550"
|
||||||
|
cx="10.589555"
|
||||||
|
cy="8.1338291"
|
||||||
|
rx="4.3999071"
|
||||||
|
ry="5.1538987" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g102393"
|
||||||
|
transform="matrix(1.0857792,0,0,1.0857792,-5.1777633,-1.0374856)">
|
||||||
|
<path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#f7b200;stroke-width:1.93888;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
|
||||||
|
id="path120048"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
sodipodi:sides="5"
|
||||||
|
sodipodi:cx="-8.2018356"
|
||||||
|
sodipodi:cy="-2.1710742"
|
||||||
|
sodipodi:r1="7.9176526"
|
||||||
|
sodipodi:r2="4.7268386"
|
||||||
|
sodipodi:arg1="-1.5707963"
|
||||||
|
sodipodi:arg2="-0.9424778"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m -8.2018354,-10.088727 2.7783658,4.0935601 4.75176914,1.3774037 -3.03464454,3.90736248 0.1583886,4.94484222 -4.6538792,-1.6786771 -4.6538794,1.6786768 0.158389,-4.94484188 -3.034645,-3.90736292 4.751769,-1.3774033 z"
|
||||||
|
inkscape:transform-center-y="-0.91462472"
|
||||||
|
transform="matrix(0.61233589,0,0,0.61233589,15.058621,11.720562)" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#f7b200;fill-opacity:1;stroke:none;stroke-width:2.56963;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
|
||||||
|
id="path855"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
sodipodi:sides="5"
|
||||||
|
sodipodi:cx="-8.2018356"
|
||||||
|
sodipodi:cy="-2.1710742"
|
||||||
|
sodipodi:r1="7.9176526"
|
||||||
|
sodipodi:r2="4.5684857"
|
||||||
|
sodipodi:arg1="-1.5707963"
|
||||||
|
sodipodi:arg2="-0.94247777"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m -8.2018354,-10.088727 2.6852884,4.2216703 4.84484654,1.2492935 -3.18524704,3.85842889 0.3089911,4.99377581 -4.6538794,-1.8370299 -4.6538792,1.8370296 0.308991,-4.99377573 -3.185247,-3.85842907 4.844847,-1.2492932 z"
|
||||||
|
inkscape:transform-center-y="-0.30053938"
|
||||||
|
transform="matrix(0.2012094,0,0,0.2012094,11.471952,11.056661)" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.5 KiB |
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c0bg8q1qhta8d"
|
||||||
|
path="res://.godot/imported/BehaviorSequence.svg-e83c81b196d7953a5989711a8e3762a9.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/rokojori_action_library/Icons/BehaviorSequence.svg"
|
||||||
|
dest_files=["res://.godot/imported/BehaviorSequence.svg-e83c81b196d7953a5989711a8e3762a9.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
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/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="Brain.svg"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8">
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="never"
|
||||||
|
id="linearGradient114405">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#c7169f;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop114401" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop114403" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="never"
|
||||||
|
xlink:href="#linearGradient114405"
|
||||||
|
id="radialGradient114407"
|
||||||
|
cx="8"
|
||||||
|
cy="8"
|
||||||
|
fx="8"
|
||||||
|
fy="8"
|
||||||
|
r="8"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#505050"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="3.6640625"
|
||||||
|
inkscape:cx="-1.9104478"
|
||||||
|
inkscape:cy="2.45629"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path115146"
|
||||||
|
style="fill:#ff82db;fill-opacity:1;stroke:#000000;stroke-width:3.4861;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
d="M 5.8309076,3.8548992 C 5.538504,3.8549729 5.1211737,3.9611482 5.1194631,4.2639761 4.9425069,3.9804441 4.4185358,4.1843523 4.1624382,4.3457257 3.055579,5.043185 2.3031667,6.4126815 2.3031341,7.9880008 c 2.7e-5,1.3064477 0.7226271,3.2917552 1.5534037,3.0616162 -0.1864958,0.459405 1.1412645,1.071276 1.9743698,1.071486 0.7865919,-0.0031 1.5497544,0.176332 2.1682659,-0.392928 0.6189579,0.569668 1.3827609,0.390289 2.1699195,0.392928 1.088731,-2.75e-4 2.642337,-0.900404 2.472966,-1.776222 0.564685,0.163911 1.054786,-1.3498657 1.054807,-2.3568802 C 13.696842,6.8660251 13.315168,5.8484548 12.695608,5.1037242 12.488198,4.8544121 11.969439,4.4423021 11.708732,4.6418417 11.782246,4.2189562 10.839029,3.8550683 10.169093,3.8548992 9.3845365,3.8583179 8.6233284,3.8184841 8.005789,4.385337 7.3851242,3.815628 6.6194341,3.8552965 5.8309076,3.8548992 Z"
|
||||||
|
sodipodi:nodetypes="ccscccccccscccc" />
|
||||||
|
<path
|
||||||
|
id="rect401"
|
||||||
|
style="color:#000000;fill:#1de3ab;fill-opacity:1;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:markers stroke fill"
|
||||||
|
d="m 44.929225,-13.918847 c -0.674094,0 -1.248047,0.571999 -1.248047,1.246093 v 2.511719 h 2 v -1.757812 h 1.744141 v -2 z m 10.84375,0 v 2 H 57.5386 v 1.757812 h 2 v -2.511719 c 0,-0.674094 -0.573952,-1.246093 -1.248047,-1.246093 z M 43.681178,-1.8133788 v 2.46874998 c 0,0.67409402 0.573953,1.24804702 1.248047,1.24804702 h 2.496094 V -0.09658182 H 45.681178 V -1.8133788 Z m 13.857422,0 v 1.71679698 H 55.772975 V 1.9034182 h 2.517578 c 0.674095,0 1.248047,-0.573953 1.248047,-1.24804702 V -1.8133788 Z" />
|
||||||
|
<path
|
||||||
|
id="path1539"
|
||||||
|
style="font-weight:bold;font-size:15.624px;line-height:1;font-family:'MS Outlook';-inkscape-font-specification:'MS Outlook Bold';fill:#1de3ab;fill-opacity:1;stroke-width:0.29295;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
|
||||||
|
d="m 51.913678,-11.337595 c -0.708287,0 -1.359413,0.08855 -1.953125,0.265625 -0.593711,0.177072 -1.145866,0.406268 -1.65625,0.6875 l 0.828125,1.671875 c 0.447888,-0.229152 0.885445,-0.411467 1.3125,-0.546875 0.427056,-0.135408 0.859404,-0.203125 1.296875,-0.203125 0.437472,0 0.776058,0.088553 1.015625,0.265625 0.249984,0.177072 0.373047,0.427104 0.373047,0.75 0,0.333312 -0.10418,0.625016 -0.3125,0.875 -0.197904,0.239568 -0.529327,0.526063 -0.998047,0.859375 -0.531215,0.385392 -0.906264,0.76044 -1.125,1.125 -0.218735,0.354144 -0.328125,0.786492 -0.328125,1.296875 v 0.5625002 h 2.015625 V -4.181345 c 0,-0.20832 0.02605,-0.385426 0.07813,-0.53125 0.0625,-0.15624 0.171885,-0.307301 0.328125,-0.453125 0.166656,-0.15624 0.404318,-0.348973 0.716797,-0.578125 0.406224,-0.291648 0.744809,-0.572934 1.015625,-0.84375 0.270816,-0.270816 0.473967,-0.56252 0.609375,-0.875 0.135408,-0.31248 0.203125,-0.682319 0.203125,-1.109375 0,-0.802031 -0.302122,-1.463576 -0.90625,-1.984375 -0.593711,-0.520799 -1.430409,-0.78125 -2.513672,-0.78125 z m -0.453125,8.9218752 c -0.374975,0 -0.692725,0.09897 -0.953125,0.296875 -0.260399,0.187488 -0.390625,0.520864 -0.390625,1 0,0.45830298 0.130226,0.79167998 0.390625,0.99999998 0.2604,0.197904 0.57815,0.296875 0.953125,0.296875 0.36456,0 0.677101,-0.09897 0.9375,-0.296875 0.2604,-0.20832 0.390625,-0.541697 0.390625,-0.99999998 0,-0.479136 -0.130225,-0.812512 -0.390625,-1 -0.260399,-0.197904 -0.57294,-0.296875 -0.9375,-0.296875 z" />
|
||||||
|
<path
|
||||||
|
id="path92548"
|
||||||
|
style="fill:#ff82db;fill-opacity:1;stroke:#fbfbfb;stroke-width:1.74305;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
d="M 5.8309076,3.8548992 C 5.538504,3.8549729 5.0729276,4.0817634 5.4330627,5.1324058 4.9666299,4.1010593 4.4185358,4.1843523 4.1624382,4.3457257 3.055579,5.043185 2.3031667,6.4126815 2.3031341,7.9880008 c 2.7e-5,1.3064477 0.8432423,3.1952632 2.1564798,2.3379252 -0.8619411,1.158973 0.5381884,1.794967 1.3712937,1.795177 0.7865919,-0.0031 1.863354,0.176332 2.1923889,-1.116619 0.2329892,1.269236 1.3586379,1.11398 2.1457965,1.116619 1.088731,-2.75e-4 2.618214,-1.141634 1.894013,-2.2345599 0.974777,0.6704949 1.633739,-0.8915278 1.63376,-1.8985423 C 13.696842,6.8660251 13.315168,5.8484548 12.695608,5.1037242 12.488198,4.8544121 12.1383,4.2493177 11.346886,4.8830722 11.951107,3.8571105 10.736684,3.7015502 10.066748,3.7013811 8.7534064,3.7047998 8.2763238,4.3033695 8.1022812,5.1090284 7.6692497,3.8740742 7.1482187,3.6164905 5.8309076,3.8548992 Z"
|
||||||
|
sodipodi:nodetypes="ccscccccccscccc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.2 KiB |
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://ddywe4nqkppim"
|
||||||
|
path="res://.godot/imported/Brain.svg-22061c8f9edbd3ff520fcf62d8a1f665.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/rokojori_action_library/Icons/Brain.svg"
|
||||||
|
dest_files=["res://.godot/imported/Brain.svg-22061c8f9edbd3ff520fcf62d8a1f665.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
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/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="BrainControl.svg"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#505050"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="20.727068"
|
||||||
|
inkscape:cx="1.8333515"
|
||||||
|
inkscape:cy="4.7763631"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="rect401"
|
||||||
|
style="color:#000000;fill:#1de3ab;fill-opacity:1;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:markers stroke fill"
|
||||||
|
d="m 44.929225,-13.918847 c -0.674094,0 -1.248047,0.571999 -1.248047,1.246093 v 2.511719 h 2 v -1.757812 h 1.744141 v -2 z m 10.84375,0 v 2 H 57.5386 v 1.757812 h 2 v -2.511719 c 0,-0.674094 -0.573952,-1.246093 -1.248047,-1.246093 z M 43.681178,-1.8133788 v 2.46874998 c 0,0.67409402 0.573953,1.24804702 1.248047,1.24804702 h 2.496094 V -0.09658182 H 45.681178 V -1.8133788 Z m 13.857422,0 v 1.71679698 H 55.772975 V 1.9034182 h 2.517578 c 0.674095,0 1.248047,-0.573953 1.248047,-1.24804702 V -1.8133788 Z" />
|
||||||
|
<path
|
||||||
|
id="path1539"
|
||||||
|
style="font-weight:bold;font-size:15.624px;line-height:1;font-family:'MS Outlook';-inkscape-font-specification:'MS Outlook Bold';fill:#1de3ab;fill-opacity:1;stroke-width:0.29295;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
|
||||||
|
d="m 51.913678,-11.337595 c -0.708287,0 -1.359413,0.08855 -1.953125,0.265625 -0.593711,0.177072 -1.145866,0.406268 -1.65625,0.6875 l 0.828125,1.671875 c 0.447888,-0.229152 0.885445,-0.411467 1.3125,-0.546875 0.427056,-0.135408 0.859404,-0.203125 1.296875,-0.203125 0.437472,0 0.776058,0.088553 1.015625,0.265625 0.249984,0.177072 0.373047,0.427104 0.373047,0.75 0,0.333312 -0.10418,0.625016 -0.3125,0.875 -0.197904,0.239568 -0.529327,0.526063 -0.998047,0.859375 -0.531215,0.385392 -0.906264,0.76044 -1.125,1.125 -0.218735,0.354144 -0.328125,0.786492 -0.328125,1.296875 v 0.5625002 h 2.015625 V -4.181345 c 0,-0.20832 0.02605,-0.385426 0.07813,-0.53125 0.0625,-0.15624 0.171885,-0.307301 0.328125,-0.453125 0.166656,-0.15624 0.404318,-0.348973 0.716797,-0.578125 0.406224,-0.291648 0.744809,-0.572934 1.015625,-0.84375 0.270816,-0.270816 0.473967,-0.56252 0.609375,-0.875 0.135408,-0.31248 0.203125,-0.682319 0.203125,-1.109375 0,-0.802031 -0.302122,-1.463576 -0.90625,-1.984375 -0.593711,-0.520799 -1.430409,-0.78125 -2.513672,-0.78125 z m -0.453125,8.9218752 c -0.374975,0 -0.692725,0.09897 -0.953125,0.296875 -0.260399,0.187488 -0.390625,0.520864 -0.390625,1 0,0.45830298 0.130226,0.79167998 0.390625,0.99999998 0.2604,0.197904 0.57815,0.296875 0.953125,0.296875 0.36456,0 0.677101,-0.09897 0.9375,-0.296875 0.2604,-0.20832 0.390625,-0.541697 0.390625,-0.99999998 0,-0.479136 -0.130225,-0.812512 -0.390625,-1 -0.260399,-0.197904 -0.57294,-0.296875 -0.9375,-0.296875 z" />
|
||||||
|
<path
|
||||||
|
id="path92548"
|
||||||
|
style="fill:#ff82db;fill-opacity:1;stroke:none;stroke-width:1.55798;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
d="M 6.0887647,4.3576783 A 3.1098158,3.6427305 0 0 0 2.9786072,8.0006902 3.1098158,3.6427305 0 0 0 6.0887647,11.642322 3.1098158,3.6427305 0 0 0 8.0006904,10.862367 3.1098158,3.6427305 0 0 0 9.9112359,11.642322 3.1098158,3.6427305 0 0 0 13.021393,8.0006902 3.1098158,3.6427305 0 0 0 9.9112359,4.3576783 3.1098158,3.6427305 0 0 0 8.0062121,5.1321117 3.1098158,3.6427305 0 0 0 6.0887647,4.3576783 Z" />
|
||||||
|
<path
|
||||||
|
id="path103023"
|
||||||
|
style="color:#000000;fill:#ffb801;fill-opacity:1;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:markers stroke fill"
|
||||||
|
d="m 1.319336,0.088867 c -0.674094,0 -1.248047,0.571999 -1.248047,1.246093 v 2.511719 h 2 V 2.088867 H 3.81543 v -2 z m 10.84375,0 v 2 h 1.765625 v 1.757812 h 2 V 1.33496 c 0,-0.674094 -0.573952,-1.246093 -1.248047,-1.246093 z M 0.071289,12.194336 v 2.468749 c 0,0.674095 0.573953,1.248048 1.248047,1.248048 H 3.81543 V 13.911132 H 2.071289 v -1.716796 z m 13.857422,0 v 1.716796 h -1.765625 v 2.000001 h 2.517578 c 0.674095,0 1.248047,-0.573953 1.248047,-1.248048 v -2.468749 z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.7 KiB |
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c37yfx3ryvoxu"
|
||||||
|
path="res://.godot/imported/BrainControl.svg-0da1cfbf5e1e82c6dfa220b6df44195a.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/rokojori_action_library/Icons/BrainControl.svg"
|
||||||
|
dest_files=["res://.godot/imported/BrainControl.svg-0da1cfbf5e1e82c6dfa220b6df44195a.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
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/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="Receptor.svg"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#505050"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="29.3125"
|
||||||
|
inkscape:cx="9.108742"
|
||||||
|
inkscape:cy="11.633262"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path1539"
|
||||||
|
style="font-weight:bold;font-size:15.624px;line-height:1;font-family:'MS Outlook';-inkscape-font-specification:'MS Outlook Bold';fill:#1de3ab;fill-opacity:1;stroke-width:0.29295;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
|
||||||
|
d="m 51.913678,-11.337595 c -0.708287,0 -1.359413,0.08855 -1.953125,0.265625 -0.593711,0.177072 -1.145866,0.406268 -1.65625,0.6875 l 0.828125,1.671875 c 0.447888,-0.229152 0.885445,-0.411467 1.3125,-0.546875 0.427056,-0.135408 0.859404,-0.203125 1.296875,-0.203125 0.437472,0 0.776058,0.088553 1.015625,0.265625 0.249984,0.177072 0.373047,0.427104 0.373047,0.75 0,0.333312 -0.10418,0.625016 -0.3125,0.875 -0.197904,0.239568 -0.529327,0.526063 -0.998047,0.859375 -0.531215,0.385392 -0.906264,0.76044 -1.125,1.125 -0.218735,0.354144 -0.328125,0.786492 -0.328125,1.296875 v 0.5625002 h 2.015625 V -4.181345 c 0,-0.20832 0.02605,-0.385426 0.07813,-0.53125 0.0625,-0.15624 0.171885,-0.307301 0.328125,-0.453125 0.166656,-0.15624 0.404318,-0.348973 0.716797,-0.578125 0.406224,-0.291648 0.744809,-0.572934 1.015625,-0.84375 0.270816,-0.270816 0.473967,-0.56252 0.609375,-0.875 0.135408,-0.31248 0.203125,-0.682319 0.203125,-1.109375 0,-0.802031 -0.302122,-1.463576 -0.90625,-1.984375 -0.593711,-0.520799 -1.430409,-0.78125 -2.513672,-0.78125 z m -0.453125,8.9218752 c -0.374975,0 -0.692725,0.09897 -0.953125,0.296875 -0.260399,0.187488 -0.390625,0.520864 -0.390625,1 0,0.45830298 0.130226,0.79167998 0.390625,0.99999998 0.2604,0.197904 0.57815,0.296875 0.953125,0.296875 0.36456,0 0.677101,-0.09897 0.9375,-0.296875 0.2604,-0.20832 0.390625,-0.541697 0.390625,-0.99999998 0,-0.479136 -0.130225,-0.812512 -0.390625,-1 -0.260399,-0.197904 -0.57294,-0.296875 -0.9375,-0.296875 z" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ff82db;fill-opacity:1;stroke:none;stroke-width:9.94378;stroke-linecap:square;stroke-linejoin:round;paint-order:stroke fill markers"
|
||||||
|
id="path92548"
|
||||||
|
cx="7.8807526"
|
||||||
|
cy="8.2403135"
|
||||||
|
rx="6.6163163"
|
||||||
|
ry="6.4118476" />
|
||||||
|
<g
|
||||||
|
id="g100943"
|
||||||
|
transform="matrix(0.84582226,0,0,0.84582226,1.0549805,0.17352877)">
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:7.54947;stroke-linecap:square;stroke-linejoin:round;paint-order:stroke fill markers"
|
||||||
|
id="ellipse100204"
|
||||||
|
cx="7.9489827"
|
||||||
|
cy="8.2061987"
|
||||||
|
rx="5.0232086"
|
||||||
|
ry="4.8679729" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:4.70623;stroke-linecap:square;stroke-linejoin:round;paint-order:stroke fill markers"
|
||||||
|
id="ellipse100206"
|
||||||
|
cx="7.7077522"
|
||||||
|
cy="7.3860149"
|
||||||
|
rx="3.131393"
|
||||||
|
ry="3.0346215" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.6 KiB |
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://jusswlaofkgc"
|
||||||
|
path="res://.godot/imported/Receptor.svg-3c1cccf5229247e268d12db0af1e1abb.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/rokojori_action_library/Icons/Receptor.svg"
|
||||||
|
dest_files=["res://.godot/imported/Receptor.svg-3c1cccf5229247e268d12db0af1e1abb.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
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/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="ReceptorBranch.svg"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#505050"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="20.727068"
|
||||||
|
inkscape:cx="12.785214"
|
||||||
|
inkscape:cy="15.583488"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path1539"
|
||||||
|
style="font-weight:bold;font-size:15.624px;line-height:1;font-family:'MS Outlook';-inkscape-font-specification:'MS Outlook Bold';fill:#1de3ab;fill-opacity:1;stroke-width:0.29295;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
|
||||||
|
d="m 51.913678,-11.337595 c -0.708287,0 -1.359413,0.08855 -1.953125,0.265625 -0.593711,0.177072 -1.145866,0.406268 -1.65625,0.6875 l 0.828125,1.671875 c 0.447888,-0.229152 0.885445,-0.411467 1.3125,-0.546875 0.427056,-0.135408 0.859404,-0.203125 1.296875,-0.203125 0.437472,0 0.776058,0.088553 1.015625,0.265625 0.249984,0.177072 0.373047,0.427104 0.373047,0.75 0,0.333312 -0.10418,0.625016 -0.3125,0.875 -0.197904,0.239568 -0.529327,0.526063 -0.998047,0.859375 -0.531215,0.385392 -0.906264,0.76044 -1.125,1.125 -0.218735,0.354144 -0.328125,0.786492 -0.328125,1.296875 v 0.5625002 h 2.015625 V -4.181345 c 0,-0.20832 0.02605,-0.385426 0.07813,-0.53125 0.0625,-0.15624 0.171885,-0.307301 0.328125,-0.453125 0.166656,-0.15624 0.404318,-0.348973 0.716797,-0.578125 0.406224,-0.291648 0.744809,-0.572934 1.015625,-0.84375 0.270816,-0.270816 0.473967,-0.56252 0.609375,-0.875 0.135408,-0.31248 0.203125,-0.682319 0.203125,-1.109375 0,-0.802031 -0.302122,-1.463576 -0.90625,-1.984375 -0.593711,-0.520799 -1.430409,-0.78125 -2.513672,-0.78125 z m -0.453125,8.9218752 c -0.374975,0 -0.692725,0.09897 -0.953125,0.296875 -0.260399,0.187488 -0.390625,0.520864 -0.390625,1 0,0.45830298 0.130226,0.79167998 0.390625,0.99999998 0.2604,0.197904 0.57815,0.296875 0.953125,0.296875 0.36456,0 0.677101,-0.09897 0.9375,-0.296875 0.2604,-0.20832 0.390625,-0.541697 0.390625,-0.99999998 0,-0.479136 -0.130225,-0.812512 -0.390625,-1 -0.260399,-0.197904 -0.57294,-0.296875 -0.9375,-0.296875 z" />
|
||||||
|
<g
|
||||||
|
id="g108125"
|
||||||
|
transform="matrix(0.79163872,0,0,0.79163872,1.7612911,1.4766487)">
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ff82db;fill-opacity:1;stroke:none;stroke-width:9.94378;stroke-linecap:square;stroke-linejoin:round;paint-order:stroke fill markers"
|
||||||
|
id="path92548"
|
||||||
|
cx="7.8807526"
|
||||||
|
cy="8.2403135"
|
||||||
|
rx="6.6163163"
|
||||||
|
ry="6.4118476" />
|
||||||
|
<g
|
||||||
|
id="g100943"
|
||||||
|
transform="matrix(0.84582226,0,0,0.84582226,1.0549805,0.17352877)">
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:7.54947;stroke-linecap:square;stroke-linejoin:round;paint-order:stroke fill markers"
|
||||||
|
id="ellipse100204"
|
||||||
|
cx="7.9489827"
|
||||||
|
cy="8.2061987"
|
||||||
|
rx="5.0232086"
|
||||||
|
ry="4.8679729" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:4.70623;stroke-linecap:square;stroke-linejoin:round;paint-order:stroke fill markers"
|
||||||
|
id="ellipse100206"
|
||||||
|
cx="7.7077522"
|
||||||
|
cy="7.3860149"
|
||||||
|
rx="3.131393"
|
||||||
|
ry="3.0346215" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
id="path103023"
|
||||||
|
style="color:#000000;fill:#1de3ab;fill-opacity:1;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:markers stroke fill"
|
||||||
|
d="m 1.319336,0.088867 c -0.674094,0 -1.248047,0.571999 -1.248047,1.246093 v 2.511719 h 2 V 2.088867 H 3.81543 v -2 z m 10.84375,0 v 2 h 1.765625 v 1.757812 h 2 V 1.33496 c 0,-0.674094 -0.573952,-1.246093 -1.248047,-1.246093 z M 0.071289,12.194336 v 2.468749 c 0,0.674095 0.573953,1.248048 1.248047,1.248048 H 3.81543 V 13.911132 H 2.071289 v -1.716796 z m 13.857422,0 v 1.716796 h -1.765625 v 2.000001 h 2.517578 c 0.674095,0 1.248047,-0.573953 1.248047,-1.248048 v -2.468749 z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.5 KiB |
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c6wwqj7hdrmpa"
|
||||||
|
path="res://.godot/imported/ReceptorBranch.svg-bb59728d991a1a6154c3682d9e33cce7.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/rokojori_action_library/Icons/ReceptorBranch.svg"
|
||||||
|
dest_files=["res://.godot/imported/ReceptorBranch.svg-bb59728d991a1a6154c3682d9e33cce7.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
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/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
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
|
||||||
|
|
@ -18,7 +18,9 @@ namespace Rokojori
|
||||||
|
|
||||||
protected override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( lookFrom == null || lookTarget == null )
|
if ( lookFrom == null || lookTarget == null ||
|
||||||
|
! IsInstanceValid( lookFrom ) || ! IsInstanceValid( lookTarget )
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
using Rokojori.Extensions;
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[GlobalClass, Tool ]
|
||||||
|
public partial class SelectNode3D : Action
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public Selector selector;
|
||||||
|
|
||||||
|
bool _enteredTree = false;
|
||||||
|
|
||||||
|
public override void _EnterTree()
|
||||||
|
{
|
||||||
|
base._EnterTree();
|
||||||
|
_enteredTree = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node _target;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Node target
|
||||||
|
{
|
||||||
|
get => _target;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if ( _target == value )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_target = value;
|
||||||
|
|
||||||
|
// Deserialization sets exported properties before _EnterTree fires, so this
|
||||||
|
// only triggers for genuine interactive edits in the editor, never for a scene
|
||||||
|
// being loaded (regardless of property order) or for runtime reassignment.
|
||||||
|
if ( _enteredTree && Engine.IsEditorHint() )
|
||||||
|
{
|
||||||
|
targetMember = "";
|
||||||
|
|
||||||
|
#if TOOLS
|
||||||
|
NotifyPropertyListChanged();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public string targetMember;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
if ( target == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node3D node3D = null;
|
||||||
|
|
||||||
|
if ( selector == null )
|
||||||
|
{
|
||||||
|
ReflectionHelper.SetValue<Node3D>( target, targetMember, node3D );
|
||||||
|
this.LogInfo( "Set Null:", HierarchyName.Of( target ), targetMember );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedNode = Unique<SelectManager>.Get().Select( selector );
|
||||||
|
|
||||||
|
|
||||||
|
if ( selectedNode is Selectable )
|
||||||
|
{
|
||||||
|
var go = selectedNode.GetParent<GameObject3D>();
|
||||||
|
|
||||||
|
if ( go != null )
|
||||||
|
{
|
||||||
|
node3D = go.body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReflectionHelper.SetValue<Node3D>( target, targetMember, node3D );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TOOLS
|
||||||
|
|
||||||
|
public override void _ValidateProperty( Godot.Collections.Dictionary property )
|
||||||
|
{
|
||||||
|
if ( property[ "name" ].AsString() != nameof( targetMember ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var members = GetTargetNode3DMemberNames();
|
||||||
|
|
||||||
|
property[ "hint" ] = (long) PropertyHint.Enum;
|
||||||
|
property[ "hint_string" ] = members.Count == 0
|
||||||
|
? "(Invalid Target)"
|
||||||
|
: "None," + string.Join( ",", members );
|
||||||
|
}
|
||||||
|
|
||||||
|
List<string> GetTargetNode3DMemberNames()
|
||||||
|
{
|
||||||
|
var names = new List<string>();
|
||||||
|
|
||||||
|
if ( target == null )
|
||||||
|
{
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
var infos = ReflectionHelper.GetDataMemberInfos( target, BindingFlags.Public | BindingFlags.Instance );
|
||||||
|
|
||||||
|
foreach ( var info in infos )
|
||||||
|
{
|
||||||
|
if ( ! info.IsDefined( typeof( ExportAttribute ) ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var memberType = info.GetMemberType();
|
||||||
|
|
||||||
|
if ( memberType == null || ! memberType.IsAssignableFrom( typeof( Node3D ) ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
names.Add( info.Name );
|
||||||
|
}
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://76pepn06ofq5
|
||||||
|
|
@ -30,10 +30,13 @@ namespace Rokojori
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var value = ReflectionHelper.GetValue<Node3D>( source, sourceMember );
|
var value = sourceMember == null || sourceMember == "" ? (Node3D) source :
|
||||||
|
ReflectionHelper.GetValue<Node3D>( source, sourceMember );
|
||||||
|
|
||||||
ReflectionHelper.SetValue<Node3D>( target, targetMember, value );
|
ReflectionHelper.SetValue<Node3D>( target, targetMember, value );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -23,7 +23,7 @@ public partial class NumberValue : Node
|
||||||
return GetType().Name + " { value = " + _value._DDD() + ", frozen = " + _frozen + " }";
|
return GetType().Name + " { value = " + _value._DDD() + ", frozen = " + _frozen + " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
void _OnValueChange( double v )
|
protected virtual void _OnValueChange( double v )
|
||||||
{
|
{
|
||||||
if ( _frozen )
|
if ( _frozen )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public Material material;
|
public Material material;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public GeometryInstance3D instanceTarget;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public FloatPropertyName propertyName;
|
public FloatPropertyName propertyName;
|
||||||
|
|
||||||
|
|
@ -58,12 +61,47 @@ namespace Rokojori
|
||||||
public bool interruptCurrent = true;
|
public bool interruptCurrent = true;
|
||||||
|
|
||||||
protected override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
if ( material != null && ! IsInstanceValid( material ) )
|
||||||
|
{
|
||||||
|
material = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( instanceTarget != null && ! IsInstanceValid( instanceTarget ) )
|
||||||
|
{
|
||||||
|
instanceTarget = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( propertyName == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this.LogInfo( "TRIGGERED" );
|
||||||
|
|
||||||
|
if ( instanceTarget != null )
|
||||||
|
{
|
||||||
|
// this.LogInfo( "INSTANCE" );
|
||||||
|
TweenInstanceUniform();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( material != null )
|
||||||
|
{
|
||||||
|
// this.LogInfo( "MATERIAL" );
|
||||||
|
TweenMaterial();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TweenMaterial()
|
||||||
{
|
{
|
||||||
if ( ! interruptCurrent && _actionID != -1 )
|
if ( ! interruptCurrent && _actionID != -1 )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( _actionID != -1 )
|
if ( _actionID != -1 )
|
||||||
{
|
{
|
||||||
|
|
@ -72,30 +110,30 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( stopAnimation )
|
if ( stopAnimation )
|
||||||
{
|
{
|
||||||
|
|
||||||
AnimationManager.StartAnimation( this, material, propertyName );
|
AnimationManager.StartAnimation( this, material, propertyName );
|
||||||
|
|
||||||
if ( setStopValue )
|
if ( setStopValue )
|
||||||
{
|
{
|
||||||
propertyName.Set( material, endValue );
|
propertyName.Set( material, endValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationManager.EndAnimation( this, material, propertyName );
|
AnimationManager.EndAnimation( this, material, propertyName );
|
||||||
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_actionID = DispatchStart();
|
_actionID = DispatchStart();
|
||||||
|
|
||||||
var startValue = propertyName.Get( material );
|
var startValue = propertyName.Get( material );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( forceStartValue && Engine.IsEditorHint() )
|
if ( forceStartValue && Engine.IsEditorHint() )
|
||||||
{
|
{
|
||||||
startValue = forcedStartValue;
|
startValue = forcedStartValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,15 +142,15 @@ namespace Rokojori
|
||||||
startValue = animationStartValue;
|
startValue = animationStartValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AnimationManager.StartAnimation( this, material, propertyName );
|
AnimationManager.StartAnimation( this, material, propertyName );
|
||||||
|
|
||||||
// this.LogInfo( "Get Float Tween", startValue );
|
// this.LogInfo( "Get Float Tween", startValue );
|
||||||
|
|
||||||
_timeID = TimelineManager.ScheduleSpanWith( duration,
|
_timeID = TimelineManager.ScheduleSpanWith( duration,
|
||||||
( span, type )=>
|
( span, type )=>
|
||||||
{
|
{
|
||||||
|
|
||||||
// this.LogInfo( "Update Float Tween", startValue );
|
// this.LogInfo( "Update Float Tween", startValue );
|
||||||
if ( span.id != _timeID )
|
if ( span.id != _timeID )
|
||||||
|
|
@ -138,12 +176,12 @@ namespace Rokojori
|
||||||
|
|
||||||
propertyName.Set( material, value );
|
propertyName.Set( material, value );
|
||||||
// ReflectionHelper.SetValue( material, propertyName , value );
|
// ReflectionHelper.SetValue( material, propertyName , value );
|
||||||
|
|
||||||
if ( type == TimelineSpanUpdateType.End )
|
|
||||||
{
|
|
||||||
// this.LogInfo( "End Float Tween", endValue );
|
|
||||||
|
|
||||||
// target._Set( targetMember, endValue );
|
if ( type == TimelineSpanUpdateType.End )
|
||||||
|
{
|
||||||
|
// this.LogInfo( "End Float Tween", endValue );
|
||||||
|
|
||||||
|
// target._Set( targetMember, endValue );
|
||||||
|
|
||||||
propertyName.Set( material, endValue );
|
propertyName.Set( material, endValue );
|
||||||
AnimationManager.EndAnimation( this, material, propertyName );
|
AnimationManager.EndAnimation( this, material, propertyName );
|
||||||
|
|
@ -156,5 +194,105 @@ namespace Rokojori
|
||||||
).id;
|
).id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TweenInstanceUniform()
|
||||||
|
{
|
||||||
|
if ( ! interruptCurrent && _actionID != -1 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _actionID != -1 )
|
||||||
|
{
|
||||||
|
CancelAction( _actionID );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( stopAnimation )
|
||||||
|
{
|
||||||
|
|
||||||
|
AnimationManager.StartAnimation( this, instanceTarget, propertyName.propertyName );
|
||||||
|
|
||||||
|
if ( setStopValue )
|
||||||
|
{
|
||||||
|
propertyName.SetInstance( instanceTarget, endValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationManager.EndAnimation( this, instanceTarget, propertyName.propertyName );
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_actionID = DispatchStart();
|
||||||
|
|
||||||
|
var startValue = propertyName.GetInstance( instanceTarget );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( forceStartValue && Engine.IsEditorHint() )
|
||||||
|
{
|
||||||
|
startValue = forcedStartValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( animateStartValue )
|
||||||
|
{
|
||||||
|
startValue = animationStartValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AnimationManager.StartAnimation( this, instanceTarget, propertyName.propertyName );
|
||||||
|
|
||||||
|
// this.LogInfo( "Get Float Tween", startValue );
|
||||||
|
|
||||||
|
_timeID = TimelineManager.ScheduleSpanWith( duration,
|
||||||
|
( span, type )=>
|
||||||
|
{
|
||||||
|
|
||||||
|
// this.LogInfo( "Update Float Tween", startValue );
|
||||||
|
if ( span.id != _timeID )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! AnimationManager.IsAnimating( this, instanceTarget, propertyName.propertyName ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var phase = span.phase;
|
||||||
|
|
||||||
|
if ( curve != null )
|
||||||
|
{
|
||||||
|
phase = curve.Sample( phase );
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = Mathf.Lerp( startValue, endValue, phase );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// this.LogInfo( "Updating Float Tween", "phase:", phase, "value:", value, instanceTarget );
|
||||||
|
|
||||||
|
propertyName.SetInstance( instanceTarget, value );
|
||||||
|
// ReflectionHelper.SetValue( material, propertyName , value );
|
||||||
|
|
||||||
|
if ( type == TimelineSpanUpdateType.End )
|
||||||
|
{
|
||||||
|
// this.LogInfo( "End Float Tween", endValue );
|
||||||
|
|
||||||
|
// target._Set( targetMember, endValue );
|
||||||
|
|
||||||
|
propertyName.SetInstance( instanceTarget, endValue );
|
||||||
|
AnimationManager.EndAnimation( this, instanceTarget, propertyName.propertyName );
|
||||||
|
DispatchEnd( _actionID );
|
||||||
|
_actionID = -1;
|
||||||
|
_timeID = -1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
this
|
||||||
|
).id;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -89,6 +89,11 @@ namespace Rokojori
|
||||||
|
|
||||||
var fromMaterial = MaterialSurfaceContainer.From( target, this.index ).GetMaterialInSlot<Material>( slot );
|
var fromMaterial = MaterialSurfaceContainer.From( target, this.index ).GetMaterialInSlot<Material>( slot );
|
||||||
|
|
||||||
|
// Registers ownership of the *slot assignment itself* (as opposed to the color/float
|
||||||
|
// properties on the material), so a second TweenMaterial targeting the same slot takes
|
||||||
|
// over cleanly instead of both tweens fighting to set the end material.
|
||||||
|
AnimationManager.StartAnimation( this, target, GetSlotKey() );
|
||||||
|
|
||||||
SetAssignedMaterial( fromMaterial );
|
SetAssignedMaterial( fromMaterial );
|
||||||
|
|
||||||
var tl = TimelineManager.Ensure( timeLine );
|
var tl = TimelineManager.Ensure( timeLine );
|
||||||
|
|
@ -180,25 +185,32 @@ namespace Rokojori
|
||||||
AnimationManager.EndAnimation( this, _assignedMaterial, f.propertyName );
|
AnimationManager.EndAnimation( this, _assignedMaterial, f.propertyName );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( MaterialAssignmentMode.Temporary_Duplicate_For_Each_Tween == assignmentMode )
|
// Only write the end material (and release ownership) if no later TweenMaterial
|
||||||
|
// has since taken over this slot - otherwise this would stomp on it after the fact.
|
||||||
|
if ( AnimationManager.IsAnimating( this, target, GetSlotKey() ) )
|
||||||
{
|
{
|
||||||
_assignedMaterial = null;
|
if ( MaterialAssignmentMode.Temporary_Duplicate_For_Each_Tween == assignmentMode )
|
||||||
var msc = MaterialSurfaceContainer.From( target, index );
|
|
||||||
msc.SetMaterialInSlot( slot, toMaterial );
|
|
||||||
|
|
||||||
var prop = new ColorPropertyName();
|
|
||||||
prop.propertyName = "albedo_color";
|
|
||||||
|
|
||||||
var info = new Color();
|
|
||||||
|
|
||||||
if ( toMaterial is BaseMaterial3D bm )
|
|
||||||
{
|
{
|
||||||
info = bm.AlbedoColor;
|
_assignedMaterial = null;
|
||||||
|
var msc = MaterialSurfaceContainer.From( target, index );
|
||||||
|
msc.SetMaterialInSlot( slot, toMaterial );
|
||||||
|
|
||||||
|
var prop = new ColorPropertyName();
|
||||||
|
prop.propertyName = "albedo_color";
|
||||||
|
|
||||||
|
var info = new Color();
|
||||||
|
|
||||||
|
if ( toMaterial is BaseMaterial3D bm )
|
||||||
|
{
|
||||||
|
info = bm.AlbedoColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this.LogInfo( "Setting:", slot, toMaterial, info, prop.Get( toMaterial ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// this.LogInfo( "Setting:", slot, toMaterial, info, prop.Get( toMaterial ) );
|
AnimationManager.EndAnimation( this, target, GetSlotKey() );
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchEnd( sequenceID );
|
DispatchEnd( sequenceID );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -208,6 +220,11 @@ namespace Rokojori
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string GetSlotKey()
|
||||||
|
{
|
||||||
|
return $"MaterialSlot:{index}:{slot}";
|
||||||
|
}
|
||||||
|
|
||||||
void SetAssignedMaterial( Material material )
|
void SetAssignedMaterial( Material material )
|
||||||
{
|
{
|
||||||
if ( MaterialAssignmentMode.Temporary_Duplicate_For_Each_Tween == assignmentMode )
|
if ( MaterialAssignmentMode.Temporary_Duplicate_For_Each_Tween == assignmentMode )
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,11 @@ namespace Rokojori
|
||||||
|
|
||||||
for ( int i = 0; i < targets.Length; i++ )
|
for ( int i = 0; i < targets.Length; i++ )
|
||||||
{
|
{
|
||||||
|
if ( ! IsInstanceValid( targets[ i ] ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var o = _targetValues[ i ];
|
var o = _targetValues[ i ];
|
||||||
|
|
||||||
o.Set( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation );
|
o.Set( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation );
|
||||||
|
|
@ -146,6 +151,11 @@ namespace Rokojori
|
||||||
|
|
||||||
for ( int i = 0; i < targets.Length; i++ )
|
for ( int i = 0; i < targets.Length; i++ )
|
||||||
{
|
{
|
||||||
|
if ( ! IsInstanceValid( targets[ i ] ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var combined = offsetData.Clone();
|
var combined = offsetData.Clone();
|
||||||
|
|
||||||
var o = _targetValues[ i ];
|
var o = _targetValues[ i ];
|
||||||
|
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
using Godot;
|
|
||||||
|
|
||||||
using Rokojori.Extensions;
|
|
||||||
namespace Rokojori;
|
|
||||||
|
|
||||||
[Tool]
|
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
|
||||||
public partial class Brain:Action
|
|
||||||
{
|
|
||||||
[Export]
|
|
||||||
public Receptor[] receptors;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public Node behaviorRoot;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public BehaviorSequence activeSequence;
|
|
||||||
|
|
||||||
bool _paused = false;
|
|
||||||
|
|
||||||
public bool paused => _paused;
|
|
||||||
|
|
||||||
public void SetPaused( bool value )
|
|
||||||
{
|
|
||||||
_paused = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void _OnTrigger()
|
|
||||||
{
|
|
||||||
if ( _paused )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( activeSequence != null && activeSequence.isExclusive && activeSequence.isRunning )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var resolved = Resolve();
|
|
||||||
|
|
||||||
if ( resolved == null )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( resolved == activeSequence )
|
|
||||||
{
|
|
||||||
if ( activeSequence.reinitialize )
|
|
||||||
{
|
|
||||||
activeSequence.CancelAllRunning();
|
|
||||||
activeSequence.Trigger();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var previous = activeSequence;
|
|
||||||
activeSequence = resolved;
|
|
||||||
|
|
||||||
if ( previous != null )
|
|
||||||
{
|
|
||||||
previous.CancelAllRunning();
|
|
||||||
}
|
|
||||||
|
|
||||||
activeSequence.Trigger();
|
|
||||||
}
|
|
||||||
|
|
||||||
BehaviorSequence Resolve()
|
|
||||||
{
|
|
||||||
if ( behaviorRoot == null )
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResolveIn( behaviorRoot );
|
|
||||||
}
|
|
||||||
|
|
||||||
BehaviorSequence ResolveIn( Node parent )
|
|
||||||
{
|
|
||||||
var walker = NodesWalker.Get();
|
|
||||||
var numChildren = walker.NumChildren( parent );
|
|
||||||
|
|
||||||
for ( int i = 0; i < numChildren; i++ )
|
|
||||||
{
|
|
||||||
var child = walker.ChildAt( parent, i );
|
|
||||||
|
|
||||||
if ( child is BehaviorSequence sequence )
|
|
||||||
{
|
|
||||||
return sequence;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( child is BehaviorBranch branch )
|
|
||||||
{
|
|
||||||
if ( branch.IsBranchActive( this ) )
|
|
||||||
{
|
|
||||||
var found = ResolveIn( branch );
|
|
||||||
|
|
||||||
if ( found != null )
|
|
||||||
{
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,7 @@ using Rokojori.Extensions;
|
||||||
namespace Rokojori;
|
namespace Rokojori;
|
||||||
|
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/BehaviorBranch.svg")]
|
||||||
public abstract partial class BehaviorBranch:Node
|
public abstract partial class BehaviorBranch:Node
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
|
|
@ -4,7 +4,7 @@ using Rokojori.Extensions;
|
||||||
namespace Rokojori;
|
namespace Rokojori;
|
||||||
|
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/BehaviorSequence.svg")]
|
||||||
public partial class BehaviorSequence:Sequence
|
public partial class BehaviorSequence:Sequence
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
|
|
@ -29,7 +29,9 @@ public partial class BehaviorSequence:Sequence
|
||||||
|
|
||||||
void OnDone( SequenceActionFinishedEvent ev )
|
void OnDone( SequenceActionFinishedEvent ev )
|
||||||
{
|
{
|
||||||
if ( _brain == null || _brain.activeSequence != this )
|
this.LogInfo( "On Done BS" );
|
||||||
|
|
||||||
|
if ( _brain == null || _brain.activeNode != this )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,321 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Rokojori.Extensions;
|
||||||
|
using System.Linq;
|
||||||
|
namespace Rokojori;
|
||||||
|
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Brain.svg")]
|
||||||
|
public partial class Brain:Action
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public Receptor[] receptors;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Node[] receporContainers;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Node behaviorRoot;
|
||||||
|
|
||||||
|
|
||||||
|
[ExportGroup( "Debugging")]
|
||||||
|
[Export]
|
||||||
|
public Node activeNode;
|
||||||
|
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool printActiveNodeSelection = false;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool printBranchResult = false;
|
||||||
|
|
||||||
|
// Non-BehaviorSequence nodes (plain Actions) don't carry this state themselves,
|
||||||
|
// so these stand in for it. Kept as protected statics in case that needs tuning later.
|
||||||
|
protected static bool defaultIsExclusive = false;
|
||||||
|
protected static bool defaultIsRunning = false;
|
||||||
|
protected static bool defaultReinitialize = true;
|
||||||
|
|
||||||
|
bool _paused = false;
|
||||||
|
|
||||||
|
public bool paused => _paused;
|
||||||
|
|
||||||
|
public void SetPaused( bool value )
|
||||||
|
{
|
||||||
|
_paused = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsExclusive( Node node )
|
||||||
|
{
|
||||||
|
return node is BehaviorSequence sequence ? sequence.isExclusive : defaultIsExclusive;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsRunning( Node node )
|
||||||
|
{
|
||||||
|
return node is BehaviorSequence sequence ? sequence.isRunning : defaultIsRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ShouldReinitialize( Node node )
|
||||||
|
{
|
||||||
|
return node is BehaviorSequence sequence ? sequence.reinitialize : defaultReinitialize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CancelIfRunning( Node node )
|
||||||
|
{
|
||||||
|
if ( node is BehaviorSequence sequence )
|
||||||
|
{
|
||||||
|
sequence.CancelAllRunning();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartBrain()
|
||||||
|
{
|
||||||
|
SetPaused( false );
|
||||||
|
|
||||||
|
receptors?.ForEachNonNull( r => r.Start() );
|
||||||
|
|
||||||
|
receporContainers?.ForEachNonNull( c => c.ForEach<Receptor>( r => r.Start() ) );
|
||||||
|
|
||||||
|
Trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The node most recently armed with a one-shot onSequenceDone listener, so a late
|
||||||
|
// event from a node the Brain has since moved away from doesn't retrigger it.
|
||||||
|
SequenceAction _listenedSequenceAction;
|
||||||
|
|
||||||
|
// The node a next-frame restart is currently scheduled for, so a plain Action
|
||||||
|
// doesn't accumulate more than one pending restart chain at a time.
|
||||||
|
Node _pendingRestartNode;
|
||||||
|
|
||||||
|
void ActivateNode( Node node )
|
||||||
|
{
|
||||||
|
if ( node is Action action )
|
||||||
|
{
|
||||||
|
action.Trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( node is BehaviorSequence )
|
||||||
|
{
|
||||||
|
// Manages its own re-trigger/loop via onSequenceDone already (see BehaviorSequence._Ready).
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( node is SequenceAction sequenceAction )
|
||||||
|
{
|
||||||
|
_listenedSequenceAction = sequenceAction;
|
||||||
|
|
||||||
|
if ( ! sequenceAction.onSequenceDone.HasAction( OnListenedSequenceActionDone ) )
|
||||||
|
{
|
||||||
|
sequenceAction.onSequenceDone.Once( OnListenedSequenceActionDone );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( node is Action )
|
||||||
|
{
|
||||||
|
ScheduleRestartNextFrame( node );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnListenedSequenceActionDone( SequenceActionFinishedEvent ev )
|
||||||
|
{
|
||||||
|
if ( activeNode != _listenedSequenceAction )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
async void ScheduleRestartNextFrame( Node node )
|
||||||
|
{
|
||||||
|
if ( _pendingRestartNode == node )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pendingRestartNode = node;
|
||||||
|
|
||||||
|
await this.RequestNextFrame();
|
||||||
|
|
||||||
|
if ( _pendingRestartNode == node )
|
||||||
|
{
|
||||||
|
_pendingRestartNode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( activeNode != node )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dedup flag for the no-match-resolved restart below, mirroring _pendingRestartNode.
|
||||||
|
bool _pendingNullResolveRestart = false;
|
||||||
|
|
||||||
|
async void ScheduleRestartNextFrameOnNullResolve()
|
||||||
|
{
|
||||||
|
if ( _pendingNullResolveRestart )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pendingNullResolveRestart = true;
|
||||||
|
|
||||||
|
await this.RequestNextFrame();
|
||||||
|
|
||||||
|
_pendingNullResolveRestart = false;
|
||||||
|
|
||||||
|
Trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<string> _branchInfo = new List<string>();
|
||||||
|
|
||||||
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
if ( _paused )
|
||||||
|
{
|
||||||
|
if ( printActiveNodeSelection )
|
||||||
|
{
|
||||||
|
this.LogInfo( "Skipped. Paused" );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( activeNode != null && IsExclusive( activeNode ) && IsRunning( activeNode ) )
|
||||||
|
{
|
||||||
|
if ( printActiveNodeSelection )
|
||||||
|
{
|
||||||
|
this.LogInfo( "Skipped. Running already exclusively" );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( printBranchResult && _branchInfo.Count > 0 )
|
||||||
|
{
|
||||||
|
_branchInfo.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
var resolved = Resolve();
|
||||||
|
|
||||||
|
if ( printBranchResult && _branchInfo.Count > 0 )
|
||||||
|
{
|
||||||
|
this.LogInfo( _branchInfo.Join( "\n" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( printActiveNodeSelection )
|
||||||
|
{
|
||||||
|
this.LogInfo( "Active Node:", resolved == null ? "Null" : ( HierarchyName.Of( resolved ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( resolved == null )
|
||||||
|
{
|
||||||
|
ScheduleRestartNextFrameOnNullResolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( resolved == activeNode )
|
||||||
|
{
|
||||||
|
if ( ShouldReinitialize( activeNode ) )
|
||||||
|
{
|
||||||
|
CancelIfRunning( activeNode );
|
||||||
|
ActivateNode( activeNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var previous = activeNode;
|
||||||
|
activeNode = resolved;
|
||||||
|
|
||||||
|
if ( previous != null )
|
||||||
|
{
|
||||||
|
CancelIfRunning( previous );
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivateNode( activeNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
Node Resolve()
|
||||||
|
{
|
||||||
|
if ( behaviorRoot == null )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResolveIn( behaviorRoot );
|
||||||
|
}
|
||||||
|
|
||||||
|
Node ResolveIn( Node parent )
|
||||||
|
{
|
||||||
|
var walker = NodesWalker.Get();
|
||||||
|
var numChildren = walker.NumChildren( parent );
|
||||||
|
|
||||||
|
for ( int i = 0; i < numChildren; i++ )
|
||||||
|
{
|
||||||
|
var child = walker.ChildAt( parent, i );
|
||||||
|
|
||||||
|
if ( child is BehaviorBranch branch && branch.IsBranchActive( this ) )
|
||||||
|
{
|
||||||
|
if ( printBranchResult )
|
||||||
|
{
|
||||||
|
_branchInfo.Add( HierarchyName.Of( child ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
var found = ResolveIn( branch );
|
||||||
|
|
||||||
|
if ( found != null )
|
||||||
|
{
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( child is SceneCondition condition && condition.Evaluate() )
|
||||||
|
{
|
||||||
|
if ( printBranchResult )
|
||||||
|
{
|
||||||
|
_branchInfo.Add( HierarchyName.Of( child ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
var found = ResolveIn( condition );
|
||||||
|
|
||||||
|
if ( found != null )
|
||||||
|
{
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( child is Receptor receptor && receptor.active )
|
||||||
|
{
|
||||||
|
if ( printBranchResult )
|
||||||
|
{
|
||||||
|
_branchInfo.Add( HierarchyName.Of( child ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
var found = ResolveIn( receptor );
|
||||||
|
|
||||||
|
if ( found != null )
|
||||||
|
{
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( child is BehaviorSequence sequence )
|
||||||
|
{
|
||||||
|
return sequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( child is Action action )
|
||||||
|
{
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ using Rokojori.Extensions;
|
||||||
namespace Rokojori;
|
namespace Rokojori;
|
||||||
|
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/BrainControl.svg")]
|
||||||
public partial class BrainControl:Action
|
public partial class BrainControl:Action
|
||||||
{
|
{
|
||||||
public enum Mode
|
public enum Mode
|
||||||
|
|
@ -31,7 +31,7 @@ public partial class BrainControl:Action
|
||||||
switch ( mode )
|
switch ( mode )
|
||||||
{
|
{
|
||||||
case Mode.Start:
|
case Mode.Start:
|
||||||
StartBrain();
|
brain.StartBrain();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Mode.Pause:
|
case Mode.Pause:
|
||||||
|
|
@ -48,21 +48,5 @@ public partial class BrainControl:Action
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartBrain()
|
|
||||||
{
|
|
||||||
brain.SetPaused( false );
|
|
||||||
|
|
||||||
if ( brain.receptors != null )
|
|
||||||
{
|
|
||||||
foreach ( var receptor in brain.receptors )
|
|
||||||
{
|
|
||||||
if ( receptor != null )
|
|
||||||
{
|
|
||||||
receptor.Start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
brain.Trigger();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ using Rokojori.Extensions;
|
||||||
namespace Rokojori;
|
namespace Rokojori;
|
||||||
|
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
[GlobalClass]
|
||||||
public partial class ConditionBranch:BehaviorBranch
|
public partial class ConditionBranch:BehaviorBranch
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
|
|
@ -4,7 +4,7 @@ using Rokojori.Extensions;
|
||||||
namespace Rokojori;
|
namespace Rokojori;
|
||||||
|
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/ReceptorBranch.svg")]
|
||||||
public partial class ReceptorBranch:BehaviorBranch
|
public partial class ReceptorBranch:BehaviorBranch
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
using Godot;
|
|
||||||
|
|
||||||
using Rokojori.Extensions;
|
|
||||||
namespace Rokojori;
|
|
||||||
|
|
||||||
[Tool]
|
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
|
||||||
public partial class FollowBehavior:BehaviorSequence
|
|
||||||
{
|
|
||||||
[Export]
|
|
||||||
public BehaviorMovement movement;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public Node3D target;
|
|
||||||
|
|
||||||
protected override void _OnTrigger()
|
|
||||||
{
|
|
||||||
if ( movement != null )
|
|
||||||
{
|
|
||||||
movement.Follow( target );
|
|
||||||
}
|
|
||||||
|
|
||||||
base._OnTrigger();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,7 @@ using Rokojori.Extensions;
|
||||||
namespace Rokojori;
|
namespace Rokojori;
|
||||||
|
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
[GlobalClass]
|
||||||
public abstract partial class BehaviorMovement:Node
|
public abstract partial class BehaviorMovement:Node
|
||||||
{
|
{
|
||||||
public abstract void GoToPosition( Vector3 worldPosition );
|
public abstract void GoToPosition( Vector3 worldPosition );
|
||||||
|
|
@ -4,7 +4,7 @@ using Rokojori.Extensions;
|
||||||
namespace Rokojori;
|
namespace Rokojori;
|
||||||
|
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
[GlobalClass]
|
||||||
public partial class CharacterBodyBehaviorMovement:BehaviorMovement
|
public partial class CharacterBodyBehaviorMovement:BehaviorMovement
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using Rokojori.Extensions;
|
||||||
|
namespace Rokojori;
|
||||||
|
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class FollowBehavior:Action
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public BehaviorMovement movement;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Node3D target;
|
||||||
|
|
||||||
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
if ( movement == null || target == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// var id = DispatchStart();
|
||||||
|
|
||||||
|
movement.Follow( target );
|
||||||
|
|
||||||
|
// await this.RequestNextFrame();
|
||||||
|
|
||||||
|
// this.LogInfo( "Done" );
|
||||||
|
|
||||||
|
// DispatchEnd( id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,25 +4,29 @@ using Rokojori.Extensions;
|
||||||
namespace Rokojori;
|
namespace Rokojori;
|
||||||
|
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Receptor.svg")]
|
||||||
public partial class Receptor:Action
|
public partial class Receptor:Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public SceneCondition sceneCondition;
|
public SceneCondition sceneCondition;
|
||||||
|
|
||||||
[Export( PropertyHint.Range, "0.1,100")]
|
[Export( PropertyHint.Range, "0.1,100")]
|
||||||
public float receiptionTriggerCoverage = 75f;
|
public float receptionTriggerCoverage = 75f;
|
||||||
|
|
||||||
[Export( PropertyHint.Range, "10,2000")]
|
[Export( PropertyHint.Range, "10,2000")]
|
||||||
public float receiptionWindowDurationMS = 500f;
|
public float receptionWindowDurationMS = 500f;
|
||||||
|
|
||||||
[Export( PropertyHint.Range, "10,1000")]
|
[Export( PropertyHint.Range, "10,1000")]
|
||||||
public float tickRateMS = 100f;
|
public float tickRateMS = 100f;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Timeline timeline;
|
public Timeline timeline;
|
||||||
|
|
||||||
|
[ExportGroup("Debugging")]
|
||||||
|
[Export]
|
||||||
|
public float fillState = 0;
|
||||||
|
|
||||||
int resultSize => Mathf.CeilToInt( receiptionWindowDurationMS / tickRateMS );
|
int resultSize => Mathf.CeilToInt( receptionWindowDurationMS / tickRateMS );
|
||||||
|
|
||||||
RingBuffer<bool> _resultsBuffer;
|
RingBuffer<bool> _resultsBuffer;
|
||||||
|
|
||||||
|
|
@ -70,8 +74,11 @@ public partial class Receptor:Action
|
||||||
|
|
||||||
void Sample()
|
void Sample()
|
||||||
{
|
{
|
||||||
|
// this.LogInfo( "Receptor Update" );
|
||||||
|
|
||||||
if ( sceneCondition == null )
|
if ( sceneCondition == null )
|
||||||
{
|
{
|
||||||
|
// this.LogInfo( "No condition" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,12 +91,15 @@ public partial class Receptor:Action
|
||||||
|
|
||||||
if ( _resultsBuffer.count != resultSize )
|
if ( _resultsBuffer.count != resultSize )
|
||||||
{
|
{
|
||||||
|
// this.LogInfo( "No activation" );
|
||||||
_activated = false;
|
_activated = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var numActive = _resultsBuffer.CountItems( b => b );
|
var numActive = _resultsBuffer.CountItems( b => b );
|
||||||
_activated = numActive / (float) resultSize >= receiptionTriggerCoverage / 100f;
|
fillState = numActive / (float) resultSize;
|
||||||
|
|
||||||
|
_activated = fillState >= receptionTriggerCoverage / 100f;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
using Godot;
|
|
||||||
|
|
||||||
using Rokojori.Extensions;
|
|
||||||
namespace Rokojori
|
|
||||||
{
|
|
||||||
public enum ThirdPersonCameraLockMode
|
|
||||||
{
|
|
||||||
Lock,
|
|
||||||
Release
|
|
||||||
}
|
|
||||||
|
|
||||||
[Tool]
|
|
||||||
[GlobalClass]
|
|
||||||
public partial class SetThirdPersonCameraLockTarget : Action
|
|
||||||
{
|
|
||||||
[Export]
|
|
||||||
public ThirdPersonCamera camera;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public Pointer source;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public ThirdPersonCameraLockMode mode = ThirdPersonCameraLockMode.Lock;
|
|
||||||
|
|
||||||
protected override void _OnTrigger()
|
|
||||||
{
|
|
||||||
if ( camera == null )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( mode == ThirdPersonCameraLockMode.Release )
|
|
||||||
{
|
|
||||||
camera.lockTarget = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
camera.lockTarget = source != null && source.pointable != null ? source.pointable.pointerPosition : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://pesdcfjnpi30
|
|
||||||
|
|
@ -17,7 +17,7 @@ namespace Rokojori
|
||||||
public Node3D target;
|
public Node3D target;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Node3D lockTarget;
|
public CameraLocker cameraLocker;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float yaw;
|
public float yaw;
|
||||||
|
|
@ -68,12 +68,6 @@ namespace Rokojori
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( lockTarget != null && ! IsInstanceValid( lockTarget ) )
|
|
||||||
{
|
|
||||||
lockTarget = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// var tl = TimeLineManager.Ensure( timeLine );
|
// var tl = TimeLineManager.Ensure( timeLine );
|
||||||
// var delta = tl.delta;
|
// var delta = tl.delta;
|
||||||
var delta = (float) gameDelta;
|
var delta = (float) gameDelta;
|
||||||
|
|
@ -81,19 +75,14 @@ namespace Rokojori
|
||||||
|
|
||||||
var targetPosition = Smoothing.Apply( settings.targetFollowSmoothing, target.GlobalPosition, delta );
|
var targetPosition = Smoothing.Apply( settings.targetFollowSmoothing, target.GlobalPosition, delta );
|
||||||
|
|
||||||
var hasLockTarget = lockTarget != null;
|
var lockTargetNode = cameraLocker != null && cameraLocker.isLocked && IsInstanceValid( cameraLocker.lockTarget ) ? cameraLocker.lockTarget.pointerPosition : null;
|
||||||
|
var hasLockTarget = lockTargetNode != null;
|
||||||
var lockTargetPosition = _lastLockTargetPosition;
|
var lockTargetPosition = _lastLockTargetPosition;
|
||||||
|
|
||||||
if ( hasLockTarget )
|
if ( hasLockTarget )
|
||||||
{
|
{
|
||||||
lockTargetPosition = Smoothing.Apply( settings.lockTargetFollowSmoothing, lockTarget.GlobalPosition, delta );
|
lockTargetPosition = Smoothing.Apply( settings.lockTargetFollowSmoothing, lockTargetNode.GlobalPosition, delta );
|
||||||
_lastLockTargetPosition = lockTargetPosition;
|
_lastLockTargetPosition = lockTargetPosition;
|
||||||
|
|
||||||
if ( settings.lockReleaseDistance > 0f && ( lockTargetPosition - targetPosition ).Length() > settings.lockReleaseDistance )
|
|
||||||
{
|
|
||||||
lockTarget = null;
|
|
||||||
hasLockTarget = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// lockBlend fades 0->1 on engage and 1->0 on release instead of snapping, so the focus
|
// lockBlend fades 0->1 on engage and 1->0 on release instead of snapping, so the focus
|
||||||
|
|
|
||||||
|
|
@ -81,9 +81,6 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public Smoothing lockBlendSmoothing = new FrameSmoothing();
|
public Smoothing lockBlendSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
[Export]
|
|
||||||
public float lockReleaseDistance = 0f;
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float lockMinPitch = -10;
|
public float lockMinPitch = -10;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,205 @@
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
using Rokojori.Extensions;
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Condition.svg")]
|
||||||
|
public partial class HasCondition: SceneCondition
|
||||||
|
{
|
||||||
|
bool _enteredTree = false;
|
||||||
|
|
||||||
|
public override void _EnterTree()
|
||||||
|
{
|
||||||
|
base._EnterTree();
|
||||||
|
_enteredTree = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTargetAssignmentChanged()
|
||||||
|
{
|
||||||
|
// Deserialization sets exported properties before _EnterTree fires, so this
|
||||||
|
// only triggers for genuine interactive edits in the editor, never for a scene
|
||||||
|
// being loaded (regardless of property order) or for runtime reassignment.
|
||||||
|
if ( ! _enteredTree || ! Engine.IsEditorHint() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
targetName = "";
|
||||||
|
|
||||||
|
#if TOOLS
|
||||||
|
NotifyPropertyListChanged();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
GodotObject _target;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public GodotObject target
|
||||||
|
{
|
||||||
|
get => _target;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if ( _target == value )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_target = value;
|
||||||
|
OnTargetAssignmentChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Node _targetNode;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Node targetNode
|
||||||
|
{
|
||||||
|
get => _targetNode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if ( _targetNode == value )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_targetNode = value;
|
||||||
|
OnTargetAssignmentChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public string targetName;
|
||||||
|
|
||||||
|
GodotObject GetEffectiveTarget()
|
||||||
|
{
|
||||||
|
return target != null ? target : (GodotObject) targetNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Evaluate()
|
||||||
|
{
|
||||||
|
var effectiveTarget = GetEffectiveTarget();
|
||||||
|
|
||||||
|
if ( effectiveTarget == null || string.IsNullOrEmpty( targetName ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = ReflectionHelper.GetDataMemberValue<object>( effectiveTarget, targetName );
|
||||||
|
|
||||||
|
return EvaluateValue( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool EvaluateValue( object value )
|
||||||
|
{
|
||||||
|
switch ( value )
|
||||||
|
{
|
||||||
|
case null:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case GodotObject go:
|
||||||
|
return GodotObject.IsInstanceValid( go );
|
||||||
|
|
||||||
|
case bool b:
|
||||||
|
return b;
|
||||||
|
|
||||||
|
case string s:
|
||||||
|
return ! string.IsNullOrEmpty( s );
|
||||||
|
|
||||||
|
case int i:
|
||||||
|
return i > 0;
|
||||||
|
|
||||||
|
case long l:
|
||||||
|
return l > 0;
|
||||||
|
|
||||||
|
case float f:
|
||||||
|
return f > 0;
|
||||||
|
|
||||||
|
case double d:
|
||||||
|
return d > 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TOOLS
|
||||||
|
|
||||||
|
static bool IsSupportedMemberType( System.Type type )
|
||||||
|
{
|
||||||
|
if ( type == null )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( type == typeof( bool ) || type == typeof( string ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( type == typeof( int ) || type == typeof( long ) || type == typeof( float ) || type == typeof( double ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( typeof( Node ).IsAssignableFrom( type ) || typeof( Resource ).IsAssignableFrom( type ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<string> GetTargetMemberNames()
|
||||||
|
{
|
||||||
|
var names = new List<string>();
|
||||||
|
var effectiveTarget = GetEffectiveTarget();
|
||||||
|
|
||||||
|
if ( effectiveTarget == null )
|
||||||
|
{
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
var infos = ReflectionHelper.GetDataMemberInfos( effectiveTarget, BindingFlags.Public | BindingFlags.Instance );
|
||||||
|
|
||||||
|
foreach ( var info in infos )
|
||||||
|
{
|
||||||
|
if ( ! info.IsDefined( typeof( ExportAttribute ) ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! IsSupportedMemberType( info.GetMemberType() ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
names.Add( info.Name );
|
||||||
|
}
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _ValidateProperty( Godot.Collections.Dictionary property )
|
||||||
|
{
|
||||||
|
if ( property[ "name" ].AsString() != nameof( targetName ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var members = GetTargetMemberNames();
|
||||||
|
|
||||||
|
property[ "hint" ] = (long) PropertyHint.Enum;
|
||||||
|
property[ "hint_string" ] = members.Count == 0
|
||||||
|
? "(Invalid Target)"
|
||||||
|
: "None," + string.Join( ",", members );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://de0vq8n1ylgjn
|
||||||
|
|
@ -14,6 +14,7 @@ namespace Rokojori
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/GameObject3D.svg") ]
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/GameObject3D.svg") ]
|
||||||
public partial class GameObject3D:Node3D, INetworkNode
|
public partial class GameObject3D:Node3D, INetworkNode
|
||||||
{
|
{
|
||||||
|
|
||||||
[ExportToolButton("Center On Children")]
|
[ExportToolButton("Center On Children")]
|
||||||
public Callable centerOnChildrenButton => Callable.From( ()=> { this.CenterOnChildren(); } );
|
public Callable centerOnChildrenButton => Callable.From( ()=> { this.CenterOnChildren(); } );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
using Rokojori;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Rokojori.Extensions;
|
||||||
|
namespace Rokojori;
|
||||||
|
|
||||||
|
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class GameObject3DFlag:SelectorFlag
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://exkchmx40u0h
|
||||||
|
|
@ -16,6 +16,40 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ForEach<[MustBeVariant] T>( this T[] array, System.Action<T> action )
|
||||||
|
{
|
||||||
|
for (int i = 0; i < array.Length; i++)
|
||||||
|
{
|
||||||
|
action( array[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ForEachNonNull<[MustBeVariant] T>( this Godot.Collections.Array<T> array, System.Action<T> action ) where T:class
|
||||||
|
{
|
||||||
|
for (int i = 0; i < array.Count; i++)
|
||||||
|
{
|
||||||
|
if ( array[ i ] == null )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
action( array[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ForEachNonNull<T>( this T[] array, System.Action<T> action ) where T:class
|
||||||
|
{
|
||||||
|
for (int i = 0; i < array.Length; i++)
|
||||||
|
{
|
||||||
|
if ( array[ i ] == null )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
action( array[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static T Find<[MustBeVariant] T>( this Godot.Collections.Array<T> array, System.Func<T,bool> evaluater, int offset = 0 )
|
public static T Find<[MustBeVariant] T>( this Godot.Collections.Array<T> array, System.Func<T,bool> evaluater, int offset = 0 )
|
||||||
{
|
{
|
||||||
for ( int i = offset; i < array.Count; i++ )
|
for ( int i = offset; i < array.Count; i++ )
|
||||||
|
|
|
||||||
|
|
@ -435,6 +435,50 @@ namespace Rokojori
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Node Select( this Node root, Selector selector )
|
||||||
|
{
|
||||||
|
var walker = nodesWalker;
|
||||||
|
|
||||||
|
var end = walker.IterationEndOf( root );
|
||||||
|
|
||||||
|
var it = root;
|
||||||
|
|
||||||
|
while ( it != end )
|
||||||
|
{
|
||||||
|
if ( selector.Selects( it ) )
|
||||||
|
{
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
it = walker.NextNode( it );
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Node> SelectAll( this Node root, Selector selector )
|
||||||
|
{
|
||||||
|
var walker = nodesWalker;
|
||||||
|
|
||||||
|
var end = walker.IterationEndOf( root );
|
||||||
|
|
||||||
|
var it = root;
|
||||||
|
|
||||||
|
var list = new List<Node>();
|
||||||
|
|
||||||
|
while ( it != end )
|
||||||
|
{
|
||||||
|
if ( selector.Selects( it ) )
|
||||||
|
{
|
||||||
|
list.Add( it );
|
||||||
|
}
|
||||||
|
|
||||||
|
it = walker.NextNode( it );
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static void ForEach<T>( this Node root, Action<T> callback ) where T:class
|
public static void ForEach<T>( this Node root, Action<T> callback ) where T:class
|
||||||
{
|
{
|
||||||
var walker = nodesWalker;
|
var walker = nodesWalker;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,293 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using Rokojori.Extensions;
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
// Single owner of lock state. LockOnPointer only tracks candidates and the current selection;
|
||||||
|
// ThirdPersonCamera (or anything else) only reads isLocked/lockTarget from here.
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class CameraLocker : Action
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public LockOnPointer source;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor engageSensor;
|
||||||
|
|
||||||
|
[ExportGroup( "Release" )]
|
||||||
|
[Export]
|
||||||
|
public float releaseDistance = 0f;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Node3D releaseDistanceOrigin;
|
||||||
|
|
||||||
|
[ExportGroup( "Cycling" )]
|
||||||
|
[Export]
|
||||||
|
public LockOnCyclingSetup cyclingSetup;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public LockOnCyclingSetup lockedCyclingSetup;
|
||||||
|
|
||||||
|
[ExportGroup( "Visualizer" )]
|
||||||
|
[Export]
|
||||||
|
public Node3D visualizerMarker;
|
||||||
|
|
||||||
|
[ExportGroup( "Candidate Events" )]
|
||||||
|
[Export]
|
||||||
|
public Action onCandidateSpotted;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action onCandidateUnlocked;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action onCandidateVanished;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action onCandidateChanged;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool triggerCanidatesWhenLocked = false;
|
||||||
|
|
||||||
|
|
||||||
|
[ExportGroup( "Lock Events" )]
|
||||||
|
[Export]
|
||||||
|
public Action onLock;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action onReleasedLock;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action onChangeLocked;
|
||||||
|
|
||||||
|
[ExportGroup( "Read Only" )]
|
||||||
|
[Export]
|
||||||
|
public Pointable lockTarget;
|
||||||
|
|
||||||
|
public bool isLocked => lockTarget != null;
|
||||||
|
|
||||||
|
Pointable _previousCandidate;
|
||||||
|
bool _wasEngaged = false;
|
||||||
|
|
||||||
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
if ( source == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
source.Trigger();
|
||||||
|
|
||||||
|
UpdateCandidateEvents();
|
||||||
|
|
||||||
|
var previousTarget = lockTarget;
|
||||||
|
var wasLocked = previousTarget != null;
|
||||||
|
|
||||||
|
// Order matters: cycling may move an existing lock, engagement may start/end one,
|
||||||
|
// auto-release may end one - each only touches lockTarget for its own reason, nothing
|
||||||
|
// here resyncs it every frame just because source.pointable drifted on its own.
|
||||||
|
UpdateCycling();
|
||||||
|
UpdateEngagement();
|
||||||
|
UpdateAutoRelease();
|
||||||
|
|
||||||
|
FireLockEvents( wasLocked, previousTarget );
|
||||||
|
|
||||||
|
UpdateVisualizer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Release()
|
||||||
|
{
|
||||||
|
if ( lockTarget == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var previousTarget = lockTarget;
|
||||||
|
lockTarget = null;
|
||||||
|
|
||||||
|
FireLockEvents( true, previousTarget );
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateCandidateEvents()
|
||||||
|
{
|
||||||
|
if ( lockTarget != null && ! triggerCanidatesWhenLocked )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var candidate = source.pointable;
|
||||||
|
|
||||||
|
if ( candidate == _previousCandidate )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_previousCandidate = candidate;
|
||||||
|
|
||||||
|
onCandidateChanged?.Trigger();
|
||||||
|
|
||||||
|
Action.TriggerSafe( candidate == null ? onCandidateVanished : onCandidateSpotted );
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateCycling()
|
||||||
|
{
|
||||||
|
var setup = isLocked ? ( lockedCyclingSetup ?? cyclingSetup ) : ( cyclingSetup ?? lockedCyclingSetup );
|
||||||
|
|
||||||
|
if ( setup == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cycled = false;
|
||||||
|
|
||||||
|
if ( setup.cycleMode == LockOnCycleMode.ClosestCycle )
|
||||||
|
{
|
||||||
|
if ( setup.cycleSensor != null && setup.cycleSensor.isDown )
|
||||||
|
{
|
||||||
|
source.CycleNext();
|
||||||
|
cycled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( setup.cycleMode == LockOnCycleMode.Directional && setup.directionalCycleInputs != null )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < setup.directionalCycleInputs.Length; i++ )
|
||||||
|
{
|
||||||
|
var input = setup.directionalCycleInputs[ i ];
|
||||||
|
|
||||||
|
if ( input == null || input.sensor == null || ! input.sensor.isDown )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
source.CycleInScreenSpaceDirection( input.direction );
|
||||||
|
cycled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cycling is the only thing that is allowed to move an already-established lock onto a
|
||||||
|
// different candidate - a deliberate, one-time assignment here, not a per-frame resync.
|
||||||
|
if ( cycled && isLocked )
|
||||||
|
{
|
||||||
|
lockTarget = source.pointable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateEngagement()
|
||||||
|
{
|
||||||
|
var engaged = engageSensor != null && engageSensor.isActive;
|
||||||
|
var risingEdge = engaged && ! _wasEngaged;
|
||||||
|
_wasEngaged = engaged;
|
||||||
|
|
||||||
|
if ( ! engaged )
|
||||||
|
{
|
||||||
|
lockTarget = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only a fresh press/toggle-on acquires a target. Once locked, the lock is held
|
||||||
|
// regardless of what source.pointable does on its own (e.g. losing/regaining the raycast
|
||||||
|
// hit) - it only changes via cycling, auto-release, or an explicit Release() call.
|
||||||
|
if ( lockTarget == null && risingEdge )
|
||||||
|
{
|
||||||
|
lockTarget = source.pointable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAutoRelease()
|
||||||
|
{
|
||||||
|
if ( lockTarget == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( IsGone( lockTarget ) )
|
||||||
|
{
|
||||||
|
lockTarget = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( IsTooFar( lockTarget ) )
|
||||||
|
{
|
||||||
|
lockTarget = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Covers both an actually freed node and one that was removed from the tree without being
|
||||||
|
// freed (e.g. pooled/recycled enemies) - either way it is no longer something the lock
|
||||||
|
// should keep pointing at.
|
||||||
|
static bool IsGone( Pointable target )
|
||||||
|
{
|
||||||
|
return target == null || ! IsInstanceValid( target ) || ! target.IsInsideTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsTooFar( Pointable target )
|
||||||
|
{
|
||||||
|
if ( releaseDistance <= 0f )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var origin = releaseDistanceOrigin ?? source.caster;
|
||||||
|
|
||||||
|
if ( origin == null )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return origin.GlobalPosition.DistanceTo( target.GlobalPosition ) > releaseDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReleaseEngageSensorIfToggled()
|
||||||
|
{
|
||||||
|
if ( engageSensor is ActivationModeSensor ams && ams.isActive )
|
||||||
|
{
|
||||||
|
ams.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireLockEvents( bool wasLocked, Pointable previousTarget )
|
||||||
|
{
|
||||||
|
var isLockedNow = lockTarget != null;
|
||||||
|
|
||||||
|
if ( isLockedNow && ! wasLocked )
|
||||||
|
{
|
||||||
|
Action.TriggerSafe( onLock );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! isLockedNow && wasLocked )
|
||||||
|
{
|
||||||
|
ReleaseEngageSensorIfToggled();
|
||||||
|
Action.TriggerSafe( onReleasedLock );
|
||||||
|
|
||||||
|
if ( source.IsCandidate( previousTarget ) )
|
||||||
|
{
|
||||||
|
Action.TriggerSafe( onCandidateUnlocked );
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isLockedNow && wasLocked && lockTarget != previousTarget )
|
||||||
|
{
|
||||||
|
Action.TriggerSafe( onChangeLocked );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateVisualizer()
|
||||||
|
{
|
||||||
|
if ( visualizerMarker == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var current = lockTarget ?? source.pointable;
|
||||||
|
|
||||||
|
if ( ! IsGone( current ) )
|
||||||
|
{
|
||||||
|
visualizerMarker.CopyGlobalPoseFrom( current.pointerPosition );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dskrrdkp3hcu6
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using Rokojori.Extensions;
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class LockOnCyclingSetup : Resource
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public LockOnCycleMode cycleMode = LockOnCycleMode.None;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor cycleSensor;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public DirectionalCycleInput[] directionalCycleInputs = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bt07jjknw0aty
|
||||||
|
|
@ -11,52 +11,28 @@ namespace Rokojori
|
||||||
Directional
|
Directional
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only tracks the current candidate list and the single selected pointable (sticky - stays on
|
||||||
|
// the selection until it is cycled away from or stops being a valid candidate). Owns no concept
|
||||||
|
// of "locked" - that is CameraLocker's job, reading/driving this pointer's pointable.
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class LockOnPointer : Pointer
|
public partial class LockOnPointer : Pointer
|
||||||
{
|
{
|
||||||
[Export]
|
public int test = 0;
|
||||||
public Sensor engageSensor;
|
|
||||||
|
List<Pointable> _candidates = new List<Pointable>();
|
||||||
|
|
||||||
[Export]
|
public int numCandidates => _candidates.Count;
|
||||||
public bool releaseWhenTargetInvalid = true;
|
|
||||||
|
|
||||||
[Export]
|
public Pointable GetCandidate( int index )
|
||||||
public Action onLockEngaged;
|
{
|
||||||
|
return _candidates[ index ];
|
||||||
|
}
|
||||||
|
|
||||||
[Export]
|
public bool IsCandidate( Pointable p )
|
||||||
public Action onLockReleased;
|
{
|
||||||
|
return p != null && _candidates.Contains( p );
|
||||||
[ExportGroup( "Cycling" )]
|
}
|
||||||
[Export]
|
|
||||||
public LockOnCycleMode cycleMode = LockOnCycleMode.None;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public Sensor cycleSensor;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public DirectionalCycleInput[] directionalCycleInputs = [];
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public Node3D closestVisualizer;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public Action onClosestFound;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public Action onClosestLost;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public Action onClosestChanged;
|
|
||||||
|
|
||||||
[ExportGroup("Read Only")]
|
|
||||||
[Export]
|
|
||||||
public Pointable closestCandidate;
|
|
||||||
|
|
||||||
|
|
||||||
bool _engaged = false;
|
|
||||||
|
|
||||||
public bool isEngaged => _engaged;
|
|
||||||
|
|
||||||
protected override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
|
|
@ -68,185 +44,68 @@ namespace Rokojori
|
||||||
if ( pointable != null && ! IsInstanceValid( pointable ) )
|
if ( pointable != null && ! IsInstanceValid( pointable ) )
|
||||||
{
|
{
|
||||||
pointable = null;
|
pointable = null;
|
||||||
|
|
||||||
if ( engageSensor.isActive && engageSensor is ActivationModeSensor ams )
|
|
||||||
{
|
|
||||||
ams.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
onLockReleased?.Trigger();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateClosestCandidate();
|
RefreshCandidates();
|
||||||
|
|
||||||
var wasLocked = pointable != null;
|
if ( pointable == null || ! _candidates.Contains( pointable ) )
|
||||||
|
|
||||||
if ( visualizer != null && pointable != null )
|
|
||||||
{
|
{
|
||||||
visualizer.CopyGlobalPoseFrom( pointable.pointerPosition );
|
SetPointable( ClosestCandidate() );
|
||||||
}
|
|
||||||
|
|
||||||
if ( engageSensor != null )
|
|
||||||
{
|
|
||||||
_engaged = engageSensor.isActive;
|
|
||||||
|
|
||||||
if ( ! _engaged )
|
|
||||||
{
|
|
||||||
if ( pointable != null )
|
|
||||||
{
|
|
||||||
SetPointable( null );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( pointable == null )
|
|
||||||
{
|
|
||||||
SetPointable( closestCandidate );
|
|
||||||
}
|
|
||||||
else if ( releaseWhenTargetInvalid && ! IsStillValidTarget( pointable ) )
|
|
||||||
{
|
|
||||||
SetPointable( null );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HandleCycling();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fires off the pointable transition (not the raw engage-sensor edge) so it also covers the
|
|
||||||
// releaseWhenTargetInvalid auto-release path above, and so pointable already holds its new
|
|
||||||
// value (or null) by the time a listener - e.g. SetThirdPersonCameraLockTarget - reads it.
|
|
||||||
var isNowLocked = pointable != null;
|
|
||||||
|
|
||||||
if ( isNowLocked != wasLocked )
|
|
||||||
{
|
|
||||||
Action.TriggerSafe( isNowLocked ? onLockEngaged : onLockReleased );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateClosestCandidate()
|
void RefreshCandidates()
|
||||||
{
|
{
|
||||||
var next = FindClosestCandidate();
|
_candidates.Clear();
|
||||||
|
|
||||||
if ( next == closestCandidate )
|
|
||||||
{
|
|
||||||
if ( closestVisualizer != null && closestCandidate != null )
|
|
||||||
{
|
|
||||||
closestVisualizer.CopyGlobalPoseFrom( closestCandidate.pointerPosition );
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
closestCandidate = next;
|
|
||||||
|
|
||||||
onClosestChanged?.Trigger();
|
|
||||||
|
|
||||||
if ( closestCandidate == null )
|
|
||||||
{
|
|
||||||
onClosestLost?.Trigger();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
onClosestFound?.Trigger();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( closestVisualizer != null && closestCandidate != null )
|
|
||||||
{
|
|
||||||
closestVisualizer.CopyGlobalPoseFrom( closestCandidate.pointerPosition );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleCycling()
|
|
||||||
{
|
|
||||||
if ( cycleMode == LockOnCycleMode.ClosestCycle )
|
|
||||||
{
|
|
||||||
if ( cycleSensor != null && cycleSensor.isDown )
|
|
||||||
{
|
|
||||||
SetPointable( FindNextClosestCandidate() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( cycleMode != LockOnCycleMode.Directional || directionalCycleInputs == null )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( int i = 0; i < directionalCycleInputs.Length; i++ )
|
|
||||||
{
|
|
||||||
var input = directionalCycleInputs[ i ];
|
|
||||||
|
|
||||||
if ( input == null || input.sensor == null || ! input.sensor.isDown )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var next = FindDirectionalCandidate( input.direction );
|
|
||||||
|
|
||||||
if ( next != null )
|
|
||||||
{
|
|
||||||
SetPointable( next );
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointable FindClosestCandidate()
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < caster.NumColliders(); i++ )
|
for ( int i = 0; i < caster.NumColliders(); i++ )
|
||||||
{
|
{
|
||||||
var p = Nodes.Find<Pointable>( caster.GetCollider( i ) );
|
var p = Nodes.Find<Pointable>( caster.GetCollider( i ) );
|
||||||
|
|
||||||
if ( p != null && p.enabled )
|
if ( p != null && p.enabled )
|
||||||
{
|
{
|
||||||
return p;
|
_candidates.Add( p );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pointable FindNextClosestCandidate()
|
Pointable ClosestCandidate()
|
||||||
{
|
{
|
||||||
var currentIndex = -1;
|
return _candidates.Count == 0 ? null : _candidates[ 0 ];
|
||||||
var candidates = new List<Pointable>();
|
|
||||||
|
|
||||||
for ( int i = 0; i < caster.NumColliders(); i++ )
|
|
||||||
{
|
|
||||||
var p = Nodes.Find<Pointable>( caster.GetCollider( i ) );
|
|
||||||
|
|
||||||
if ( p == null || ! p.enabled )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( p == pointable )
|
|
||||||
{
|
|
||||||
currentIndex = candidates.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
candidates.Add( p );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( candidates.Count == 0 )
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( currentIndex == -1 )
|
|
||||||
{
|
|
||||||
return candidates[ 0 ];
|
|
||||||
}
|
|
||||||
|
|
||||||
return candidates[ ( currentIndex + 1 ) % candidates.Count ];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pointable FindDirectionalCandidate( Vector2 direction )
|
public void CycleNext()
|
||||||
|
{
|
||||||
|
if ( _candidates.Count == 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentIndex = _candidates.IndexOf( pointable );
|
||||||
|
var nextIndex = currentIndex == -1 ? 0 : ( currentIndex + 1 ) % _candidates.Count;
|
||||||
|
|
||||||
|
SetPointable( _candidates[ nextIndex ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CyclePrevious()
|
||||||
|
{
|
||||||
|
if ( _candidates.Count == 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentIndex = _candidates.IndexOf( pointable );
|
||||||
|
var previousIndex = currentIndex == -1 ? 0 : ( currentIndex - 1 + _candidates.Count ) % _candidates.Count;
|
||||||
|
|
||||||
|
SetPointable( _candidates[ previousIndex ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CycleInScreenSpaceDirection( Vector2 screenSpaceDirection )
|
||||||
{
|
{
|
||||||
if ( pointable == null )
|
if ( pointable == null )
|
||||||
{
|
{
|
||||||
return FindClosestCandidate();
|
SetPointable( ClosestCandidate() );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var right = caster.GlobalTransform.Basis.X;
|
var right = caster.GlobalTransform.Basis.X;
|
||||||
|
|
@ -256,11 +115,11 @@ namespace Rokojori
|
||||||
Pointable best = null;
|
Pointable best = null;
|
||||||
var bestScore = float.NegativeInfinity;
|
var bestScore = float.NegativeInfinity;
|
||||||
|
|
||||||
for ( int i = 0; i < caster.NumColliders(); i++ )
|
for ( int i = 0; i < _candidates.Count; i++ )
|
||||||
{
|
{
|
||||||
var candidate = Nodes.Find<Pointable>( caster.GetCollider( i ) );
|
var candidate = _candidates[ i ];
|
||||||
|
|
||||||
if ( candidate == null || candidate == pointable || ! candidate.enabled )
|
if ( candidate == pointable )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -273,7 +132,7 @@ namespace Rokojori
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var score = projected.Normalized().Dot( direction );
|
var score = projected.Normalized().Dot( screenSpaceDirection );
|
||||||
|
|
||||||
if ( score > bestScore )
|
if ( score > bestScore )
|
||||||
{
|
{
|
||||||
|
|
@ -282,20 +141,10 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return best;
|
if ( best != null )
|
||||||
}
|
|
||||||
|
|
||||||
bool IsStillValidTarget( Pointable p )
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < caster.NumColliders(); i++ )
|
|
||||||
{
|
{
|
||||||
if ( Nodes.Find<Pointable>( caster.GetCollider( i ) ) == p )
|
SetPointable( best );
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using Rokojori.Extensions;
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class ReleaseCameraLock : Action
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public CameraLocker cameraLocker;
|
||||||
|
|
||||||
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
cameraLocker?.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://b6ipiialv2te8
|
||||||
|
|
@ -24,7 +24,18 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public FlagMode mode = FlagMode.Needs_One_Flag;
|
public FlagMode flagMode = FlagMode.Needs_One_Flag;
|
||||||
|
|
||||||
|
public enum IterationMode
|
||||||
|
{
|
||||||
|
Only_Node,
|
||||||
|
Only_Iterator,
|
||||||
|
Node_And_Iterator
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public IterationMode iterationMode= IterationMode.Node_And_Iterator;
|
||||||
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public TreeIteratorType iteratorType = TreeIteratorType.DirectChildren;
|
public TreeIteratorType iteratorType = TreeIteratorType.DirectChildren;
|
||||||
|
|
@ -40,8 +51,13 @@ namespace Rokojori
|
||||||
numPresent ++;
|
numPresent ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( numPresent == flag.Length )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ( numPresent == flag.Length || mode == FlagMode.Needs_One_Flag && numPresent > 0 )
|
if ( flagMode == FlagMode.Needs_One_Flag && numPresent > 0 )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -51,6 +67,21 @@ namespace Rokojori
|
||||||
|
|
||||||
public override bool Selects( Node node )
|
public override bool Selects( Node node )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if ( IterationMode.Only_Node == iterationMode )
|
||||||
|
{
|
||||||
|
return node is Selectable s && SelectsSelectable( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( IterationMode.Only_Iterator != iterationMode )
|
||||||
|
{
|
||||||
|
if ( node is Selectable s && SelectsSelectable( s ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var iterator = TreeIterator<Node>.GetIterator( iteratorType, node, NodesWalker.Get() );
|
var iterator = TreeIterator<Node>.GetIterator( iteratorType, node, NodesWalker.Get() );
|
||||||
|
|
||||||
while ( iterator.HasNext() )
|
while ( iterator.HasNext() )
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
using Rokojori.Extensions;
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Selector.svg")]
|
||||||
|
public partial class SelectManager:Node
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public Node root;
|
||||||
|
|
||||||
|
Dictionary<Selector,Node> _singleSelections = new Dictionary<Selector, Node>();
|
||||||
|
Dictionary<Selector,List<Node>> _listSelections = new Dictionary<Selector, List<Node>>();
|
||||||
|
|
||||||
|
public Node GetSelectionRoot()
|
||||||
|
{
|
||||||
|
return root == null ? GetTree().Root : root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node Select( Selector selector )
|
||||||
|
{
|
||||||
|
if ( selector == null )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! _singleSelections.ContainsKey( selector ) )
|
||||||
|
{
|
||||||
|
_singleSelections[ selector ] = GetSelectionRoot().Select( selector );
|
||||||
|
}
|
||||||
|
|
||||||
|
return _singleSelections[ selector ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Node> SelectAll( Selector selector )
|
||||||
|
{
|
||||||
|
if ( selector == null )
|
||||||
|
{
|
||||||
|
return new List<Node>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! _singleSelections.ContainsKey( selector ) )
|
||||||
|
{
|
||||||
|
_listSelections[ selector ] = GetSelectionRoot().SelectAll( selector );
|
||||||
|
}
|
||||||
|
|
||||||
|
return _listSelections[ selector ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://7ogqhvo3x5og
|
||||||
|
|
@ -36,6 +36,8 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
var variant = Variant.From<T>( value );
|
var variant = Variant.From<T>( value );
|
||||||
mi.SetInstanceShaderParameter( propertyName, variant );
|
mi.SetInstanceShaderParameter( propertyName, variant );
|
||||||
|
|
||||||
|
// RJLog.Log( "Set", propertyName, variant );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,20 @@ public static class ListExtensions
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ForEachNonNull<T>( this List<T> elements, Action<T> callback ) where T:class
|
||||||
|
{
|
||||||
|
foreach ( var e in elements )
|
||||||
|
{
|
||||||
|
if ( e == null )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static List<T> Sub<T>( this List<T> elements, int start, int length = 0 )
|
public static List<T> Sub<T>( this List<T> elements, int start, int length = 0 )
|
||||||
{
|
{
|
||||||
var end = length == 0 ? elements.Count : ( start + length );
|
var end = length == 0 ? elements.Count : ( start + length );
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
using Rokojori;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Rokojori.Extensions;
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/UIImage.svg")]
|
||||||
|
public partial class CustomUIImageType:UIImageType
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public Material material;
|
||||||
|
|
||||||
|
|
||||||
|
protected override void _Assign( UIImage image )
|
||||||
|
{
|
||||||
|
image.Material = material;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dd3mbku3iiltt
|
||||||
|
|
@ -613,7 +613,10 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return control.GetWindow().Size.X;
|
// return control.GetWindow().Size.X;
|
||||||
|
return control.GetViewport().GetVisibleRect().Size.X;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -625,7 +628,8 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return control.GetWindow().Size.Y;
|
// return control.GetWindow().Size.Y;
|
||||||
|
return control.GetViewport().GetVisibleRect().Size.Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,11 @@ public abstract partial class ParticleVFXData:Resource
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! IsInstanceValid( particles ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( particles.Amount != preset.maxParticles )
|
if ( particles.Amount != preset.maxParticles )
|
||||||
{
|
{
|
||||||
particles.Amount = preset.maxParticles;
|
particles.Amount = preset.maxParticles;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue