Compare commits
19 Commits
whitleands
...
9eebc75fa3
| Author | SHA1 | Date | |
|---|---|---|---|
| 9eebc75fa3 | |||
| 1b5b364313 | |||
| c6893b7ee8 | |||
| fc887c2519 | |||
| 9da7b074d4 | |||
| d0d052f65b | |||
| 67a99051bd | |||
| fb848a9848 | |||
| bc30a169dc | |||
| f5576959b7 | |||
| b8ab8f4971 | |||
| 77df5fbbfd | |||
|
|
ed5eb706a1 | ||
|
|
58f9188794 | ||
|
|
b463f55f53 | ||
| c0a68da7d1 | |||
| 97bbca95e8 | |||
|
|
ed25b40969 | ||
| 2b1370bd40 |
BIN
addons/PageFlip/Assets/back.png
Normal file
|
After Width: | Height: | Size: 766 KiB |
@@ -2,16 +2,16 @@
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d4e1lbng4uqk"
|
||||
path="res://.godot/imported/quad_main.png-af26b29d5c3350fc4d75e08ad350ccc7.ctex"
|
||||
uid="uid://bjowpx1ap4uxt"
|
||||
path="res://.godot/imported/back.png-bddbf3418b746eb53bc79fd4d0989d41.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/quad_main.png"
|
||||
dest_files=["res://.godot/imported/quad_main.png-af26b29d5c3350fc4d75e08ad350ccc7.ctex"]
|
||||
source_file="res://addons/PageFlip/Assets/back.png"
|
||||
dest_files=["res://.godot/imported/back.png-bddbf3418b746eb53bc79fd4d0989d41.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
BIN
addons/PageFlip/Assets/blank_page.png
Normal file
|
After Width: | Height: | Size: 300 KiB |
40
addons/PageFlip/Assets/blank_page.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cen51wqc15b14"
|
||||
path="res://.godot/imported/blank_page.png-589b6dfce0585742cc1d305c391c9cd9.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/PageFlip/Assets/blank_page.png"
|
||||
dest_files=["res://.godot/imported/blank_page.png-589b6dfce0585742cc1d305c391c9cd9.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
|
||||
BIN
addons/PageFlip/Assets/book_impact.ogg
Normal file
19
addons/PageFlip/Assets/book_impact.ogg.import
Normal file
@@ -0,0 +1,19 @@
|
||||
[remap]
|
||||
|
||||
importer="oggvorbisstr"
|
||||
type="AudioStreamOggVorbis"
|
||||
uid="uid://bhitebdghyhua"
|
||||
path="res://.godot/imported/book_impact.ogg-ae2f194921fcd1bc549a3ddb37fab4ba.oggvorbisstr"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/PageFlip/Assets/book_impact.ogg"
|
||||
dest_files=["res://.godot/imported/book_impact.ogg-ae2f194921fcd1bc549a3ddb37fab4ba.oggvorbisstr"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
||||
BIN
addons/PageFlip/Assets/front.png
Normal file
|
After Width: | Height: | Size: 765 KiB |
40
addons/PageFlip/Assets/front.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dbdwbowx32d3v"
|
||||
path="res://.godot/imported/front.png-76dff7071666496195badceef4e0ce67.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/PageFlip/Assets/front.png"
|
||||
dest_files=["res://.godot/imported/front.png-76dff7071666496195badceef4e0ce67.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
|
||||
BIN
addons/PageFlip/Assets/interior.png
Normal file
|
After Width: | Height: | Size: 772 KiB |
40
addons/PageFlip/Assets/interior.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dt1tiecgw5rip"
|
||||
path="res://.godot/imported/interior.png-d4b06daf084fdb8a90836ec57d2dd53f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/PageFlip/Assets/interior.png"
|
||||
dest_files=["res://.godot/imported/interior.png-d4b06daf084fdb8a90836ec57d2dd53f.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
|
||||
BIN
addons/PageFlip/Assets/page_flip.ogg
Normal file
19
addons/PageFlip/Assets/page_flip.ogg.import
Normal file
@@ -0,0 +1,19 @@
|
||||
[remap]
|
||||
|
||||
importer="oggvorbisstr"
|
||||
type="AudioStreamOggVorbis"
|
||||
uid="uid://bylfc3b5pmbij"
|
||||
path="res://.godot/imported/page_flip.ogg-aabb6ae51ff161ae6afa52da11fe75de.oggvorbisstr"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/PageFlip/Assets/page_flip.ogg"
|
||||
dest_files=["res://.godot/imported/page_flip.ogg-aabb6ae51ff161ae6afa52da11fe75de.oggvorbisstr"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
||||
49
addons/PageFlip/Assets/page_flip_final.gdshader
Normal file
@@ -0,0 +1,49 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D front_texture : source_color, filter_linear_mipmap;
|
||||
uniform sampler2D back_texture : source_color, filter_linear_mipmap;
|
||||
|
||||
uniform sampler2D spine_shadow_gradient : source_color, filter_linear, repeat_disable;
|
||||
uniform float shadow_intensity : hint_range(0.0, 1.0) = 0.0;
|
||||
uniform float max_shadow_spread : hint_range(0.0, 1.0) = 0.35;
|
||||
|
||||
uniform bool debug_mode = false;
|
||||
uniform bool is_backward = false;
|
||||
|
||||
void fragment() {
|
||||
vec2 uv_dx = dFdx(UV);
|
||||
vec2 uv_dy = dFdy(UV);
|
||||
float face_dir = uv_dx.x * uv_dy.y - uv_dx.y * uv_dy.x;
|
||||
bool is_front = face_dir > 0.0;
|
||||
|
||||
vec4 base_color;
|
||||
|
||||
if (is_front) {
|
||||
if (is_backward) {
|
||||
// Let's try flipping Y just in case they meant upside down!
|
||||
// And keep X normal, since UV goes 0 to 1.
|
||||
base_color = texture(front_texture, UV);
|
||||
} else {
|
||||
base_color = texture(front_texture, UV);
|
||||
}
|
||||
} else {
|
||||
if (is_backward) {
|
||||
base_color = texture(back_texture, vec2(1.0 - UV.x, UV.y));
|
||||
} else {
|
||||
base_color = texture(back_texture, vec2(1.0 - UV.x, UV.y));
|
||||
}
|
||||
}
|
||||
|
||||
float current_spread = max_shadow_spread * (shadow_intensity + 0.001);
|
||||
float sample_x = UV.x / current_spread;
|
||||
float shadow_alpha = texture(spine_shadow_gradient, vec2(sample_x, 0.0)).a;
|
||||
|
||||
if (sample_x > 1.0) {
|
||||
shadow_alpha = 0.0;
|
||||
}
|
||||
|
||||
shadow_alpha *= shadow_intensity;
|
||||
|
||||
vec3 final_rgb = mix(base_color.rgb, vec3(0.0, 0.0, 0.0), shadow_alpha);
|
||||
COLOR = vec4(final_rgb, base_color.a);
|
||||
}
|
||||
1
addons/PageFlip/Assets/page_flip_final.gdshader.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b57sdbj15qx37
|
||||
9
addons/PageFlip/Assets/page_flip_shader_material.tres
Normal file
@@ -0,0 +1,9 @@
|
||||
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://ddw2ie8wnrnre"]
|
||||
|
||||
[ext_resource type="Shader" uid="uid://b57sdbj15qx37" path="res://addons/PageFlip/Assets/page_flip_final.gdshader" id="1_cl0rr"]
|
||||
|
||||
[resource]
|
||||
shader = ExtResource("1_cl0rr")
|
||||
shader_parameter/shadow_intensity = 0.0
|
||||
shader_parameter/max_shadow_spread = 0.35
|
||||
shader_parameter/debug_mode = false
|
||||
8
addons/PageFlip/Assets/shadow_gradient.tres
Normal file
@@ -0,0 +1,8 @@
|
||||
[gd_resource type="GradientTexture2D" format=3 uid="uid://rm7bporlv3cf"]
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_3i6i7"]
|
||||
offsets = PackedFloat32Array(0, 0.2731183, 0.44731182, 1)
|
||||
colors = PackedColorArray(0, 0, 0, 0.521, 0, 0, 0, 0.492, 0, 0, 0, 0.358, 0, 0, 0, 0)
|
||||
|
||||
[resource]
|
||||
gradient = SubResource("Gradient_3i6i7")
|
||||
BIN
addons/PageFlip/Assets/spine.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
40
addons/PageFlip/Assets/spine.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cit41jypw2sy1"
|
||||
path="res://.godot/imported/spine.png-c2fa10bef4996b84a954651c908149a7.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/PageFlip/Assets/spine.png"
|
||||
dest_files=["res://.godot/imported/spine.png-c2fa10bef4996b84a954651c908149a7.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
|
||||
229
addons/PageFlip/book_api.gd
Normal file
@@ -0,0 +1,229 @@
|
||||
@tool
|
||||
class_name BookAPI
|
||||
extends RefCounted
|
||||
|
||||
## Static utility class for the PageFlip2D system by Newold.
|
||||
## Provides helper methods to configure the book and facilitate interaction
|
||||
## from embedded scenes (UI, puzzles, maps).
|
||||
##
|
||||
## [b]How to use:[/b][br]
|
||||
## This class is designed to be used statically. You do not need to instance it.
|
||||
## Simply call [code]BookAPI.function_name()[/code] from anywhere in your project.
|
||||
## It automatically tracks the active [PageFlip2D] instance.
|
||||
## (When a PageFlip scene enters the tree, it registers itself as the current_book.)
|
||||
|
||||
# ==============================================================================
|
||||
# ENUMS (Mirrored for easy access)
|
||||
# ==============================================================================
|
||||
|
||||
enum JumpTarget {
|
||||
## Jump to the closed state showing the Front Cover.
|
||||
FRONT_COVER,
|
||||
## Jump to the closed state showing the Back Cover.
|
||||
BACK_COVER,
|
||||
## Jump to a specific content page number.
|
||||
CONTENT_PAGE
|
||||
}
|
||||
|
||||
# Internal reference to the currently active book.
|
||||
static var _current_book: PageFlip2D
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# SETUP & REFERENCES
|
||||
# ==============================================================================
|
||||
|
||||
## Registers a book instance as the currently active one.
|
||||
## Automatically called by [PageFlip2D] in its [method Node._ready].
|
||||
static func set_current_book(book: PageFlip2D) -> void:
|
||||
_current_book = book
|
||||
|
||||
|
||||
## Returns the currently active book instance, or null if none is registered.
|
||||
static func get_current_book() -> PageFlip2D:
|
||||
return _current_book
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# NAVIGATION CONTROLS
|
||||
# ==============================================================================
|
||||
|
||||
## Turns the page forward (to the next page/spread).
|
||||
## Does nothing if the book is animating or at the end.
|
||||
static func next_page() -> void:
|
||||
if is_instance_valid(_current_book):
|
||||
force_release_control(_current_book)
|
||||
_current_book.next_page()
|
||||
|
||||
|
||||
## Turns the page backward (to the previous page/spread).
|
||||
## Does nothing if the book is animating or at the beginning.
|
||||
static func prev_page() -> void:
|
||||
if is_instance_valid(_current_book):
|
||||
force_release_control(_current_book)
|
||||
_current_book.prev_page()
|
||||
|
||||
|
||||
## Forces the active book to close towards a specific cover.
|
||||
## [param to_front_cover]: If true, closes to the Front Cover (Right to Left). If false, closes to Back Cover.
|
||||
static func force_close_book(to_front_cover: bool) -> void:
|
||||
if is_instance_valid(_current_book):
|
||||
force_release_control(_current_book)
|
||||
_current_book.force_close_book(to_front_cover)
|
||||
|
||||
|
||||
## Navigates to a specific page number (1-based index).
|
||||
## Acts as a wrapper for go_to_spread, calculating the correct index automatically.
|
||||
## [b]ASYNC:[/b] Must be called with 'await' if animated is true.
|
||||
## [param page_num]: The 1-based page number (1 = first texture in pages_paths).
|
||||
## [param target]: Specifies if the target is a content page or a cover.
|
||||
static func go_to_page(page_num: int = 1, target: JumpTarget = JumpTarget.CONTENT_PAGE, animated: bool = true) -> void:
|
||||
var book = _current_book
|
||||
if not is_instance_valid(book): return
|
||||
|
||||
var target_spread_idx: int = 0
|
||||
|
||||
match target:
|
||||
JumpTarget.FRONT_COVER:
|
||||
target_spread_idx = -1
|
||||
JumpTarget.BACK_COVER:
|
||||
target_spread_idx = book.total_spreads
|
||||
JumpTarget.CONTENT_PAGE:
|
||||
# Calculate spread index: 1-2 -> Spread 0, 3-4 -> Spread 1, etc.
|
||||
var safe_page = max(1, page_num)
|
||||
target_spread_idx = int(safe_page / 2.0)
|
||||
target_spread_idx = clampi(target_spread_idx, 0, book.total_spreads - 1)
|
||||
|
||||
await go_to_spread(book, target_spread_idx, animated)
|
||||
|
||||
|
||||
## Navigates to a specific spread index directly.
|
||||
## [b]ASYNC:[/b] Must be called with 'await' if animated is true.
|
||||
## - Animated: Fast-forwards through pages with dynamic speed.
|
||||
## - Instant: Snaps to page and manually triggers the scene activation handshake.
|
||||
static func go_to_spread(book: PageFlip2D, target_spread: int, animated: bool = true) -> void:
|
||||
if not is_instance_valid(book): return
|
||||
|
||||
# Clamp target
|
||||
var final_target = clampi(target_spread, -1, book.total_spreads)
|
||||
var diff = final_target - book.current_spread
|
||||
|
||||
if diff == 0:
|
||||
return
|
||||
|
||||
force_release_control(book)
|
||||
|
||||
if not animated:
|
||||
# INSTANT TELEPORT
|
||||
book.current_spread = final_target
|
||||
book.call("_update_static_visuals_immediate")
|
||||
book.call("_update_volume_visuals")
|
||||
# Force check for interactive scenes after teleport
|
||||
book.call("_check_scene_activation")
|
||||
|
||||
else:
|
||||
# ANIMATED FAST-FORWARD
|
||||
if book.is_animating: return # Don't interrupt an existing animation
|
||||
|
||||
var original_speed = book.anim_player.speed_scale
|
||||
|
||||
# --- DYNAMIC SPEED CALCULATION ---
|
||||
var steps = abs(diff)
|
||||
# Base speed: 1.5x -> Max speed: 10.0x
|
||||
var dynamic_speed = remap(float(steps), 0.0, float(book.total_spreads), 1.5, 10.0)
|
||||
book.anim_player.speed_scale = dynamic_speed
|
||||
|
||||
var going_forward = diff > 0
|
||||
|
||||
for i in range(steps):
|
||||
if not is_instance_valid(book): break
|
||||
|
||||
if going_forward: book.next_page()
|
||||
else: book.prev_page()
|
||||
|
||||
# Wait for the physical page turn to finish before starting the next one.
|
||||
if book.anim_player.is_playing():
|
||||
await book.anim_player.animation_finished
|
||||
else:
|
||||
await book.get_tree().process_frame
|
||||
|
||||
# RESTORE STATE
|
||||
if is_instance_valid(book):
|
||||
book.anim_player.speed_scale = original_speed
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# STATE & INTERACTION HELPERS
|
||||
# ==============================================================================
|
||||
|
||||
## Returns true if the book (active or specific) is currently animating.
|
||||
static func is_busy(book_instance: PageFlip2D = null) -> bool:
|
||||
var book = book_instance if book_instance else _current_book
|
||||
if not is_instance_valid(book): return false
|
||||
return book.is_animating
|
||||
|
||||
|
||||
## Locates the PageFlip2D controller ancestor from any node inside an interactive page.
|
||||
static func find_book_controller(caller_node: Node) -> PageFlip2D:
|
||||
var current = caller_node
|
||||
while current:
|
||||
if current is PageFlip2D:
|
||||
return current
|
||||
current = current.get_parent()
|
||||
return null
|
||||
|
||||
|
||||
## Safely locks or unlocks the book's ability to turn pages manually.
|
||||
## WARNING: If locked, the interactive scene MUST be responsible for unlocking it later.
|
||||
static func set_interaction_lock(book: PageFlip2D, locked: bool) -> void:
|
||||
if not is_instance_valid(book): return
|
||||
book.call("_pageflip_set_input_enabled", not locked)
|
||||
|
||||
|
||||
## Forces the book to regain input control immediately.
|
||||
## Useful as a failsafe if an interactive scene closes unexpectedly.
|
||||
static func force_release_control(book: PageFlip2D) -> void:
|
||||
if not is_instance_valid(book): return
|
||||
book.call("_pageflip_set_input_enabled", true)
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# CONFIGURATION HELPERS
|
||||
# ==============================================================================
|
||||
|
||||
## Configures the visual properties of a Book instance via a dictionary.
|
||||
static func configure_visuals(book: PageFlip2D, data: Dictionary) -> void:
|
||||
if not is_instance_valid(book): return
|
||||
|
||||
if "pages" in data:
|
||||
book.pages_paths = data["pages"]
|
||||
book.call("_prepare_book_content")
|
||||
|
||||
if "cover_front_out" in data: book.tex_cover_front_out = data["cover_front_out"]
|
||||
if "cover_front_in" in data: book.tex_cover_front_in = data["cover_front_in"]
|
||||
if "cover_back_in" in data: book.tex_cover_back_in = data["cover_back_in"]
|
||||
if "cover_back_out" in data: book.tex_cover_back_out = data["cover_back_out"]
|
||||
|
||||
if "spine_col" in data: book.spine_color = data["spine_col"]
|
||||
if "spine_width" in data:
|
||||
book.spine_width = data["spine_width"]
|
||||
book.call("_build_spine")
|
||||
|
||||
if "size" in data:
|
||||
book.target_page_size = data["size"]
|
||||
book.call("_apply_new_size")
|
||||
|
||||
book.call("_update_static_visuals_immediate")
|
||||
book.call("_update_volume_visuals")
|
||||
|
||||
|
||||
## Configures the physics simulation of the page turning effect.
|
||||
static func configure_physics(book: PageFlip2D, data: Dictionary) -> void:
|
||||
if not is_instance_valid(book) or not book.dynamic_poly: return
|
||||
|
||||
var rigger = book.dynamic_poly
|
||||
for key in data.keys():
|
||||
rigger.set(key, data[key])
|
||||
|
||||
if rigger.has_method("rebuild"):
|
||||
rigger.rebuild(book.target_page_size)
|
||||
1
addons/PageFlip/book_api.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c2dx1dksgeey6
|
||||
1416
addons/PageFlip/page_flip.gd
Normal file
1
addons/PageFlip/page_flip.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ctw83iqgqxjjt
|
||||
1980
addons/PageFlip/page_flip.tscn
Normal file
587
addons/PageFlip/page_rigger.gd
Normal file
@@ -0,0 +1,587 @@
|
||||
@tool
|
||||
class_name DynamicPage
|
||||
extends Polygon2D
|
||||
|
||||
# ==============================================================================
|
||||
# ENUMS & CONSTANTS
|
||||
# ==============================================================================
|
||||
|
||||
## Defines the material physical properties for the page simulation.
|
||||
enum PagePreset {
|
||||
CUSTOM,
|
||||
DEFAULT,
|
||||
STANDARD_PAPER,
|
||||
HEAVY_GRIMOIRE,
|
||||
LIGHT_MAGAZINE,
|
||||
OLD_SCROLL,
|
||||
RIGID_BOARD,
|
||||
WET_CLOTH,
|
||||
PLASTIC_SHEET,
|
||||
METAL_PLATE
|
||||
}
|
||||
|
||||
## Determines the direction of the page turn curve.
|
||||
enum CurlMode {
|
||||
STRAIGHT,
|
||||
TOP_CORNER_FIRST,
|
||||
BOTTOM_CORNER_FIRST
|
||||
}
|
||||
|
||||
const SKELETON_NAME = "AutoSkeleton"
|
||||
const SHADOW_NAME = "AutoShadow"
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# SIGNALS
|
||||
# ==============================================================================
|
||||
|
||||
signal change_page_requested
|
||||
signal end_animation
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# INTERNAL CACHE
|
||||
# ==============================================================================
|
||||
|
||||
var _custom_cache: Dictionary = {}
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# CONFIGURATION
|
||||
# ==============================================================================
|
||||
|
||||
@export_category("Rig Generator")
|
||||
|
||||
## Horizontal mesh subdivision. Higher values create smoother bends.
|
||||
@export_range(1, 20) var subdivision_x: int = 8
|
||||
## Vertical mesh subdivision. Higher values allow for better corner curling.
|
||||
@export_range(1, 10) var subdivision_y: int = 5
|
||||
## Generates the mesh, skeleton, weights and animations.
|
||||
@export var rebuild_all: bool = false : set = _on_generate_pressed
|
||||
|
||||
|
||||
@export_category("Animation Generator")
|
||||
|
||||
@export_group("Quick Presets")
|
||||
## Select a material style to auto-configure physics.
|
||||
@export var animation_preset: PagePreset = PagePreset.CUSTOM : set = _on_preset_changed
|
||||
|
||||
|
||||
@export_group("Manual Configuration")
|
||||
## The AnimationPlayer node to store the generated animations.
|
||||
@export var anim_player: AnimationPlayer
|
||||
## Duration of the page turn animation in seconds.
|
||||
@export var anim_duration: float = 0.75
|
||||
|
||||
|
||||
@export_subgroup("Paper Physics")
|
||||
## Stiffness of the material. 0.5 = Rubber, 5.0 = Wood.
|
||||
@export_range(0.5, 5.0, 0.1) var paper_stiffness: float = 2.0
|
||||
## Bend angle during the lift phase (Negative = Tip drags down).
|
||||
@export_range(-180.0, 180.0) var lift_bend: float = -10.0
|
||||
## Bend angle during the landing phase (Negative = Tip floats up).
|
||||
@export_range(-180.0, 180.0) var land_bend: float = -8.0
|
||||
|
||||
|
||||
@export_subgroup("Curl Effect")
|
||||
## Which part of the page initiates the movement.
|
||||
@export var curl_mode: CurlMode = CurlMode.TOP_CORNER_FIRST
|
||||
## Time delay for the trailing corner (0.0 = None, 1.0 = High lag).
|
||||
@export_range(0.0, 1.0, 0.05) var curl_lag: float = 0.8
|
||||
|
||||
|
||||
@export_subgroup("Shadow FX")
|
||||
## Create a dynamic shadow behind the page (Background Shadow).
|
||||
@export var enable_shadow: bool = false
|
||||
## The gradient texture used for the back shadow.
|
||||
@export var shadow_gradient: GradientTexture2D
|
||||
|
||||
|
||||
@export_subgroup("Fine Timing")
|
||||
## Normalized time (0.0 - 1.0) for the peak lift position.
|
||||
@export_range(0.05, 0.45, 0.01) var timing_peak_lift: float = 0.15
|
||||
## Normalized time (0.0 - 1.0) for the landing contact.
|
||||
@export_range(0.55, 0.95, 0.01) var timing_peak_land: float = 0.85
|
||||
|
||||
@export var generate_anims_btn: bool = false : set = _on_anim_pressed
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# RUNTIME INITIALIZATION
|
||||
# ==============================================================================
|
||||
|
||||
func _ready():
|
||||
self.z_index = 10
|
||||
if animation_preset == PagePreset.CUSTOM:
|
||||
_save_state_to_cache()
|
||||
|
||||
|
||||
func rebuild(current_page_size: Vector2 = Vector2.ZERO) -> void:
|
||||
if not anim_player: return
|
||||
_clean_previous_rig()
|
||||
_create_rig_logic(current_page_size)
|
||||
_generate_animations_logic()
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# PRESET LOGIC
|
||||
# ==============================================================================
|
||||
|
||||
func _on_preset_changed(val):
|
||||
if animation_preset == PagePreset.CUSTOM:
|
||||
_save_state_to_cache()
|
||||
|
||||
animation_preset = val
|
||||
|
||||
if val == PagePreset.CUSTOM:
|
||||
if not _custom_cache.is_empty():
|
||||
_load_state_from_cache()
|
||||
print("[PageRigger] Restored Custom Settings.")
|
||||
notify_property_list_changed()
|
||||
return
|
||||
|
||||
# Defaults
|
||||
curl_mode = CurlMode.BOTTOM_CORNER_FIRST
|
||||
curl_lag = 0.3
|
||||
enable_shadow = false
|
||||
anim_duration = 0.75
|
||||
|
||||
match val:
|
||||
PagePreset.DEFAULT:
|
||||
paper_stiffness = 2.0; lift_bend = -15.0; land_bend = 5.0
|
||||
curl_mode = CurlMode.TOP_CORNER_FIRST; curl_lag = 0.5
|
||||
anim_duration = 0.75; timing_peak_lift = 0.15; timing_peak_land = 0.85
|
||||
|
||||
PagePreset.STANDARD_PAPER:
|
||||
paper_stiffness = 2.5; lift_bend = -12.0; land_bend = 3.0
|
||||
curl_mode = CurlMode.TOP_CORNER_FIRST; curl_lag = 0.4
|
||||
anim_duration = 0.65; timing_peak_lift = 0.12; timing_peak_land = 0.88
|
||||
|
||||
PagePreset.HEAVY_GRIMOIRE:
|
||||
paper_stiffness = 4.0; lift_bend = -3.0; land_bend = 1.0
|
||||
curl_mode = CurlMode.STRAIGHT; curl_lag = 0.1
|
||||
anim_duration = 1.1; timing_peak_lift = 0.25; timing_peak_land = 0.75
|
||||
|
||||
PagePreset.LIGHT_MAGAZINE:
|
||||
paper_stiffness = 0.8; lift_bend = -16.0; land_bend = 0.0
|
||||
curl_mode = CurlMode.BOTTOM_CORNER_FIRST; curl_lag = 0.6
|
||||
anim_duration = 0.8; timing_peak_lift = 0.10; timing_peak_land = 0.92
|
||||
|
||||
PagePreset.OLD_SCROLL:
|
||||
paper_stiffness = 1.8; lift_bend = -20.0; land_bend = 8.0
|
||||
curl_mode = CurlMode.TOP_CORNER_FIRST; curl_lag = 0.9
|
||||
anim_duration = 0.9; timing_peak_lift = 0.18; timing_peak_land = 0.82
|
||||
|
||||
PagePreset.RIGID_BOARD:
|
||||
paper_stiffness = 5.0; lift_bend = 0.0; land_bend = 0.0
|
||||
curl_mode = CurlMode.STRAIGHT; curl_lag = 0.0
|
||||
anim_duration = 0.8; timing_peak_lift = 0.2; timing_peak_land = 0.8
|
||||
|
||||
PagePreset.WET_CLOTH:
|
||||
paper_stiffness = 0.3; lift_bend = -28.0; land_bend = -0.0
|
||||
curl_mode = CurlMode.BOTTOM_CORNER_FIRST; curl_lag = 0.6
|
||||
anim_duration = 1.3; timing_peak_lift = 0.2; timing_peak_land = 0.95
|
||||
|
||||
PagePreset.PLASTIC_SHEET:
|
||||
paper_stiffness = 3.5; lift_bend = -12.0; land_bend = 12.0
|
||||
curl_mode = CurlMode.TOP_CORNER_FIRST; curl_lag = 0.2
|
||||
anim_duration = 0.5; timing_peak_lift = 0.08; timing_peak_land = 0.92
|
||||
|
||||
PagePreset.METAL_PLATE:
|
||||
paper_stiffness = 5.0; lift_bend = 0.0; land_bend = 0.0
|
||||
curl_mode = CurlMode.STRAIGHT; curl_lag = 0.0
|
||||
anim_duration = 1.4; timing_peak_lift = 0.15; timing_peak_land = 0.98
|
||||
|
||||
notify_property_list_changed()
|
||||
if anim_player and skeleton != NodePath(""):
|
||||
_generate_animations_logic()
|
||||
print("[PageRigger] Preset Applied: ", PagePreset.keys()[val])
|
||||
|
||||
|
||||
func _save_state_to_cache():
|
||||
_custom_cache = {
|
||||
"stiffness": paper_stiffness, "lift": lift_bend, "land": land_bend,
|
||||
"curl_m": curl_mode, "curl_l": curl_lag,
|
||||
"t_lift": timing_peak_lift, "t_land": timing_peak_land,
|
||||
"dur": anim_duration, "shadow": enable_shadow
|
||||
}
|
||||
|
||||
|
||||
func _load_state_from_cache():
|
||||
paper_stiffness = _custom_cache.get("stiffness", 1.5)
|
||||
lift_bend = _custom_cache.get("lift", -30.0)
|
||||
land_bend = _custom_cache.get("land", -15.0)
|
||||
curl_mode = _custom_cache.get("curl_m", CurlMode.BOTTOM_CORNER_FIRST)
|
||||
curl_lag = _custom_cache.get("curl_l", 0.3)
|
||||
timing_peak_lift = _custom_cache.get("t_lift", 0.15)
|
||||
timing_peak_land = _custom_cache.get("t_land", 0.85)
|
||||
anim_duration = _custom_cache.get("dur", 1.0)
|
||||
enable_shadow = false # Force disable shadow
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# RIGGING LOGIC
|
||||
# ==============================================================================
|
||||
|
||||
func _calculate_polygon_rect() -> Rect2:
|
||||
if polygon.size() == 0:
|
||||
return Rect2(0,0,0,0)
|
||||
|
||||
var min_v = polygon[0]
|
||||
var max_v = polygon[0]
|
||||
|
||||
for v in polygon:
|
||||
min_v.x = min(min_v.x, v.x)
|
||||
min_v.y = min(min_v.y, v.y)
|
||||
max_v.x = max(max_v.x, v.x)
|
||||
max_v.y = max(max_v.y, v.y)
|
||||
|
||||
return Rect2(min_v, max_v - min_v)
|
||||
|
||||
|
||||
func _create_rig_logic(current_page_size: Vector2 = Vector2.ZERO):
|
||||
self.z_index = 10
|
||||
|
||||
var original_size = Vector2(512, 820)
|
||||
var tex_size: Vector2 = Vector2.ZERO
|
||||
if current_page_size != Vector2.ZERO:
|
||||
tex_size = current_page_size
|
||||
elif texture:
|
||||
tex_size = texture.get_size()
|
||||
if tex_size == Vector2.ZERO:
|
||||
tex_size = original_size
|
||||
|
||||
var step_x = tex_size.x / subdivision_x
|
||||
var step_y = tex_size.y / subdivision_y
|
||||
|
||||
# Prepare Gradient Texture for Background Shadow
|
||||
var applied_shadow_tex: Texture2D = null
|
||||
if not shadow_gradient:
|
||||
shadow_gradient = preload("uid://rm7bporlv3cf")
|
||||
var dup = shadow_gradient.duplicate()
|
||||
if dup is GradientTexture2D:
|
||||
dup.width = int(tex_size.x)
|
||||
applied_shadow_tex = dup
|
||||
|
||||
# --- 0. BACKGROUND SHADOW ---
|
||||
if enable_shadow:
|
||||
var shadow = Polygon2D.new()
|
||||
shadow.name = SHADOW_NAME
|
||||
shadow.z_index = -1
|
||||
|
||||
if applied_shadow_tex:
|
||||
shadow.texture = applied_shadow_tex
|
||||
shadow.color = Color.WHITE
|
||||
else:
|
||||
shadow.color = Color(0, 0, 0, 0.5)
|
||||
|
||||
var margin = 4.0
|
||||
shadow.polygon = PackedVector2Array([
|
||||
Vector2(margin, margin), Vector2(tex_size.x - margin, margin),
|
||||
Vector2(tex_size.x - margin, tex_size.y - margin), Vector2(margin, tex_size.y - margin)
|
||||
])
|
||||
shadow.uv = shadow.polygon
|
||||
add_child(shadow)
|
||||
|
||||
# --- 1. MESH & UV ---
|
||||
var new_uvs = PackedVector2Array()
|
||||
for y in range(subdivision_y + 1):
|
||||
for x in range(subdivision_x + 1):
|
||||
new_uvs.append(Vector2(x * step_x, y * step_y))
|
||||
self.uv = new_uvs
|
||||
self.polygon = new_uvs
|
||||
|
||||
var new_polygons = []
|
||||
var rc = subdivision_x + 1
|
||||
for y in range(subdivision_y):
|
||||
for x in range(subdivision_x):
|
||||
var i = y * rc + x
|
||||
new_polygons.append(PackedInt32Array([i, i + 1, i + rc + 1, i + rc]))
|
||||
self.polygons = new_polygons
|
||||
|
||||
# --- 2. SKELETON ---
|
||||
var sk = Skeleton2D.new()
|
||||
sk.name = SKELETON_NAME
|
||||
add_child(sk)
|
||||
self.skeleton = NodePath(SKELETON_NAME)
|
||||
|
||||
# --- 3. BONES (Structured Hierarchy) ---
|
||||
for y in range(subdivision_y + 1):
|
||||
var parent_bone: Bone2D = null
|
||||
|
||||
for x in range(subdivision_x + 1):
|
||||
var b = Bone2D.new()
|
||||
b.name = "Bone_%d_%d" % [x, y]
|
||||
b.set_autocalculate_length_and_angle(false)
|
||||
b.set_length(step_x)
|
||||
|
||||
if x == 0:
|
||||
# Root bone (Spine)
|
||||
sk.add_child(b)
|
||||
b.position = Vector2(0, y * step_y)
|
||||
else:
|
||||
# Child bone
|
||||
if parent_bone:
|
||||
parent_bone.add_child(b)
|
||||
b.position = Vector2(step_x, 0)
|
||||
|
||||
b.set_rest(b.transform)
|
||||
parent_bone = b
|
||||
|
||||
# --- 4. WEIGHTS (Gradient Skinning) ---
|
||||
_apply_weights_to_polygon(self, sk)
|
||||
|
||||
queue_redraw()
|
||||
notify_property_list_changed()
|
||||
|
||||
|
||||
func _apply_weights_to_polygon(poly: Polygon2D, sk: Skeleton2D):
|
||||
poly.clear_bones()
|
||||
|
||||
var bone_map = {}
|
||||
for y in range(subdivision_y + 1):
|
||||
for x in range(subdivision_x + 1):
|
||||
var bname = "Bone_%d_%d" % [x, y]
|
||||
var bone_node = sk.find_child(bname, true, false)
|
||||
if bone_node:
|
||||
bone_map[bname] = bone_node.get_path()
|
||||
|
||||
var vertex_count = poly.polygon.size()
|
||||
|
||||
var weights_per_bone = {}
|
||||
|
||||
for bpath in bone_map.values():
|
||||
var w_arr = PackedFloat32Array()
|
||||
w_arr.resize(vertex_count)
|
||||
w_arr.fill(0.0)
|
||||
weights_per_bone[bpath] = w_arr
|
||||
|
||||
var vert_idx = 0
|
||||
for y in range(subdivision_y + 1):
|
||||
for x in range(subdivision_x + 1):
|
||||
var primary_name = "Bone_%d_%d" % [x, y]
|
||||
var prev_name = "Bone_%d_%d" % [x - 1, y]
|
||||
var next_name = "Bone_%d_%d" % [x + 1, y]
|
||||
|
||||
var primary_path = bone_map.get(primary_name)
|
||||
var prev_path = bone_map.get(prev_name)
|
||||
var next_path = bone_map.get(next_name)
|
||||
|
||||
var w_center = 0.7
|
||||
var w_neighbor = 0.15
|
||||
|
||||
if primary_path: weights_per_bone[primary_path][vert_idx] += w_center
|
||||
if prev_path: weights_per_bone[prev_path][vert_idx] += w_neighbor
|
||||
else: weights_per_bone[primary_path][vert_idx] += w_neighbor
|
||||
if next_path: weights_per_bone[next_path][vert_idx] += w_neighbor
|
||||
else: weights_per_bone[primary_path][vert_idx] += w_neighbor
|
||||
|
||||
vert_idx += 1
|
||||
|
||||
for bpath in weights_per_bone:
|
||||
poly.add_bone(bpath, weights_per_bone[bpath])
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# ANIMATION LOGIC
|
||||
# ==============================================================================
|
||||
|
||||
func _generate_animations_logic():
|
||||
var library: AnimationLibrary
|
||||
if anim_player.has_animation_library(""): library = anim_player.get_animation_library("")
|
||||
else: library = AnimationLibrary.new(); anim_player.add_animation_library("", library)
|
||||
|
||||
_create_single_anim(library, "turn_flexible_page", false, false)
|
||||
_create_single_anim(library, "turn_rigid_page", true, false)
|
||||
_create_single_anim(library, "turn_flexible_page_mirror", false, true)
|
||||
_create_single_anim(library, "turn_rigid_page_mirror", true, true)
|
||||
notify_property_list_changed()
|
||||
|
||||
|
||||
func _create_single_anim(library: AnimationLibrary, anim_name: String, is_rigid: bool, is_mirror: bool):
|
||||
var anim = Animation.new()
|
||||
anim.length = anim_duration
|
||||
anim.step = 0.01
|
||||
|
||||
if library.has_animation(anim_name): library.remove_animation(anim_name)
|
||||
library.add_animation(anim_name, anim)
|
||||
|
||||
var sk_node = find_child(SKELETON_NAME, true, false)
|
||||
if not sk_node: return
|
||||
|
||||
var my_path = anim_player.get_node(anim_player.root_node).get_path_to(self)
|
||||
|
||||
var visible_col = Color(1, 1, 1, 1)
|
||||
var invisible_col = Color(1, 1, 1, 0)
|
||||
var faded_col = Color(1, 1, 1, 0.6)
|
||||
|
||||
var t_mid = anim_duration * 0.5
|
||||
var t_end_snap = anim_duration * 0.95
|
||||
|
||||
# ==========================================================================
|
||||
# 1. VISIBILITY & Z-INDEX
|
||||
# ==========================================================================
|
||||
var z_track = anim.add_track(Animation.TYPE_VALUE)
|
||||
anim.track_set_path(z_track, str(my_path) + ":z_index")
|
||||
anim.track_set_interpolation_type(z_track, Animation.INTERPOLATION_NEAREST)
|
||||
anim.track_insert_key(z_track, 0.0, 10)
|
||||
anim.track_insert_key(z_track, anim_duration * 0.15, 25)
|
||||
anim.track_insert_key(z_track, anim_duration * 0.65, 10)
|
||||
|
||||
# ==========================================================================
|
||||
# 2. BACKGROUND SHADOW
|
||||
# ==========================================================================
|
||||
var shadow_node = find_child(SHADOW_NAME, true, false)
|
||||
if shadow_node and enable_shadow:
|
||||
var shadow_path = anim_player.get_node(anim_player.root_node).get_path_to(shadow_node)
|
||||
var t_scale = anim.add_track(Animation.TYPE_VALUE)
|
||||
anim.track_set_path(t_scale, str(shadow_path) + ":scale")
|
||||
anim.track_set_interpolation_type(t_scale, Animation.INTERPOLATION_CUBIC)
|
||||
var t_mod = anim.add_track(Animation.TYPE_VALUE)
|
||||
anim.track_set_path(t_mod, str(shadow_path) + ":modulate")
|
||||
|
||||
var s_start = Vector2(-1.0, 1.0) if is_mirror else Vector2(1.0, 1.0)
|
||||
var s_end = Vector2(1.0, 1.0) if is_mirror else Vector2(-1.0, 1.0)
|
||||
|
||||
anim.track_insert_key(t_scale, 0.0, s_start)
|
||||
anim.track_insert_key(t_mod, 0.0, invisible_col)
|
||||
anim.track_insert_key(t_mod, anim_duration * 0.1, visible_col)
|
||||
|
||||
anim.track_insert_key(t_scale, t_mid, Vector2(0.01, 1.0))
|
||||
anim.track_insert_key(t_mod, t_mid, faded_col)
|
||||
|
||||
anim.track_insert_key(t_scale, t_end_snap, s_end)
|
||||
anim.track_insert_key(t_scale, anim_duration, s_end)
|
||||
anim.track_insert_key(t_mod, t_end_snap, invisible_col)
|
||||
anim.track_insert_key(t_mod, anim_duration, invisible_col)
|
||||
|
||||
# ==========================================================================
|
||||
# 3. BONE ANIMATION
|
||||
# ==========================================================================
|
||||
for y in range(subdivision_y + 1):
|
||||
var row_factor = 1.0
|
||||
if not is_rigid and curl_mode != CurlMode.STRAIGHT:
|
||||
var y_ratio = float(y) / float(max(1, subdivision_y))
|
||||
if curl_mode == CurlMode.TOP_CORNER_FIRST:
|
||||
row_factor = lerp(1.0, 1.0 - curl_lag, y_ratio)
|
||||
elif curl_mode == CurlMode.BOTTOM_CORNER_FIRST:
|
||||
row_factor = lerp(1.0 - curl_lag, 1.0, y_ratio)
|
||||
|
||||
var time_offset = (1.0 - row_factor) * (anim_duration * 0.1)
|
||||
|
||||
for x in range(subdivision_x + 1):
|
||||
var bone_name = "Bone_%d_%d" % [x, y]
|
||||
var bone = sk_node.find_child(bone_name, true, false)
|
||||
if not bone: continue
|
||||
|
||||
var t_idx = anim.add_track(Animation.TYPE_VALUE)
|
||||
var path = anim_player.get_node(anim_player.root_node).get_path_to(bone)
|
||||
anim.track_set_path(t_idx, str(path) + ":rotation_degrees")
|
||||
anim.track_set_interpolation_type(t_idx, Animation.INTERPOLATION_CUBIC)
|
||||
|
||||
var deg_flat_right = 0.0; var deg_flat_left = -179.9; var deg_mid = -90.0
|
||||
|
||||
if is_rigid:
|
||||
if x == 0:
|
||||
var s = deg_flat_left if is_mirror else deg_flat_right
|
||||
var e = deg_flat_right if is_mirror else deg_flat_left
|
||||
anim.track_insert_key(t_idx, 0.0, s)
|
||||
anim.track_insert_key(t_idx, anim_duration * 0.5, deg_mid)
|
||||
anim.track_insert_key(t_idx, anim_duration, e)
|
||||
else:
|
||||
anim.track_insert_key(t_idx, 0.0, 0.0)
|
||||
anim.track_insert_key(t_idx, anim_duration, 0.0)
|
||||
else:
|
||||
var x_ratio = float(x) / float(subdivision_x)
|
||||
var influence = pow(x_ratio, paper_stiffness)
|
||||
var t_lift = clamp((anim_duration * timing_peak_lift) + time_offset, 0.0, (anim_duration * 0.5) - 0.05)
|
||||
var t_mid_bone = anim_duration * 0.5
|
||||
var t_land = clamp((anim_duration * timing_peak_land) - time_offset, t_mid_bone + 0.05, anim_duration)
|
||||
|
||||
if x == 0:
|
||||
# ROOT BONE
|
||||
var s = deg_flat_left if is_mirror else deg_flat_right
|
||||
var e = deg_flat_right if is_mirror else deg_flat_left
|
||||
var sl = -15.0 * row_factor
|
||||
if is_mirror: sl = deg_flat_left - sl
|
||||
var slt = lerp(-90.0, -180.0, timing_peak_land)
|
||||
if is_mirror: slt = lerp(-90.0, 0.0, timing_peak_land)
|
||||
|
||||
anim.track_insert_key(t_idx, 0.0, s)
|
||||
anim.track_insert_key(t_idx, t_lift, sl)
|
||||
anim.track_insert_key(t_idx, t_mid_bone, deg_mid)
|
||||
anim.track_insert_key(t_idx, t_land, slt)
|
||||
|
||||
var t_settle = lerp(t_land, anim_duration, 0.7)
|
||||
var s_settle = lerp(slt, e, 0.85)
|
||||
anim.track_insert_key(t_idx, t_settle, s_settle)
|
||||
|
||||
anim.track_insert_key(t_idx, anim_duration, e)
|
||||
else:
|
||||
# SURFACE BONES (CURVED)
|
||||
var bm = -1.0 if is_mirror else 1.0
|
||||
|
||||
anim.track_insert_key(t_idx, 0.0, 0.0)
|
||||
anim.track_insert_key(t_idx, t_lift, lift_bend * row_factor * bm * influence)
|
||||
# REMOVED FORCED 0.0 AT MIDPOINT FOR ORGANIC CURVE
|
||||
|
||||
var val_land = land_bend * row_factor * bm * influence
|
||||
anim.track_insert_key(t_idx, t_land, val_land)
|
||||
|
||||
var t_settle = lerp(t_land, anim_duration, 0.75)
|
||||
anim.track_insert_key(t_idx, t_settle, val_land * 0.15)
|
||||
|
||||
anim.track_insert_key(t_idx, anim_duration, 0.0)
|
||||
|
||||
# ==========================================================================
|
||||
# 4. MAIN POLYGON SCALE ("SQUASH & STRETCH")
|
||||
# ==========================================================================
|
||||
if not is_rigid:
|
||||
var t_main_scale = anim.add_track(Animation.TYPE_VALUE)
|
||||
anim.track_set_path(t_main_scale, str(my_path) + ":scale")
|
||||
anim.track_set_interpolation_type(t_main_scale, Animation.INTERPOLATION_LINEAR)
|
||||
var squash_x = 0.88
|
||||
|
||||
anim.track_insert_key(t_main_scale, 0.0, Vector2(1, 1))
|
||||
anim.track_insert_key(t_main_scale, t_mid, Vector2(1, 1))
|
||||
anim.track_insert_key(t_main_scale, t_mid + (anim_duration * 0.1), Vector2(squash_x, 1))
|
||||
anim.track_insert_key(t_main_scale, anim_duration * 0.85, Vector2(1, 1))
|
||||
anim.track_insert_key(t_main_scale, anim_duration, Vector2(1, 1))
|
||||
|
||||
var method_track = anim.add_track(Animation.TYPE_METHOD)
|
||||
anim.track_set_path(method_track, str(my_path))
|
||||
anim.track_insert_key(method_track, anim_duration * 0.5, {"method": "_trigger_midpoint", "args": []})
|
||||
anim.track_insert_key(method_track, anim_duration, {"method": "_trigger_end", "args": []})
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# HELPER FUNCTIONS
|
||||
# ==============================================================================
|
||||
|
||||
func _trigger_midpoint(): emit_signal("change_page_requested")
|
||||
func _trigger_end(): emit_signal("end_animation")
|
||||
|
||||
|
||||
func _on_generate_pressed(val):
|
||||
if val:
|
||||
rebuild_all=false
|
||||
_clean_previous_rig()
|
||||
_create_rig_logic()
|
||||
_generate_animations_logic()
|
||||
|
||||
|
||||
func _on_anim_pressed(val):
|
||||
if val:
|
||||
generate_anims_btn=false
|
||||
if anim_player and skeleton!=NodePath(""):
|
||||
_generate_animations_logic()
|
||||
|
||||
|
||||
func _clean_previous_rig():
|
||||
for c in get_children():
|
||||
remove_child(c)
|
||||
c.free()
|
||||
var old_shadow = find_child(SHADOW_NAME, true, false)
|
||||
if old_shadow: old_shadow.free()
|
||||
clear_bones()
|
||||
skeleton = NodePath("")
|
||||
1
addons/PageFlip/page_rigger.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ce5ib2f4qff24
|
||||
@@ -15,8 +15,8 @@ var _enable_state_machine: bool = true
|
||||
@export var anim_player: AnimationPlayer
|
||||
|
||||
@export_group("Entities")
|
||||
enum EntityType { HUMANOID, ANIMAL }
|
||||
@export var entity_type: EntityType = EntityType.HUMANOID
|
||||
enum EntityType { FARMER, CITIZEN_WALKER, CITIZEN_SITTER, CAT, CROW, FOX, GOAT, RACOON, WAGYU }
|
||||
@export var entity_type: EntityType = EntityType.FARMER
|
||||
@export var entity_name: String = ""
|
||||
@export var allowed_biomes: Array[String] = []
|
||||
@export_range(0.0, 100.0, 0.1) var spawn_uniqueness: float = 1.0
|
||||
@@ -32,7 +32,8 @@ func _ready() -> void:
|
||||
toggle_enable_state_machine()
|
||||
|
||||
func toggle_enable_state_machine() -> void:
|
||||
state_machine.enable = _enable_state_machine
|
||||
if state_machine:
|
||||
state_machine.enable = _enable_state_machine
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if !_enable_state_machine:
|
||||
|
||||
38
core/ai/agents/cat/ai_cat.gd
Normal file
@@ -0,0 +1,38 @@
|
||||
extends AIBase
|
||||
|
||||
class_name AICat
|
||||
|
||||
@export_group("Cat Colors")
|
||||
@export var mesh: MeshInstance3D
|
||||
@export var fur_colors: Array[Color] = []
|
||||
@export var eye_colors: Array[Color] = []
|
||||
|
||||
@export var fur_material_index: int = 0
|
||||
@export var eye_material_index: int = 1
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
_apply_random_color()
|
||||
|
||||
func _apply_random_color() -> void:
|
||||
if fur_colors.is_empty() or eye_colors.is_empty():
|
||||
return
|
||||
|
||||
if not mesh or not mesh.mesh:
|
||||
return
|
||||
|
||||
var max_index = min(fur_colors.size(), eye_colors.size())
|
||||
var random_idx = randi() % max_index
|
||||
|
||||
_override_material_color(mesh, fur_material_index, fur_colors[random_idx])
|
||||
_override_material_color(mesh, eye_material_index, eye_colors[random_idx])
|
||||
|
||||
func _override_material_color(mesh_node: MeshInstance3D, surface_idx: int, color: Color) -> void:
|
||||
if surface_idx < 0 or surface_idx >= mesh_node.mesh.get_surface_count():
|
||||
return
|
||||
|
||||
var mat = mesh_node.mesh.surface_get_material(surface_idx)
|
||||
if mat and mat is StandardMaterial3D:
|
||||
var new_mat = mat.duplicate() as StandardMaterial3D
|
||||
new_mat.albedo_color = color
|
||||
mesh_node.set_surface_override_material(surface_idx, new_mat)
|
||||
1
core/ai/agents/cat/ai_cat.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cx67xas1hxv3x
|
||||
@@ -2,12 +2,63 @@
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://clx701xdwelgx" path="res://core/ai/agents/base/ai_base.tscn" id="1_85o24"]
|
||||
[ext_resource type="Script" uid="uid://d3hy70ec8vqo5" path="res://core/ai/framework/run_animation_state.gd" id="2_6mu8r"]
|
||||
[ext_resource type="Script" uid="uid://cx67xas1hxv3x" path="res://core/ai/agents/cat/ai_cat.gd" id="2_cat_script"]
|
||||
[ext_resource type="PackedScene" uid="uid://c5rccx22gs6jt" path="res://core/ai/agents/cat/Cat_rig.fbx" id="2_rohxe"]
|
||||
[ext_resource type="Script" uid="uid://bngfthvt04ivv" path="res://core/ai/framework/patrol_state.gd" id="3_0jm3k"]
|
||||
[ext_resource type="Script" uid="uid://dty1p02kqviwf" path="res://core/ai/framework/sit_state.gd" id="3_scd7t"]
|
||||
[ext_resource type="Shader" uid="uid://d0ch5ofrgf7y6" path="res://core/daynight/trunk_shader.gdshader" id="7_rxsfd"]
|
||||
|
||||
[node name="AiCat" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_85o24")]
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_1rb57"]
|
||||
render_priority = 0
|
||||
shader = ExtResource("7_rxsfd")
|
||||
shader_parameter/albedo_color = Color(0.7389186, 0.53468716, 0.19165063, 1)
|
||||
shader_parameter/use_texture = true
|
||||
shader_parameter/uv_scale = Vector2(1, 1)
|
||||
shader_parameter/palette_shift_y = 0.0
|
||||
shader_parameter/gradient_start_y = 0.0
|
||||
shader_parameter/gradient_end_y = 10.0
|
||||
shader_parameter/light_steps = 3.0
|
||||
shader_parameter/step_softness = 0.1
|
||||
shader_parameter/shadow_color = Color(0.4, 0.4, 0.6, 1)
|
||||
shader_parameter/shadow_offset = 0.0
|
||||
shader_parameter/cast_shadow_strength = 0.6
|
||||
shader_parameter/use_ghibli_glint = true
|
||||
shader_parameter/glint_color = Color(1, 0.95, 0.85, 1)
|
||||
shader_parameter/glint_intensity = 1.0
|
||||
shader_parameter/glint_sharpness = 32.0
|
||||
shader_parameter/emission_color = Color(0, 0, 0, 1)
|
||||
shader_parameter/emission_energy = 0.0
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_42ie3"]
|
||||
render_priority = 0
|
||||
shader = ExtResource("7_rxsfd")
|
||||
shader_parameter/albedo_color = Color(0.099985994, 0.09998601, 0.099985965, 1)
|
||||
shader_parameter/use_texture = true
|
||||
shader_parameter/uv_scale = Vector2(1, 1)
|
||||
shader_parameter/palette_shift_y = 0.0
|
||||
shader_parameter/gradient_start_y = 0.0
|
||||
shader_parameter/gradient_end_y = 10.0
|
||||
shader_parameter/light_steps = 3.0
|
||||
shader_parameter/step_softness = 0.1
|
||||
shader_parameter/shadow_color = Color(0.4, 0.4, 0.6, 1)
|
||||
shader_parameter/shadow_offset = 0.0
|
||||
shader_parameter/cast_shadow_strength = 0.6
|
||||
shader_parameter/use_ghibli_glint = true
|
||||
shader_parameter/glint_color = Color(1, 0.95, 0.85, 1)
|
||||
shader_parameter/glint_intensity = 1.0
|
||||
shader_parameter/glint_sharpness = 32.0
|
||||
shader_parameter/emission_color = Color(0, 0, 0, 1)
|
||||
shader_parameter/emission_energy = 0.0
|
||||
|
||||
[node name="AiCat" unique_id=1228675528 node_paths=PackedStringArray("mesh", "anim_player") instance=ExtResource("1_85o24")]
|
||||
script = ExtResource("2_cat_script")
|
||||
mesh = NodePath("Cat_rig/Rig_Cat/Skeleton3D/Cat")
|
||||
fur_colors = Array[Color]([Color(0.8716863, 0.762116, 0.1809479, 1)])
|
||||
eye_colors = Array[Color]([Color(0.12955844, 0.12955847, 0.12955844, 1), Color(0.6901961, 0.3019608, 0.12156863, 1), Color(0.6830768, 0.6830776, 0.68307686, 1), Color(0.6273405, 0.15743047, 0, 1)])
|
||||
fur_material_index = 0
|
||||
eye_material_index = 1
|
||||
anim_player = NodePath("Cat_rig/AnimationPlayer")
|
||||
entity_type = 1
|
||||
entity_type = 3
|
||||
entity_name = "Cat"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
@@ -17,9 +68,16 @@ initial_state = NodePath("IdleState")
|
||||
script = ExtResource("2_6mu8r")
|
||||
state_id = &"idle"
|
||||
next_state_id = &"patrol"
|
||||
random_next_state_ids = Array[StringName]([&"patrol", &"sit"])
|
||||
animation_name = "Cat_Idle"
|
||||
|
||||
[node name="PatrolState" type="Node" parent="StateMachine" index="1" unique_id=1861645340]
|
||||
[node name="SitState" type="Node" parent="StateMachine" index="1" unique_id=860354787]
|
||||
script = ExtResource("3_scd7t")
|
||||
state_id = &"sit"
|
||||
next_state_id = &"idle"
|
||||
animation_name = "Cat_Sit"
|
||||
|
||||
[node name="PatrolState" type="Node" parent="StateMachine" index="2" unique_id=1861645340]
|
||||
script = ExtResource("3_0jm3k")
|
||||
state_id = &"patrol"
|
||||
next_state_id = &"idle"
|
||||
@@ -28,7 +86,7 @@ exit_on_action_finished = true
|
||||
|
||||
[node name="Cat_rig" parent="." index="3" unique_id=1332997618 instance=ExtResource("2_rohxe")]
|
||||
|
||||
[node name="Skeleton3D" parent="Cat_rig/Rig_Cat" parent_id_path=PackedInt32Array(1332997618, 1292226211) index="0" unique_id=807490174]
|
||||
[node name="Skeleton3D" parent="Cat_rig/Rig_Cat" parent_id_path=PackedInt32Array(1332997618, 1024066488) index="0" unique_id=1455145313]
|
||||
bones/1/position = Vector3(1.6719584e-08, 0.23547882, 0.34218493)
|
||||
bones/1/rotation = Quaternion(0.12769094, -0.6954821, -0.12769029, 0.69548184)
|
||||
bones/2/rotation = Quaternion(-1.5819447e-07, -1.9079575e-07, -0.5904159, 0.8070992)
|
||||
@@ -57,4 +115,8 @@ bones/27/rotation = Quaternion(-8.140452e-08, 1.1560887e-07, -0.47071794, 0.8822
|
||||
bones/28/position = Vector3(0.18089616, -0.000116375166, 0.011642809)
|
||||
bones/28/rotation = Quaternion(4.5638826e-05, -8.8217595e-05, 0.5290293, 0.84860367)
|
||||
|
||||
[node name="Cat" parent="Cat_rig/Rig_Cat/Skeleton3D" index="0" unique_id=869144045]
|
||||
surface_material_override/0 = SubResource("ShaderMaterial_1rb57")
|
||||
surface_material_override/1 = SubResource("ShaderMaterial_42ie3")
|
||||
|
||||
[editable path="Cat_rig"]
|
||||
|
||||
@@ -7,18 +7,22 @@
|
||||
|
||||
[node name="AiCrow" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_tx3nx")]
|
||||
anim_player = NodePath("Crow_rig/AnimationPlayer")
|
||||
entity_type = 4
|
||||
entity_name = "Crow"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
initial_state = NodePath("WaitTrainState")
|
||||
|
||||
[node name="WaitTrainState" type="Node" parent="StateMachine" index="0" unique_id=1000000000]
|
||||
script = ExtResource("3_wait")
|
||||
fly_distance_threshold = 10.0
|
||||
state_id = &"wait"
|
||||
next_state_id = &"fly"
|
||||
animation_name = "Idle_Crow"
|
||||
|
||||
[node name="FlyAwayState" type="Node" parent="StateMachine" index="1" unique_id=1000000001]
|
||||
script = ExtResource("4_fly")
|
||||
destroy_after_seconds = 20.0
|
||||
state_id = &"fly"
|
||||
animation_name = "Fly_Crow"
|
||||
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
[ext_resource type="Script" uid="uid://b5y4u0itec8g1" path="res://core/ai/framework/run_state.gd" id="4_d1sp2"]
|
||||
|
||||
[node name="AiFox" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_m3efo")]
|
||||
navigation_layers = 4
|
||||
anim_player = NodePath("Fox_rig/AnimationPlayer")
|
||||
entity_type = 5
|
||||
entity_name = "Fox"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
initial_state = NodePath("IdleState")
|
||||
@@ -35,7 +38,7 @@ exit_on_action_finished = true
|
||||
|
||||
[node name="Fox_rig" parent="." index="3" unique_id=2044859181 instance=ExtResource("2_xaafp")]
|
||||
|
||||
[node name="Skeleton3D" parent="Fox_rig/Rig_Fox" parent_id_path=PackedInt32Array(2044859181, 1371677834) index="0" unique_id=625291101]
|
||||
[node name="Skeleton3D" parent="Fox_rig/Rig_Fox" parent_id_path=PackedInt32Array(2044859181, 975246732) index="0" unique_id=1559174379]
|
||||
bones/1/position = Vector3(1.2443564e-08, 0.24551632, 0.408434)
|
||||
bones/1/rotation = Quaternion(0.12769088, -0.6954821, -0.12769023, 0.69548184)
|
||||
bones/2/rotation = Quaternion(-1.492881e-07, -1.7862074e-07, -0.5904159, 0.8070992)
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
[node name="AiGoat" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_f7hhh")]
|
||||
anim_player = NodePath("Goat_rig/AnimationPlayer")
|
||||
entity_type = 6
|
||||
entity_name = "Goat"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
initial_state = NodePath("IdleState")
|
||||
@@ -26,7 +28,7 @@ exit_on_action_finished = true
|
||||
|
||||
[node name="Goat_rig" parent="." index="3" unique_id=1336829719 instance=ExtResource("2_oxwbf")]
|
||||
|
||||
[node name="Skeleton3D" parent="Goat_rig/Rig_Goat" parent_id_path=PackedInt32Array(1336829719, 1896192446) index="0" unique_id=1573667924]
|
||||
[node name="Skeleton3D" parent="Goat_rig/Rig_Goat" parent_id_path=PackedInt32Array(1336829719, 123281310) index="0" unique_id=1526518923]
|
||||
bones/1/position = Vector3(-8.352713e-09, 0.36986786, 0.8951362)
|
||||
bones/1/rotation = Quaternion(0.1276911, -0.695482, -0.12769035, 0.69548184)
|
||||
bones/2/rotation = Quaternion(-8.7811394e-08, -9.458198e-08, -0.5904155, 0.80709946)
|
||||
|
||||
BIN
core/ai/agents/human/Farmer1.fbx
Normal file
44
core/ai/agents/human/Farmer1.fbx.import
Normal file
@@ -0,0 +1,44 @@
|
||||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://b3j2dbcqwodx1"
|
||||
path="res://.godot/imported/Farmer1.fbx-c6b3fa9e901f9ab5b38c67c1343eab85.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/ai/agents/human/Farmer1.fbx"
|
||||
dest_files=["res://.godot/imported/Farmer1.fbx-c6b3fa9e901f9ab5b38c67c1343eab85.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=true
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
fbx/importer=0
|
||||
fbx/allow_geometry_helper_nodes=false
|
||||
fbx/embedded_image_handling=1
|
||||
fbx/naming_version=2
|
||||
BIN
core/ai/agents/human/Farmer2.fbx
Normal file
44
core/ai/agents/human/Farmer2.fbx.import
Normal file
@@ -0,0 +1,44 @@
|
||||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://c5x3ycaxixpxy"
|
||||
path="res://.godot/imported/Farmer2.fbx-da830fcedaed7d46b77458a4c0e1f611.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/ai/agents/human/Farmer2.fbx"
|
||||
dest_files=["res://.godot/imported/Farmer2.fbx-da830fcedaed7d46b77458a4c0e1f611.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=true
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
fbx/importer=0
|
||||
fbx/allow_geometry_helper_nodes=false
|
||||
fbx/embedded_image_handling=1
|
||||
fbx/naming_version=2
|
||||
@@ -3,6 +3,7 @@
|
||||
[ext_resource type="PackedScene" uid="uid://bdqeshcwwnyc4" path="res://core/ai/agents/human/ai_citizen.tscn" id="1_cduuu"]
|
||||
|
||||
[node name="AiCitizenSitter" unique_id=1228675528 instance=ExtResource("1_cduuu")]
|
||||
entity_type = 2
|
||||
entity_name = "CitizenSitter"
|
||||
|
||||
[node name="Skeleton3D" parent="BaseMesh/BaseMesh" parent_id_path=PackedInt32Array(1846171523, 1142246531) index="0" unique_id=928995817]
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[ext_resource type="Script" uid="uid://bngfthvt04ivv" path="res://core/ai/framework/patrol_state.gd" id="3_8d0tj"]
|
||||
|
||||
[node name="AiCitizenWalker" unique_id=1228675528 instance=ExtResource("1_dms8s")]
|
||||
entity_type = 1
|
||||
entity_name = "CitizenWalker"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
[ext_resource type="Script" uid="uid://d3hy70ec8vqo5" path="res://core/ai/framework/run_animation_state.gd" id="4_2oda6"]
|
||||
|
||||
[node name="AiFarmer" unique_id=1228675528 instance=ExtResource("1_l2y7m")]
|
||||
navigation_layers = 2
|
||||
entity_name = "Farmer"
|
||||
allowed_biomes = Array[String](["countryside"])
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
initial_state = NodePath("GatherState")
|
||||
initial_state = NodePath("IdleState")
|
||||
|
||||
[node name="PatrolState" type="Node" parent="StateMachine" index="0" unique_id=930272128]
|
||||
script = ExtResource("3_2oda6")
|
||||
@@ -33,8 +34,41 @@ state_id = &"idle"
|
||||
next_state_id = &"patrol"
|
||||
animation_name = "custom/idle"
|
||||
|
||||
[node name="Skeleton3D" parent="BaseMesh/BaseMesh" parent_id_path=PackedInt32Array(1846171523, 1142246531) index="0" unique_id=928995817]
|
||||
bones/8/rotation = Quaternion(-0.6173422, -0.37346625, 0.5666242, -0.3979305)
|
||||
bones/46/rotation = Quaternion(0.059241787, 0.12928401, 0.9836761, -0.110261135)
|
||||
[node name="Skeleton3D" parent="BaseMesh/BaseMesh" parent_id_path=PackedInt32Array(1846171523, 1363988051) index="0" unique_id=1848874512]
|
||||
bones/0/position = Vector3(-0.0015795716, 0.9761277, 0.0012886743)
|
||||
bones/0/rotation = Quaternion(0.008345705, 0.02440254, -0.0222881, 0.999419)
|
||||
bones/1/rotation = Quaternion(-0.033856627, 0.0019547925, 0.01148837, 0.9993588)
|
||||
bones/2/rotation = Quaternion(0.003385691, 0.0057030413, 0.004773842, 0.9999666)
|
||||
bones/3/rotation = Quaternion(0.0033856947, 0.0057030534, 0.0047738357, 0.9999666)
|
||||
bones/4/rotation = Quaternion(0.03554347, -0.0036022358, -0.01067691, 0.9993046)
|
||||
bones/5/rotation = Quaternion(0.023500564, -0.0268053, 0.016007349, 0.9992362)
|
||||
bones/8/rotation = Quaternion(-0.677935, -0.3162402, 0.5391133, -0.3869797)
|
||||
bones/9/rotation = Quaternion(0.33057448, -0.0144906035, -0.024771411, 0.9433436)
|
||||
bones/10/rotation = Quaternion(0.071588665, 0.16423635, 0.26876602, 0.9463965)
|
||||
bones/11/rotation = Quaternion(-0.11033899, 0.19317266, 0.18225361, 0.95775425)
|
||||
bones/12/rotation = Quaternion(0.28979003, -0.100065045, 0.021221647, 0.95160836)
|
||||
bones/13/rotation = Quaternion(-0.01075587, -0.003262491, 0.085242614, 0.9962969)
|
||||
bones/17/rotation = Quaternion(0.372185, -0.04203017, 0.003265603, 0.9272007)
|
||||
bones/18/rotation = Quaternion(0.6449709, -0.022805, 0.11591787, 0.7550203)
|
||||
bones/22/rotation = Quaternion(0.5152635, -0.09862117, 0.07484319, 0.8480425)
|
||||
bones/23/rotation = Quaternion(0.7634141, -0.01797779, 0.14009176, 0.63027775)
|
||||
bones/27/rotation = Quaternion(0.6460654, -0.34361044, 0.58023506, 0.35757324)
|
||||
bones/28/rotation = Quaternion(0.3564352, 0.033001784, 0.1479881, 0.9219352)
|
||||
bones/29/rotation = Quaternion(0.10407414, -0.119882874, -0.20823832, 0.96510804)
|
||||
bones/30/rotation = Quaternion(-0.040577345, -0.20657076, -0.14159827, 0.96728075)
|
||||
bones/31/rotation = Quaternion(0.18718895, 0.11185156, -0.005364931, 0.97592044)
|
||||
bones/32/rotation = Quaternion(0.077440694, -0.18545257, 0.02808432, 0.9791944)
|
||||
bones/36/rotation = Quaternion(0.33726785, 0.06133867, 0.07482985, 0.93642324)
|
||||
bones/37/rotation = Quaternion(0.5483169, 0.027307179, -0.058035128, 0.83380747)
|
||||
bones/41/rotation = Quaternion(0.4086348, 0.09420283, 0.037183065, 0.90706164)
|
||||
bones/42/rotation = Quaternion(0.59161603, 0.030198008, -0.037664413, 0.8047733)
|
||||
bones/46/rotation = Quaternion(0.060233127, 0.24369022, 0.966249, -0.05787964)
|
||||
bones/47/rotation = Quaternion(-0.56581247, 0.0105282655, -0.0027436528, 0.8244622)
|
||||
bones/48/rotation = Quaternion(0.46872035, 0.0146656195, -0.0033694527, 0.88321847)
|
||||
bones/49/rotation = Quaternion(0.49349385, 0.06718427, -0.01829647, 0.86695755)
|
||||
bones/52/rotation = Quaternion(-0.0765912, 0.12600712, 0.988389, -0.03665043)
|
||||
bones/53/rotation = Quaternion(-0.25056988, -0.06629382, 0.018621337, 0.96564656)
|
||||
bones/54/rotation = Quaternion(0.549743, -0.041815143, -0.046032935, 0.83301574)
|
||||
bones/55/rotation = Quaternion(0.3627838, -0.05369254, 0.01255593, 0.9302406)
|
||||
|
||||
[editable path="BaseMesh"]
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
[ext_resource type="Animation" uid="uid://ptj85lvvtjpg" path="res://core/ai/agents/human/sitting.res" id="4_8kg0q"]
|
||||
[ext_resource type="Animation" uid="uid://oq22ilhxjejj" path="res://core/ai/agents/human/idle.res" id="4_cuxdk"]
|
||||
[ext_resource type="Animation" uid="uid://6xnsf8x7nmsl" path="res://core/ai/agents/human/walking.res" id="6_cuxdk"]
|
||||
[ext_resource type="PackedScene" uid="uid://b3j2dbcqwodx1" path="res://core/ai/agents/human/Farmer1.fbx" id="7_hguxe"]
|
||||
[ext_resource type="PackedScene" uid="uid://c5x3ycaxixpxy" path="res://core/ai/agents/human/Farmer2.fbx" id="8_ke7sb"]
|
||||
[ext_resource type="Script" uid="uid://dauqq8cqmwrqh" path="res://core/ai/agents/human/dress_human.gd" id="9_2tpdi"]
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_8kg0q"]
|
||||
_data = {
|
||||
@@ -15,13 +18,79 @@ _data = {
|
||||
&"walking": ExtResource("6_cuxdk")
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ke7sb"]
|
||||
_data = {
|
||||
&"gathering": ExtResource("3_8kg0q"),
|
||||
&"idle": ExtResource("4_cuxdk"),
|
||||
&"sitting": ExtResource("4_8kg0q"),
|
||||
&"walking": ExtResource("6_cuxdk")
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_2tpdi"]
|
||||
_data = {
|
||||
&"gathering": ExtResource("3_8kg0q"),
|
||||
&"idle": ExtResource("4_cuxdk"),
|
||||
&"sitting": ExtResource("4_8kg0q"),
|
||||
&"walking": ExtResource("6_cuxdk")
|
||||
}
|
||||
|
||||
[node name="AiHuman" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_hko2w")]
|
||||
anim_player = NodePath("BaseMesh/AnimationPlayer")
|
||||
|
||||
[node name="BaseMesh" parent="." index="3" unique_id=1846171523 instance=ExtResource("3_ef4cu")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.9, 0)
|
||||
|
||||
[node name="Skeleton3D" parent="BaseMesh/BaseMesh" parent_id_path=PackedInt32Array(1846171523, 1142246531) index="0" unique_id=928995817]
|
||||
[node name="Skeleton3D" parent="BaseMesh/BaseMesh" parent_id_path=PackedInt32Array(1846171523, 2032005240) index="0" unique_id=1876883359]
|
||||
bones/0/position = Vector3(-0.0024333135, 0.9952637, 6.9276895e-05)
|
||||
bones/0/rotation = Quaternion(-0.0049152793, -0.050206795, -0.026513178, 0.99837476)
|
||||
bones/1/rotation = Quaternion(-0.025209453, 0.006135946, 0.009180705, 0.9996213)
|
||||
bones/2/rotation = Quaternion(0.020680578, 0.011754706, 0.015464293, 0.99959743)
|
||||
bones/3/rotation = Quaternion(0.020680578, 0.011754692, 0.015464287, 0.99959743)
|
||||
bones/4/rotation = Quaternion(-0.053108443, 0.009324013, 0.011697456, 0.9984768)
|
||||
bones/5/rotation = Quaternion(0.03947722, 0.0123098595, -0.024802445, 0.99883676)
|
||||
bones/8/rotation = Quaternion(-0.5728458, -0.38286844, 0.60871977, -0.39334446)
|
||||
bones/9/rotation = Quaternion(0.44939622, 0.29187396, 0.053696252, 0.84259677)
|
||||
bones/10/rotation = Quaternion(-0.013349593, 0.006303966, 0.231745, 0.97266454)
|
||||
bones/11/rotation = Quaternion(-0.13493852, -0.23365982, 0.088579476, 0.95882654)
|
||||
bones/12/rotation = Quaternion(0.1921569, 0.10821218, -0.024087887, 0.9750824)
|
||||
bones/13/rotation = Quaternion(0.025333803, 0.00917047, 0.048555605, 0.9984571)
|
||||
bones/14/rotation = Quaternion(-0.0120385215, 0.035021365, -0.027293455, 0.99894124)
|
||||
bones/17/rotation = Quaternion(0.09417869, -0.072669275, -0.17156787, 0.9779642)
|
||||
bones/18/rotation = Quaternion(0.14308922, 0.0019350327, -0.0097575225, 0.98965985)
|
||||
bones/19/rotation = Quaternion(0.114431076, 0.0009974723, -0.016153814, 0.99329937)
|
||||
bones/22/rotation = Quaternion(0.11025663, -0.026056329, -0.115814656, 0.9867886)
|
||||
bones/23/rotation = Quaternion(0.08941777, 0.0010620031, -0.023814844, 0.9957089)
|
||||
bones/24/rotation = Quaternion(0.18236126, 0.0039793584, -0.014504941, 0.9831166)
|
||||
bones/27/rotation = Quaternion(0.5637914, -0.40525162, 0.5912719, 0.41025364)
|
||||
bones/28/rotation = Quaternion(0.5117543, -0.062450167, 0.07040776, 0.8539615)
|
||||
bones/29/rotation = Quaternion(0.06749446, 0.22771753, -0.20722775, 0.9490237)
|
||||
bones/30/rotation = Quaternion(-0.0005478785, -0.33554533, -0.112540804, 0.93527734)
|
||||
bones/31/rotation = Quaternion(0.13877106, 0.12508087, 0.031252213, 0.9818965)
|
||||
bones/32/rotation = Quaternion(-0.01564488, 0.0028465544, -0.073795564, 0.9971466)
|
||||
bones/33/rotation = Quaternion(0.09055836, 0.16444178, -0.016598457, 0.9820808)
|
||||
bones/36/rotation = Quaternion(0.048626706, 0.08521321, 0.1502388, 0.98376954)
|
||||
bones/37/rotation = Quaternion(0.20746112, 0.00031290663, 0.0112788575, 0.97817826)
|
||||
bones/38/rotation = Quaternion(0.15843387, -0.0010695796, -0.0025179624, 0.9873659)
|
||||
bones/41/rotation = Quaternion(0.16202472, 0.04171574, 0.09497025, 0.98131984)
|
||||
bones/42/rotation = Quaternion(0.14799795, 0.00100551, 0.030993575, 0.9885015)
|
||||
bones/43/rotation = Quaternion(0.04765674, -0.005312021, -0.037802245, 0.9981341)
|
||||
bones/46/rotation = Quaternion(0.024758164, 0.13509843, 0.9874187, -0.07835583)
|
||||
bones/47/rotation = Quaternion(-0.1871983, 0.0008643933, -0.010582049, 0.98226476)
|
||||
bones/48/rotation = Quaternion(0.46037424, -0.13497493, 0.042778272, 0.87636036)
|
||||
bones/49/rotation = Quaternion(0.3209879, 0.038273156, 0.0024189365, 0.9463065)
|
||||
bones/52/rotation = Quaternion(-0.060150255, 0.009860813, 0.99663967, -0.05471906)
|
||||
bones/53/rotation = Quaternion(-0.10502596, -0.00032293255, 0.008123855, 0.9944363)
|
||||
bones/54/rotation = Quaternion(0.51151097, 0.066536464, -0.07767137, 0.8531686)
|
||||
bones/55/rotation = Quaternion(0.3453064, -0.067497015, 0.02391528, 0.93575406)
|
||||
|
||||
[node name="AnimationPlayer" parent="BaseMesh" index="1" unique_id=226905852]
|
||||
libraries/custom = SubResource("AnimationLibrary_8kg0q")
|
||||
|
||||
[node name="Farmer1" parent="." index="4" unique_id=925374995 instance=ExtResource("7_hguxe")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.9, 0)
|
||||
visible = false
|
||||
|
||||
[node name="Skeleton3D" parent="Farmer1/BaseMesh" parent_id_path=PackedInt32Array(925374995, 35893719) index="0" unique_id=264693097]
|
||||
bones/0/position = Vector3(0.00060560287, 0.9719096, 0.007789615)
|
||||
bones/0/rotation = Quaternion(-0.03158553, -0.024531638, -0.086598895, 0.9954402)
|
||||
bones/1/rotation = Quaternion(-0.068302006, -0.011589706, 0.088431515, 0.99367017)
|
||||
@@ -29,7 +98,7 @@ bones/2/rotation = Quaternion(0.013750468, -0.0028497525, 0.022636604, 0.9996452
|
||||
bones/3/rotation = Quaternion(0.014052153, -0.0046672956, 0.021981178, 0.99964875)
|
||||
bones/4/rotation = Quaternion(0.08060878, 0.0009885994, -0.05385771, 0.99528927)
|
||||
bones/5/rotation = Quaternion(-0.08819712, -0.010719821, 0.004734955, 0.9960341)
|
||||
bones/8/rotation = Quaternion(-0.5780019, -0.40066734, 0.5948007, -0.38934776)
|
||||
bones/8/rotation = Quaternion(-0.6173422, -0.37346625, 0.5666242, -0.3979305)
|
||||
bones/9/rotation = Quaternion(0.5403529, 0.038538188, -0.087646246, 0.8359735)
|
||||
bones/10/rotation = Quaternion(-0.009744837, 0.0007412914, 0.18789424, 0.98214066)
|
||||
bones/11/rotation = Quaternion(0.019992959, 0.15807849, 0.15262179, 0.9753554)
|
||||
@@ -55,7 +124,7 @@ bones/38/rotation = Quaternion(0.13336712, -0.0009009653, 0.002359003, 0.9910635
|
||||
bones/41/rotation = Quaternion(0.12012116, 0.015946638, 0.088212825, 0.9887037)
|
||||
bones/42/rotation = Quaternion(0.11693482, 0.00096280884, 0.06057904, 0.99128985)
|
||||
bones/43/rotation = Quaternion(0.22191456, 0.026510797, -0.016629422, 0.9745638)
|
||||
bones/46/rotation = Quaternion(0.00039673893, 0.021240532, 0.99960107, -0.018613452)
|
||||
bones/46/rotation = Quaternion(0.059241787, 0.12928401, 0.9836761, -0.110261135)
|
||||
bones/47/rotation = Quaternion(-0.34151906, -0.06546942, 0.0071559767, 0.93756455)
|
||||
bones/48/rotation = Quaternion(0.60213244, 0.010313871, -0.012120304, 0.7982376)
|
||||
bones/49/rotation = Quaternion(0.31586254, 0.059334766, -0.020474449, 0.9467265)
|
||||
@@ -64,7 +133,65 @@ bones/53/rotation = Quaternion(-0.20515193, 0.049833227, 0.0071537, 0.9774345)
|
||||
bones/54/rotation = Quaternion(0.55275166, -0.049315806, -0.007871797, 0.8318483)
|
||||
bones/55/rotation = Quaternion(0.326561, -0.058840513, 0.019667907, 0.9431378)
|
||||
|
||||
[node name="AnimationPlayer" parent="BaseMesh" index="1" unique_id=2096005878]
|
||||
libraries/custom = SubResource("AnimationLibrary_8kg0q")
|
||||
[node name="AnimationPlayer" parent="Farmer1" index="1" unique_id=1795570086]
|
||||
libraries/custom = SubResource("AnimationLibrary_ke7sb")
|
||||
|
||||
[node name="Farmer2" parent="." index="5" unique_id=1239853450 instance=ExtResource("8_ke7sb")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.9, 0)
|
||||
visible = false
|
||||
|
||||
[node name="Skeleton3D" parent="Farmer2/BaseMesh" parent_id_path=PackedInt32Array(1239853450, 2123768022) index="0" unique_id=1560566445]
|
||||
bones/0/position = Vector3(0.00060560287, 0.9719096, 0.007789615)
|
||||
bones/0/rotation = Quaternion(-0.03158553, -0.024531638, -0.086598895, 0.9954402)
|
||||
bones/1/rotation = Quaternion(-0.068302006, -0.011589706, 0.088431515, 0.99367017)
|
||||
bones/2/rotation = Quaternion(0.013750468, -0.0028497525, 0.022636604, 0.99964523)
|
||||
bones/3/rotation = Quaternion(0.014052153, -0.0046672956, 0.021981178, 0.99964875)
|
||||
bones/4/rotation = Quaternion(0.08060878, 0.0009885994, -0.05385771, 0.99528927)
|
||||
bones/5/rotation = Quaternion(-0.08819712, -0.010719821, 0.004734955, 0.9960341)
|
||||
bones/8/rotation = Quaternion(-0.6173422, -0.37346625, 0.5666242, -0.3979305)
|
||||
bones/9/rotation = Quaternion(0.5403529, 0.038538188, -0.087646246, 0.8359735)
|
||||
bones/10/rotation = Quaternion(-0.009744837, 0.0007412914, 0.18789424, 0.98214066)
|
||||
bones/11/rotation = Quaternion(0.019992959, 0.15807849, 0.15262179, 0.9753554)
|
||||
bones/12/rotation = Quaternion(0.11525436, -0.03521942, -0.0147265345, 0.9926023)
|
||||
bones/13/rotation = Quaternion(0.004553697, -0.0011956134, 0.0748576, 0.9971832)
|
||||
bones/14/rotation = Quaternion(-0.021573644, -0.09607655, -0.02610063, 0.9947978)
|
||||
bones/17/rotation = Quaternion(0.10615231, -0.012490018, -0.06538699, 0.9921191)
|
||||
bones/18/rotation = Quaternion(0.112639524, -0.0005986789, -0.020016164, 0.99343413)
|
||||
bones/19/rotation = Quaternion(0.13624819, 0.001439244, -0.018421004, 0.9905025)
|
||||
bones/22/rotation = Quaternion(0.051831737, -0.007218998, -0.063239366, 0.9966254)
|
||||
bones/23/rotation = Quaternion(0.12439526, 0.00031310506, -0.03746358, 0.99152523)
|
||||
bones/24/rotation = Quaternion(0.14832872, 0.0028264069, -0.017447466, 0.9887802)
|
||||
bones/27/rotation = Quaternion(0.6085938, -0.37735197, 0.5827399, 0.3842309)
|
||||
bones/28/rotation = Quaternion(0.42811802, -0.12440211, 0.04666202, 0.8939026)
|
||||
bones/29/rotation = Quaternion(-0.010464899, -0.0008133942, -0.24076757, 0.97052604)
|
||||
bones/30/rotation = Quaternion(0.01554073, -0.15455346, -0.11519627, 0.9811226)
|
||||
bones/31/rotation = Quaternion(0.109474085, 0.02398801, 0.02464503, 0.99339455)
|
||||
bones/32/rotation = Quaternion(-0.03558804, 0.04901748, 0.08471445, 0.9945624)
|
||||
bones/33/rotation = Quaternion(0.014632019, 0.019343862, -0.1317728, 0.9909832)
|
||||
bones/36/rotation = Quaternion(0.19392295, 0.020005528, 0.11780725, 0.973712)
|
||||
bones/37/rotation = Quaternion(0.090232305, 2.462184e-07, 0.01726049, 0.9957712)
|
||||
bones/38/rotation = Quaternion(0.13336712, -0.0009009653, 0.002359003, 0.9910635)
|
||||
bones/41/rotation = Quaternion(0.12012116, 0.015946638, 0.088212825, 0.9887037)
|
||||
bones/42/rotation = Quaternion(0.11693482, 0.00096280884, 0.06057904, 0.99128985)
|
||||
bones/43/rotation = Quaternion(0.22191456, 0.026510797, -0.016629422, 0.9745638)
|
||||
bones/46/rotation = Quaternion(0.059241787, 0.12928401, 0.9836761, -0.110261135)
|
||||
bones/47/rotation = Quaternion(-0.34151906, -0.06546942, 0.0071559767, 0.93756455)
|
||||
bones/48/rotation = Quaternion(0.60213244, 0.010313871, -0.012120304, 0.7982376)
|
||||
bones/49/rotation = Quaternion(0.31586254, 0.059334766, -0.020474449, 0.9467265)
|
||||
bones/52/rotation = Quaternion(-0.07240856, 0.034467246, 0.9931159, -0.085380435)
|
||||
bones/53/rotation = Quaternion(-0.20515193, 0.049833227, 0.0071537, 0.9774345)
|
||||
bones/54/rotation = Quaternion(0.55275166, -0.049315806, -0.007871797, 0.8318483)
|
||||
bones/55/rotation = Quaternion(0.326561, -0.058840513, 0.019667907, 0.9431378)
|
||||
|
||||
[node name="AnimationPlayer" parent="Farmer2" index="1" unique_id=916643412]
|
||||
libraries/custom = SubResource("AnimationLibrary_2tpdi")
|
||||
|
||||
[node name="DressHuman" type="Node3D" parent="." index="6" unique_id=107727715 node_paths=PackedStringArray("farmers", "main_anim_player")]
|
||||
script = ExtResource("9_2tpdi")
|
||||
farmers = [NodePath("../Farmer1"), NodePath("../Farmer2")]
|
||||
colors = Array[Color]([Color(0, 0, 0, 1), Color(1, 1, 1, 1), Color(1, 0, 0, 1), Color(0, 1, 0, 1), Color(0, 0, 1, 1)])
|
||||
main_anim_player = NodePath("../BaseMesh/AnimationPlayer")
|
||||
|
||||
[editable path="BaseMesh"]
|
||||
[editable path="Farmer1"]
|
||||
[editable path="Farmer2"]
|
||||
|
||||
59
core/ai/agents/human/dress_human.gd
Normal file
@@ -0,0 +1,59 @@
|
||||
extends Node
|
||||
|
||||
@export var farmers: Array[Node3D]
|
||||
@export var colors: Array[Color]
|
||||
|
||||
@export var main_anim_player: AnimationPlayer
|
||||
var dress_anim_player: AnimationPlayer
|
||||
|
||||
func _ready() -> void:
|
||||
if farmers.is_empty():
|
||||
return
|
||||
|
||||
for farmer in farmers:
|
||||
if farmer:
|
||||
farmer.hide()
|
||||
|
||||
var selected_farmer = farmers.pick_random()
|
||||
if selected_farmer:
|
||||
selected_farmer.show()
|
||||
|
||||
dress_anim_player = selected_farmer.get_node_or_null("AnimationPlayer")
|
||||
|
||||
if main_anim_player and dress_anim_player:
|
||||
main_anim_player.current_animation_changed.connect(_on_animation_sync)
|
||||
main_anim_player.animation_started.connect(_on_animation_sync)
|
||||
|
||||
if main_anim_player.current_animation != "":
|
||||
_on_animation_sync(main_anim_player.current_animation)
|
||||
dress_anim_player.seek(main_anim_player.current_animation_position)
|
||||
|
||||
if colors.size() > 0:
|
||||
var parts_to_color = ["pants", "shirt"]
|
||||
var shared_color = colors.pick_random()
|
||||
|
||||
for part_name in parts_to_color:
|
||||
var piece_node = _find_mesh_case_insensitive(selected_farmer, part_name)
|
||||
|
||||
if piece_node:
|
||||
var mat = StandardMaterial3D.new()
|
||||
mat.albedo_color = shared_color
|
||||
|
||||
piece_node.set_surface_override_material(0, mat)
|
||||
|
||||
func _on_animation_sync(anim_name: StringName) -> void:
|
||||
if dress_anim_player and dress_anim_player.has_animation(anim_name):
|
||||
dress_anim_player.play(anim_name)
|
||||
dress_anim_player.speed_scale = main_anim_player.speed_scale
|
||||
|
||||
func _find_mesh_case_insensitive(parent: Node, part_name: String) -> MeshInstance3D:
|
||||
var target = part_name.to_lower()
|
||||
for child in parent.get_children():
|
||||
if child.name.to_lower().contains(target) and child is MeshInstance3D:
|
||||
return child
|
||||
|
||||
var found = _find_mesh_case_insensitive(child, target)
|
||||
if found:
|
||||
return found
|
||||
|
||||
return null
|
||||
1
core/ai/agents/human/dress_human.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dauqq8cqmwrqh
|
||||
@@ -6,7 +6,10 @@
|
||||
[ext_resource type="Script" uid="uid://bngfthvt04ivv" path="res://core/ai/framework/patrol_state.gd" id="3_x67t3"]
|
||||
|
||||
[node name="AiRacoon" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_seif5")]
|
||||
navigation_layers = 4
|
||||
anim_player = NodePath("Raccoon_rig/AnimationPlayer")
|
||||
entity_type = 7
|
||||
entity_name = "Racoon"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
initial_state = NodePath("IdleState")
|
||||
@@ -26,7 +29,7 @@ exit_on_action_finished = true
|
||||
|
||||
[node name="Raccoon_rig" parent="." index="3" unique_id=338211330 instance=ExtResource("2_obtl0")]
|
||||
|
||||
[node name="Skeleton3D" parent="Raccoon_rig/Rig_Raccoon" parent_id_path=PackedInt32Array(338211330, 1484615769) index="0" unique_id=689430915]
|
||||
[node name="Skeleton3D" parent="Raccoon_rig/Rig_Raccoon" parent_id_path=PackedInt32Array(338211330, 1450300070) index="0" unique_id=745849430]
|
||||
bones/1/position = Vector3(2.0224038e-08, 0.20926544, 0.2908604)
|
||||
bones/1/rotation = Quaternion(0.12769087, -0.6954821, -0.12769023, 0.69548184)
|
||||
bones/1/scale = Vector3(1, 0.99999994, 0.99999994)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
[node name="AiWagyu" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_01jto")]
|
||||
anim_player = NodePath("Wagyu_rig/AnimationPlayer")
|
||||
entity_type = 1
|
||||
entity_type = 8
|
||||
entity_name = "Wagyu"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
|
||||
40
core/ai/framework/sit_state.gd
Normal file
@@ -0,0 +1,40 @@
|
||||
extends State
|
||||
|
||||
class_name SitState
|
||||
|
||||
var reverse: bool = false
|
||||
|
||||
func enter() -> void:
|
||||
reverse = false
|
||||
super.enter()
|
||||
|
||||
if agent.anim_player and not agent.anim_player.animation_finished.is_connected(_on_animation_finished):
|
||||
agent.anim_player.animation_finished.connect(_on_animation_finished)
|
||||
|
||||
if runtime_timer and not runtime_timer.is_stopped():
|
||||
runtime_timer.stop()
|
||||
|
||||
run_animation()
|
||||
|
||||
func exit() -> void:
|
||||
super.exit()
|
||||
if agent.anim_player and agent.anim_player.animation_finished.is_connected(_on_animation_finished):
|
||||
agent.anim_player.animation_finished.disconnect(_on_animation_finished)
|
||||
|
||||
func _on_animation_finished(anim_name: StringName) -> void:
|
||||
if animation_name == anim_name:
|
||||
if not reverse:
|
||||
if min_wait_time > 0:
|
||||
var wait_time := randf_range(min_wait_time, max_wait_time)
|
||||
runtime_timer.start(wait_time)
|
||||
else:
|
||||
_on_timer_timeout()
|
||||
else:
|
||||
transitioned.emit(self, get_next_state())
|
||||
|
||||
func _on_timer_timeout() -> void:
|
||||
reverse = true
|
||||
if agent.anim_player and agent.anim_player.has_animation(animation_name):
|
||||
agent.anim_player.play_backwards(animation_name, blend_time)
|
||||
else:
|
||||
transitioned.emit(self, get_next_state())
|
||||
1
core/ai/framework/sit_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dty1p02kqviwf
|
||||
@@ -4,11 +4,6 @@ extends Node3D
|
||||
const CHUNK_TYPE_BIOME: int = 0
|
||||
const CHUNK_TYPE_STRAIGHT_TRACK: int = 1
|
||||
const CHUNK_TYPE_CURVED_TRACK: int = 2
|
||||
const ENTITY_TYPE_HUMANOID: int = 0
|
||||
const ENTITY_TYPE_ANIMAL: int = 1
|
||||
const ENTITY_SPAWN_ANY: int = 0
|
||||
const ENTITY_SPAWN_HUMANOID_ONLY: int = 1
|
||||
const ENTITY_SPAWN_ANIMAL_ONLY: int = 2
|
||||
|
||||
const CHUNK_GENERATION_FRAME_BUDGET_USEC: int = 1000 #2 ms/frame to generate chunks
|
||||
const CHUNK_CLEANUP_FRAME_BUDGET_USEC: int = 1000 #1 ms/frame per cleanup
|
||||
@@ -922,11 +917,10 @@ func _spawn_entities_for_chunk(root: Node, biome_name: String) -> void:
|
||||
|
||||
func _get_spawn_point_type_filter(spawn_point: Node) -> int:
|
||||
if "allowed_type" in spawn_point:
|
||||
match spawn_point.allowed_type:
|
||||
ENTITY_SPAWN_HUMANOID_ONLY:
|
||||
return ENTITY_TYPE_HUMANOID
|
||||
ENTITY_SPAWN_ANIMAL_ONLY:
|
||||
return ENTITY_TYPE_ANIMAL
|
||||
if spawn_point.allowed_type == 0:
|
||||
return -1
|
||||
else:
|
||||
return spawn_point.allowed_type - 1
|
||||
return -1
|
||||
|
||||
func _pick_compatible_entity(biome_name: String, type_filter: int) -> PackedScene:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extends Marker3D
|
||||
class_name EntitySpawnPoint
|
||||
|
||||
enum AllowedType { ANY, HUMANOID_ONLY, ANIMAL_ONLY }
|
||||
enum AllowedType { ANY, FARMER, CITIZEN_WALKER, CITIZEN_SITTER, CAT, CROW, FOX, GOAT, RACOON, WAGYU }
|
||||
|
||||
@export var allowed_type: AllowedType = AllowedType.ANY
|
||||
@export_range(0.0, 1.0, 0.01) var spawn_chance: float = 1.0
|
||||
|
||||
@@ -392,7 +392,14 @@ func train_move(delta: float) -> void:
|
||||
|
||||
#Calculate train distance for steam stats
|
||||
func _track_steam_distance(distance_units: float) -> void:
|
||||
if distance_units <= 0.0 or not SteamManager.is_on_steam:
|
||||
if distance_units <= 0.0:
|
||||
return
|
||||
|
||||
# Always track the global distance in our save file (for UI and persistency)
|
||||
GameState.save_data.total_distance_km += distance_units * DISTANCE_KM_PER_UNIT
|
||||
|
||||
# Steam specific logic
|
||||
if not SteamManager.is_on_steam:
|
||||
return
|
||||
|
||||
_pending_steam_distance_km += distance_units * DISTANCE_KM_PER_UNIT
|
||||
|
||||
@@ -12,6 +12,10 @@ var environment_config: EnvironmentConfig
|
||||
@export var time_scale: float = 1.0
|
||||
@export var paused: bool = false
|
||||
|
||||
var _time_tween: Tween
|
||||
|
||||
var time_transition_duration: float = 2
|
||||
|
||||
signal time_changed(time: float)
|
||||
|
||||
var current_time: float = 0.0
|
||||
@@ -67,16 +71,30 @@ func get_time_option_index(currtime: float) -> int:
|
||||
return TIME_OPTION_DAY
|
||||
return TIME_OPTION_SUNSET
|
||||
|
||||
|
||||
|
||||
func _time_option_changed(index: int) -> void:
|
||||
var target_time: float = 0.0
|
||||
match index:
|
||||
TIME_OPTION_SUNRISE:
|
||||
set_time(environment_config.sunrise)
|
||||
target_time = environment_config.sunrise
|
||||
TIME_OPTION_DAY:
|
||||
set_time(environment_config.day)
|
||||
target_time = environment_config.day
|
||||
TIME_OPTION_SUNSET:
|
||||
set_time(environment_config.sunset)
|
||||
target_time = environment_config.sunset
|
||||
TIME_OPTION_NIGHT:
|
||||
set_time(environment_config.night)
|
||||
target_time = environment_config.night
|
||||
|
||||
if _time_tween:
|
||||
_time_tween.kill()
|
||||
|
||||
_time_tween = create_tween()
|
||||
|
||||
# Always move forward in time for a natural transition
|
||||
if target_time < current_time:
|
||||
target_time += 1.0
|
||||
|
||||
_time_tween.tween_method(set_time, current_time, target_time, time_transition_duration)
|
||||
|
||||
func _on_set_day_time(value: float) -> void:
|
||||
set_time(value)
|
||||
|
||||
BIN
core/game_menu/assets/page.png
Normal file
|
After Width: | Height: | Size: 583 KiB |
40
core/game_menu/assets/page.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://kvn5l0n11a3q"
|
||||
path="res://.godot/imported/page.png-6c8405fbc970a849a62cab2019c549ca.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page.png"
|
||||
dest_files=["res://.godot/imported/page.png-6c8405fbc970a849a62cab2019c549ca.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
|
||||
BIN
core/game_menu/assets/page_1/1_dx.png
Normal file
|
After Width: | Height: | Size: 133 KiB |
40
core/game_menu/assets/page_1/1_dx.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dyvwywse5raqt"
|
||||
path="res://.godot/imported/1_dx.png-72d52e4e36c6fed20f7226414ff0abd6.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_1/1_dx.png"
|
||||
dest_files=["res://.godot/imported/1_dx.png-72d52e4e36c6fed20f7226414ff0abd6.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
|
||||
BIN
core/game_menu/assets/page_1/1_sx.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
40
core/game_menu/assets/page_1/1_sx.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dbpfa1xgxxn8s"
|
||||
path="res://.godot/imported/1_sx.png-f04965d63490ae436799d59856936013.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_1/1_sx.png"
|
||||
dest_files=["res://.godot/imported/1_sx.png-f04965d63490ae436799d59856936013.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
|
||||
BIN
core/game_menu/assets/page_1/barretta_main.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
40
core/game_menu/assets/page_1/barretta_main.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d2s020wikunuo"
|
||||
path="res://.godot/imported/barretta_main.png-d118ead98672de7a9802ba85eaf04053.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_1/barretta_main.png"
|
||||
dest_files=["res://.godot/imported/barretta_main.png-d118ead98672de7a9802ba85eaf04053.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
|
||||
BIN
core/game_menu/assets/page_1/barretta_second.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
40
core/game_menu/assets/page_1/barretta_second.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ct7o3u6i5rka6"
|
||||
path="res://.godot/imported/barretta_second.png-7f0af7da51c3ebb821e017a3fe148c6e.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_1/barretta_second.png"
|
||||
dest_files=["res://.godot/imported/barretta_second.png-7f0af7da51c3ebb821e017a3fe148c6e.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
|
||||
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
BIN
core/game_menu/assets/page_1/rings.png
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
40
core/game_menu/assets/page_1/rings.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://clvc6nlbgyvp1"
|
||||
path="res://.godot/imported/rings.png-21117a64acb1855b44e3ce941dd421bd.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_1/rings.png"
|
||||
dest_files=["res://.godot/imported/rings.png-21117a64acb1855b44e3ce941dd421bd.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
|
||||
BIN
core/game_menu/assets/page_2/2_dx.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
40
core/game_menu/assets/page_2/2_dx.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://drwe2xcnp8vs1"
|
||||
path="res://.godot/imported/2_dx.png-1c9a95db875176635d05c1084fc67cb1.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_2/2_dx.png"
|
||||
dest_files=["res://.godot/imported/2_dx.png-1c9a95db875176635d05c1084fc67cb1.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
|
||||
BIN
core/game_menu/assets/page_2/2_sx.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
40
core/game_menu/assets/page_2/2_sx.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cgllgxrstcoy7"
|
||||
path="res://.godot/imported/2_sx.png-396d61afe82f03c22efe87c2626240ae.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_2/2_sx.png"
|
||||
dest_files=["res://.godot/imported/2_sx.png-396d61afe82f03c22efe87c2626240ae.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
|
||||
BIN
core/game_menu/assets/page_3/3_dx.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
40
core/game_menu/assets/page_3/3_dx.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b6ae0kp1m0x74"
|
||||
path="res://.godot/imported/3_dx.png-c85d01f060ffa9993163c423a29a54fc.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/3_dx.png"
|
||||
dest_files=["res://.godot/imported/3_dx.png-c85d01f060ffa9993163c423a29a54fc.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
|
||||
BIN
core/game_menu/assets/page_3/3_sx.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
40
core/game_menu/assets/page_3/3_sx.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://diuai5vtjx23l"
|
||||
path="res://.godot/imported/3_sx.png-537fe112f093326f28478c136b142922.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/3_sx.png"
|
||||
dest_files=["res://.godot/imported/3_sx.png-537fe112f093326f28478c136b142922.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
|
||||
BIN
core/game_menu/assets/page_3/coming_soon_01.png
Normal file
|
After Width: | Height: | Size: 143 KiB |
40
core/game_menu/assets/page_3/coming_soon_01.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://vg5y4qgc26ko"
|
||||
path="res://.godot/imported/coming_soon_01.png-25c9049aaff7242878eb6f73c7097db7.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/coming_soon_01.png"
|
||||
dest_files=["res://.godot/imported/coming_soon_01.png-25c9049aaff7242878eb6f73c7097db7.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
|
||||
BIN
core/game_menu/assets/page_3/coming_soon_02.png
Normal file
|
After Width: | Height: | Size: 140 KiB |
40
core/game_menu/assets/page_3/coming_soon_02.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bmatlcouch6jm"
|
||||
path="res://.godot/imported/coming_soon_02.png-3a0cf6d408d00a891bcda63b2e091de2.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/coming_soon_02.png"
|
||||
dest_files=["res://.godot/imported/coming_soon_02.png-3a0cf6d408d00a891bcda63b2e091de2.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
|
||||
BIN
core/game_menu/assets/page_3/coming_soon_03.png
Normal file
|
After Width: | Height: | Size: 140 KiB |
40
core/game_menu/assets/page_3/coming_soon_03.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bm55xiv8jgnni"
|
||||
path="res://.godot/imported/coming_soon_03.png-57925084415215faf6655b4afb668ed8.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/coming_soon_03.png"
|
||||
dest_files=["res://.godot/imported/coming_soon_03.png-57925084415215faf6655b4afb668ed8.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
|
||||
BIN
core/game_menu/assets/page_3/coming_soon_04.png
Normal file
|
After Width: | Height: | Size: 145 KiB |
40
core/game_menu/assets/page_3/coming_soon_04.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cj81qdlrulal2"
|
||||
path="res://.godot/imported/coming_soon_04.png-8f40cb1c6984110b3c2b3d9c3c9c8658.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/coming_soon_04.png"
|
||||
dest_files=["res://.godot/imported/coming_soon_04.png-8f40cb1c6984110b3c2b3d9c3c9c8658.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
|
||||
BIN
core/game_menu/assets/page_3/coming_soon_05.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
40
core/game_menu/assets/page_3/coming_soon_05.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://biu4i40ck272q"
|
||||
path="res://.godot/imported/coming_soon_05.png-ac2ff567503cb2e314861075714ac8fb.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/coming_soon_05.png"
|
||||
dest_files=["res://.godot/imported/coming_soon_05.png-ac2ff567503cb2e314861075714ac8fb.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
|
||||
|
Before Width: | Height: | Size: 1.7 MiB |
@@ -2,7 +2,7 @@
|
||||
|
||||
[ext_resource type="Script" uid="uid://c7q3d823b1v1h" path="res://core/game_menu/biome_picker.gd" id="1_jqji0"]
|
||||
[ext_resource type="Texture2D" uid="uid://dc0sl04wem136" path="res://core/game_menu/assets/page_1/color_main_biome.png" id="2_8s4h5"]
|
||||
[ext_resource type="Texture2D" uid="uid://dj6pt25w5i4jq" path="res://core/game_menu/assets/page_1/lucchetto.png" id="2_jqji0"]
|
||||
[ext_resource type="Texture2D" uid="uid://bx6gsh5uchkge" path="res://core/game_menu/assets/lock.png" id="3_jqji0"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_jqji0"]
|
||||
|
||||
@@ -65,18 +65,19 @@ stretch_mode = 3
|
||||
[node name="TextureRect" type="TextureRect" parent="Texture" unique_id=288045010]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.36645964
|
||||
anchor_top = 0.41690964
|
||||
anchor_right = 0.6335404
|
||||
anchor_bottom = 0.58309036
|
||||
offset_left = 1.5
|
||||
offset_top = 8.5
|
||||
offset_right = -1.5
|
||||
offset_bottom = -8.5
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -26.8755
|
||||
offset_top = -34.375504
|
||||
offset_right = 26.8755
|
||||
offset_bottom = 34.375504
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("2_jqji0")
|
||||
texture = ExtResource("3_jqji0")
|
||||
expand_mode = 1
|
||||
|
||||
[connection signal="pressed" from="." to="." method="_on_pressed"]
|
||||
|
||||
@@ -19,6 +19,8 @@ func setup() -> void:
|
||||
_add_collectible(collectible)
|
||||
if unlocked_collectible_ids.has(collectible.id):
|
||||
_unlock_collectible(collectible.id)
|
||||
if is_inside_tree():
|
||||
await get_tree().process_frame
|
||||
|
||||
func on_collectible_unlocked(collectible_id: StringName) -> void:
|
||||
_unlock_collectible(collectible_id)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
extends Control
|
||||
|
||||
@onready var tabs: Array[GameMenuTab] = [$%Tab1, $%Tab2, $%Tab3]
|
||||
@onready var pages: Array[GameMenuPage] = [$%Page1, $%Page2, $%Page3]
|
||||
var current_index = 0
|
||||
|
||||
func _ready() -> void:
|
||||
for tab: GameMenuTab in tabs:
|
||||
@@ -10,10 +8,12 @@ func _ready() -> void:
|
||||
|
||||
on_tab_pressed(0, true)
|
||||
|
||||
|
||||
|
||||
func on_tab_pressed(index: int, disable_animation: bool = false) -> void:
|
||||
for page in pages:
|
||||
page.hide_page()
|
||||
|
||||
if BookAPI.is_busy() and not disable_animation:
|
||||
return
|
||||
|
||||
for tab in tabs:
|
||||
if tab.index == index:
|
||||
if disable_animation:
|
||||
@@ -25,9 +25,5 @@ func on_tab_pressed(index: int, disable_animation: bool = false) -> void:
|
||||
tab.deselect_without_animation()
|
||||
else:
|
||||
tab.deselect()
|
||||
|
||||
pages[index].show_page()
|
||||
current_index = index
|
||||
|
||||
func open() -> void:
|
||||
pages[current_index].show_page()
|
||||
BookAPI.go_to_page((index + 1) * 2)
|
||||
|
||||
@@ -3,7 +3,7 @@ extends Control
|
||||
@onready var photo: Photo = $%Photo
|
||||
@onready var panel: Panel = $%Panel
|
||||
|
||||
|
||||
var is_closing: bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
GameState.on_photo_highlighted.connect(_on_photo_highlighted)
|
||||
@@ -15,10 +15,13 @@ func _on_photo_highlighted(texture: Texture) -> void:
|
||||
TweenFX.fold_in(photo)
|
||||
photo.setup(texture)
|
||||
|
||||
|
||||
var is_closing: bool = false
|
||||
|
||||
func _on_panel_gui_input(event: InputEvent) -> void:
|
||||
func _input(event: InputEvent) -> void:
|
||||
if not visible:
|
||||
return
|
||||
|
||||
if event is InputEventMouse:
|
||||
get_viewport().set_input_as_handled()
|
||||
|
||||
if is_closing:
|
||||
return
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
|
||||
@@ -25,9 +25,11 @@ grow_vertical = 2
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchor_left = 0.3625
|
||||
anchor_top = 0.14351852
|
||||
anchor_top = 0.21481481
|
||||
anchor_right = 0.6375
|
||||
anchor_bottom = 0.8564815
|
||||
anchor_bottom = 0.78518516
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="ColorRect" parent="Photo" index="0" unique_id=1208008621]
|
||||
@@ -37,6 +39,10 @@ offset_top = 0.0
|
||||
offset_right = 0.0
|
||||
offset_bottom = 0.0
|
||||
|
||||
[connection signal="gui_input" from="Panel" to="." method="_on_panel_gui_input"]
|
||||
[node name="MarginContainer" parent="Photo/ColorRect" index="0" unique_id=1141643525]
|
||||
theme_override_constants/margin_left = 20
|
||||
theme_override_constants/margin_top = 30
|
||||
theme_override_constants/margin_right = 20
|
||||
theme_override_constants/margin_bottom = 185
|
||||
|
||||
[editable path="Photo"]
|
||||
|
||||
@@ -11,6 +11,7 @@ func _ready() -> void:
|
||||
play_button.pressed.connect(_on_play_button_pressed)
|
||||
save_button.pressed.connect(_on_save_button_pressed)
|
||||
quit_button.pressed.connect(_on_quit_button_pressed)
|
||||
resume_button.pressed.connect(func(): UIEvents.resume_game_requested.emit())
|
||||
|
||||
func _on_play_button_pressed() -> void:
|
||||
SceneManager.change_scene(SceneConfig.SceneName.GAME)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://id854u4gh12f" path="res://core/game_menu/page.tscn" id="1_uxih6"]
|
||||
[ext_resource type="Texture2D" uid="uid://bd80xo2id3xdm" path="res://core/game_menu/assets/decoration_page1.png" id="2_3i50p"]
|
||||
[ext_resource type="PackedScene" uid="uid://bh1kxsp5jyxfx" path="res://core/game_menu/train_selector.tscn" id="3_ijm38"]
|
||||
[ext_resource type="PackedScene" uid="uid://bc60gon7fmvbr" path="res://core/game_menu/biome_selector.tscn" id="12_7yi8x"]
|
||||
|
||||
[node name="Page1" unique_id=2037261222 instance=ExtResource("1_uxih6")]
|
||||
anchors_preset = 15
|
||||
@@ -16,6 +14,7 @@ grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="Background" parent="." index="0" unique_id=1203110384]
|
||||
visible = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
@@ -36,17 +35,3 @@ pivot_offset_ratio = Vector2(0.5, 0.5)
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("2_3i50p")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="TrainSelector" parent="." index="2" unique_id=1039769375 instance=ExtResource("3_ijm38")]
|
||||
layout_mode = 0
|
||||
offset_left = 211.0
|
||||
offset_top = 365.0
|
||||
offset_right = 871.0
|
||||
offset_bottom = 758.0
|
||||
|
||||
[node name="BiomeSelector" parent="." index="3" unique_id=1957954960 instance=ExtResource("12_7yi8x")]
|
||||
layout_mode = 0
|
||||
offset_left = 1038.0
|
||||
offset_top = 365.0
|
||||
offset_right = 1738.0
|
||||
offset_bottom = 783.0
|
||||
|
||||
52
core/game_menu/page_1_left.tscn
Normal file
@@ -0,0 +1,52 @@
|
||||
[gd_scene format=3 uid="uid://h8hbdm1uno7q"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://0yyr318wl7co" path="res://core/game_menu/page_interactive.gd" id="1_script"]
|
||||
[ext_resource type="PackedScene" uid="uid://bh1kxsp5jyxfx" path="res://core/game_menu/train_selector.tscn" id="2_train"]
|
||||
[ext_resource type="Texture2D" uid="uid://kvn5l0n11a3q" path="res://core/game_menu/assets/page.png" id="3_page_bg"]
|
||||
[ext_resource type="Texture2D" uid="uid://dbpfa1xgxxn8s" path="res://core/game_menu/assets/page_1/1_sx.png" id="3_sm65a"]
|
||||
|
||||
[node name="Page1Left" type="Control" unique_id=1881242741]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_right = -1160.0
|
||||
offset_bottom = -506.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="PageBackground" type="TextureRect" parent="." unique_id=820333238]
|
||||
layout_mode = 1
|
||||
anchors_preset = 9
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 760.0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_page_bg")
|
||||
expand_mode = 1
|
||||
flip_h = true
|
||||
|
||||
[node name="PageBackground2" type="TextureRect" parent="." unique_id=1693418558]
|
||||
layout_mode = 1
|
||||
anchors_preset = 9
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 760.0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_sm65a")
|
||||
|
||||
[node name="TrainSelector" parent="." unique_id=2114418660 instance=ExtResource("2_train")]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -346.0
|
||||
offset_top = -154.5
|
||||
offset_right = 279.0
|
||||
offset_bottom = 154.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
58
core/game_menu/page_1_right.tscn
Normal file
@@ -0,0 +1,58 @@
|
||||
[gd_scene format=3 uid="uid://d06kfd33fgepf"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://0yyr318wl7co" path="res://core/game_menu/page_interactive.gd" id="1_script"]
|
||||
[ext_resource type="PackedScene" uid="uid://bc60gon7fmvbr" path="res://core/game_menu/biome_selector.tscn" id="2_biome"]
|
||||
[ext_resource type="Texture2D" uid="uid://dyvwywse5raqt" path="res://core/game_menu/assets/page_1/1_dx.png" id="3_6tfbo"]
|
||||
[ext_resource type="Texture2D" uid="uid://kvn5l0n11a3q" path="res://core/game_menu/assets/page.png" id="3_page_bg"]
|
||||
|
||||
[node name="Page1Right" type="Control" unique_id=2093612752]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_right = -1160.0
|
||||
offset_bottom = -506.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="PageBackground" type="TextureRect" parent="." unique_id=1432670109]
|
||||
layout_mode = 1
|
||||
anchors_preset = 11
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -760.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_page_bg")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="PageBackground2" type="TextureRect" parent="." unique_id=1327230938]
|
||||
layout_mode = 1
|
||||
anchors_preset = 11
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -760.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_6tfbo")
|
||||
stretch_mode = 2
|
||||
|
||||
[node name="BiomeSelector" parent="." unique_id=679177937 instance=ExtResource("2_biome")]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -301.0
|
||||
offset_top = -158.0
|
||||
offset_right = 368.0
|
||||
offset_bottom = 158.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
@@ -1,13 +1,7 @@
|
||||
[gd_scene format=3 uid="uid://4bamw5busnvc"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://id854u4gh12f" path="res://core/game_menu/page.tscn" id="1_ka6tx"]
|
||||
[ext_resource type="Texture2D" uid="uid://xgx0211eo8hi" path="res://core/game_menu/assets/page_2/photocollections_text.png" id="2_4uwhd"]
|
||||
[ext_resource type="Texture2D" uid="uid://d3qq4ho24phyw" path="res://core/game_menu/assets/decoration_page2.png" id="2_xqdsh"]
|
||||
[ext_resource type="Texture2D" uid="uid://xfl3ks4dbfaw" path="res://core/game_menu/assets/page_2/achievements_text.png" id="3_4uwhd"]
|
||||
[ext_resource type="PackedScene" uid="uid://b6r787sik5yil" path="res://core/game_menu/photo_gallery.tscn" id="4_3tfra"]
|
||||
[ext_resource type="PackedScene" uid="uid://bvw086glfpcba" path="res://core/game_menu/collectible_gallery.tscn" id="5_w0bcg"]
|
||||
[ext_resource type="PackedScene" uid="uid://c7t3p8sp54apy" path="res://core/game_menu/highlighted_photo.tscn" id="6_2273a"]
|
||||
[ext_resource type="Texture2D" uid="uid://bx6gsh5uchkge" path="res://core/game_menu/assets/lock.png" id="8_48jk0"]
|
||||
|
||||
[node name="Page2" unique_id=2037261222 instance=ExtResource("1_ka6tx")]
|
||||
anchors_preset = 15
|
||||
@@ -31,49 +25,4 @@ mouse_filter = 2
|
||||
texture = ExtResource("2_xqdsh")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="PhotoCollectionText" type="TextureRect" parent="." index="2" unique_id=240014191]
|
||||
layout_mode = 0
|
||||
offset_left = 260.0
|
||||
offset_top = 330.0
|
||||
offset_right = 827.0
|
||||
offset_bottom = 415.0
|
||||
texture = ExtResource("2_4uwhd")
|
||||
stretch_mode = 3
|
||||
|
||||
[node name="AchievementsText" type="TextureRect" parent="." index="3" unique_id=1478291812]
|
||||
layout_mode = 0
|
||||
offset_left = 1184.0
|
||||
offset_top = 330.0
|
||||
offset_right = 1579.0
|
||||
offset_bottom = 401.0
|
||||
texture = ExtResource("3_4uwhd")
|
||||
stretch_mode = 3
|
||||
|
||||
[node name="PhotoGallery" parent="." index="4" unique_id=354419843 instance=ExtResource("4_3tfra")]
|
||||
layout_mode = 1
|
||||
offset_left = 244.0
|
||||
offset_top = 410.0
|
||||
offset_right = 844.0
|
||||
offset_bottom = 850.0
|
||||
|
||||
[node name="CollectibleGallery" parent="." index="5" unique_id=708445500 instance=ExtResource("5_w0bcg")]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
offset_left = 1050.0
|
||||
offset_top = 425.0
|
||||
offset_right = 1690.0
|
||||
offset_bottom = 835.0011
|
||||
|
||||
[node name="HighlightedPhoto" parent="." index="6" unique_id=888465569 instance=ExtResource("6_2273a")]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
|
||||
[node name="LockTexture" type="TextureRect" parent="." index="7" unique_id=1369712242]
|
||||
layout_mode = 0
|
||||
offset_left = 1265.0
|
||||
offset_top = 449.0
|
||||
offset_right = 1547.0
|
||||
offset_bottom = 809.6977
|
||||
texture = ExtResource("8_48jk0")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
57
core/game_menu/page_2_left.tscn
Normal file
@@ -0,0 +1,57 @@
|
||||
[gd_scene format=3 uid="uid://ct0pbs1nyi3d1"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://0yyr318wl7co" path="res://core/game_menu/page_interactive.gd" id="1_script"]
|
||||
[ext_resource type="Texture2D" uid="uid://xgx0211eo8hi" path="res://core/game_menu/assets/page_2/photocollections_text.png" id="2_text"]
|
||||
[ext_resource type="PackedScene" uid="uid://b6r787sik5yil" path="res://core/game_menu/photo_gallery.tscn" id="3_gallery"]
|
||||
[ext_resource type="Texture2D" uid="uid://cgllgxrstcoy7" path="res://core/game_menu/assets/page_2/2_sx.png" id="3_sfb5f"]
|
||||
[ext_resource type="Texture2D" uid="uid://kvn5l0n11a3q" path="res://core/game_menu/assets/page.png" id="4_page_bg"]
|
||||
|
||||
[node name="Page2Left" type="Control" unique_id=922443654]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_right = -1160.0
|
||||
offset_bottom = -506.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="PageBackground" type="TextureRect" parent="." unique_id=1425677666]
|
||||
layout_mode = 1
|
||||
anchors_preset = 9
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 760.0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("4_page_bg")
|
||||
expand_mode = 1
|
||||
flip_h = true
|
||||
|
||||
[node name="PageBackground2" type="TextureRect" parent="." unique_id=1817272886]
|
||||
layout_mode = 1
|
||||
anchors_preset = 9
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 760.0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_sfb5f")
|
||||
stretch_mode = 2
|
||||
|
||||
[node name="PhotoCollectionText" type="TextureRect" parent="." unique_id=643307421]
|
||||
layout_mode = 0
|
||||
offset_left = 96.0
|
||||
offset_top = 27.0
|
||||
offset_right = 663.0
|
||||
offset_bottom = 112.0
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("2_text")
|
||||
stretch_mode = 3
|
||||
|
||||
[node name="PhotoGallery" parent="." unique_id=1823812771 instance=ExtResource("3_gallery")]
|
||||
layout_mode = 1
|
||||
offset_left = 80.0
|
||||
offset_top = 107.0
|
||||
offset_right = 680.0
|
||||
offset_bottom = 547.0
|
||||
103
core/game_menu/page_2_right.tscn
Normal file
@@ -0,0 +1,103 @@
|
||||
[gd_scene format=3 uid="uid://clno1ahv2byng"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://0yyr318wl7co" path="res://core/game_menu/page_interactive.gd" id="1_script"]
|
||||
[ext_resource type="Texture2D" uid="uid://xfl3ks4dbfaw" path="res://core/game_menu/assets/page_2/achievements_text.png" id="3_4uwhd"]
|
||||
[ext_resource type="Texture2D" uid="uid://drwe2xcnp8vs1" path="res://core/game_menu/assets/page_2/2_dx.png" id="3_msl27"]
|
||||
[ext_resource type="PackedScene" uid="uid://bvw086glfpcba" path="res://core/game_menu/collectible_gallery.tscn" id="5_w0bcg"]
|
||||
[ext_resource type="Texture2D" uid="uid://bx6gsh5uchkge" path="res://core/game_menu/assets/lock.png" id="8_48jk0"]
|
||||
[ext_resource type="Texture2D" uid="uid://vg5y4qgc26ko" path="res://core/game_menu/assets/page_3/coming_soon_01.png" id="8_71v1w"]
|
||||
[ext_resource type="Texture2D" uid="uid://bmatlcouch6jm" path="res://core/game_menu/assets/page_3/coming_soon_02.png" id="9_g7kul"]
|
||||
[ext_resource type="Texture2D" uid="uid://kvn5l0n11a3q" path="res://core/game_menu/assets/page.png" id="9_page_bg"]
|
||||
[ext_resource type="Texture2D" uid="uid://bm55xiv8jgnni" path="res://core/game_menu/assets/page_3/coming_soon_03.png" id="10_h6k52"]
|
||||
[ext_resource type="Texture2D" uid="uid://cj81qdlrulal2" path="res://core/game_menu/assets/page_3/coming_soon_04.png" id="11_7aajs"]
|
||||
[ext_resource type="Texture2D" uid="uid://biu4i40ck272q" path="res://core/game_menu/assets/page_3/coming_soon_05.png" id="12_dn2di"]
|
||||
|
||||
[sub_resource type="AnimatedTexture" id="AnimatedTexture_0x02d"]
|
||||
frames = 5
|
||||
frame_0/texture = ExtResource("8_71v1w")
|
||||
frame_0/duration = 0.15
|
||||
frame_1/texture = ExtResource("9_g7kul")
|
||||
frame_1/duration = 0.15
|
||||
frame_2/texture = ExtResource("10_h6k52")
|
||||
frame_2/duration = 0.15
|
||||
frame_3/texture = ExtResource("11_7aajs")
|
||||
frame_3/duration = 0.15
|
||||
frame_4/texture = ExtResource("12_dn2di")
|
||||
frame_4/duration = 0.15
|
||||
|
||||
[node name="Page2Right" type="Control" unique_id=944053844]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_right = -1160.0
|
||||
offset_bottom = -506.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="PageBackground" type="TextureRect" parent="." unique_id=1387851649]
|
||||
layout_mode = 1
|
||||
anchors_preset = 11
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -760.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("9_page_bg")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="PageBackground2" type="TextureRect" parent="." unique_id=1602066462]
|
||||
layout_mode = 1
|
||||
anchors_preset = 11
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -760.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_msl27")
|
||||
stretch_mode = 2
|
||||
|
||||
[node name="AchievementsText" type="TextureRect" parent="." unique_id=766898810]
|
||||
layout_mode = 0
|
||||
offset_left = 261.0
|
||||
offset_top = 34.5
|
||||
offset_right = 656.0
|
||||
offset_bottom = 105.5
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_4uwhd")
|
||||
stretch_mode = 3
|
||||
|
||||
[node name="CollectibleGallery" parent="." unique_id=916407522 instance=ExtResource("5_w0bcg")]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
offset_left = 127.0
|
||||
offset_top = 129.5
|
||||
offset_right = 767.0
|
||||
offset_bottom = 539.5
|
||||
|
||||
[node name="LockTexture" type="TextureRect" parent="." unique_id=535700029]
|
||||
layout_mode = 0
|
||||
offset_left = 342.0
|
||||
offset_top = 153.5
|
||||
offset_right = 624.0
|
||||
offset_bottom = 514.2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("8_48jk0")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="." unique_id=1942592146]
|
||||
layout_mode = 0
|
||||
offset_left = 596.0
|
||||
offset_top = 86.0
|
||||
offset_right = 743.0
|
||||
offset_bottom = 233.0
|
||||
texture = SubResource("AnimatedTexture_0x02d")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://id854u4gh12f" path="res://core/game_menu/page.tscn" id="1_ua8fn"]
|
||||
[ext_resource type="Texture2D" uid="uid://fpnhk1ygcrmu" path="res://core/game_menu/assets/page_3/bg_timbri.png" id="2_ckqcb"]
|
||||
[ext_resource type="PackedScene" uid="uid://cxf8s80ivwj1p" path="res://core/game_menu/option_menu.tscn" id="2_tymfi"]
|
||||
[ext_resource type="Texture2D" uid="uid://db2yhovnqq4cp" path="res://core/game_menu/assets/decoration_page3.png" id="2_yx6jr"]
|
||||
[ext_resource type="PackedScene" uid="uid://caqf471x0kttc" path="res://core/game_menu/settings_menu.tscn" id="4_twko7"]
|
||||
|
||||
[node name="Page3" unique_id=2037261222 instance=ExtResource("1_ua8fn")]
|
||||
anchors_preset = 15
|
||||
@@ -37,33 +35,4 @@ anchor_bottom = 0.7740741
|
||||
texture = ExtResource("2_ckqcb")
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="OptionMenu" parent="." index="3" unique_id=1055457221 instance=ExtResource("2_tymfi")]
|
||||
layout_mode = 0
|
||||
anchors_preset = 0
|
||||
anchor_left = 0.7213542
|
||||
anchor_top = 0.5212963
|
||||
anchor_right = 0.7213542
|
||||
anchor_bottom = 0.5212963
|
||||
grow_horizontal = 1
|
||||
grow_vertical = 1
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="PlayButton" parent="OptionMenu/VBoxContainer" parent_id_path=PackedInt32Array(1055457221, 508055524) index="0" unique_id=1990327704]
|
||||
visible = false
|
||||
|
||||
[node name="SettingsButton" parent="OptionMenu/VBoxContainer" parent_id_path=PackedInt32Array(1055457221, 508055524) index="2" unique_id=1931222561]
|
||||
visible = false
|
||||
|
||||
[node name="SettingsMenu" parent="." index="4" unique_id=1639777294 instance=ExtResource("4_twko7")]
|
||||
layout_mode = 1
|
||||
anchor_top = 0.5388889
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.5388889
|
||||
offset_left = 278.11
|
||||
offset_top = -240.0
|
||||
offset_right = 902.11
|
||||
offset_bottom = 285.0
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 6
|
||||
|
||||
[editable path="OptionMenu"]
|
||||
|
||||
50
core/game_menu/page_3_left.tscn
Normal file
@@ -0,0 +1,50 @@
|
||||
[gd_scene format=3 uid="uid://dhjocrxlqosyr"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://0yyr318wl7co" path="res://core/game_menu/page_interactive.gd" id="1_script"]
|
||||
[ext_resource type="PackedScene" uid="uid://caqf471x0kttc" path="res://core/game_menu/settings_menu.tscn" id="2_settings"]
|
||||
[ext_resource type="Texture2D" uid="uid://diuai5vtjx23l" path="res://core/game_menu/assets/page_3/3_sx.png" id="3_jdqrf"]
|
||||
[ext_resource type="Texture2D" uid="uid://kvn5l0n11a3q" path="res://core/game_menu/assets/page.png" id="3_page_bg"]
|
||||
|
||||
[node name="Page3Left" type="Control" unique_id=1419303211]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_right = -1160.0
|
||||
offset_bottom = -506.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="PageBackground" type="TextureRect" parent="." unique_id=1048771500]
|
||||
layout_mode = 1
|
||||
anchors_preset = 9
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 760.0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_page_bg")
|
||||
expand_mode = 1
|
||||
flip_h = true
|
||||
|
||||
[node name="PageBackground2" type="TextureRect" parent="." unique_id=1869708897]
|
||||
layout_mode = 1
|
||||
anchors_preset = 9
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 760.0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_jdqrf")
|
||||
stretch_mode = 2
|
||||
|
||||
[node name="SettingsMenu" parent="." unique_id=1402645746 instance=ExtResource("2_settings")]
|
||||
layout_mode = 0
|
||||
anchors_preset = 0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = 68.0
|
||||
offset_top = 24.5
|
||||
offset_right = 692.0
|
||||
offset_bottom = 549.5
|
||||
size_flags_horizontal = 6
|
||||