27 Commits

Author SHA1 Message Date
siim 01d6ecf475 go to bear level fix and vibration of controller when gate is opening 2026-09-03 18:20:19 +03:00
siim 931ddf0eeb can turn "gamepad_vibration" on and off in debug mode 2026-09-03 18:04:58 +03:00
siim 50073b2574 controller vibrate when taking damage 2026-09-03 17:53:44 +03:00
siim 07f8a71f2c torches light animation 2026-09-03 07:53:55 +03:00
richard 34dc5b026e Lobby barrel-smash reward + roll/slam barrel destruction
Bull's boulder roll now homes on and ploughs through lobby barrels, and
the slam shockwave bursts them within its radius. HUD tallies barrels on
load and fires a confetti "WOooOoW!" + two gold bonus HP pips when the
last one breaks; gates open from run state as fights are cleared.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-03 01:38:57 +03:00
richard 5c1e881a53 Combat overhaul: charge/gore, bear ram, matador taunt reactions
Bull charge damage:
- Tunnel-proof swept detection (prev→now segment) for matador gore and bear
  ram, so a 66 m/s dash no longer skips clean over the thin HitArea.
- Horns-first cone (bull_gore_arc): running into an enemy only wounds it when
  charging roughly at it, not a sideways brush.
- Dash is a committed lunge: bypasses the horns cone AND the survival roll, so a
  dash connect is a guaranteed kill. Cruise charges keep a speed-scaled roll
  (mat_charge_pierce). Roll ability defers to its own pop (is_rolling guard).

Bear:
- Horns-first swept ram detection (edge-triggered: one charge = one wound);
  a tunnelling or point-blank charge now lands where body_entered wouldn't.
- Overhead smash lane extends faster (0.1s) and further (20 m).
- Leap slam launches the bull from anywhere in the circle (ring_frac 0).
- Removed stray-quote syntax errors that broke the script.

Matador:
- Collider-driven stab (BladeHitbox) with recovery beat + taunt-after-hit so it
  stops machine-gunning the bull.
- A taunting matador answers a charge: spear from range, sword up close.

Spear projectile masks the BULL layer so throws connect.

Tests: matador_charge/stab/spear/taunt_react, bear_ram/hitbox/fx (+ unified
_fake_bull stand-in). Trimmed verbose comments.

Note: bear claw-emitter/death work is still WIP (3 bear_boss_test failures).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-03 01:01:42 +03:00
siim 4efc6763f0 lobby little tweak 2026-09-01 21:34:02 +03:00
siim 76d4fee33c Lobby level gates trigger areas 2026-09-01 21:22:16 +03:00
siim 271be0b26b + torches 2026-09-01 08:58:56 +03:00
siim 98c6f1285a underground_lobby 2026-08-31 21:52:13 +03:00
siim 4d66df8c7e bear long range slam. and not rotating while attacking animore. but dash and movement damage not working now 2026-08-29 09:30:03 +03:00
siim 41f18cb5d6 bear fx v2 2026-08-28 21:43:59 +03:00
siim 6b6a926715 bear_fx 2026-08-28 20:23:13 +03:00
siim dae7ec06da barrel materials 2026-08-28 19:43:09 +03:00
siim 1eb06876e9 breakable barrels 2026-08-28 19:02:19 +03:00
richard 1021a07b04 Put dead matadors on a corpse collision layer
A killed matador's ragdoll shared the WORLD layer with the bull, so the
bull collided with the bodies and spazzed out on them. Give corpses a
dedicated CORPSE layer masked to itself, and tag the ground/walls with
CORPSE too (at level load, so it also reaches colliders baked into the
instanced GLB arenas). The corpse still rests on the arena, but the bull
— which only masks WORLD — passes straight through the bodies.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-27 23:27:10 +03:00
richard c365f76d80 Merge remote-tracking branch 'origin/main' 2026-08-27 21:34:23 +03:00
richard 32ac46f840 lobby cam 2026-08-27 21:34:18 +03:00
siim bd10d1789b bear max hp 30 2026-08-27 21:30:48 +03:00
siim 170d8ff3f1 siim timmimised väiksed 2026-08-27 21:15:36 +03:00
siim 550bf2c5ad adjustable wave size with debug parameter "mat_wave_size" 2026-08-27 20:36:00 +03:00
siim 02f3e283de landing. don't bounce! 2026-08-27 08:30:03 +03:00
siim 9123574947 crowd billbord placement + mat sword run fix 2026-08-26 22:32:30 +03:00
siim aadf59d2d0 lobby collisions 2026-08-26 21:09:41 +03:00
richard d57c3dc2a2 Merge remote-tracking branch 'origin/main' 2026-08-26 20:38:14 +03:00
richard 09ae6bfbf4 lobby level 2026-08-26 20:38:07 +03:00
richard 40c1b8e680 debug param save works, bull/bear hitbox 2026-08-26 20:37:50 +03:00
115 changed files with 13141 additions and 2649 deletions
+1 -1
View File
@@ -2,4 +2,4 @@ disable:
- class-definitions-order
- no-else-return
max-line-length: 120
max-file-lines: 1200
max-file-lines: 3000
+93
View File
@@ -0,0 +1,93 @@
[gd_resource type="Animation" format=3 uid="uid://bq71flatfddll"]
[resource]
resource_name = "Bear_fx_smash_hit"
length = 0.23333333
tracks/0/type = "position_3d"
tracks/0/imported = true
tracks/0/enabled = true
tracks/0/path = NodePath("Bear_fx_smash_hit")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, 0, -0.51246816, 7.1560388, 0.033333335, 1, 0, -0.51246816, 7.1560388, 0.06666667, 1, 1.2735307, -1.4730668, 5.139501, 0.1, 1, 1.3610363, 0.27301335, 5.141279, 0.13333334, 1, 1.3735371, 2.1639488, 5.153728, 0.16666667, 1, 1.3573295, -0.04170864, 5.1945124, 0.2, 1, 1.3061407, -0.3338372, 5.1877995, 0.23333333, 1, 1.2735307, -0.37556988, 5.1810856)
tracks/1/type = "rotation_3d"
tracks/1/imported = true
tracks/1/enabled = true
tracks/1/path = NodePath("Bear_fx_smash_hit")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = PackedFloat32Array(0, 1, 0, 0, 0, 1, 0.033333335, 1, 0, 0, 0, 1, 0.06666667, 1, 0.045591418, -0.036703378, -0.0016762356, 0.9982843, 0.1, 1, 0.06741002, -0.02538766, 0.014408795, 0.99729824, 0.13333334, 1, 0.05603578, -0.017236687, 0.029419938, 0.99784636, 0.16666667, 1, -0.071329094, -0.014488678, 0.036211126, 0.9966901, 0.23333333, 1, -0.039237745, -0.015645763, 0.035726424, 0.99846846)
tracks/2/type = "scale_3d"
tracks/2/imported = true
tracks/2/enabled = true
tracks/2/path = NodePath("Bear_fx_smash_hit")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = PackedFloat32Array(0, 1, 0, 0, 0, 0.033333335, 1, 0, 0, 0, 0.06666667, 1, 0.55657715, 0.55657715, 0.5565772, 0.23333333, 1, 0.55657715, 0.55657715, 0.55657715)
tracks/3/type = "position_3d"
tracks/3/imported = true
tracks/3/enabled = true
tracks/3/path = NodePath("Bear_fx_jump_smash")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = PackedFloat32Array(0, 1, 0, -0.51246816, 0)
tracks/4/type = "scale_3d"
tracks/4/imported = true
tracks/4/enabled = true
tracks/4/path = NodePath("Bear_fx_jump_smash")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = PackedFloat32Array(0, 1, 0, 0, 0)
tracks/5/type = "position_3d"
tracks/5/imported = true
tracks/5/enabled = true
tracks/5/path = NodePath("Bear_fx_claw_attack_R")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = PackedFloat32Array(0, 1, -3.188013, 1.0970955, 1.7545929)
tracks/6/type = "rotation_3d"
tracks/6/imported = true
tracks/6/enabled = true
tracks/6/path = NodePath("Bear_fx_claw_attack_R")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = PackedFloat32Array(0, 1, 0, 0, 0, 1)
tracks/7/type = "scale_3d"
tracks/7/imported = true
tracks/7/enabled = true
tracks/7/path = NodePath("Bear_fx_claw_attack_R")
tracks/7/interp = 1
tracks/7/loop_wrap = true
tracks/7/keys = PackedFloat32Array(0, 1, 0, 0, 0)
tracks/8/type = "position_3d"
tracks/8/imported = true
tracks/8/enabled = true
tracks/8/path = NodePath("Bear_fx_claw_attack_L")
tracks/8/interp = 1
tracks/8/loop_wrap = true
tracks/8/keys = PackedFloat32Array(0, 1, -3.188013, 1.0970955, 1.7545929)
tracks/9/type = "rotation_3d"
tracks/9/imported = true
tracks/9/enabled = true
tracks/9/path = NodePath("Bear_fx_claw_attack_L")
tracks/9/interp = 1
tracks/9/loop_wrap = true
tracks/9/keys = PackedFloat32Array(0, 1, 0, 0, 0, 1)
tracks/10/type = "scale_3d"
tracks/10/imported = true
tracks/10/enabled = true
tracks/10/path = NodePath("Bear_fx_claw_attack_L")
tracks/10/interp = 1
tracks/10/loop_wrap = true
tracks/10/keys = PackedFloat32Array(0, 1, 0, 0, 0)
tracks/11/type = "method"
tracks/11/imported = false
tracks/11/enabled = true
tracks/11/path = NodePath("..")
tracks/11/interp = 1
tracks/11/loop_wrap = true
tracks/11/keys = {
"times": PackedFloat32Array(),
"transitions": PackedFloat32Array(),
"values": []
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
+45
View File
@@ -0,0 +1,45 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://dctmlh4hnuux1"
path="res://.godot/imported/Lobby_underground.glb-55ed49331d7074ef560bfa0a498b89a7.scn"
[deps]
source_file="res://Assets/Lobby_underground.glb"
dest_files=["res://.godot/imported/Lobby_underground.glb-55ed49331d7074ef560bfa0a498b89a7.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
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=false
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={}
gltf/naming_version=2
gltf/embedded_image_handling=1
gltf/texture_map_mode=1
Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

+45
View File
@@ -0,0 +1,45 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dc4gf36fgsabp"
path.s3tc="res://.godot/imported/Lobby_underground_rock.png-76733dc5212e6c79a91e71ce008ebf6f.s3tc.ctex"
path.etc2="res://.godot/imported/Lobby_underground_rock.png-76733dc5212e6c79a91e71ce008ebf6f.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
generator_parameters={
"md5": "de3796fe2c1123ae5ba27a0532fda6bd"
}
[deps]
source_file="res://Assets/Lobby_underground_rock.png"
dest_files=["res://.godot/imported/Lobby_underground_rock.png-76733dc5212e6c79a91e71ce008ebf6f.s3tc.ctex", "res://.godot/imported/Lobby_underground_rock.png-76733dc5212e6c79a91e71ce008ebf6f.etc2.ctex"]
[params]
compress/mode=2
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=true
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=0
Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

@@ -0,0 +1,45 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://v0hdo12xule3"
path.s3tc="res://.godot/imported/Lobby_underground_rock_B.jpg-c5e86461201f99688c8146fff239a62b.s3tc.ctex"
path.etc2="res://.godot/imported/Lobby_underground_rock_B.jpg-c5e86461201f99688c8146fff239a62b.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
generator_parameters={
"md5": "335b739e743244a64c47e2564a9a3652"
}
[deps]
source_file="res://Assets/Lobby_underground_rock_B.jpg"
dest_files=["res://.godot/imported/Lobby_underground_rock_B.jpg-c5e86461201f99688c8146fff239a62b.s3tc.ctex", "res://.godot/imported/Lobby_underground_rock_B.jpg-c5e86461201f99688c8146fff239a62b.etc2.ctex"]
[params]
compress/mode=2
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=true
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=0
Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

@@ -0,0 +1,45 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dcy7fdio5k84j"
path.s3tc="res://.godot/imported/Lobby_underground_rock_B.png-3133a2540f4e1417fb5588bad79e38c8.s3tc.ctex"
path.etc2="res://.godot/imported/Lobby_underground_rock_B.png-3133a2540f4e1417fb5588bad79e38c8.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
generator_parameters={
"md5": "16ea5e4b01e9b3952b950ff65535e5d5"
}
[deps]
source_file="res://Assets/Lobby_underground_rock_B.png"
dest_files=["res://.godot/imported/Lobby_underground_rock_B.png-3133a2540f4e1417fb5588bad79e38c8.s3tc.ctex", "res://.godot/imported/Lobby_underground_rock_B.png-3133a2540f4e1417fb5588bad79e38c8.etc2.ctex"]
[params]
compress/mode=2
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=true
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=0
Binary file not shown.
Binary file not shown.
@@ -3,13 +3,13 @@
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://2e6fbder27w1"
path="res://.godot/imported/cubes_fx_test.glb-29490ce7011d666c1c4917a1a92679e4.scn"
uid="uid://dnltsqmuqcxh1"
path="res://.godot/imported/Barrel.glb-8809615fbcbd5dc5b64a229316967555.scn"
[deps]
source_file="res://Assets/fx/cubes_fx_test.glb"
dest_files=["res://.godot/imported/cubes_fx_test.glb-29490ce7011d666c1c4917a1a92679e4.scn"]
source_file="res://Assets/breakables/Barrel.glb"
dest_files=["res://.godot/imported/Barrel.glb-8809615fbcbd5dc5b64a229316967555.scn"]
[params]
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+15
View File
@@ -0,0 +1,15 @@
extends Node3D
## Lobby geometry — watches the run state and raises the bear-gate grid once the arena has
## been cleared. The DP flag stays as a designer override for testing the animation.
var bear_gate_open := false
func _process(_delta: float) -> void:
if bear_gate_open:
return
if Run.bear_gate_open() or DP.b("gate_unlocked_bear"):
bear_gate_open = true
$AnimationPlayer.play("Gate_opening")
if DP.b("gamepad_vibration"):
Input.start_joy_vibration(0, 0.5, .5, 7)
+1
View File
@@ -0,0 +1 @@
uid://cwbf7jfkr8j10
+10 -253
View File
@@ -2,8 +2,9 @@
[ext_resource type="Script" uid="uid://cn7fhjkro7637" path="res://bear.gd" id="1_beargd"]
[ext_resource type="PackedScene" uid="uid://cofv5dbavesis" path="res://Assets/Bear.glb" id="2_bearglb"]
[ext_resource type="Script" uid="uid://bsbed05ifr18s" path="res://bear_test_cube.gd" id="3_rog1v"]
[ext_resource type="PackedScene" uid="uid://bdbx0wwa73rhp" path="res://Assets/fx/Bear_FX.glb" id="4_rog1v"]
[ext_resource type="PackedScene" uid="uid://bdbx0wwa73rhp" path="res://Assets/fx/Bear_FX.glb" id="3_bearfx"]
[ext_resource type="Material" uid="uid://blpkmyikjnhbo" path="res://Materials/M_bear_claw_fx.tres" id="4_clawfx"]
[ext_resource type="PackedScene" path="res://BearAttackHitboxes.tscn" id="5_hitboxes"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_body"]
radius = 1.0
@@ -29,259 +30,15 @@ shape = SubResource("CapsuleShape3D_hit")
[node name="bear_model" parent="." unique_id=359217823 instance=ExtResource("2_bearglb")]
[node name="Skeleton3D" parent="bear_model/bear-rig" parent_id_path=PackedInt32Array(359217823, 1619621659) index="0" unique_id=1324818366]
bones/1/position = Vector3(0.04601016, 1.9209582, 0.9051311)
bones/1/rotation = Quaternion(0.5270001, -0.011489415, -0.05297156, 0.848135)
bones/2/rotation = Quaternion(0.29015693, 0.002787927, 0.00639222, 0.9569537)
bones/2/scale = Vector3(0.9999999, 1.0000008, 0.99999934)
bones/3/rotation = Quaternion(0.06707396, 0.012082217, 0.011868715, 0.9976043)
bones/4/rotation = Quaternion(0.3487565, 0.010761848, 0.013076123, 0.93706036)
bones/5/rotation = Quaternion(0.15472108, -0.21109715, -0.09227382, 0.96072114)
bones/6/rotation = Quaternion(0.4204113, 0.23492317, -0.11518617, 0.86879086)
bones/7/rotation = Quaternion(0.76830006, 0.36476925, -0.4668917, -0.24222025)
bones/8/rotation = Quaternion(0.5460264, -0.71257937, 0.40870878, -0.16444752)
bones/9/rotation = Quaternion(-0.02719195, -0.14156067, -0.26938534, 0.9521832)
bones/10/rotation = Quaternion(-0.12630412, -0.39785445, -0.057911687, 0.90686566)
bones/11/rotation = Quaternion(0.70209646, -0.35357565, 0.59454584, -0.16899753)
bones/12/rotation = Quaternion(0.5294657, 0.7712517, -0.33475664, -0.1130258)
bones/13/rotation = Quaternion(-0.04075809, 0.17025389, 0.28913936, 0.94114333)
bones/14/rotation = Quaternion(-0.03496992, 0.2568669, -0.0008229511, 0.9658136)
bones/15/rotation = Quaternion(0.9957146, -0.032195006, 0.031220285, 0.08087847)
bones/16/rotation = Quaternion(0.9367782, -0.012506716, 0.033659726, 0.3480767)
bones/17/rotation = Quaternion(-0.860235, -0.08192984, 0.009118035, 0.50319016)
bones/17/scale = Vector3(0.9999998, 1.0000002, 1)
bones/19/rotation = Quaternion(-4.514978e-15, 1, 7.4505806e-08, -5.523351e-07)
bones/20/rotation = Quaternion(0.9729887, -0.014750167, 0.014303936, 0.22993676)
bones/21/rotation = Quaternion(0.9366144, -0.00601367, 0.016095275, 0.34994036)
bones/22/rotation = Quaternion(-0.7732739, -0.06955802, 0.0075612683, 0.6302)
bones/22/scale = Vector3(0.9999997, 0.9999998, 0.9999999)
bones/24/rotation = Quaternion(6.628114e-12, 0.99999994, 5.2154085e-08, -0.00035543842)
bones/25/position = Vector3(1.0117401, 1.3159828, 3.9725027)
bones/25/rotation = Quaternion(-0.27285534, 0.9274522, 0.08017836, 0.2428039)
bones/25/scale = Vector3(1.0000001, 12.140265, 1.0000001)
bones/26/position = Vector3(-0.9025072, 1.4953425, 4.006362)
bones/26/rotation = Quaternion(0.5100001, 0.6936306, 0.15438241, -0.48470873)
bones/26/scale = Vector3(0.99999994, 11.348344, 1)
bones/27/position = Vector3(0.70899034, 1.0356265, 0.611243)
bones/27/rotation = Quaternion(0.7965308, 0.01196337, -0.0119632045, 0.6043613)
bones/27/scale = Vector3(0.99999994, 29.328602, 1)
bones/28/position = Vector3(-0.9047001, 1.0118608, 0.8510791)
bones/28/rotation = Quaternion(0.776662, 0.010376095, -0.010376263, 0.6297467)
bones/28/scale = Vector3(1, 26.535925, 1)
bones/30/position = Vector3(0.07262612, 0.67294323, -1.1644177)
bones/30/rotation = Quaternion(-0.7183768, 0.04937226, -0.02237074, 0.69353926)
bones/31/position = Vector3(5.9604645e-08, -1.4631644, 0.23291233)
bones/31/rotation = Quaternion(1.1641533e-09, 1.8335415e-09, 2.328307e-10, 1)
bones/31/scale = Vector3(0.99999994, 0.9999999, 0.99999994)
bones/32/position = Vector3(-0.0331195, -2.362161, -0.036310136)
bones/32/rotation = Quaternion(0.20497073, -0.020519394, -0.033738203, 0.9779712)
bones/32/scale = Vector3(0.9999999, 0.9999999, 0.99999994)
bones/33/position = Vector3(8.195639e-08, -1.4631642, 0.23291235)
bones/33/rotation = Quaternion(-8.288772e-08, 3.4342527e-09, -4.1909525e-09, 1)
bones/33/scale = Vector3(0.9999998, 0.9999998, 0.99999994)
bones/35/position = Vector3(-7.893884e-09, -1.0594703, 5.2079617e-08)
bones/35/rotation = Quaternion(0.99971783, 1.2737803e-07, 5.365157e-06, -0.023754692)
bones/35/scale = Vector3(0.99999976, 0.9999998, 1.0000012)
bones/39/position = Vector3(0.8199172, 0.25251278, 0.47214246)
bones/39/rotation = Quaternion(0.9961935, -0.035078514, -0.0045541152, 0.07967066)
bones/39/scale = Vector3(1.0000004, 0.9999996, 0.9999991)
bones/40/rotation = Quaternion(0.93738276, 1.2575202e-07, 3.4991626e-08, 0.3483009)
bones/40/scale = Vector3(1.0000004, 1.0000001, 1.0000001)
bones/41/rotation = Quaternion(-0.860235, -0.081929855, 0.009117997, 0.5031899)
bones/41/scale = Vector3(0.99999946, 0.99999976, 0.9999996)
bones/42/position = Vector3(-1.9729964e-07, 0.56145483, 7.283501e-08)
bones/46/scale = Vector3(0.99999946, 0.99999964, 0.9999999)
bones/48/rotation = Quaternion(9.8842406e-08, -0.054423165, -1.786034e-08, 0.998518)
bones/48/scale = Vector3(0.9999993, 0.9999996, 0.9999999)
bones/50/scale = Vector3(0.99999994, 0.99999994, 0.9999998)
bones/51/rotation = Quaternion(-6.30798e-08, 0.026635498, 6.253992e-09, 0.99964523)
bones/51/scale = Vector3(0.9999999, 0.99999964, 0.99999964)
bones/53/position = Vector3(-0.8199191, 0.25251284, 0.47213903)
bones/53/rotation = Quaternion(0.9730908, -0.0186988, -0.0024160824, 0.22964936)
bones/53/scale = Vector3(1, 0.99999875, 0.99999946)
bones/54/rotation = Quaternion(0.9367526, -1.1281111e-07, -3.6940495e-08, 0.34999225)
bones/55/rotation = Quaternion(-0.77327377, -0.06955799, 0.007561261, 0.6302002)
bones/55/scale = Vector3(1.0000002, 1, 1.0000002)
bones/56/position = Vector3(-5.9126133e-08, 0.5614537, 7.70865e-07)
bones/57/rotation = Quaternion(0.70073944, -0.70073956, -0.094679825, -0.09467953)
bones/60/scale = Vector3(1.0000004, 1.0000004, 1.0000002)
bones/62/rotation = Quaternion(5.8764627e-08, -0.042629674, 2.4442278e-08, 0.99909097)
bones/62/scale = Vector3(1.0000002, 1.0000002, 1.0000001)
bones/64/scale = Vector3(1.0000004, 1.0000004, 1)
bones/65/rotation = Quaternion(8.029546e-08, 0.01272784, 4.3857337e-08, 0.999919)
bones/65/scale = Vector3(1.0000002, 1.0000004, 1.0000004)
bones/67/rotation = Quaternion(0.7179022, -7.671307e-07, 7.885642e-07, 0.696144)
bones/67/scale = Vector3(1.0000004, 0.9999986, 0.99999994)
bones/68/rotation = Quaternion(0.9776482, 2.0029378e-07, 1.0460874e-06, -0.2102479)
bones/68/scale = Vector3(1.0000004, 1.0000004, 0.9999982)
bones/69/position = Vector3(-2.4645832e-08, -6.861796e-09, 7.455772e-08)
bones/69/rotation = Quaternion(-0.8315212, 2.5276703e-08, -9.3330055e-09, 0.5554931)
bones/69/scale = Vector3(1, 1.0000001, 1.0000002)
bones/70/rotation = Quaternion(0.67750055, 8.820757e-08, 7.575834e-08, 0.7355223)
bones/70/scale = Vector3(1, 1, 1)
bones/71/scale = Vector3(0.9999999, 1, 0.9999999)
bones/72/rotation = Quaternion(-2.1641608e-07, -4.6565607e-10, -4.6576065e-10, 1)
bones/75/rotation = Quaternion(0.25299338, 0.020847347, 0.028576687, 0.9668212)
bones/76/position = Vector3(1.01587794e-07, -1.5306958e-07, -4.3554866e-07)
bones/76/rotation = Quaternion(-0.5206146, -3.634943e-08, 7.6474e-08, 0.8537919)
bones/77/rotation = Quaternion(0.9373828, 1.2785249e-07, 3.3241214e-08, 0.3483008)
bones/78/position = Vector3(0.8199172, 0.25251257, 0.47214243)
bones/78/rotation = Quaternion(0.99571455, -0.032195, 0.031220287, 0.08087897)
bones/78/scale = Vector3(1.0000004, 0.9999997, 0.99999905)
bones/80/rotation = Quaternion(0.7179022, -7.6713064e-07, 7.885641e-07, 0.696144)
bones/80/scale = Vector3(1.0000004, 0.9999986, 0.99999994)
bones/81/rotation = Quaternion(0.97764814, 1.9846473e-07, 1.0426893e-06, -0.21024783)
bones/81/scale = Vector3(1.0000004, 1.0000002, 0.9999982)
bones/82/position = Vector3(6.103571e-08, 8.8816435e-08, -3.6955274e-09)
bones/82/rotation = Quaternion(-0.8315211, 2.3407136e-08, -1.2821512e-08, 0.5554932)
bones/82/scale = Vector3(0.99999994, 0.99999994, 1)
bones/83/rotation = Quaternion(0.6775009, -8.600083e-08, -8.977273e-08, 0.735522)
bones/83/scale = Vector3(1, 1.0000001, 1)
bones/84/scale = Vector3(0.99999994, 1.0000001, 0.9999999)
bones/85/rotation = Quaternion(2.6833732e-07, -9.313788e-10, -2.5612494e-09, 1)
bones/85/scale = Vector3(1.0000001, 1, 1.0000001)
bones/87/rotation = Quaternion(-0.5230753, 0.20132942, 0.026226493, 0.8277505)
bones/88/rotation = Quaternion(0.10320552, 0.011111915, 0.015231778, 0.99448144)
bones/89/position = Vector3(2.953037e-07, 4.9207458e-08, -4.3015167e-08)
bones/89/rotation = Quaternion(-0.5201237, 5.177172e-08, -1.16139375e-07, 0.8540909)
bones/90/rotation = Quaternion(0.9367527, -1.0975643e-07, -3.3382268e-08, 0.34999216)
bones/91/position = Vector3(-0.8199192, 0.2525128, 0.47213912)
bones/91/rotation = Quaternion(0.9729887, -0.0147501845, 0.014303951, 0.22993667)
bones/91/scale = Vector3(1.0000002, 0.999999, 0.99999964)
bones/96/position = Vector3(-0.016559705, -1.9126627, 0.09830098)
bones/96/rotation = Quaternion(0.10305436, -0.010316663, -0.016962789, 0.99447757)
bones/96/scale = Vector3(0.9999998, 1, 1)
bones/97/rotation = Quaternion(0.997074, -1.2813135e-07, 1.666339e-06, -0.07644201)
bones/98/position = Vector3(0.0013585633, -0.23419222, 0.016214281)
bones/98/rotation = Quaternion(-0.15130657, -0.005602528, -0.008209973, 0.98843694)
bones/98/scale = Vector3(1.0000001, 1.0000006, 1.0000029)
bones/101/position = Vector3(-0.016559973, 1.4684486, 0.06451648)
bones/101/rotation = Quaternion(0.99944556, 0.016124567, -0.011581497, -0.02673253)
bones/101/scale = Vector3(1.0000001, 0.9999993, 0.99999183)
bones/102/rotation = Quaternion(0.95545256, -6.924111e-08, 2.2887033e-07, -0.29514462)
bones/103/position = Vector3(-0.00705543, 0.6694702, -0.06780842)
bones/103/rotation = Quaternion(0.15471841, -0.21109664, -0.09227309, 0.9607217)
bones/103/scale = Vector3(1.0000005, 1.0000286, 1.0000087)
bones/104/rotation = Quaternion(0.420411, 0.23492327, -0.115186565, 0.86879104)
bones/104/scale = Vector3(0.9999993, 0.9999884, 0.9999856)
bones/105/rotation = Quaternion(0.91976035, -0.013162326, 0.0148637965, 0.39197809)
bones/105/scale = Vector3(1, 1.0000005, 1.0000114)
bones/106/position = Vector3(-0.010389687, -0.091948025, 0.0016658108)
bones/106/rotation = Quaternion(0.82734275, 0.15726796, -0.14167279, -0.52028793)
bones/107/rotation = Quaternion(0.77328545, 0.16233337, -0.107321426, 0.6034564)
bones/107/scale = Vector3(0.9999966, 0.99997723, 0.9999995)
bones/108/position = Vector3(-1.1340098e-08, 7.923448e-07, 9.0939814e-08)
bones/108/rotation = Quaternion(0.42463258, 0.043219328, 0.08968367, -0.89987564)
bones/110/rotation = Quaternion(5.443812e-06, 3.6259098e-09, -1.2069942e-06, 1)
bones/110/scale = Vector3(0.99999994, 0.99999976, 1.0000001)
bones/113/position = Vector3(0.08179821, 0.64012206, 0.7106584)
bones/113/rotation = Quaternion(0.7683008, 0.36476624, -0.46689337, -0.24221936)
bones/114/position = Vector3(0.08595797, 0.6463289, -0.32087424)
bones/114/rotation = Quaternion(0.5615046, -0.7056476, 0.3871702, -0.19202453)
bones/114/scale = Vector3(1.0000049, 1.0000027, 1.0000052)
bones/115/rotation = Quaternion(-0.037640397, -0.10443457, -0.2681242, 0.9569672)
bones/115/scale = Vector3(0.9999974, 1.0000036, 0.99999976)
bones/116/rotation = Quaternion(-0.12630361, -0.39785278, -0.057911348, 0.90686655)
bones/116/scale = Vector3(1.0000005, 0.9999972, 1.0000013)
bones/119/scale = Vector3(1.0000043, 0.9999975, 0.99999744)
bones/121/rotation = Quaternion(-2.7027176e-07, -0.20424414, 2.9341666e-07, 0.97892)
bones/121/scale = Vector3(1.0000037, 0.99999774, 0.9999977)
bones/123/scale = Vector3(1.000003, 0.9999977, 0.99999917)
bones/124/rotation = Quaternion(1.2542905e-06, -0.033494003, 5.941339e-07, 0.999439)
bones/124/scale = Vector3(1.0000037, 0.9999978, 0.99999875)
bones/126/rotation = Quaternion(-0.51635414, -0.1681693, 0.6340872, 0.5504825)
bones/126/scale = Vector3(1.0000056, 1.0000031, 1.0000038)
bones/127/rotation = Quaternion(-0.24332374, 0.12663902, 0.6612198, 0.6982439)
bones/127/scale = Vector3(1.0000057, 1.0000007, 1.0000064)
bones/128/position = Vector3(3.0230987e-07, -5.5011895e-07, -6.94335e-08)
bones/128/rotation = Quaternion(0.17027588, 0.93388194, -0.2967173, 0.104064964)
bones/129/rotation = Quaternion(-0.037640374, -0.10443452, -0.26812422, 0.9569671)
bones/131/rotation = Quaternion(-0.54023695, -0.3639527, 0.10910668, 0.7508517)
bones/132/rotation = Quaternion(-0.13163939, 0.9186296, -0.34996635, -0.12772812)
bones/133/rotation = Quaternion(-0.012778445, 0.011854936, 0.00015161023, 0.99984807)
bones/133/scale = Vector3(1.0422997, 1.0422999, 1.0422992)
bones/134/rotation = Quaternion(0.02152282, -2.7759576e-08, -1.5735115e-07, 0.99976844)
bones/134/scale = Vector3(0.98826313, 0.9882641, 0.9882627)
bones/135/position = Vector3(0.08595812, 0.646329, -0.3208742)
bones/135/rotation = Quaternion(0.5460276, -0.7125794, 0.40870702, -0.16444758)
bones/135/scale = Vector3(1.000007, 1.0000004, 1.0000051)
bones/137/position = Vector3(-0.09762837, 0.6401221, 0.7106583)
bones/137/rotation = Quaternion(0.7020965, -0.35357338, 0.5945473, -0.16899663)
bones/138/position = Vector3(-0.08595776, 0.646329, -0.3208746)
bones/138/rotation = Quaternion(0.5492876, 0.7627154, -0.30113, -0.16083841)
bones/138/scale = Vector3(1.0000051, 1.0000018, 1.0000046)
bones/139/rotation = Quaternion(-0.058682628, 0.11130926, 0.28603986, 0.94991994)
bones/139/scale = Vector3(0.9999983, 1.0000024, 0.9999992)
bones/140/rotation = Quaternion(-0.034969915, 0.25686622, -0.0008231461, 0.96581376)
bones/140/scale = Vector3(1.0000031, 0.9999977, 0.9999988)
bones/143/scale = Vector3(1.000005, 0.99999815, 0.9999967)
bones/145/rotation = Quaternion(-4.0431777e-07, 0.1295653, -5.1404834e-07, 0.99157095)
bones/145/scale = Vector3(1.0000045, 0.99999803, 0.9999968)
bones/147/scale = Vector3(1.0000035, 0.99999845, 0.9999981)
bones/148/rotation = Quaternion(1.9343124e-06, 0.025161995, -3.222267e-07, 0.9996834)
bones/148/scale = Vector3(1.000004, 0.9999991, 0.999998)
bones/150/rotation = Quaternion(-0.5163542, 0.16816999, -0.6340877, 0.5504816)
bones/150/scale = Vector3(1.0000052, 1.0000039, 1.0000025)
bones/151/rotation = Quaternion(-0.24332343, -0.1266389, -0.6612192, 0.6982446)
bones/151/scale = Vector3(1.0000049, 1.0000005, 1.0000063)
bones/152/position = Vector3(-2.0525843e-07, -4.4378166e-07, 2.2242949e-07)
bones/152/rotation = Quaternion(-0.1980554, 0.9486651, -0.20058647, -0.14343536)
bones/153/rotation = Quaternion(-0.058682676, 0.11130926, 0.2860399, 0.94991994)
bones/155/rotation = Quaternion(-0.48170745, 0.21343125, -0.09362694, 0.84477156)
bones/155/scale = Vector3(0.99999994, 1, 0.9999998)
bones/156/rotation = Quaternion(0.2123156, 0.9450362, -0.15822437, 0.19181721)
bones/157/rotation = Quaternion(-0.01277751, -0.011854968, -0.0001513001, 0.9998481)
bones/157/scale = Vector3(1.0423003, 1.0422994, 1.0423005)
bones/158/rotation = Quaternion(0.021521209, -2.5687226e-07, -2.570953e-07, 0.9997684)
bones/158/scale = Vector3(0.9882631, 0.98826426, 0.9882618)
bones/159/position = Vector3(-0.085957706, 0.6463291, -0.32087478)
bones/159/rotation = Quaternion(0.5294669, 0.7712517, -0.33475488, -0.1130262)
bones/159/scale = Vector3(1.0000075, 1.0000001, 1.0000042)
bones/161/position = Vector3(0.08179821, 0.64012206, 0.7106584)
bones/161/rotation = Quaternion(0.7683008, 0.36476624, -0.46689337, -0.24221936)
bones/162/position = Vector3(-0.09762837, 0.6401221, 0.7106583)
bones/162/rotation = Quaternion(0.7020965, -0.35357338, 0.5945473, -0.16899663)
bones/165/position = Vector3(-1.5017577e-08, 0.26895812, -1.6243575e-08)
bones/165/rotation = Quaternion(-0.019247467, -0.20323175, 0.97894067, -0.0012537595)
bones/166/position = Vector3(0.016703974, -2.2814677, 2.0323193)
bones/167/position = Vector3(0.7698192, 2.760036, -1.7026894)
bones/167/rotation = Quaternion(-0.93479383, -0.013274327, 0.31412983, 0.16524744)
bones/167/scale = Vector3(0.9999947, 0.9999997, 1.0000055)
bones/168/position = Vector3(0.18381567, -0.9622623, 0.9894084)
bones/168/rotation = Quaternion(0.93622446, 1.3019375e-07, -0.34127164, -0.08377019)
bones/168/scale = Vector3(1.0000024, 1.0000011, 1.0000095)
bones/170/position = Vector3(0.748137, 0.69556385, 3.7252903e-09)
bones/170/rotation = Quaternion(0.019250846, -0.20323181, 0.9789406, 0.001253055)
bones/171/position = Vector3(0.381392, -2.057497, 2.0762825)
bones/172/position = Vector3(-0.9278099, 2.7545004, -1.5181485)
bones/172/rotation = Quaternion(-0.91823035, 0.06278634, -0.38804358, 0.04830265)
bones/172/scale = Vector3(0.99999493, 0.9999995, 1.0000055)
bones/173/position = Vector3(0.18381546, -0.96226203, 0.9894083)
bones/173/rotation = Quaternion(0.9362244, 3.755922e-07, 0.3412715, -0.0837717)
bones/173/scale = Vector3(1.0000001, 1.0000001, 0.9999949)
bones/183/position = Vector3(-1.982537e-07, 5.9604563e-08, -1.517833e-08)
bones/185/rotation = Quaternion(5.4077844e-07, -0.20349081, 0.97907686, -1.12395135e-07)
bones/186/position = Vector3(0.78680634, 2.8457582, -0.41063747)
bones/186/rotation = Quaternion(-0.9983755, 0.019092962, -0.050729975, -0.017562928)
bones/186/scale = Vector3(0.9999997, 0.99999994, 1)
bones/187/rotation = Quaternion(0.15451065, -2.0305349e-09, -2.0850066e-09, 0.9879911)
bones/187/scale = Vector3(1.0000002, 0.99999994, 0.9999999)
bones/197/position = Vector3(7.903883e-08, 1.4901151e-07, 8.8932055e-08)
bones/199/rotation = Quaternion(0.00034800146, -0.20349097, 0.9790768, -7.2328476e-05)
bones/200/position = Vector3(-0.84339374, 2.905353, -0.57784474)
bones/200/rotation = Quaternion(-0.9983755, 0.019092962, -0.050729975, -0.017562928)
bones/200/scale = Vector3(0.9999997, 0.99999994, 1)
bones/201/rotation = Quaternion(0.15451066, -1.9585848e-09, -2.5450761e-09, 0.9879911)
bones/201/scale = Vector3(1.0000002, 0.99999994, 0.99999994)
[node name="Bear_FX" parent="bear_model" unique_id=2070553519 instance=ExtResource("3_bearfx")]
[node name="test_cube" type="Node3D" parent="." unique_id=646988893]
script = ExtResource("3_rog1v")
[node name="Bear_fx_claw_attack_R" parent="bear_model/Bear_FX" index="2" unique_id=1939248432]
surface_material_override/0 = ExtResource("4_clawfx")
[node name="Bear_FX" parent="test_cube" unique_id=1183391245 instance=ExtResource("4_rog1v")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.1459732, 0, -1.528423)
[node name="Bear_fx_claw_attack_L" parent="bear_model/Bear_FX" index="3" unique_id=834640978]
surface_material_override/0 = ExtResource("4_clawfx")
[node name="Bear_fx_claw_attack_R" parent="test_cube/Bear_FX" index="1" unique_id=941189652]
transform = Transform3D(0.26165774, 0.06970292, -0.23443498, -0.046572562, 0.18028688, 0.0016228362, 0.22878301, 0.056650188, 0.2721929, -0.40204993, 0.29855162, 0.917461)
[node name="AttackHitboxes" parent="bear_model" instance=ExtResource("5_hitboxes")]
[editable path="bear_model"]
[editable path="test_cube/Bear_FX"]
[editable path="bear_model/Bear_FX"]
+319
View File
@@ -0,0 +1,319 @@
[gd_scene format=3 uid="uid://o8ocjfprxa7u"]
[ext_resource type="Script" uid="uid://cn7fhjkro7637" path="res://bear.gd" id="1_beargd"]
[ext_resource type="PackedScene" uid="uid://cofv5dbavesis" path="res://Assets/Bear.glb" id="2_bearglb"]
[ext_resource type="Script" uid="uid://bsbed05ifr18s" path="res://bear_test_cube.gd" id="3_rog1v"]
[ext_resource type="PackedScene" uid="uid://bdbx0wwa73rhp" path="res://Assets/fx/Bear_FX.glb" id="4_rog1v"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_body"]
radius = 1.0
height = 2.4
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_hit"]
radius = 1.3
height = 2.7
[sub_resource type="BoxShape3D" id="BoxShape3D_bfebr"]
size = Vector3(6.2019043, 8.561401, 7.0739746)
[sub_resource type="BoxShape3D" id="BoxShape3D_rog1v"]
size = Vector3(14.399288, 51.902206, 5.741211)
[node name="Bear" type="CharacterBody3D" unique_id=1573237287]
script = ExtResource("1_beargd")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=830443382]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 0)
shape = SubResource("CapsuleShape3D_body")
[node name="HitArea" type="Area3D" parent="." unique_id=365327397]
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="HitArea" unique_id=2111867348]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.35, 0)
shape = SubResource("CapsuleShape3D_hit")
[node name="bear_model" parent="." unique_id=359217823 instance=ExtResource("2_bearglb")]
[node name="test_cube" type="Node3D" parent="bear_model" unique_id=646988893]
script = ExtResource("3_rog1v")
[node name="Bear_FX" parent="bear_model/test_cube" unique_id=1183391245 instance=ExtResource("4_rog1v")]
[node name="Bear_fx_jump_smash" parent="bear_model/test_cube/Bear_FX" index="0" unique_id=750478984]
visible = false
[node name="Bear_fx_claw_attack_R" parent="bear_model/test_cube/Bear_FX" index="1" unique_id=88064381]
visible = false
[node name="Bear_fx_claw_attack_L" parent="bear_model/test_cube/Bear_FX" index="2" unique_id=1378755061]
visible = false
[node name="Bear_fx_smash_hit" parent="bear_model/test_cube/Bear_FX" index="3" unique_id=1711579105]
transform = Transform3D(0.55488384, -0.039024748, -0.018949924, 0.041069064, 0.55086076, 0.06814586, 0.013977209, -0.06933683, 0.5520644, 1.327292, -0.21312934, 5.190573)
[node name="RigidBody3D" type="AnimatableBody3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit" index="0" unique_id=1764208051]
transform = Transform3D(1.0000001, -1.21071935e-08, -1.8626451e-08, -9.313226e-10, 0.99999994, 7.450581e-09, 3.7252903e-09, -1.4901161e-08, 0.99999994, 0, 0, 0)
collision_layer = 8
collision_mask = 2
[node name="CollisionShape3D2" type="CollisionShape3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit/RigidBody3D" unique_id=1779197150]
transform = Transform3D(0.99993557, -0.00749125, -0.010078691, 0.0077760145, 0.999569, 0.028562747, 0.009858355, -0.028639637, 0.9995405, -1.5136471, 0.9093375, 35.591957)
shape = SubResource("BoxShape3D_bfebr")
disabled = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit/RigidBody3D" unique_id=1276552823]
transform = Transform3D(0.9935104, -0.040698394, -0.10621016, -0.108634494, -0.06290151, -0.9920882, 0.03369555, 0.99719334, -0.06691426, -1.6357545, -0.5093044, 12.68803)
shape = SubResource("BoxShape3D_rog1v")
[node name="Skeleton3D" parent="bear_model/bear-rig" parent_id_path=PackedInt32Array(359217823, 1017999212) index="0" unique_id=1624609914]
bones/1/position = Vector3(0.00851878, 0.24701798, 1.2888045)
bones/1/rotation = Quaternion(0.29791054, -0.060797628, -0.056875575, 0.9509564)
bones/2/rotation = Quaternion(0.084239505, -0.026013458, 0.009274505, 0.9960628)
bones/2/scale = Vector3(0.9999999, 1.0000008, 0.99999934)
bones/3/rotation = Quaternion(-0.14812404, -0.039577905, 0.049865585, 0.98691756)
bones/4/rotation = Quaternion(-0.40577498, -0.03082885, 0.05040324, 0.9120612)
bones/5/rotation = Quaternion(0.27801633, 0.0014148077, 0.015671793, 0.96044755)
bones/6/rotation = Quaternion(0.50370073, 0.13519946, -0.093789615, 0.8480627)
bones/7/rotation = Quaternion(0.75079185, 0.54212743, -0.37154716, 0.06604591)
bones/8/rotation = Quaternion(0.22344273, -0.32689556, 0.65874565, -0.63973963)
bones/9/rotation = Quaternion(0.026405705, -0.27415153, -0.3226086, 0.9055757)
bones/10/rotation = Quaternion(0.030285481, -0.31167626, -0.037417818, 0.94896823)
bones/11/rotation = Quaternion(0.751943, -0.5788067, 0.30500817, 0.080837056)
bones/12/rotation = Quaternion(0.28422552, 0.2936944, -0.68526876, -0.6027987)
bones/13/rotation = Quaternion(0.020711409, 0.24585825, 0.3386082, 0.9080029)
bones/14/rotation = Quaternion(0.098969, 0.19860524, -0.007872087, 0.97503805)
bones/15/rotation = Quaternion(0.6979166, 0.16086513, -0.15598965, 0.680222)
bones/16/rotation = Quaternion(0.89734674, 0.09874082, -0.25790086, 0.34424722)
bones/17/rotation = Quaternion(-0.13802421, 0.26758972, 0.081159085, 0.9501359)
bones/17/scale = Vector3(0.9999998, 1.0000002, 1)
bones/19/rotation = Quaternion(-4.514978e-15, 1, 7.4505806e-08, -5.523351e-07)
bones/20/rotation = Quaternion(-0.49266306, -0.27058616, 0.262383, 0.7843606)
bones/21/rotation = Quaternion(0.0016915401, 0.70246154, -0.001669446, 0.7117178)
bones/22/rotation = Quaternion(-0.5496364, -0.3220462, -0.22350304, 0.73772115)
bones/22/scale = Vector3(0.9999997, 0.9999998, 0.9999999)
bones/23/rotation = Quaternion(-0.00015351747, 0.902104, -0.4315187, 0.00032039074)
bones/24/rotation = Quaternion(6.628114e-12, 0.99999994, 5.2154085e-08, -0.00035543842)
bones/25/position = Vector3(1.0191536, 3.5353048, 3.5049686)
bones/25/rotation = Quaternion(-0.087474234, 0.16733547, 0.98056763, 0.053239316)
bones/25/scale = Vector3(1, 17.518272, 1.0000001)
bones/26/position = Vector3(-1.0831825, 3.749937, 2.5891113)
bones/26/rotation = Quaternion(0.016340872, 0.19671263, 0.9801456, 0.01875816)
bones/26/scale = Vector3(1.0000001, 18.765795, 1)
bones/27/position = Vector3(1.0193456, -0.43209565, 2.5343885)
bones/27/rotation = Quaternion(0.61800283, -0.11976056, 0.11976072, 0.7677157)
bones/27/scale = Vector3(0.99999994, 16.85072, 1)
bones/28/position = Vector3(-0.8340287, 1.0348616, 1.282705)
bones/28/rotation = Quaternion(0.82860446, -0.029359974, 0.02935981, 0.5582926)
bones/28/scale = Vector3(0.99999994, 32.068844, 1)
bones/30/position = Vector3(0.032563455, -0.8335703, -0.9236449)
bones/30/rotation = Quaternion(-0.8670657, 0.042821795, -0.07139772, 0.4911883)
bones/31/position = Vector3(2.3450447e-08, -1.4631646, 0.23291242)
bones/31/rotation = Quaternion(-6.0737464e-09, 4.8699293e-09, -1.4618977e-09, 1)
bones/31/scale = Vector3(0.99999994, 0.9999999, 0.99999994)
bones/32/position = Vector3(-0.04394375, -1.087056, 0.096768975)
bones/32/rotation = Quaternion(-0.8343034, 0.119118, -0.061490715, 0.5347595)
bones/32/scale = Vector3(0.9999999, 0.99999976, 0.99999964)
bones/33/position = Vector3(3.977649e-08, -1.4631644, 0.23291251)
bones/33/rotation = Quaternion(-8.833673e-08, -2.419923e-08, -6.733043e-09, 1)
bones/33/scale = Vector3(0.9999998, 0.9999998, 0.99999994)
bones/35/position = Vector3(1.0184407e-08, -1.0594703, -5.9146995e-08)
bones/35/rotation = Quaternion(0.99971783, 1.3593646e-07, 5.3695976e-06, -0.023754615)
bones/35/scale = Vector3(0.99999976, 0.9999998, 1.0000012)
bones/39/position = Vector3(0.8199172, 0.25251278, 0.47214246)
bones/39/rotation = Quaternion(0.71402234, 0.34199142, 0.043267474, 0.60937834)
bones/39/scale = Vector3(1.0000004, 0.9999996, 0.9999991)
bones/40/rotation = Quaternion(0.9336719, 1.2799235e-07, 3.7337827e-08, 0.3581296)
bones/40/scale = Vector3(1.0000004, 1.0000001, 1.0000001)
bones/41/rotation = Quaternion(-0.13802455, 0.26758966, 0.08115916, 0.9501359)
bones/41/scale = Vector3(0.99999946, 0.99999976, 0.9999996)
bones/42/position = Vector3(-1.9729964e-07, 0.56145483, 7.283501e-08)
bones/46/scale = Vector3(0.99999946, 0.99999964, 0.9999999)
bones/48/rotation = Quaternion(-2.9741386e-07, 0.13593404, 1.01778824e-07, 0.9907179)
bones/48/scale = Vector3(0.9999993, 0.9999996, 0.9999999)
bones/50/scale = Vector3(0.99999994, 0.99999994, 0.9999998)
bones/51/rotation = Quaternion(-2.5567479e-08, -0.20499781, -2.3086146e-08, 0.9787625)
bones/51/scale = Vector3(0.9999999, 0.99999964, 0.99999964)
bones/53/position = Vector3(-0.8199191, 0.25251284, 0.47213903)
bones/53/rotation = Quaternion(-0.5351706, 0.35860845, -0.15898216, 0.74814254)
bones/53/scale = Vector3(1, 0.99999875, 0.99999946)
bones/54/rotation = Quaternion(0.0023762286, -4.7362324e-08, -6.475868e-08, 0.9999972)
bones/55/rotation = Quaternion(-0.54963607, -0.322046, -0.22350314, 0.73772144)
bones/55/scale = Vector3(1.0000002, 1, 1.0000002)
bones/56/position = Vector3(0.0013532753, 0.57868266, 0.05537574)
bones/56/rotation = Quaternion(-0.00015348212, 0.90210384, -0.43151882, 0.0003204293)
bones/57/rotation = Quaternion(0.70073944, -0.70073956, -0.094679825, -0.09467953)
bones/60/scale = Vector3(1.0000004, 1.0000004, 1.0000002)
bones/62/rotation = Quaternion(-1.7092354e-08, -0.18223058, 2.6700846e-08, 0.98325586)
bones/62/scale = Vector3(1.0000002, 1.0000002, 1.0000001)
bones/64/scale = Vector3(1.0000004, 1.0000004, 1)
bones/65/rotation = Quaternion(-1.0345744e-08, -0.3796584, -4.0675246e-08, 0.9251268)
bones/65/scale = Vector3(1.0000002, 1.0000004, 1.0000004)
bones/67/rotation = Quaternion(0.7179022, -7.671307e-07, 7.885642e-07, 0.696144)
bones/67/scale = Vector3(1.0000004, 0.9999986, 0.99999994)
bones/68/rotation = Quaternion(0.9776482, 2.0029378e-07, 1.0460874e-06, -0.2102479)
bones/68/scale = Vector3(1.0000004, 1.0000004, 0.9999982)
bones/69/position = Vector3(-2.4645832e-08, -6.861796e-09, 7.455772e-08)
bones/69/rotation = Quaternion(-0.8315212, 2.5276703e-08, -9.3330055e-09, 0.5554931)
bones/69/scale = Vector3(1, 1.0000001, 1.0000002)
bones/70/rotation = Quaternion(0.67750055, 8.820757e-08, 7.575834e-08, 0.7355223)
bones/70/scale = Vector3(1, 1, 1)
bones/71/scale = Vector3(0.9999999, 1, 0.9999999)
bones/72/rotation = Quaternion(-2.1641608e-07, -4.6565607e-10, -4.6576065e-10, 1)
bones/75/rotation = Quaternion(-0.34314692, -0.20321459, -0.2785586, 0.8737043)
bones/76/position = Vector3(1.01587794e-07, -1.5306958e-07, -4.3554866e-07)
bones/76/rotation = Quaternion(-0.51764834, -7.167482e-08, 1.7163823e-07, 0.85559356)
bones/77/rotation = Quaternion(0.93367195, 1.2110854e-07, 3.8556042e-08, 0.35812962)
bones/78/position = Vector3(0.8199172, 0.25251257, 0.47214243)
bones/78/rotation = Quaternion(0.6979164, 0.16086517, -0.15598962, 0.6802223)
bones/78/scale = Vector3(1.0000004, 0.9999997, 0.99999905)
bones/80/rotation = Quaternion(0.7179022, -7.6713064e-07, 7.885641e-07, 0.696144)
bones/80/scale = Vector3(1.0000004, 0.9999986, 0.99999994)
bones/81/rotation = Quaternion(0.97764814, 1.9846473e-07, 1.0426893e-06, -0.21024783)
bones/81/scale = Vector3(1.0000004, 1.0000002, 0.9999982)
bones/82/position = Vector3(6.103571e-08, 8.8816435e-08, -3.6955274e-09)
bones/82/rotation = Quaternion(-0.8315211, 2.3407136e-08, -1.2821512e-08, 0.5554932)
bones/82/scale = Vector3(0.99999994, 0.99999994, 1)
bones/83/rotation = Quaternion(0.6775009, -8.600083e-08, -8.977273e-08, 0.735522)
bones/83/scale = Vector3(1, 1.0000001, 1)
bones/84/scale = Vector3(0.99999994, 1.0000001, 0.9999999)
bones/85/rotation = Quaternion(2.6833732e-07, -9.313788e-10, -2.5612494e-09, 1)
bones/85/scale = Vector3(1.0000001, 1, 1.0000001)
bones/87/rotation = Quaternion(-0.5230753, 0.20132942, 0.026226493, 0.8277505)
bones/88/rotation = Quaternion(0.61967987, 0.23118778, 0.3169036, 0.679795)
bones/89/position = Vector3(2.953037e-07, 4.9207458e-08, -4.3015167e-08)
bones/89/rotation = Quaternion(-0.001144886, -2.973514e-08, 2.817069e-08, 0.9999994)
bones/90/rotation = Quaternion(0.0023764072, -4.0769752e-08, -7.0690255e-08, 0.99999726)
bones/91/position = Vector3(-0.8199192, 0.2525128, 0.47213912)
bones/91/rotation = Quaternion(-0.49266297, -0.27058598, 0.2623832, 0.78436047)
bones/91/scale = Vector3(1.0000002, 0.999999, 0.99999964)
bones/96/position = Vector3(-0.021971898, -1.2751104, 0.16484088)
bones/96/rotation = Quaternion(-0.47603267, 0.067788206, -0.035077166, 0.8761091)
bones/96/scale = Vector3(0.9999999, 0.9999999, 0.99999976)
bones/97/rotation = Quaternion(0.997074, -1.2813135e-07, 1.666339e-06, -0.07644201)
bones/98/position = Vector3(0.01993539, 0.08757691, 0.045667563)
bones/98/rotation = Quaternion(0.1475291, 0.03397043, -0.019923227, 0.9882734)
bones/98/scale = Vector3(1, 1.0000011, 1.0000023)
bones/101/position = Vector3(-0.021972047, 0.8282039, 0.0959422)
bones/101/rotation = Quaternion(0.8371564, 0.04015539, 0.06490996, 0.5416119)
bones/101/scale = Vector3(1, 1.0000066, 0.99998474)
bones/102/rotation = Quaternion(0.95545256, -6.924111e-08, 2.2887033e-07, -0.29514462)
bones/103/position = Vector3(0.17285576, 0.72785676, 1.0822707)
bones/103/rotation = Quaternion(0.27801546, 0.0014157619, 0.015671493, 0.9604477)
bones/103/scale = Vector3(1.0000002, 1.000013, 1.0000246)
bones/104/rotation = Quaternion(0.5037003, 0.13519715, -0.093790196, 0.84806323)
bones/104/scale = Vector3(1.0000721, 1.0000457, 0.99993384)
bones/105/rotation = Quaternion(0.97757924, -0.053521663, -0.054415643, -0.19624804)
bones/105/scale = Vector3(1.0000001, 1.0000083, 1.0000036)
bones/106/position = Vector3(0.023142539, -0.54231995, -0.9607401)
bones/106/rotation = Quaternion(0.99272084, -0.08158898, -0.03307842, -0.08218607)
bones/107/rotation = Quaternion(0.903578, -0.12777254, -0.05477002, -0.4052421)
bones/107/scale = Vector3(0.9999992, 0.9999624, 1.0000123)
bones/108/position = Vector3(-1.1340098e-08, 7.923448e-07, 9.0939814e-08)
bones/108/rotation = Quaternion(0.98967296, 0.0031370325, 0.10343237, -0.09919364)
bones/110/rotation = Quaternion(9.815354e-07, 7.072085e-10, -9.586452e-08, 1)
bones/110/scale = Vector3(0.99999994, 0.99999976, 1.0000001)
bones/113/position = Vector3(0.07716276, 0.6410925, 0.71644557)
bones/113/rotation = Quaternion(0.75079244, 0.54212654, -0.3715475, 0.0660462)
bones/114/position = Vector3(-0.031743176, 0.60466695, -0.39704067)
bones/114/rotation = Quaternion(0.4176498, -0.11118397, 0.55639553, -0.70966953)
bones/114/scale = Vector3(1.0000015, 1.0000038, 1.0000079)
bones/115/rotation = Quaternion(-0.07547326, 0.02173067, -0.31477332, 0.945912)
bones/115/scale = Vector3(0.9999974, 1.0000036, 0.99999976)
bones/116/rotation = Quaternion(0.03028559, -0.3116764, -0.037417784, 0.9489682)
bones/116/scale = Vector3(1.0000005, 0.9999972, 1.0000013)
bones/119/scale = Vector3(1.0000043, 0.9999975, 0.99999744)
bones/121/rotation = Quaternion(-4.820391e-08, -0.1579088, -2.0880496e-08, 0.98745376)
bones/121/scale = Vector3(1.0000037, 0.99999774, 0.9999977)
bones/123/scale = Vector3(1.000003, 0.9999977, 0.99999917)
bones/124/rotation = Quaternion(-3.1036683e-07, 0.17317644, 6.989145e-08, 0.9848908)
bones/124/scale = Vector3(1.0000037, 0.9999978, 0.99999875)
bones/126/rotation = Quaternion(-0.5163543, -0.16816929, 0.6340875, 0.550482)
bones/126/scale = Vector3(1.0000015, 1.000007, 1.000004)
bones/127/rotation = Quaternion(-0.24332331, 0.12663932, 0.6612194, 0.6982444)
bones/127/scale = Vector3(1.0000017, 1.0000014, 1.0000097)
bones/128/position = Vector3(-0.008928956, 0.128764, -0.06877987)
bones/128/rotation = Quaternion(0.025037244, 0.39930493, -0.88358396, 0.24332726)
bones/129/rotation = Quaternion(-0.07547334, 0.021730714, -0.31477335, 0.94591194)
bones/131/rotation = Quaternion(-0.41802245, -0.28161782, 0.08442414, 0.85954714)
bones/132/rotation = Quaternion(-0.5281791, -0.34319904, -0.62196887, -0.46518382)
bones/133/rotation = Quaternion(-0.012777329, 0.011854946, 0.00015161165, 0.9998482)
bones/133/scale = Vector3(1.0423008, 1.0423008, 1.0423006)
bones/134/rotation = Quaternion(0.02152103, -3.688601e-08, -1.5255387e-07, 0.99976844)
bones/134/scale = Vector3(0.9882629, 0.9882634, 0.98826265)
bones/135/position = Vector3(-0.0317431, 0.60466677, -0.39704087)
bones/135/rotation = Quaternion(0.22344373, -0.32689255, 0.658746, -0.6397405)
bones/135/scale = Vector3(1.0000048, 1.0000036, 1.0000046)
bones/137/position = Vector3(-0.33244255, 0.70370555, 0.67530614)
bones/137/rotation = Quaternion(0.7519437, -0.5788053, 0.30500948, 0.08083551)
bones/138/position = Vector3(-0.19594865, 0.65740275, -0.22511396)
bones/138/rotation = Quaternion(0.36201134, 0.22157827, -0.6475769, -0.63284683)
bones/138/scale = Vector3(1.0000019, 1.0000045, 1.0000057)
bones/139/rotation = Quaternion(-0.018797327, 0.13857716, 0.33871746, 0.9304373)
bones/139/scale = Vector3(0.9999983, 1.0000024, 0.9999992)
bones/140/rotation = Quaternion(0.09896898, 0.1986053, -0.00787212, 0.975038)
bones/140/scale = Vector3(1.0000031, 0.9999977, 0.9999988)
bones/143/scale = Vector3(1.000005, 0.99999815, 0.9999967)
bones/145/rotation = Quaternion(-1.7910523e-07, 0.10005118, -9.714451e-08, 0.9949823)
bones/145/scale = Vector3(1.0000045, 0.99999803, 0.9999968)
bones/147/scale = Vector3(1.0000035, 0.99999845, 0.9999981)
bones/148/rotation = Quaternion(2.0844507e-07, 0.011625211, 4.5709146e-07, 0.9999325)
bones/148/scale = Vector3(1.000004, 0.9999991, 0.999998)
bones/150/rotation = Quaternion(-0.51635444, 0.16816957, -0.63408744, 0.55048186)
bones/150/scale = Vector3(1.000001, 1.0000067, 1.000004)
bones/151/rotation = Quaternion(-0.24332346, -0.12663896, -0.6612195, 0.6982443)
bones/151/scale = Vector3(1.0000011, 1.0000017, 1.0000095)
bones/152/position = Vector3(0.027921734, -0.124764316, 0.07102555)
bones/152/rotation = Quaternion(-0.12973516, 0.47151387, -0.86254627, -0.12983702)
bones/153/rotation = Quaternion(-0.018797398, 0.13857722, 0.33871746, 0.9304373)
bones/155/rotation = Quaternion(-0.36541468, 0.16190512, -0.07102372, 0.91390073)
bones/155/scale = Vector3(0.99999994, 1, 0.9999998)
bones/156/rotation = Quaternion(0.68045896, -0.19169958, -0.3896983, 0.59022206)
bones/157/rotation = Quaternion(-0.01277751, -0.011854968, -0.0001513001, 0.9998481)
bones/157/scale = Vector3(1.0423003, 1.0422994, 1.0423005)
bones/158/rotation = Quaternion(0.021521209, -2.5687226e-07, -2.570953e-07, 0.9997684)
bones/158/scale = Vector3(0.9882631, 0.98826426, 0.9882618)
bones/159/position = Vector3(-0.19594839, 0.65740275, -0.2251139)
bones/159/rotation = Quaternion(0.28422734, 0.29369113, -0.68527013, -0.60279787)
bones/159/scale = Vector3(1.0000027, 1.0000043, 1.0000049)
bones/161/position = Vector3(0.07716276, 0.6410925, 0.71644557)
bones/161/rotation = Quaternion(0.75079244, 0.54212654, -0.3715475, 0.0660462)
bones/162/position = Vector3(-0.33244255, 0.70370555, 0.67530614)
bones/162/rotation = Quaternion(0.7519437, -0.5788053, 0.30500948, 0.08083551)
bones/165/position = Vector3(-1.5017577e-08, 0.26895812, -1.6243575e-08)
bones/165/rotation = Quaternion(-0.019247467, -0.20323175, 0.97894067, -0.0012537595)
bones/166/position = Vector3(0.0034187725, -3.131728, 0.9674823)
bones/167/position = Vector3(0.209171, 5.0901713, -2.6670303)
bones/167/rotation = Quaternion(0.16656846, 0.015223213, 0.18356222, 0.9686734)
bones/167/scale = Vector3(0.9999988, 0.9999987, 1.0000023)
bones/168/position = Vector3(0.18381567, -0.9622623, 0.9894084)
bones/168/rotation = Quaternion(0.9362244, -6.2652596e-08, -0.34127164, -0.083770975)
bones/168/scale = Vector3(1.0000011, 1.0000015, 1.0000101)
bones/170/position = Vector3(0.748137, 0.69556385, 3.7252903e-09)
bones/170/rotation = Quaternion(0.019250846, -0.20323181, 0.9789406, 0.001253055)
bones/171/position = Vector3(0.6322718, -2.6572587, 0.6064028)
bones/172/position = Vector3(-1.5122895, 4.4686184, -2.7014794)
bones/172/rotation = Quaternion(0.21553025, -0.03620148, 0.11066054, 0.9695311)
bones/172/scale = Vector3(0.99999887, 0.9999985, 1.0000024)
bones/173/position = Vector3(0.18381546, -0.96226203, 0.9894083)
bones/173/rotation = Quaternion(0.93622434, -2.9748788e-08, 0.34127158, -0.083771475)
bones/173/scale = Vector3(0.999999, 1.0000014, 0.99999464)
bones/175/position = Vector3(0.2542465, -2.2077389, 0.9589075)
bones/175/rotation = Quaternion(-0.008919476, -0.00021326332, -0.000697989, 0.99996)
bones/183/position = Vector3(-1.982537e-07, 5.9604563e-08, -1.517833e-08)
bones/185/rotation = Quaternion(5.4077844e-07, -0.20349081, 0.97907686, -1.12395135e-07)
bones/186/position = Vector3(0.57634556, 3.7607954, 0.15364014)
bones/186/rotation = Quaternion(-0.9604305, -0.020206233, -0.08076539, -0.26578543)
bones/186/scale = Vector3(0.9999997, 0.99999994, 1)
bones/187/rotation = Quaternion(0.15451065, -2.0305349e-09, -2.0850066e-09, 0.9879911)
bones/187/scale = Vector3(1.0000002, 0.99999994, 0.9999999)
bones/197/position = Vector3(-0.0011225368, -0.015787723, -0.051779967)
bones/199/rotation = Quaternion(0.00034800146, -0.20349097, 0.9790768, -7.2328476e-05)
bones/200/position = Vector3(-1.0407574, 3.6267605, -0.083099455)
bones/200/rotation = Quaternion(-0.9604305, -0.020206233, -0.08076539, -0.26578543)
bones/200/scale = Vector3(0.9999997, 0.99999994, 1)
bones/201/rotation = Quaternion(0.15451066, -1.9585848e-09, -2.5450761e-09, 0.9879911)
bones/201/scale = Vector3(1.0000002, 0.99999994, 0.99999994)
[editable path="bear_model"]
[editable path="bear_model/test_cube/Bear_FX"]
+319
View File
@@ -0,0 +1,319 @@
[gd_scene format=3 uid="uid://o8ocjfprxa7u"]
[ext_resource type="Script" uid="uid://cn7fhjkro7637" path="res://bear.gd" id="1_beargd"]
[ext_resource type="PackedScene" uid="uid://cofv5dbavesis" path="res://Assets/Bear.glb" id="2_bearglb"]
[ext_resource type="Script" uid="uid://bsbed05ifr18s" path="res://bear_test_cube.gd" id="3_rog1v"]
[ext_resource type="PackedScene" uid="uid://bdbx0wwa73rhp" path="res://Assets/fx/Bear_FX.glb" id="4_rog1v"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_body"]
radius = 1.0
height = 2.4
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_hit"]
radius = 1.3
height = 2.7
[sub_resource type="BoxShape3D" id="BoxShape3D_bfebr"]
size = Vector3(6.2019043, 8.561401, 7.0739746)
[sub_resource type="BoxShape3D" id="BoxShape3D_rog1v"]
size = Vector3(14.399288, 51.902206, 5.741211)
[node name="Bear" type="CharacterBody3D" unique_id=1573237287]
script = ExtResource("1_beargd")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=830443382]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 0)
shape = SubResource("CapsuleShape3D_body")
[node name="HitArea" type="Area3D" parent="." unique_id=365327397]
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="HitArea" unique_id=2111867348]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.35, 0)
shape = SubResource("CapsuleShape3D_hit")
[node name="bear_model" parent="." unique_id=359217823 instance=ExtResource("2_bearglb")]
[node name="test_cube" type="Node3D" parent="bear_model" unique_id=646988893]
script = ExtResource("3_rog1v")
[node name="Bear_FX" parent="bear_model/test_cube" unique_id=1183391245 instance=ExtResource("4_rog1v")]
[node name="Bear_fx_jump_smash" parent="bear_model/test_cube/Bear_FX" index="0" unique_id=750478984]
visible = false
[node name="Bear_fx_claw_attack_R" parent="bear_model/test_cube/Bear_FX" index="1" unique_id=88064381]
visible = false
[node name="Bear_fx_claw_attack_L" parent="bear_model/test_cube/Bear_FX" index="2" unique_id=1378755061]
visible = false
[node name="Bear_fx_smash_hit" parent="bear_model/test_cube/Bear_FX" index="3" unique_id=1711579105]
transform = Transform3D(0.55488384, -0.039024748, -0.018949924, 0.041069064, 0.55086076, 0.06814586, 0.013977209, -0.06933683, 0.5520644, 1.327292, -0.21312934, 5.190573)
[node name="RigidBody3D" type="AnimatableBody3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit" index="0" unique_id=1764208051]
transform = Transform3D(1.0000001, -1.21071935e-08, -1.8626451e-08, -9.313226e-10, 0.99999994, 7.450581e-09, 3.7252903e-09, -1.4901161e-08, 0.99999994, 0, 0, 0)
collision_layer = 8
collision_mask = 2
[node name="CollisionShape3D2" type="CollisionShape3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit/RigidBody3D" unique_id=1779197150]
transform = Transform3D(0.99993557, -0.00749125, -0.010078691, 0.0077760145, 0.999569, 0.028562747, 0.009858355, -0.028639637, 0.9995405, -1.5136471, 0.9093375, 35.591957)
shape = SubResource("BoxShape3D_bfebr")
disabled = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit/RigidBody3D" unique_id=1276552823]
transform = Transform3D(0.9935104, -0.040698394, -0.10621016, -0.108634494, -0.06290151, -0.9920882, 0.03369555, 0.99719334, -0.06691426, -1.6357545, -0.5093044, 12.68803)
shape = SubResource("BoxShape3D_rog1v")
[node name="Skeleton3D" parent="bear_model/bear-rig" parent_id_path=PackedInt32Array(359217823, 1017999212) index="0" unique_id=1624609914]
bones/1/position = Vector3(0.00851878, 0.24701798, 1.2888045)
bones/1/rotation = Quaternion(0.29791054, -0.060797628, -0.056875575, 0.9509564)
bones/2/rotation = Quaternion(0.084239505, -0.026013458, 0.009274505, 0.9960628)
bones/2/scale = Vector3(0.9999999, 1.0000008, 0.99999934)
bones/3/rotation = Quaternion(-0.14812404, -0.039577905, 0.049865585, 0.98691756)
bones/4/rotation = Quaternion(-0.40577498, -0.03082885, 0.05040324, 0.9120612)
bones/5/rotation = Quaternion(0.27801633, 0.0014148077, 0.015671793, 0.96044755)
bones/6/rotation = Quaternion(0.50370073, 0.13519946, -0.093789615, 0.8480627)
bones/7/rotation = Quaternion(0.75079185, 0.54212743, -0.37154716, 0.06604591)
bones/8/rotation = Quaternion(0.22344273, -0.32689556, 0.65874565, -0.63973963)
bones/9/rotation = Quaternion(0.026405705, -0.27415153, -0.3226086, 0.9055757)
bones/10/rotation = Quaternion(0.030285481, -0.31167626, -0.037417818, 0.94896823)
bones/11/rotation = Quaternion(0.751943, -0.5788067, 0.30500817, 0.080837056)
bones/12/rotation = Quaternion(0.28422552, 0.2936944, -0.68526876, -0.6027987)
bones/13/rotation = Quaternion(0.020711409, 0.24585825, 0.3386082, 0.9080029)
bones/14/rotation = Quaternion(0.098969, 0.19860524, -0.007872087, 0.97503805)
bones/15/rotation = Quaternion(0.6979166, 0.16086513, -0.15598965, 0.680222)
bones/16/rotation = Quaternion(0.89734674, 0.09874082, -0.25790086, 0.34424722)
bones/17/rotation = Quaternion(-0.13802421, 0.26758972, 0.081159085, 0.9501359)
bones/17/scale = Vector3(0.9999998, 1.0000002, 1)
bones/19/rotation = Quaternion(-4.514978e-15, 1, 7.4505806e-08, -5.523351e-07)
bones/20/rotation = Quaternion(-0.49266306, -0.27058616, 0.262383, 0.7843606)
bones/21/rotation = Quaternion(0.0016915401, 0.70246154, -0.001669446, 0.7117178)
bones/22/rotation = Quaternion(-0.5496364, -0.3220462, -0.22350304, 0.73772115)
bones/22/scale = Vector3(0.9999997, 0.9999998, 0.9999999)
bones/23/rotation = Quaternion(-0.00015351747, 0.902104, -0.4315187, 0.00032039074)
bones/24/rotation = Quaternion(6.628114e-12, 0.99999994, 5.2154085e-08, -0.00035543842)
bones/25/position = Vector3(1.0191536, 3.5353048, 3.5049686)
bones/25/rotation = Quaternion(-0.087474234, 0.16733547, 0.98056763, 0.053239316)
bones/25/scale = Vector3(1, 17.518272, 1.0000001)
bones/26/position = Vector3(-1.0831825, 3.749937, 2.5891113)
bones/26/rotation = Quaternion(0.016340872, 0.19671263, 0.9801456, 0.01875816)
bones/26/scale = Vector3(1.0000001, 18.765795, 1)
bones/27/position = Vector3(1.0193456, -0.43209565, 2.5343885)
bones/27/rotation = Quaternion(0.61800283, -0.11976056, 0.11976072, 0.7677157)
bones/27/scale = Vector3(0.99999994, 16.85072, 1)
bones/28/position = Vector3(-0.8340287, 1.0348616, 1.282705)
bones/28/rotation = Quaternion(0.82860446, -0.029359974, 0.02935981, 0.5582926)
bones/28/scale = Vector3(0.99999994, 32.068844, 1)
bones/30/position = Vector3(0.032563455, -0.8335703, -0.9236449)
bones/30/rotation = Quaternion(-0.8670657, 0.042821795, -0.07139772, 0.4911883)
bones/31/position = Vector3(2.3450447e-08, -1.4631646, 0.23291242)
bones/31/rotation = Quaternion(-6.0737464e-09, 4.8699293e-09, -1.4618977e-09, 1)
bones/31/scale = Vector3(0.99999994, 0.9999999, 0.99999994)
bones/32/position = Vector3(-0.04394375, -1.087056, 0.096768975)
bones/32/rotation = Quaternion(-0.8343034, 0.119118, -0.061490715, 0.5347595)
bones/32/scale = Vector3(0.9999999, 0.99999976, 0.99999964)
bones/33/position = Vector3(3.977649e-08, -1.4631644, 0.23291251)
bones/33/rotation = Quaternion(-8.833673e-08, -2.419923e-08, -6.733043e-09, 1)
bones/33/scale = Vector3(0.9999998, 0.9999998, 0.99999994)
bones/35/position = Vector3(1.0184407e-08, -1.0594703, -5.9146995e-08)
bones/35/rotation = Quaternion(0.99971783, 1.3593646e-07, 5.3695976e-06, -0.023754615)
bones/35/scale = Vector3(0.99999976, 0.9999998, 1.0000012)
bones/39/position = Vector3(0.8199172, 0.25251278, 0.47214246)
bones/39/rotation = Quaternion(0.71402234, 0.34199142, 0.043267474, 0.60937834)
bones/39/scale = Vector3(1.0000004, 0.9999996, 0.9999991)
bones/40/rotation = Quaternion(0.9336719, 1.2799235e-07, 3.7337827e-08, 0.3581296)
bones/40/scale = Vector3(1.0000004, 1.0000001, 1.0000001)
bones/41/rotation = Quaternion(-0.13802455, 0.26758966, 0.08115916, 0.9501359)
bones/41/scale = Vector3(0.99999946, 0.99999976, 0.9999996)
bones/42/position = Vector3(-1.9729964e-07, 0.56145483, 7.283501e-08)
bones/46/scale = Vector3(0.99999946, 0.99999964, 0.9999999)
bones/48/rotation = Quaternion(-2.9741386e-07, 0.13593404, 1.01778824e-07, 0.9907179)
bones/48/scale = Vector3(0.9999993, 0.9999996, 0.9999999)
bones/50/scale = Vector3(0.99999994, 0.99999994, 0.9999998)
bones/51/rotation = Quaternion(-2.5567479e-08, -0.20499781, -2.3086146e-08, 0.9787625)
bones/51/scale = Vector3(0.9999999, 0.99999964, 0.99999964)
bones/53/position = Vector3(-0.8199191, 0.25251284, 0.47213903)
bones/53/rotation = Quaternion(-0.5351706, 0.35860845, -0.15898216, 0.74814254)
bones/53/scale = Vector3(1, 0.99999875, 0.99999946)
bones/54/rotation = Quaternion(0.0023762286, -4.7362324e-08, -6.475868e-08, 0.9999972)
bones/55/rotation = Quaternion(-0.54963607, -0.322046, -0.22350314, 0.73772144)
bones/55/scale = Vector3(1.0000002, 1, 1.0000002)
bones/56/position = Vector3(0.0013532753, 0.57868266, 0.05537574)
bones/56/rotation = Quaternion(-0.00015348212, 0.90210384, -0.43151882, 0.0003204293)
bones/57/rotation = Quaternion(0.70073944, -0.70073956, -0.094679825, -0.09467953)
bones/60/scale = Vector3(1.0000004, 1.0000004, 1.0000002)
bones/62/rotation = Quaternion(-1.7092354e-08, -0.18223058, 2.6700846e-08, 0.98325586)
bones/62/scale = Vector3(1.0000002, 1.0000002, 1.0000001)
bones/64/scale = Vector3(1.0000004, 1.0000004, 1)
bones/65/rotation = Quaternion(-1.0345744e-08, -0.3796584, -4.0675246e-08, 0.9251268)
bones/65/scale = Vector3(1.0000002, 1.0000004, 1.0000004)
bones/67/rotation = Quaternion(0.7179022, -7.671307e-07, 7.885642e-07, 0.696144)
bones/67/scale = Vector3(1.0000004, 0.9999986, 0.99999994)
bones/68/rotation = Quaternion(0.9776482, 2.0029378e-07, 1.0460874e-06, -0.2102479)
bones/68/scale = Vector3(1.0000004, 1.0000004, 0.9999982)
bones/69/position = Vector3(-2.4645832e-08, -6.861796e-09, 7.455772e-08)
bones/69/rotation = Quaternion(-0.8315212, 2.5276703e-08, -9.3330055e-09, 0.5554931)
bones/69/scale = Vector3(1, 1.0000001, 1.0000002)
bones/70/rotation = Quaternion(0.67750055, 8.820757e-08, 7.575834e-08, 0.7355223)
bones/70/scale = Vector3(1, 1, 1)
bones/71/scale = Vector3(0.9999999, 1, 0.9999999)
bones/72/rotation = Quaternion(-2.1641608e-07, -4.6565607e-10, -4.6576065e-10, 1)
bones/75/rotation = Quaternion(-0.34314692, -0.20321459, -0.2785586, 0.8737043)
bones/76/position = Vector3(1.01587794e-07, -1.5306958e-07, -4.3554866e-07)
bones/76/rotation = Quaternion(-0.51764834, -7.167482e-08, 1.7163823e-07, 0.85559356)
bones/77/rotation = Quaternion(0.93367195, 1.2110854e-07, 3.8556042e-08, 0.35812962)
bones/78/position = Vector3(0.8199172, 0.25251257, 0.47214243)
bones/78/rotation = Quaternion(0.6979164, 0.16086517, -0.15598962, 0.6802223)
bones/78/scale = Vector3(1.0000004, 0.9999997, 0.99999905)
bones/80/rotation = Quaternion(0.7179022, -7.6713064e-07, 7.885641e-07, 0.696144)
bones/80/scale = Vector3(1.0000004, 0.9999986, 0.99999994)
bones/81/rotation = Quaternion(0.97764814, 1.9846473e-07, 1.0426893e-06, -0.21024783)
bones/81/scale = Vector3(1.0000004, 1.0000002, 0.9999982)
bones/82/position = Vector3(6.103571e-08, 8.8816435e-08, -3.6955274e-09)
bones/82/rotation = Quaternion(-0.8315211, 2.3407136e-08, -1.2821512e-08, 0.5554932)
bones/82/scale = Vector3(0.99999994, 0.99999994, 1)
bones/83/rotation = Quaternion(0.6775009, -8.600083e-08, -8.977273e-08, 0.735522)
bones/83/scale = Vector3(1, 1.0000001, 1)
bones/84/scale = Vector3(0.99999994, 1.0000001, 0.9999999)
bones/85/rotation = Quaternion(2.6833732e-07, -9.313788e-10, -2.5612494e-09, 1)
bones/85/scale = Vector3(1.0000001, 1, 1.0000001)
bones/87/rotation = Quaternion(-0.5230753, 0.20132942, 0.026226493, 0.8277505)
bones/88/rotation = Quaternion(0.61967987, 0.23118778, 0.3169036, 0.679795)
bones/89/position = Vector3(2.953037e-07, 4.9207458e-08, -4.3015167e-08)
bones/89/rotation = Quaternion(-0.001144886, -2.973514e-08, 2.817069e-08, 0.9999994)
bones/90/rotation = Quaternion(0.0023764072, -4.0769752e-08, -7.0690255e-08, 0.99999726)
bones/91/position = Vector3(-0.8199192, 0.2525128, 0.47213912)
bones/91/rotation = Quaternion(-0.49266297, -0.27058598, 0.2623832, 0.78436047)
bones/91/scale = Vector3(1.0000002, 0.999999, 0.99999964)
bones/96/position = Vector3(-0.021971898, -1.2751104, 0.16484088)
bones/96/rotation = Quaternion(-0.47603267, 0.067788206, -0.035077166, 0.8761091)
bones/96/scale = Vector3(0.9999999, 0.9999999, 0.99999976)
bones/97/rotation = Quaternion(0.997074, -1.2813135e-07, 1.666339e-06, -0.07644201)
bones/98/position = Vector3(0.01993539, 0.08757691, 0.045667563)
bones/98/rotation = Quaternion(0.1475291, 0.03397043, -0.019923227, 0.9882734)
bones/98/scale = Vector3(1, 1.0000011, 1.0000023)
bones/101/position = Vector3(-0.021972047, 0.8282039, 0.0959422)
bones/101/rotation = Quaternion(0.8371564, 0.04015539, 0.06490996, 0.5416119)
bones/101/scale = Vector3(1, 1.0000066, 0.99998474)
bones/102/rotation = Quaternion(0.95545256, -6.924111e-08, 2.2887033e-07, -0.29514462)
bones/103/position = Vector3(0.17285576, 0.72785676, 1.0822707)
bones/103/rotation = Quaternion(0.27801546, 0.0014157619, 0.015671493, 0.9604477)
bones/103/scale = Vector3(1.0000002, 1.000013, 1.0000246)
bones/104/rotation = Quaternion(0.5037003, 0.13519715, -0.093790196, 0.84806323)
bones/104/scale = Vector3(1.0000721, 1.0000457, 0.99993384)
bones/105/rotation = Quaternion(0.97757924, -0.053521663, -0.054415643, -0.19624804)
bones/105/scale = Vector3(1.0000001, 1.0000083, 1.0000036)
bones/106/position = Vector3(0.023142539, -0.54231995, -0.9607401)
bones/106/rotation = Quaternion(0.99272084, -0.08158898, -0.03307842, -0.08218607)
bones/107/rotation = Quaternion(0.903578, -0.12777254, -0.05477002, -0.4052421)
bones/107/scale = Vector3(0.9999992, 0.9999624, 1.0000123)
bones/108/position = Vector3(-1.1340098e-08, 7.923448e-07, 9.0939814e-08)
bones/108/rotation = Quaternion(0.98967296, 0.0031370325, 0.10343237, -0.09919364)
bones/110/rotation = Quaternion(9.815354e-07, 7.072085e-10, -9.586452e-08, 1)
bones/110/scale = Vector3(0.99999994, 0.99999976, 1.0000001)
bones/113/position = Vector3(0.07716276, 0.6410925, 0.71644557)
bones/113/rotation = Quaternion(0.75079244, 0.54212654, -0.3715475, 0.0660462)
bones/114/position = Vector3(-0.031743176, 0.60466695, -0.39704067)
bones/114/rotation = Quaternion(0.4176498, -0.11118397, 0.55639553, -0.70966953)
bones/114/scale = Vector3(1.0000015, 1.0000038, 1.0000079)
bones/115/rotation = Quaternion(-0.07547326, 0.02173067, -0.31477332, 0.945912)
bones/115/scale = Vector3(0.9999974, 1.0000036, 0.99999976)
bones/116/rotation = Quaternion(0.03028559, -0.3116764, -0.037417784, 0.9489682)
bones/116/scale = Vector3(1.0000005, 0.9999972, 1.0000013)
bones/119/scale = Vector3(1.0000043, 0.9999975, 0.99999744)
bones/121/rotation = Quaternion(-4.820391e-08, -0.1579088, -2.0880496e-08, 0.98745376)
bones/121/scale = Vector3(1.0000037, 0.99999774, 0.9999977)
bones/123/scale = Vector3(1.000003, 0.9999977, 0.99999917)
bones/124/rotation = Quaternion(-3.1036683e-07, 0.17317644, 6.989145e-08, 0.9848908)
bones/124/scale = Vector3(1.0000037, 0.9999978, 0.99999875)
bones/126/rotation = Quaternion(-0.5163543, -0.16816929, 0.6340875, 0.550482)
bones/126/scale = Vector3(1.0000015, 1.000007, 1.000004)
bones/127/rotation = Quaternion(-0.24332331, 0.12663932, 0.6612194, 0.6982444)
bones/127/scale = Vector3(1.0000017, 1.0000014, 1.0000097)
bones/128/position = Vector3(-0.008928956, 0.128764, -0.06877987)
bones/128/rotation = Quaternion(0.025037244, 0.39930493, -0.88358396, 0.24332726)
bones/129/rotation = Quaternion(-0.07547334, 0.021730714, -0.31477335, 0.94591194)
bones/131/rotation = Quaternion(-0.41802245, -0.28161782, 0.08442414, 0.85954714)
bones/132/rotation = Quaternion(-0.5281791, -0.34319904, -0.62196887, -0.46518382)
bones/133/rotation = Quaternion(-0.012777329, 0.011854946, 0.00015161165, 0.9998482)
bones/133/scale = Vector3(1.0423008, 1.0423008, 1.0423006)
bones/134/rotation = Quaternion(0.02152103, -3.688601e-08, -1.5255387e-07, 0.99976844)
bones/134/scale = Vector3(0.9882629, 0.9882634, 0.98826265)
bones/135/position = Vector3(-0.0317431, 0.60466677, -0.39704087)
bones/135/rotation = Quaternion(0.22344373, -0.32689255, 0.658746, -0.6397405)
bones/135/scale = Vector3(1.0000048, 1.0000036, 1.0000046)
bones/137/position = Vector3(-0.33244255, 0.70370555, 0.67530614)
bones/137/rotation = Quaternion(0.7519437, -0.5788053, 0.30500948, 0.08083551)
bones/138/position = Vector3(-0.19594865, 0.65740275, -0.22511396)
bones/138/rotation = Quaternion(0.36201134, 0.22157827, -0.6475769, -0.63284683)
bones/138/scale = Vector3(1.0000019, 1.0000045, 1.0000057)
bones/139/rotation = Quaternion(-0.018797327, 0.13857716, 0.33871746, 0.9304373)
bones/139/scale = Vector3(0.9999983, 1.0000024, 0.9999992)
bones/140/rotation = Quaternion(0.09896898, 0.1986053, -0.00787212, 0.975038)
bones/140/scale = Vector3(1.0000031, 0.9999977, 0.9999988)
bones/143/scale = Vector3(1.000005, 0.99999815, 0.9999967)
bones/145/rotation = Quaternion(-1.7910523e-07, 0.10005118, -9.714451e-08, 0.9949823)
bones/145/scale = Vector3(1.0000045, 0.99999803, 0.9999968)
bones/147/scale = Vector3(1.0000035, 0.99999845, 0.9999981)
bones/148/rotation = Quaternion(2.0844507e-07, 0.011625211, 4.5709146e-07, 0.9999325)
bones/148/scale = Vector3(1.000004, 0.9999991, 0.999998)
bones/150/rotation = Quaternion(-0.51635444, 0.16816957, -0.63408744, 0.55048186)
bones/150/scale = Vector3(1.000001, 1.0000067, 1.000004)
bones/151/rotation = Quaternion(-0.24332346, -0.12663896, -0.6612195, 0.6982443)
bones/151/scale = Vector3(1.0000011, 1.0000017, 1.0000095)
bones/152/position = Vector3(0.027921734, -0.124764316, 0.07102555)
bones/152/rotation = Quaternion(-0.12973516, 0.47151387, -0.86254627, -0.12983702)
bones/153/rotation = Quaternion(-0.018797398, 0.13857722, 0.33871746, 0.9304373)
bones/155/rotation = Quaternion(-0.36541468, 0.16190512, -0.07102372, 0.91390073)
bones/155/scale = Vector3(0.99999994, 1, 0.9999998)
bones/156/rotation = Quaternion(0.68045896, -0.19169958, -0.3896983, 0.59022206)
bones/157/rotation = Quaternion(-0.01277751, -0.011854968, -0.0001513001, 0.9998481)
bones/157/scale = Vector3(1.0423003, 1.0422994, 1.0423005)
bones/158/rotation = Quaternion(0.021521209, -2.5687226e-07, -2.570953e-07, 0.9997684)
bones/158/scale = Vector3(0.9882631, 0.98826426, 0.9882618)
bones/159/position = Vector3(-0.19594839, 0.65740275, -0.2251139)
bones/159/rotation = Quaternion(0.28422734, 0.29369113, -0.68527013, -0.60279787)
bones/159/scale = Vector3(1.0000027, 1.0000043, 1.0000049)
bones/161/position = Vector3(0.07716276, 0.6410925, 0.71644557)
bones/161/rotation = Quaternion(0.75079244, 0.54212654, -0.3715475, 0.0660462)
bones/162/position = Vector3(-0.33244255, 0.70370555, 0.67530614)
bones/162/rotation = Quaternion(0.7519437, -0.5788053, 0.30500948, 0.08083551)
bones/165/position = Vector3(-1.5017577e-08, 0.26895812, -1.6243575e-08)
bones/165/rotation = Quaternion(-0.019247467, -0.20323175, 0.97894067, -0.0012537595)
bones/166/position = Vector3(0.0034187725, -3.131728, 0.9674823)
bones/167/position = Vector3(0.209171, 5.0901713, -2.6670303)
bones/167/rotation = Quaternion(0.16656846, 0.015223213, 0.18356222, 0.9686734)
bones/167/scale = Vector3(0.9999988, 0.9999987, 1.0000023)
bones/168/position = Vector3(0.18381567, -0.9622623, 0.9894084)
bones/168/rotation = Quaternion(0.9362244, -6.2652596e-08, -0.34127164, -0.083770975)
bones/168/scale = Vector3(1.0000011, 1.0000015, 1.0000101)
bones/170/position = Vector3(0.748137, 0.69556385, 3.7252903e-09)
bones/170/rotation = Quaternion(0.019250846, -0.20323181, 0.9789406, 0.001253055)
bones/171/position = Vector3(0.6322718, -2.6572587, 0.6064028)
bones/172/position = Vector3(-1.5122895, 4.4686184, -2.7014794)
bones/172/rotation = Quaternion(0.21553025, -0.03620148, 0.11066054, 0.9695311)
bones/172/scale = Vector3(0.99999887, 0.9999985, 1.0000024)
bones/173/position = Vector3(0.18381546, -0.96226203, 0.9894083)
bones/173/rotation = Quaternion(0.93622434, -2.9748788e-08, 0.34127158, -0.083771475)
bones/173/scale = Vector3(0.999999, 1.0000014, 0.99999464)
bones/175/position = Vector3(0.2542465, -2.2077389, 0.9589075)
bones/175/rotation = Quaternion(-0.008919476, -0.00021326332, -0.000697989, 0.99996)
bones/183/position = Vector3(-1.982537e-07, 5.9604563e-08, -1.517833e-08)
bones/185/rotation = Quaternion(5.4077844e-07, -0.20349081, 0.97907686, -1.12395135e-07)
bones/186/position = Vector3(0.57634556, 3.7607954, 0.15364014)
bones/186/rotation = Quaternion(-0.9604305, -0.020206233, -0.08076539, -0.26578543)
bones/186/scale = Vector3(0.9999997, 0.99999994, 1)
bones/187/rotation = Quaternion(0.15451065, -2.0305349e-09, -2.0850066e-09, 0.9879911)
bones/187/scale = Vector3(1.0000002, 0.99999994, 0.9999999)
bones/197/position = Vector3(-0.0011225368, -0.015787723, -0.051779967)
bones/199/rotation = Quaternion(0.00034800146, -0.20349097, 0.9790768, -7.2328476e-05)
bones/200/position = Vector3(-1.0407574, 3.6267605, -0.083099455)
bones/200/rotation = Quaternion(-0.9604305, -0.020206233, -0.08076539, -0.26578543)
bones/200/scale = Vector3(0.9999997, 0.99999994, 1)
bones/201/rotation = Quaternion(0.15451066, -1.9585848e-09, -2.5450761e-09, 0.9879911)
bones/201/scale = Vector3(1.0000002, 0.99999994, 0.99999994)
[editable path="bear_model"]
[editable path="bear_model/test_cube/Bear_FX"]
+319
View File
@@ -0,0 +1,319 @@
[gd_scene format=3 uid="uid://o8ocjfprxa7u"]
[ext_resource type="Script" uid="uid://cn7fhjkro7637" path="res://bear.gd" id="1_beargd"]
[ext_resource type="PackedScene" uid="uid://cofv5dbavesis" path="res://Assets/Bear.glb" id="2_bearglb"]
[ext_resource type="Script" uid="uid://bsbed05ifr18s" path="res://bear_test_cube.gd" id="3_rog1v"]
[ext_resource type="PackedScene" uid="uid://bdbx0wwa73rhp" path="res://Assets/fx/Bear_FX.glb" id="4_rog1v"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_body"]
radius = 1.0
height = 2.4
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_hit"]
radius = 1.3
height = 2.7
[sub_resource type="BoxShape3D" id="BoxShape3D_bfebr"]
size = Vector3(6.2019043, 8.561401, 7.0739746)
[sub_resource type="BoxShape3D" id="BoxShape3D_rog1v"]
size = Vector3(14.399288, 51.902206, 5.741211)
[node name="Bear" type="CharacterBody3D" unique_id=1573237287]
script = ExtResource("1_beargd")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=830443382]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 0)
shape = SubResource("CapsuleShape3D_body")
[node name="HitArea" type="Area3D" parent="." unique_id=365327397]
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="HitArea" unique_id=2111867348]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.35, 0)
shape = SubResource("CapsuleShape3D_hit")
[node name="bear_model" parent="." unique_id=359217823 instance=ExtResource("2_bearglb")]
[node name="test_cube" type="Node3D" parent="bear_model" unique_id=646988893]
script = ExtResource("3_rog1v")
[node name="Bear_FX" parent="bear_model/test_cube" unique_id=1183391245 instance=ExtResource("4_rog1v")]
[node name="Bear_fx_jump_smash" parent="bear_model/test_cube/Bear_FX" index="0" unique_id=750478984]
visible = false
[node name="Bear_fx_claw_attack_R" parent="bear_model/test_cube/Bear_FX" index="1" unique_id=88064381]
visible = false
[node name="Bear_fx_claw_attack_L" parent="bear_model/test_cube/Bear_FX" index="2" unique_id=1378755061]
visible = false
[node name="Bear_fx_smash_hit" parent="bear_model/test_cube/Bear_FX" index="3" unique_id=1711579105]
transform = Transform3D(0.55488384, -0.039024748, -0.018949924, 0.041069064, 0.55086076, 0.06814586, 0.013977209, -0.06933683, 0.5520644, 1.327292, -0.21312934, 5.190573)
[node name="RigidBody3D" type="AnimatableBody3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit" index="0" unique_id=1764208051]
transform = Transform3D(1.0000001, -1.21071935e-08, -1.8626451e-08, -9.313226e-10, 0.99999994, 7.450581e-09, 3.7252903e-09, -1.4901161e-08, 0.99999994, 0, 0, 0)
collision_layer = 8
collision_mask = 2
[node name="CollisionShape3D2" type="CollisionShape3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit/RigidBody3D" unique_id=1779197150]
transform = Transform3D(0.99993557, -0.00749125, -0.010078691, 0.0077760145, 0.999569, 0.028562747, 0.009858355, -0.028639637, 0.9995405, -1.5136471, 0.9093375, 35.591957)
shape = SubResource("BoxShape3D_bfebr")
disabled = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit/RigidBody3D" unique_id=1276552823]
transform = Transform3D(0.9935104, -0.040698394, -0.10621016, -0.108634494, -0.06290151, -0.9920882, 0.03369555, 0.99719334, -0.06691426, -1.6357545, -0.5093044, 12.68803)
shape = SubResource("BoxShape3D_rog1v")
[node name="Skeleton3D" parent="bear_model/bear-rig" parent_id_path=PackedInt32Array(359217823, 1017999212) index="0" unique_id=1624609914]
bones/1/position = Vector3(0.00851878, 0.24701798, 1.2888045)
bones/1/rotation = Quaternion(0.29791054, -0.060797628, -0.056875575, 0.9509564)
bones/2/rotation = Quaternion(0.084239505, -0.026013458, 0.009274505, 0.9960628)
bones/2/scale = Vector3(0.9999999, 1.0000008, 0.99999934)
bones/3/rotation = Quaternion(-0.14812404, -0.039577905, 0.049865585, 0.98691756)
bones/4/rotation = Quaternion(-0.40577498, -0.03082885, 0.05040324, 0.9120612)
bones/5/rotation = Quaternion(0.27801633, 0.0014148077, 0.015671793, 0.96044755)
bones/6/rotation = Quaternion(0.50370073, 0.13519946, -0.093789615, 0.8480627)
bones/7/rotation = Quaternion(0.75079185, 0.54212743, -0.37154716, 0.06604591)
bones/8/rotation = Quaternion(0.22344273, -0.32689556, 0.65874565, -0.63973963)
bones/9/rotation = Quaternion(0.026405705, -0.27415153, -0.3226086, 0.9055757)
bones/10/rotation = Quaternion(0.030285481, -0.31167626, -0.037417818, 0.94896823)
bones/11/rotation = Quaternion(0.751943, -0.5788067, 0.30500817, 0.080837056)
bones/12/rotation = Quaternion(0.28422552, 0.2936944, -0.68526876, -0.6027987)
bones/13/rotation = Quaternion(0.020711409, 0.24585825, 0.3386082, 0.9080029)
bones/14/rotation = Quaternion(0.098969, 0.19860524, -0.007872087, 0.97503805)
bones/15/rotation = Quaternion(0.6979166, 0.16086513, -0.15598965, 0.680222)
bones/16/rotation = Quaternion(0.89734674, 0.09874082, -0.25790086, 0.34424722)
bones/17/rotation = Quaternion(-0.13802421, 0.26758972, 0.081159085, 0.9501359)
bones/17/scale = Vector3(0.9999998, 1.0000002, 1)
bones/19/rotation = Quaternion(-4.514978e-15, 1, 7.4505806e-08, -5.523351e-07)
bones/20/rotation = Quaternion(-0.49266306, -0.27058616, 0.262383, 0.7843606)
bones/21/rotation = Quaternion(0.0016915401, 0.70246154, -0.001669446, 0.7117178)
bones/22/rotation = Quaternion(-0.5496364, -0.3220462, -0.22350304, 0.73772115)
bones/22/scale = Vector3(0.9999997, 0.9999998, 0.9999999)
bones/23/rotation = Quaternion(-0.00015351747, 0.902104, -0.4315187, 0.00032039074)
bones/24/rotation = Quaternion(6.628114e-12, 0.99999994, 5.2154085e-08, -0.00035543842)
bones/25/position = Vector3(1.0191536, 3.5353048, 3.5049686)
bones/25/rotation = Quaternion(-0.087474234, 0.16733547, 0.98056763, 0.053239316)
bones/25/scale = Vector3(1, 17.518272, 1.0000001)
bones/26/position = Vector3(-1.0831825, 3.749937, 2.5891113)
bones/26/rotation = Quaternion(0.016340872, 0.19671263, 0.9801456, 0.01875816)
bones/26/scale = Vector3(1.0000001, 18.765795, 1)
bones/27/position = Vector3(1.0193456, -0.43209565, 2.5343885)
bones/27/rotation = Quaternion(0.61800283, -0.11976056, 0.11976072, 0.7677157)
bones/27/scale = Vector3(0.99999994, 16.85072, 1)
bones/28/position = Vector3(-0.8340287, 1.0348616, 1.282705)
bones/28/rotation = Quaternion(0.82860446, -0.029359974, 0.02935981, 0.5582926)
bones/28/scale = Vector3(0.99999994, 32.068844, 1)
bones/30/position = Vector3(0.032563455, -0.8335703, -0.9236449)
bones/30/rotation = Quaternion(-0.8670657, 0.042821795, -0.07139772, 0.4911883)
bones/31/position = Vector3(2.3450447e-08, -1.4631646, 0.23291242)
bones/31/rotation = Quaternion(-6.0737464e-09, 4.8699293e-09, -1.4618977e-09, 1)
bones/31/scale = Vector3(0.99999994, 0.9999999, 0.99999994)
bones/32/position = Vector3(-0.04394375, -1.087056, 0.096768975)
bones/32/rotation = Quaternion(-0.8343034, 0.119118, -0.061490715, 0.5347595)
bones/32/scale = Vector3(0.9999999, 0.99999976, 0.99999964)
bones/33/position = Vector3(3.977649e-08, -1.4631644, 0.23291251)
bones/33/rotation = Quaternion(-8.833673e-08, -2.419923e-08, -6.733043e-09, 1)
bones/33/scale = Vector3(0.9999998, 0.9999998, 0.99999994)
bones/35/position = Vector3(1.0184407e-08, -1.0594703, -5.9146995e-08)
bones/35/rotation = Quaternion(0.99971783, 1.3593646e-07, 5.3695976e-06, -0.023754615)
bones/35/scale = Vector3(0.99999976, 0.9999998, 1.0000012)
bones/39/position = Vector3(0.8199172, 0.25251278, 0.47214246)
bones/39/rotation = Quaternion(0.71402234, 0.34199142, 0.043267474, 0.60937834)
bones/39/scale = Vector3(1.0000004, 0.9999996, 0.9999991)
bones/40/rotation = Quaternion(0.9336719, 1.2799235e-07, 3.7337827e-08, 0.3581296)
bones/40/scale = Vector3(1.0000004, 1.0000001, 1.0000001)
bones/41/rotation = Quaternion(-0.13802455, 0.26758966, 0.08115916, 0.9501359)
bones/41/scale = Vector3(0.99999946, 0.99999976, 0.9999996)
bones/42/position = Vector3(-1.9729964e-07, 0.56145483, 7.283501e-08)
bones/46/scale = Vector3(0.99999946, 0.99999964, 0.9999999)
bones/48/rotation = Quaternion(-2.9741386e-07, 0.13593404, 1.01778824e-07, 0.9907179)
bones/48/scale = Vector3(0.9999993, 0.9999996, 0.9999999)
bones/50/scale = Vector3(0.99999994, 0.99999994, 0.9999998)
bones/51/rotation = Quaternion(-2.5567479e-08, -0.20499781, -2.3086146e-08, 0.9787625)
bones/51/scale = Vector3(0.9999999, 0.99999964, 0.99999964)
bones/53/position = Vector3(-0.8199191, 0.25251284, 0.47213903)
bones/53/rotation = Quaternion(-0.5351706, 0.35860845, -0.15898216, 0.74814254)
bones/53/scale = Vector3(1, 0.99999875, 0.99999946)
bones/54/rotation = Quaternion(0.0023762286, -4.7362324e-08, -6.475868e-08, 0.9999972)
bones/55/rotation = Quaternion(-0.54963607, -0.322046, -0.22350314, 0.73772144)
bones/55/scale = Vector3(1.0000002, 1, 1.0000002)
bones/56/position = Vector3(0.0013532753, 0.57868266, 0.05537574)
bones/56/rotation = Quaternion(-0.00015348212, 0.90210384, -0.43151882, 0.0003204293)
bones/57/rotation = Quaternion(0.70073944, -0.70073956, -0.094679825, -0.09467953)
bones/60/scale = Vector3(1.0000004, 1.0000004, 1.0000002)
bones/62/rotation = Quaternion(-1.7092354e-08, -0.18223058, 2.6700846e-08, 0.98325586)
bones/62/scale = Vector3(1.0000002, 1.0000002, 1.0000001)
bones/64/scale = Vector3(1.0000004, 1.0000004, 1)
bones/65/rotation = Quaternion(-1.0345744e-08, -0.3796584, -4.0675246e-08, 0.9251268)
bones/65/scale = Vector3(1.0000002, 1.0000004, 1.0000004)
bones/67/rotation = Quaternion(0.7179022, -7.671307e-07, 7.885642e-07, 0.696144)
bones/67/scale = Vector3(1.0000004, 0.9999986, 0.99999994)
bones/68/rotation = Quaternion(0.9776482, 2.0029378e-07, 1.0460874e-06, -0.2102479)
bones/68/scale = Vector3(1.0000004, 1.0000004, 0.9999982)
bones/69/position = Vector3(-2.4645832e-08, -6.861796e-09, 7.455772e-08)
bones/69/rotation = Quaternion(-0.8315212, 2.5276703e-08, -9.3330055e-09, 0.5554931)
bones/69/scale = Vector3(1, 1.0000001, 1.0000002)
bones/70/rotation = Quaternion(0.67750055, 8.820757e-08, 7.575834e-08, 0.7355223)
bones/70/scale = Vector3(1, 1, 1)
bones/71/scale = Vector3(0.9999999, 1, 0.9999999)
bones/72/rotation = Quaternion(-2.1641608e-07, -4.6565607e-10, -4.6576065e-10, 1)
bones/75/rotation = Quaternion(-0.34314692, -0.20321459, -0.2785586, 0.8737043)
bones/76/position = Vector3(1.01587794e-07, -1.5306958e-07, -4.3554866e-07)
bones/76/rotation = Quaternion(-0.51764834, -7.167482e-08, 1.7163823e-07, 0.85559356)
bones/77/rotation = Quaternion(0.93367195, 1.2110854e-07, 3.8556042e-08, 0.35812962)
bones/78/position = Vector3(0.8199172, 0.25251257, 0.47214243)
bones/78/rotation = Quaternion(0.6979164, 0.16086517, -0.15598962, 0.6802223)
bones/78/scale = Vector3(1.0000004, 0.9999997, 0.99999905)
bones/80/rotation = Quaternion(0.7179022, -7.6713064e-07, 7.885641e-07, 0.696144)
bones/80/scale = Vector3(1.0000004, 0.9999986, 0.99999994)
bones/81/rotation = Quaternion(0.97764814, 1.9846473e-07, 1.0426893e-06, -0.21024783)
bones/81/scale = Vector3(1.0000004, 1.0000002, 0.9999982)
bones/82/position = Vector3(6.103571e-08, 8.8816435e-08, -3.6955274e-09)
bones/82/rotation = Quaternion(-0.8315211, 2.3407136e-08, -1.2821512e-08, 0.5554932)
bones/82/scale = Vector3(0.99999994, 0.99999994, 1)
bones/83/rotation = Quaternion(0.6775009, -8.600083e-08, -8.977273e-08, 0.735522)
bones/83/scale = Vector3(1, 1.0000001, 1)
bones/84/scale = Vector3(0.99999994, 1.0000001, 0.9999999)
bones/85/rotation = Quaternion(2.6833732e-07, -9.313788e-10, -2.5612494e-09, 1)
bones/85/scale = Vector3(1.0000001, 1, 1.0000001)
bones/87/rotation = Quaternion(-0.5230753, 0.20132942, 0.026226493, 0.8277505)
bones/88/rotation = Quaternion(0.61967987, 0.23118778, 0.3169036, 0.679795)
bones/89/position = Vector3(2.953037e-07, 4.9207458e-08, -4.3015167e-08)
bones/89/rotation = Quaternion(-0.001144886, -2.973514e-08, 2.817069e-08, 0.9999994)
bones/90/rotation = Quaternion(0.0023764072, -4.0769752e-08, -7.0690255e-08, 0.99999726)
bones/91/position = Vector3(-0.8199192, 0.2525128, 0.47213912)
bones/91/rotation = Quaternion(-0.49266297, -0.27058598, 0.2623832, 0.78436047)
bones/91/scale = Vector3(1.0000002, 0.999999, 0.99999964)
bones/96/position = Vector3(-0.021971898, -1.2751104, 0.16484088)
bones/96/rotation = Quaternion(-0.47603267, 0.067788206, -0.035077166, 0.8761091)
bones/96/scale = Vector3(0.9999999, 0.9999999, 0.99999976)
bones/97/rotation = Quaternion(0.997074, -1.2813135e-07, 1.666339e-06, -0.07644201)
bones/98/position = Vector3(0.01993539, 0.08757691, 0.045667563)
bones/98/rotation = Quaternion(0.1475291, 0.03397043, -0.019923227, 0.9882734)
bones/98/scale = Vector3(1, 1.0000011, 1.0000023)
bones/101/position = Vector3(-0.021972047, 0.8282039, 0.0959422)
bones/101/rotation = Quaternion(0.8371564, 0.04015539, 0.06490996, 0.5416119)
bones/101/scale = Vector3(1, 1.0000066, 0.99998474)
bones/102/rotation = Quaternion(0.95545256, -6.924111e-08, 2.2887033e-07, -0.29514462)
bones/103/position = Vector3(0.17285576, 0.72785676, 1.0822707)
bones/103/rotation = Quaternion(0.27801546, 0.0014157619, 0.015671493, 0.9604477)
bones/103/scale = Vector3(1.0000002, 1.000013, 1.0000246)
bones/104/rotation = Quaternion(0.5037003, 0.13519715, -0.093790196, 0.84806323)
bones/104/scale = Vector3(1.0000721, 1.0000457, 0.99993384)
bones/105/rotation = Quaternion(0.97757924, -0.053521663, -0.054415643, -0.19624804)
bones/105/scale = Vector3(1.0000001, 1.0000083, 1.0000036)
bones/106/position = Vector3(0.023142539, -0.54231995, -0.9607401)
bones/106/rotation = Quaternion(0.99272084, -0.08158898, -0.03307842, -0.08218607)
bones/107/rotation = Quaternion(0.903578, -0.12777254, -0.05477002, -0.4052421)
bones/107/scale = Vector3(0.9999992, 0.9999624, 1.0000123)
bones/108/position = Vector3(-1.1340098e-08, 7.923448e-07, 9.0939814e-08)
bones/108/rotation = Quaternion(0.98967296, 0.0031370325, 0.10343237, -0.09919364)
bones/110/rotation = Quaternion(9.815354e-07, 7.072085e-10, -9.586452e-08, 1)
bones/110/scale = Vector3(0.99999994, 0.99999976, 1.0000001)
bones/113/position = Vector3(0.07716276, 0.6410925, 0.71644557)
bones/113/rotation = Quaternion(0.75079244, 0.54212654, -0.3715475, 0.0660462)
bones/114/position = Vector3(-0.031743176, 0.60466695, -0.39704067)
bones/114/rotation = Quaternion(0.4176498, -0.11118397, 0.55639553, -0.70966953)
bones/114/scale = Vector3(1.0000015, 1.0000038, 1.0000079)
bones/115/rotation = Quaternion(-0.07547326, 0.02173067, -0.31477332, 0.945912)
bones/115/scale = Vector3(0.9999974, 1.0000036, 0.99999976)
bones/116/rotation = Quaternion(0.03028559, -0.3116764, -0.037417784, 0.9489682)
bones/116/scale = Vector3(1.0000005, 0.9999972, 1.0000013)
bones/119/scale = Vector3(1.0000043, 0.9999975, 0.99999744)
bones/121/rotation = Quaternion(-4.820391e-08, -0.1579088, -2.0880496e-08, 0.98745376)
bones/121/scale = Vector3(1.0000037, 0.99999774, 0.9999977)
bones/123/scale = Vector3(1.000003, 0.9999977, 0.99999917)
bones/124/rotation = Quaternion(-3.1036683e-07, 0.17317644, 6.989145e-08, 0.9848908)
bones/124/scale = Vector3(1.0000037, 0.9999978, 0.99999875)
bones/126/rotation = Quaternion(-0.5163543, -0.16816929, 0.6340875, 0.550482)
bones/126/scale = Vector3(1.0000015, 1.000007, 1.000004)
bones/127/rotation = Quaternion(-0.24332331, 0.12663932, 0.6612194, 0.6982444)
bones/127/scale = Vector3(1.0000017, 1.0000014, 1.0000097)
bones/128/position = Vector3(-0.008928956, 0.128764, -0.06877987)
bones/128/rotation = Quaternion(0.025037244, 0.39930493, -0.88358396, 0.24332726)
bones/129/rotation = Quaternion(-0.07547334, 0.021730714, -0.31477335, 0.94591194)
bones/131/rotation = Quaternion(-0.41802245, -0.28161782, 0.08442414, 0.85954714)
bones/132/rotation = Quaternion(-0.5281791, -0.34319904, -0.62196887, -0.46518382)
bones/133/rotation = Quaternion(-0.012777329, 0.011854946, 0.00015161165, 0.9998482)
bones/133/scale = Vector3(1.0423008, 1.0423008, 1.0423006)
bones/134/rotation = Quaternion(0.02152103, -3.688601e-08, -1.5255387e-07, 0.99976844)
bones/134/scale = Vector3(0.9882629, 0.9882634, 0.98826265)
bones/135/position = Vector3(-0.0317431, 0.60466677, -0.39704087)
bones/135/rotation = Quaternion(0.22344373, -0.32689255, 0.658746, -0.6397405)
bones/135/scale = Vector3(1.0000048, 1.0000036, 1.0000046)
bones/137/position = Vector3(-0.33244255, 0.70370555, 0.67530614)
bones/137/rotation = Quaternion(0.7519437, -0.5788053, 0.30500948, 0.08083551)
bones/138/position = Vector3(-0.19594865, 0.65740275, -0.22511396)
bones/138/rotation = Quaternion(0.36201134, 0.22157827, -0.6475769, -0.63284683)
bones/138/scale = Vector3(1.0000019, 1.0000045, 1.0000057)
bones/139/rotation = Quaternion(-0.018797327, 0.13857716, 0.33871746, 0.9304373)
bones/139/scale = Vector3(0.9999983, 1.0000024, 0.9999992)
bones/140/rotation = Quaternion(0.09896898, 0.1986053, -0.00787212, 0.975038)
bones/140/scale = Vector3(1.0000031, 0.9999977, 0.9999988)
bones/143/scale = Vector3(1.000005, 0.99999815, 0.9999967)
bones/145/rotation = Quaternion(-1.7910523e-07, 0.10005118, -9.714451e-08, 0.9949823)
bones/145/scale = Vector3(1.0000045, 0.99999803, 0.9999968)
bones/147/scale = Vector3(1.0000035, 0.99999845, 0.9999981)
bones/148/rotation = Quaternion(2.0844507e-07, 0.011625211, 4.5709146e-07, 0.9999325)
bones/148/scale = Vector3(1.000004, 0.9999991, 0.999998)
bones/150/rotation = Quaternion(-0.51635444, 0.16816957, -0.63408744, 0.55048186)
bones/150/scale = Vector3(1.000001, 1.0000067, 1.000004)
bones/151/rotation = Quaternion(-0.24332346, -0.12663896, -0.6612195, 0.6982443)
bones/151/scale = Vector3(1.0000011, 1.0000017, 1.0000095)
bones/152/position = Vector3(0.027921734, -0.124764316, 0.07102555)
bones/152/rotation = Quaternion(-0.12973516, 0.47151387, -0.86254627, -0.12983702)
bones/153/rotation = Quaternion(-0.018797398, 0.13857722, 0.33871746, 0.9304373)
bones/155/rotation = Quaternion(-0.36541468, 0.16190512, -0.07102372, 0.91390073)
bones/155/scale = Vector3(0.99999994, 1, 0.9999998)
bones/156/rotation = Quaternion(0.68045896, -0.19169958, -0.3896983, 0.59022206)
bones/157/rotation = Quaternion(-0.01277751, -0.011854968, -0.0001513001, 0.9998481)
bones/157/scale = Vector3(1.0423003, 1.0422994, 1.0423005)
bones/158/rotation = Quaternion(0.021521209, -2.5687226e-07, -2.570953e-07, 0.9997684)
bones/158/scale = Vector3(0.9882631, 0.98826426, 0.9882618)
bones/159/position = Vector3(-0.19594839, 0.65740275, -0.2251139)
bones/159/rotation = Quaternion(0.28422734, 0.29369113, -0.68527013, -0.60279787)
bones/159/scale = Vector3(1.0000027, 1.0000043, 1.0000049)
bones/161/position = Vector3(0.07716276, 0.6410925, 0.71644557)
bones/161/rotation = Quaternion(0.75079244, 0.54212654, -0.3715475, 0.0660462)
bones/162/position = Vector3(-0.33244255, 0.70370555, 0.67530614)
bones/162/rotation = Quaternion(0.7519437, -0.5788053, 0.30500948, 0.08083551)
bones/165/position = Vector3(-1.5017577e-08, 0.26895812, -1.6243575e-08)
bones/165/rotation = Quaternion(-0.019247467, -0.20323175, 0.97894067, -0.0012537595)
bones/166/position = Vector3(0.0034187725, -3.131728, 0.9674823)
bones/167/position = Vector3(0.209171, 5.0901713, -2.6670303)
bones/167/rotation = Quaternion(0.16656846, 0.015223213, 0.18356222, 0.9686734)
bones/167/scale = Vector3(0.9999988, 0.9999987, 1.0000023)
bones/168/position = Vector3(0.18381567, -0.9622623, 0.9894084)
bones/168/rotation = Quaternion(0.9362244, -6.2652596e-08, -0.34127164, -0.083770975)
bones/168/scale = Vector3(1.0000011, 1.0000015, 1.0000101)
bones/170/position = Vector3(0.748137, 0.69556385, 3.7252903e-09)
bones/170/rotation = Quaternion(0.019250846, -0.20323181, 0.9789406, 0.001253055)
bones/171/position = Vector3(0.6322718, -2.6572587, 0.6064028)
bones/172/position = Vector3(-1.5122895, 4.4686184, -2.7014794)
bones/172/rotation = Quaternion(0.21553025, -0.03620148, 0.11066054, 0.9695311)
bones/172/scale = Vector3(0.99999887, 0.9999985, 1.0000024)
bones/173/position = Vector3(0.18381546, -0.96226203, 0.9894083)
bones/173/rotation = Quaternion(0.93622434, -2.9748788e-08, 0.34127158, -0.083771475)
bones/173/scale = Vector3(0.999999, 1.0000014, 0.99999464)
bones/175/position = Vector3(0.2542465, -2.2077389, 0.9589075)
bones/175/rotation = Quaternion(-0.008919476, -0.00021326332, -0.000697989, 0.99996)
bones/183/position = Vector3(-1.982537e-07, 5.9604563e-08, -1.517833e-08)
bones/185/rotation = Quaternion(5.4077844e-07, -0.20349081, 0.97907686, -1.12395135e-07)
bones/186/position = Vector3(0.57634556, 3.7607954, 0.15364014)
bones/186/rotation = Quaternion(-0.9604305, -0.020206233, -0.08076539, -0.26578543)
bones/186/scale = Vector3(0.9999997, 0.99999994, 1)
bones/187/rotation = Quaternion(0.15451065, -2.0305349e-09, -2.0850066e-09, 0.9879911)
bones/187/scale = Vector3(1.0000002, 0.99999994, 0.9999999)
bones/197/position = Vector3(-0.0011225368, -0.015787723, -0.051779967)
bones/199/rotation = Quaternion(0.00034800146, -0.20349097, 0.9790768, -7.2328476e-05)
bones/200/position = Vector3(-1.0407574, 3.6267605, -0.083099455)
bones/200/rotation = Quaternion(-0.9604305, -0.020206233, -0.08076539, -0.26578543)
bones/200/scale = Vector3(0.9999997, 0.99999994, 1)
bones/201/rotation = Quaternion(0.15451066, -1.9585848e-09, -2.5450761e-09, 0.9879911)
bones/201/scale = Vector3(1.0000002, 0.99999994, 0.99999994)
[editable path="bear_model"]
[editable path="bear_model/test_cube/Bear_FX"]
+319
View File
@@ -0,0 +1,319 @@
[gd_scene format=3 uid="uid://o8ocjfprxa7u"]
[ext_resource type="Script" uid="uid://cn7fhjkro7637" path="res://bear.gd" id="1_beargd"]
[ext_resource type="PackedScene" uid="uid://cofv5dbavesis" path="res://Assets/Bear.glb" id="2_bearglb"]
[ext_resource type="Script" uid="uid://bsbed05ifr18s" path="res://bear_test_cube.gd" id="3_rog1v"]
[ext_resource type="PackedScene" uid="uid://bdbx0wwa73rhp" path="res://Assets/fx/Bear_FX.glb" id="4_rog1v"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_body"]
radius = 1.0
height = 2.4
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_hit"]
radius = 1.3
height = 2.7
[sub_resource type="BoxShape3D" id="BoxShape3D_bfebr"]
size = Vector3(6.2019043, 8.561401, 7.0739746)
[sub_resource type="BoxShape3D" id="BoxShape3D_rog1v"]
size = Vector3(14.399288, 51.902206, 5.741211)
[node name="Bear" type="CharacterBody3D" unique_id=1573237287]
script = ExtResource("1_beargd")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=830443382]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 0)
shape = SubResource("CapsuleShape3D_body")
[node name="HitArea" type="Area3D" parent="." unique_id=365327397]
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="HitArea" unique_id=2111867348]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.35, 0)
shape = SubResource("CapsuleShape3D_hit")
[node name="bear_model" parent="." unique_id=359217823 instance=ExtResource("2_bearglb")]
[node name="test_cube" type="Node3D" parent="bear_model" unique_id=646988893]
script = ExtResource("3_rog1v")
[node name="Bear_FX" parent="bear_model/test_cube" unique_id=1183391245 instance=ExtResource("4_rog1v")]
[node name="Bear_fx_jump_smash" parent="bear_model/test_cube/Bear_FX" index="0" unique_id=750478984]
visible = false
[node name="Bear_fx_claw_attack_R" parent="bear_model/test_cube/Bear_FX" index="1" unique_id=88064381]
visible = false
[node name="Bear_fx_claw_attack_L" parent="bear_model/test_cube/Bear_FX" index="2" unique_id=1378755061]
visible = false
[node name="Bear_fx_smash_hit" parent="bear_model/test_cube/Bear_FX" index="3" unique_id=1711579105]
transform = Transform3D(0.55488384, -0.039024748, -0.018949924, 0.041069064, 0.55086076, 0.06814586, 0.013977209, -0.06933683, 0.5520644, 1.327292, -0.21312934, 5.190573)
[node name="RigidBody3D" type="AnimatableBody3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit" index="0" unique_id=1764208051]
transform = Transform3D(1.0000001, -1.21071935e-08, -1.8626451e-08, -9.313226e-10, 0.99999994, 7.450581e-09, 3.7252903e-09, -1.4901161e-08, 0.99999994, 0, 0, 0)
collision_layer = 8
collision_mask = 2
[node name="CollisionShape3D2" type="CollisionShape3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit/RigidBody3D" unique_id=1779197150]
transform = Transform3D(0.99993557, -0.00749125, -0.010078691, 0.0077760145, 0.999569, 0.028562747, 0.009858355, -0.028639637, 0.9995405, -1.5136471, 0.9093375, 35.591957)
shape = SubResource("BoxShape3D_bfebr")
disabled = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="bear_model/test_cube/Bear_FX/Bear_fx_smash_hit/RigidBody3D" unique_id=1276552823]
transform = Transform3D(0.9935104, -0.040698394, -0.10621016, -0.108634494, -0.06290151, -0.9920882, 0.03369555, 0.99719334, -0.06691426, -1.6357545, -0.5093044, 12.68803)
shape = SubResource("BoxShape3D_rog1v")
[node name="Skeleton3D" parent="bear_model/bear-rig" parent_id_path=PackedInt32Array(359217823, 1017999212) index="0" unique_id=1624609914]
bones/1/position = Vector3(0.00851878, 0.24701798, 1.2888045)
bones/1/rotation = Quaternion(0.29791054, -0.060797628, -0.056875575, 0.9509564)
bones/2/rotation = Quaternion(0.084239505, -0.026013458, 0.009274505, 0.9960628)
bones/2/scale = Vector3(0.9999999, 1.0000008, 0.99999934)
bones/3/rotation = Quaternion(-0.14812404, -0.039577905, 0.049865585, 0.98691756)
bones/4/rotation = Quaternion(-0.40577498, -0.03082885, 0.05040324, 0.9120612)
bones/5/rotation = Quaternion(0.27801633, 0.0014148077, 0.015671793, 0.96044755)
bones/6/rotation = Quaternion(0.50370073, 0.13519946, -0.093789615, 0.8480627)
bones/7/rotation = Quaternion(0.75079185, 0.54212743, -0.37154716, 0.06604591)
bones/8/rotation = Quaternion(0.22344273, -0.32689556, 0.65874565, -0.63973963)
bones/9/rotation = Quaternion(0.026405705, -0.27415153, -0.3226086, 0.9055757)
bones/10/rotation = Quaternion(0.030285481, -0.31167626, -0.037417818, 0.94896823)
bones/11/rotation = Quaternion(0.751943, -0.5788067, 0.30500817, 0.080837056)
bones/12/rotation = Quaternion(0.28422552, 0.2936944, -0.68526876, -0.6027987)
bones/13/rotation = Quaternion(0.020711409, 0.24585825, 0.3386082, 0.9080029)
bones/14/rotation = Quaternion(0.098969, 0.19860524, -0.007872087, 0.97503805)
bones/15/rotation = Quaternion(0.6979166, 0.16086513, -0.15598965, 0.680222)
bones/16/rotation = Quaternion(0.89734674, 0.09874082, -0.25790086, 0.34424722)
bones/17/rotation = Quaternion(-0.13802421, 0.26758972, 0.081159085, 0.9501359)
bones/17/scale = Vector3(0.9999998, 1.0000002, 1)
bones/19/rotation = Quaternion(-4.514978e-15, 1, 7.4505806e-08, -5.523351e-07)
bones/20/rotation = Quaternion(-0.49266306, -0.27058616, 0.262383, 0.7843606)
bones/21/rotation = Quaternion(0.0016915401, 0.70246154, -0.001669446, 0.7117178)
bones/22/rotation = Quaternion(-0.5496364, -0.3220462, -0.22350304, 0.73772115)
bones/22/scale = Vector3(0.9999997, 0.9999998, 0.9999999)
bones/23/rotation = Quaternion(-0.00015351747, 0.902104, -0.4315187, 0.00032039074)
bones/24/rotation = Quaternion(6.628114e-12, 0.99999994, 5.2154085e-08, -0.00035543842)
bones/25/position = Vector3(1.0191536, 3.5353048, 3.5049686)
bones/25/rotation = Quaternion(-0.087474234, 0.16733547, 0.98056763, 0.053239316)
bones/25/scale = Vector3(1, 17.518272, 1.0000001)
bones/26/position = Vector3(-1.0831825, 3.749937, 2.5891113)
bones/26/rotation = Quaternion(0.016340872, 0.19671263, 0.9801456, 0.01875816)
bones/26/scale = Vector3(1.0000001, 18.765795, 1)
bones/27/position = Vector3(1.0193456, -0.43209565, 2.5343885)
bones/27/rotation = Quaternion(0.61800283, -0.11976056, 0.11976072, 0.7677157)
bones/27/scale = Vector3(0.99999994, 16.85072, 1)
bones/28/position = Vector3(-0.8340287, 1.0348616, 1.282705)
bones/28/rotation = Quaternion(0.82860446, -0.029359974, 0.02935981, 0.5582926)
bones/28/scale = Vector3(0.99999994, 32.068844, 1)
bones/30/position = Vector3(0.032563455, -0.8335703, -0.9236449)
bones/30/rotation = Quaternion(-0.8670657, 0.042821795, -0.07139772, 0.4911883)
bones/31/position = Vector3(2.3450447e-08, -1.4631646, 0.23291242)
bones/31/rotation = Quaternion(-6.0737464e-09, 4.8699293e-09, -1.4618977e-09, 1)
bones/31/scale = Vector3(0.99999994, 0.9999999, 0.99999994)
bones/32/position = Vector3(-0.04394375, -1.087056, 0.096768975)
bones/32/rotation = Quaternion(-0.8343034, 0.119118, -0.061490715, 0.5347595)
bones/32/scale = Vector3(0.9999999, 0.99999976, 0.99999964)
bones/33/position = Vector3(3.977649e-08, -1.4631644, 0.23291251)
bones/33/rotation = Quaternion(-8.833673e-08, -2.419923e-08, -6.733043e-09, 1)
bones/33/scale = Vector3(0.9999998, 0.9999998, 0.99999994)
bones/35/position = Vector3(1.0184407e-08, -1.0594703, -5.9146995e-08)
bones/35/rotation = Quaternion(0.99971783, 1.3593646e-07, 5.3695976e-06, -0.023754615)
bones/35/scale = Vector3(0.99999976, 0.9999998, 1.0000012)
bones/39/position = Vector3(0.8199172, 0.25251278, 0.47214246)
bones/39/rotation = Quaternion(0.71402234, 0.34199142, 0.043267474, 0.60937834)
bones/39/scale = Vector3(1.0000004, 0.9999996, 0.9999991)
bones/40/rotation = Quaternion(0.9336719, 1.2799235e-07, 3.7337827e-08, 0.3581296)
bones/40/scale = Vector3(1.0000004, 1.0000001, 1.0000001)
bones/41/rotation = Quaternion(-0.13802455, 0.26758966, 0.08115916, 0.9501359)
bones/41/scale = Vector3(0.99999946, 0.99999976, 0.9999996)
bones/42/position = Vector3(-1.9729964e-07, 0.56145483, 7.283501e-08)
bones/46/scale = Vector3(0.99999946, 0.99999964, 0.9999999)
bones/48/rotation = Quaternion(-2.9741386e-07, 0.13593404, 1.01778824e-07, 0.9907179)
bones/48/scale = Vector3(0.9999993, 0.9999996, 0.9999999)
bones/50/scale = Vector3(0.99999994, 0.99999994, 0.9999998)
bones/51/rotation = Quaternion(-2.5567479e-08, -0.20499781, -2.3086146e-08, 0.9787625)
bones/51/scale = Vector3(0.9999999, 0.99999964, 0.99999964)
bones/53/position = Vector3(-0.8199191, 0.25251284, 0.47213903)
bones/53/rotation = Quaternion(-0.5351706, 0.35860845, -0.15898216, 0.74814254)
bones/53/scale = Vector3(1, 0.99999875, 0.99999946)
bones/54/rotation = Quaternion(0.0023762286, -4.7362324e-08, -6.475868e-08, 0.9999972)
bones/55/rotation = Quaternion(-0.54963607, -0.322046, -0.22350314, 0.73772144)
bones/55/scale = Vector3(1.0000002, 1, 1.0000002)
bones/56/position = Vector3(0.0013532753, 0.57868266, 0.05537574)
bones/56/rotation = Quaternion(-0.00015348212, 0.90210384, -0.43151882, 0.0003204293)
bones/57/rotation = Quaternion(0.70073944, -0.70073956, -0.094679825, -0.09467953)
bones/60/scale = Vector3(1.0000004, 1.0000004, 1.0000002)
bones/62/rotation = Quaternion(-1.7092354e-08, -0.18223058, 2.6700846e-08, 0.98325586)
bones/62/scale = Vector3(1.0000002, 1.0000002, 1.0000001)
bones/64/scale = Vector3(1.0000004, 1.0000004, 1)
bones/65/rotation = Quaternion(-1.0345744e-08, -0.3796584, -4.0675246e-08, 0.9251268)
bones/65/scale = Vector3(1.0000002, 1.0000004, 1.0000004)
bones/67/rotation = Quaternion(0.7179022, -7.671307e-07, 7.885642e-07, 0.696144)
bones/67/scale = Vector3(1.0000004, 0.9999986, 0.99999994)
bones/68/rotation = Quaternion(0.9776482, 2.0029378e-07, 1.0460874e-06, -0.2102479)
bones/68/scale = Vector3(1.0000004, 1.0000004, 0.9999982)
bones/69/position = Vector3(-2.4645832e-08, -6.861796e-09, 7.455772e-08)
bones/69/rotation = Quaternion(-0.8315212, 2.5276703e-08, -9.3330055e-09, 0.5554931)
bones/69/scale = Vector3(1, 1.0000001, 1.0000002)
bones/70/rotation = Quaternion(0.67750055, 8.820757e-08, 7.575834e-08, 0.7355223)
bones/70/scale = Vector3(1, 1, 1)
bones/71/scale = Vector3(0.9999999, 1, 0.9999999)
bones/72/rotation = Quaternion(-2.1641608e-07, -4.6565607e-10, -4.6576065e-10, 1)
bones/75/rotation = Quaternion(-0.34314692, -0.20321459, -0.2785586, 0.8737043)
bones/76/position = Vector3(1.01587794e-07, -1.5306958e-07, -4.3554866e-07)
bones/76/rotation = Quaternion(-0.51764834, -7.167482e-08, 1.7163823e-07, 0.85559356)
bones/77/rotation = Quaternion(0.93367195, 1.2110854e-07, 3.8556042e-08, 0.35812962)
bones/78/position = Vector3(0.8199172, 0.25251257, 0.47214243)
bones/78/rotation = Quaternion(0.6979164, 0.16086517, -0.15598962, 0.6802223)
bones/78/scale = Vector3(1.0000004, 0.9999997, 0.99999905)
bones/80/rotation = Quaternion(0.7179022, -7.6713064e-07, 7.885641e-07, 0.696144)
bones/80/scale = Vector3(1.0000004, 0.9999986, 0.99999994)
bones/81/rotation = Quaternion(0.97764814, 1.9846473e-07, 1.0426893e-06, -0.21024783)
bones/81/scale = Vector3(1.0000004, 1.0000002, 0.9999982)
bones/82/position = Vector3(6.103571e-08, 8.8816435e-08, -3.6955274e-09)
bones/82/rotation = Quaternion(-0.8315211, 2.3407136e-08, -1.2821512e-08, 0.5554932)
bones/82/scale = Vector3(0.99999994, 0.99999994, 1)
bones/83/rotation = Quaternion(0.6775009, -8.600083e-08, -8.977273e-08, 0.735522)
bones/83/scale = Vector3(1, 1.0000001, 1)
bones/84/scale = Vector3(0.99999994, 1.0000001, 0.9999999)
bones/85/rotation = Quaternion(2.6833732e-07, -9.313788e-10, -2.5612494e-09, 1)
bones/85/scale = Vector3(1.0000001, 1, 1.0000001)
bones/87/rotation = Quaternion(-0.5230753, 0.20132942, 0.026226493, 0.8277505)
bones/88/rotation = Quaternion(0.61967987, 0.23118778, 0.3169036, 0.679795)
bones/89/position = Vector3(2.953037e-07, 4.9207458e-08, -4.3015167e-08)
bones/89/rotation = Quaternion(-0.001144886, -2.973514e-08, 2.817069e-08, 0.9999994)
bones/90/rotation = Quaternion(0.0023764072, -4.0769752e-08, -7.0690255e-08, 0.99999726)
bones/91/position = Vector3(-0.8199192, 0.2525128, 0.47213912)
bones/91/rotation = Quaternion(-0.49266297, -0.27058598, 0.2623832, 0.78436047)
bones/91/scale = Vector3(1.0000002, 0.999999, 0.99999964)
bones/96/position = Vector3(-0.021971898, -1.2751104, 0.16484088)
bones/96/rotation = Quaternion(-0.47603267, 0.067788206, -0.035077166, 0.8761091)
bones/96/scale = Vector3(0.9999999, 0.9999999, 0.99999976)
bones/97/rotation = Quaternion(0.997074, -1.2813135e-07, 1.666339e-06, -0.07644201)
bones/98/position = Vector3(0.01993539, 0.08757691, 0.045667563)
bones/98/rotation = Quaternion(0.1475291, 0.03397043, -0.019923227, 0.9882734)
bones/98/scale = Vector3(1, 1.0000011, 1.0000023)
bones/101/position = Vector3(-0.021972047, 0.8282039, 0.0959422)
bones/101/rotation = Quaternion(0.8371564, 0.04015539, 0.06490996, 0.5416119)
bones/101/scale = Vector3(1, 1.0000066, 0.99998474)
bones/102/rotation = Quaternion(0.95545256, -6.924111e-08, 2.2887033e-07, -0.29514462)
bones/103/position = Vector3(0.17285576, 0.72785676, 1.0822707)
bones/103/rotation = Quaternion(0.27801546, 0.0014157619, 0.015671493, 0.9604477)
bones/103/scale = Vector3(1.0000002, 1.000013, 1.0000246)
bones/104/rotation = Quaternion(0.5037003, 0.13519715, -0.093790196, 0.84806323)
bones/104/scale = Vector3(1.0000721, 1.0000457, 0.99993384)
bones/105/rotation = Quaternion(0.97757924, -0.053521663, -0.054415643, -0.19624804)
bones/105/scale = Vector3(1.0000001, 1.0000083, 1.0000036)
bones/106/position = Vector3(0.023142539, -0.54231995, -0.9607401)
bones/106/rotation = Quaternion(0.99272084, -0.08158898, -0.03307842, -0.08218607)
bones/107/rotation = Quaternion(0.903578, -0.12777254, -0.05477002, -0.4052421)
bones/107/scale = Vector3(0.9999992, 0.9999624, 1.0000123)
bones/108/position = Vector3(-1.1340098e-08, 7.923448e-07, 9.0939814e-08)
bones/108/rotation = Quaternion(0.98967296, 0.0031370325, 0.10343237, -0.09919364)
bones/110/rotation = Quaternion(9.815354e-07, 7.072085e-10, -9.586452e-08, 1)
bones/110/scale = Vector3(0.99999994, 0.99999976, 1.0000001)
bones/113/position = Vector3(0.07716276, 0.6410925, 0.71644557)
bones/113/rotation = Quaternion(0.75079244, 0.54212654, -0.3715475, 0.0660462)
bones/114/position = Vector3(-0.031743176, 0.60466695, -0.39704067)
bones/114/rotation = Quaternion(0.4176498, -0.11118397, 0.55639553, -0.70966953)
bones/114/scale = Vector3(1.0000015, 1.0000038, 1.0000079)
bones/115/rotation = Quaternion(-0.07547326, 0.02173067, -0.31477332, 0.945912)
bones/115/scale = Vector3(0.9999974, 1.0000036, 0.99999976)
bones/116/rotation = Quaternion(0.03028559, -0.3116764, -0.037417784, 0.9489682)
bones/116/scale = Vector3(1.0000005, 0.9999972, 1.0000013)
bones/119/scale = Vector3(1.0000043, 0.9999975, 0.99999744)
bones/121/rotation = Quaternion(-4.820391e-08, -0.1579088, -2.0880496e-08, 0.98745376)
bones/121/scale = Vector3(1.0000037, 0.99999774, 0.9999977)
bones/123/scale = Vector3(1.000003, 0.9999977, 0.99999917)
bones/124/rotation = Quaternion(-3.1036683e-07, 0.17317644, 6.989145e-08, 0.9848908)
bones/124/scale = Vector3(1.0000037, 0.9999978, 0.99999875)
bones/126/rotation = Quaternion(-0.5163543, -0.16816929, 0.6340875, 0.550482)
bones/126/scale = Vector3(1.0000015, 1.000007, 1.000004)
bones/127/rotation = Quaternion(-0.24332331, 0.12663932, 0.6612194, 0.6982444)
bones/127/scale = Vector3(1.0000017, 1.0000014, 1.0000097)
bones/128/position = Vector3(-0.008928956, 0.128764, -0.06877987)
bones/128/rotation = Quaternion(0.025037244, 0.39930493, -0.88358396, 0.24332726)
bones/129/rotation = Quaternion(-0.07547334, 0.021730714, -0.31477335, 0.94591194)
bones/131/rotation = Quaternion(-0.41802245, -0.28161782, 0.08442414, 0.85954714)
bones/132/rotation = Quaternion(-0.5281791, -0.34319904, -0.62196887, -0.46518382)
bones/133/rotation = Quaternion(-0.012777329, 0.011854946, 0.00015161165, 0.9998482)
bones/133/scale = Vector3(1.0423008, 1.0423008, 1.0423006)
bones/134/rotation = Quaternion(0.02152103, -3.688601e-08, -1.5255387e-07, 0.99976844)
bones/134/scale = Vector3(0.9882629, 0.9882634, 0.98826265)
bones/135/position = Vector3(-0.0317431, 0.60466677, -0.39704087)
bones/135/rotation = Quaternion(0.22344373, -0.32689255, 0.658746, -0.6397405)
bones/135/scale = Vector3(1.0000048, 1.0000036, 1.0000046)
bones/137/position = Vector3(-0.33244255, 0.70370555, 0.67530614)
bones/137/rotation = Quaternion(0.7519437, -0.5788053, 0.30500948, 0.08083551)
bones/138/position = Vector3(-0.19594865, 0.65740275, -0.22511396)
bones/138/rotation = Quaternion(0.36201134, 0.22157827, -0.6475769, -0.63284683)
bones/138/scale = Vector3(1.0000019, 1.0000045, 1.0000057)
bones/139/rotation = Quaternion(-0.018797327, 0.13857716, 0.33871746, 0.9304373)
bones/139/scale = Vector3(0.9999983, 1.0000024, 0.9999992)
bones/140/rotation = Quaternion(0.09896898, 0.1986053, -0.00787212, 0.975038)
bones/140/scale = Vector3(1.0000031, 0.9999977, 0.9999988)
bones/143/scale = Vector3(1.000005, 0.99999815, 0.9999967)
bones/145/rotation = Quaternion(-1.7910523e-07, 0.10005118, -9.714451e-08, 0.9949823)
bones/145/scale = Vector3(1.0000045, 0.99999803, 0.9999968)
bones/147/scale = Vector3(1.0000035, 0.99999845, 0.9999981)
bones/148/rotation = Quaternion(2.0844507e-07, 0.011625211, 4.5709146e-07, 0.9999325)
bones/148/scale = Vector3(1.000004, 0.9999991, 0.999998)
bones/150/rotation = Quaternion(-0.51635444, 0.16816957, -0.63408744, 0.55048186)
bones/150/scale = Vector3(1.000001, 1.0000067, 1.000004)
bones/151/rotation = Quaternion(-0.24332346, -0.12663896, -0.6612195, 0.6982443)
bones/151/scale = Vector3(1.0000011, 1.0000017, 1.0000095)
bones/152/position = Vector3(0.027921734, -0.124764316, 0.07102555)
bones/152/rotation = Quaternion(-0.12973516, 0.47151387, -0.86254627, -0.12983702)
bones/153/rotation = Quaternion(-0.018797398, 0.13857722, 0.33871746, 0.9304373)
bones/155/rotation = Quaternion(-0.36541468, 0.16190512, -0.07102372, 0.91390073)
bones/155/scale = Vector3(0.99999994, 1, 0.9999998)
bones/156/rotation = Quaternion(0.68045896, -0.19169958, -0.3896983, 0.59022206)
bones/157/rotation = Quaternion(-0.01277751, -0.011854968, -0.0001513001, 0.9998481)
bones/157/scale = Vector3(1.0423003, 1.0422994, 1.0423005)
bones/158/rotation = Quaternion(0.021521209, -2.5687226e-07, -2.570953e-07, 0.9997684)
bones/158/scale = Vector3(0.9882631, 0.98826426, 0.9882618)
bones/159/position = Vector3(-0.19594839, 0.65740275, -0.2251139)
bones/159/rotation = Quaternion(0.28422734, 0.29369113, -0.68527013, -0.60279787)
bones/159/scale = Vector3(1.0000027, 1.0000043, 1.0000049)
bones/161/position = Vector3(0.07716276, 0.6410925, 0.71644557)
bones/161/rotation = Quaternion(0.75079244, 0.54212654, -0.3715475, 0.0660462)
bones/162/position = Vector3(-0.33244255, 0.70370555, 0.67530614)
bones/162/rotation = Quaternion(0.7519437, -0.5788053, 0.30500948, 0.08083551)
bones/165/position = Vector3(-1.5017577e-08, 0.26895812, -1.6243575e-08)
bones/165/rotation = Quaternion(-0.019247467, -0.20323175, 0.97894067, -0.0012537595)
bones/166/position = Vector3(0.0034187725, -3.131728, 0.9674823)
bones/167/position = Vector3(0.209171, 5.0901713, -2.6670303)
bones/167/rotation = Quaternion(0.16656846, 0.015223213, 0.18356222, 0.9686734)
bones/167/scale = Vector3(0.9999988, 0.9999987, 1.0000023)
bones/168/position = Vector3(0.18381567, -0.9622623, 0.9894084)
bones/168/rotation = Quaternion(0.9362244, -6.2652596e-08, -0.34127164, -0.083770975)
bones/168/scale = Vector3(1.0000011, 1.0000015, 1.0000101)
bones/170/position = Vector3(0.748137, 0.69556385, 3.7252903e-09)
bones/170/rotation = Quaternion(0.019250846, -0.20323181, 0.9789406, 0.001253055)
bones/171/position = Vector3(0.6322718, -2.6572587, 0.6064028)
bones/172/position = Vector3(-1.5122895, 4.4686184, -2.7014794)
bones/172/rotation = Quaternion(0.21553025, -0.03620148, 0.11066054, 0.9695311)
bones/172/scale = Vector3(0.99999887, 0.9999985, 1.0000024)
bones/173/position = Vector3(0.18381546, -0.96226203, 0.9894083)
bones/173/rotation = Quaternion(0.93622434, -2.9748788e-08, 0.34127158, -0.083771475)
bones/173/scale = Vector3(0.999999, 1.0000014, 0.99999464)
bones/175/position = Vector3(0.2542465, -2.2077389, 0.9589075)
bones/175/rotation = Quaternion(-0.008919476, -0.00021326332, -0.000697989, 0.99996)
bones/183/position = Vector3(-1.982537e-07, 5.9604563e-08, -1.517833e-08)
bones/185/rotation = Quaternion(5.4077844e-07, -0.20349081, 0.97907686, -1.12395135e-07)
bones/186/position = Vector3(0.57634556, 3.7607954, 0.15364014)
bones/186/rotation = Quaternion(-0.9604305, -0.020206233, -0.08076539, -0.26578543)
bones/186/scale = Vector3(0.9999997, 0.99999994, 1)
bones/187/rotation = Quaternion(0.15451065, -2.0305349e-09, -2.0850066e-09, 0.9879911)
bones/187/scale = Vector3(1.0000002, 0.99999994, 0.9999999)
bones/197/position = Vector3(-0.0011225368, -0.015787723, -0.051779967)
bones/199/rotation = Quaternion(0.00034800146, -0.20349097, 0.9790768, -7.2328476e-05)
bones/200/position = Vector3(-1.0407574, 3.6267605, -0.083099455)
bones/200/rotation = Quaternion(-0.9604305, -0.020206233, -0.08076539, -0.26578543)
bones/200/scale = Vector3(0.9999997, 0.99999994, 1)
bones/201/rotation = Quaternion(0.15451066, -1.9585848e-09, -2.5450761e-09, 0.9879911)
bones/201/scale = Vector3(1.0000002, 0.99999994, 0.99999994)
[editable path="bear_model"]
[editable path="bear_model/test_cube/Bear_FX"]
+70
View File
@@ -0,0 +1,70 @@
[gd_scene format=3]
[ext_resource type="Script" path="res://hitbox.gd" id="1_qxn4a"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_6dow8"]
height = 3.0
radius = 4.0
[sub_resource type="BoxShape3D" id="BoxShape3D_tmmfg"]
size = Vector3(2.6, 2.5, 20)
[sub_resource type="Animation" id="Animation_wcwtv"]
length = 0.25
tracks/0/type = "scale_3d"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("LeapSlamHitbox/CollisionShape3D")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, 0.12, 1, 0.12, 0.06, 1, 1, 1, 1, 0.25, 1, 1, 1, 1)
[sub_resource type="Animation" id="Animation_bg5u7"]
length = 0.3
tracks/0/type = "scale_3d"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SmashHitbox/CollisionShape3D")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, 1, 1, 0.02, 0.1, 1, 1, 1, 1, 0.3, 1, 1, 1, 1)
tracks/1/type = "position_3d"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("SmashHitbox/CollisionShape3D")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = PackedFloat32Array(0, 1, 0, 0.9, 0.2, 0.1, 1, 0, 0.9, 10, 0.3, 1, 0, 0.9, 10)
[sub_resource type="AnimationLibrary" id="AnimationLibrary_u1id2"]
_data = {
&"leap_slam": SubResource("Animation_wcwtv"),
&"smash_travel": SubResource("Animation_bg5u7")
}
[node name="AttackHitboxes" type="Node3D" unique_id=2010404706]
[node name="LeapSlamHitbox" type="Area3D" parent="." unique_id=1751893032]
collision_layer = 0
collision_mask = 2
monitoring = false
monitorable = false
script = ExtResource("1_qxn4a")
[node name="CollisionShape3D" type="CollisionShape3D" parent="LeapSlamHitbox" unique_id=1320172052]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
shape = SubResource("CylinderShape3D_6dow8")
[node name="SmashHitbox" type="Area3D" parent="." unique_id=1579648726]
collision_layer = 0
collision_mask = 2
monitoring = false
monitorable = false
script = ExtResource("1_qxn4a")
[node name="CollisionShape3D" type="CollisionShape3D" parent="SmashHitbox" unique_id=528637962]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 10)
shape = SubResource("BoxShape3D_tmmfg")
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=2139876757]
libraries/ = SubResource("AnimationLibrary_u1id2")
+10 -1
View File
@@ -24,7 +24,9 @@ I am a **Godot 4.6+ expert**. I follow current best practices for GDScript, scen
| `matador.gd` | Matador AI (wander / ragdoll state machine) |
| `levels/matador_spawn.gd` | Arena spawner — one matador per designer-placed child `Node3D` spawn point (each enters with a jump-roll toward center); falls back to a programmatic spread if no spawn points are present. Also handles the split-on-death hydra logic |
| `levels/bear_spawn.gd` | Bear-level spawner — instantiates `enemy_scene` at the arena center; emits the same `all_defeated` / `matador_killed` signals as `matador_spawn.gd` |
| `Bear.tscn` / `bear.gd` | Dark-Souls-style bear boss (`CharacterBody3D`). Routine state machine (wind-up → active → recovery) picking telegraphed moves by range band: Double Swipe / Overhead Smash (close), Leap Slam (mid-far), plus Stalk (2-leg walk-in) / Prowl (4-leg lope) positioning. Melee steps in during the swing (`bear_lunge_speed`) + tracks the bull; the leap is frame-synced to JUMP_SMASH so the paws hit ground on the impact frame (`bear_leap_impact_frame`); slams kick up dust + shake. Combos chain, hyper-armour mid-swing + poise (`bear_stagger_cd`), phase 2 enrage under `bear_enrage_frac` HP. Never damages the bull by colliding — only swings/slams. Joins `&"matador"` so bull abilities already hit it. Tuning under the `Bear` DP section |
| `Bear.tscn` / `bear.gd` | Dark-Souls-style bear boss (`CharacterBody3D`). Routine state machine (wind-up → active → recovery) picking telegraphed moves by range band: Double Swipe / Overhead Smash (close), Leap Slam (mid-far), plus Stalk (2-leg walk-in) / Prowl (4-leg lope) positioning. Melee steps in during the swing (`bear_lunge_speed`) + tracks the bull; the leap is frame-synced to JUMP_SMASH so the paws hit ground on the impact frame (`bear_leap_impact_frame`); slams kick up dust + shake. Combos chain, hyper-armour mid-swing + poise (`bear_stagger_cd`), phase 2 enrage under `bear_enrage_frac` HP. Never damages the bull by colliding — only swings/slams. A horns-first bull charge wounds it (`_sweep_bull_ram`: swept prev→now so a tunnelling/point-blank charge still lands, gated by `bear_ram_reach` + `bull_gore_arc`, edge-triggered = one charge per wound). Joins `&"matador"` so bull abilities already hit it. Tuning under the `Bear` DP section |
| `BearAttackHitboxes.tscn` | The bear's attack colliders as a self-contained sub-scene (instanced under `bear_model`): a `LeapSlamHitbox` (Hitbox + cylinder = ground circle) and `SmashHitbox` (Hitbox + box = forward shockwave lane), plus an `AnimationPlayer` whose `leap_slam` / `smash_travel` clips author each collider's size + travel — scrub to tweak, like `Bear_FX`. `bear.gd` only fires the clip, arms the knock-up shaping, and sweeps for overlaps while it runs (see `_setup_attack_hitboxes` / `_start_attack_hitbox`) |
| `Sword.tscn` / `hitbox.gd` | The matador's sword wrapper (glb + editor-tweakable `BladeHitbox`). `hitbox.gd` (`class_name Hitbox`, Area3D) is the shared attack collider: `activate()`/`deactivate()` gate an active window, `sweep()` catches bodies already inside (AoE), and knock-up can ramp by distance (`knock_up_min_dist`/`_max_dist`) for the bear's outer-ring launch / further-hit-flies-higher |
| `levels/run_state.gd` | Run progression autoload (`Run`) — Slay-the-Spire map + player position across fights |
| `levels/level_def.gd` | `LevelDef` resource — a level's name / map colour / `scene_path` (always the shell) / `level_scene` (the level module instanced into the shell) / optional `enemy_scene` (arena wave vs. a boss like the bear) |
| `levels/map_node.gd` | `MapNode` — one runtime node on the run map (position, level, links) |
@@ -106,6 +108,13 @@ godot --headless --script tests/performance_test.gd # frame-budget regression
godot --headless --script tests/gameplay_test.gd # full scene, bone sanity, ~4 s
godot --headless --script tests/level_switch_test.gd # no arena geometry leaks into the bear level, ~2 s
godot --headless --script tests/bear_boss_test.gd # bear boss moveset: routines, leap landing, hyper-armour, ~10 s
godot --headless --script tests/bear_fx_test.gd # bear attack-FX: each Bear_FX clip pops its mesh + self-hides, ~2 s
godot --headless --script tests/bear_hitbox_test.gd # bear attack colliders: leap launches everywhere (ring_frac slider) + smash lane travel, ~3 s
godot --headless --script tests/bear_ram_test.gd # a horns-first bull charge wounds the bear once; away/wide/slow spared, ~3 s
godot --headless --script tests/matador_stab_test.gd # matador's BladeHitbox thrust gores a stationary bull, and a landed stab breaks it off to taunt (anti-spam), ~2 s
godot --headless --script tests/matador_taunt_react_test.gd # a taunting matador answers a charge: spear from range, sword up close, ignores non-charges, ~2 s
godot --headless --script tests/matador_charge_test.gd # bull's charge is swept (tunnel-proof) so a fast dash still gores; a committed charge pierces the survival roll, ~2 s
godot --headless --script tests/matador_spear_test.gd # thrown spear masks the BULL layer and hits a stationary bull, ~2 s
# Gameplay test with real rendering (inspect frame strip visually):
godot --script tests/gameplay_test.gd # opens a window, saves real screenshots
-137
View File
@@ -1,137 +0,0 @@
[gd_scene format=3 uid="uid://c4df4qgpc3d5g"]
[ext_resource type="PackedScene" uid="uid://eu2lqjhowj4t" path="res://Assets/Matador.glb" id="1_eicjn"]
[ext_resource type="Script" uid="uid://dycnoiadljbb1" path="res://Assets/matador_intro_menu.gd" id="2_5jr0i"]
[ext_resource type="PackedScene" uid="uid://dio67r8ambe7h" path="res://Assets/arena_placeholder_v01.glb" id="3_1v6n4"]
[ext_resource type="PackedScene" uid="uid://dxe72ig8gfbcg" path="res://Assets/arena model2026.glb" id="3_5jr0i"]
[ext_resource type="PackedScene" uid="uid://crtm0xtiql3r8" path="res://Player.tscn" id="4_eicjn"]
[ext_resource type="Texture2D" uid="uid://3syhacswepyj" path="res://HDRI/kloppenheim_06_puresky_4k.hdr" id="6_1v6n4"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_eicjn"]
[sub_resource type="PanoramaSkyMaterial" id="PanoramaSkyMaterial_w7j4y"]
panorama = ExtResource("6_1v6n4")
energy_multiplier = 5.6
[sub_resource type="Sky" id="Sky_3el7n"]
sky_material = SubResource("PanoramaSkyMaterial_w7j4y")
[sub_resource type="Environment" id="Environment_5jr0i"]
background_mode = 2
background_energy_multiplier = 0.18
sky = SubResource("Sky_3el7n")
ambient_light_color = Color(0.31061712, 0.31061712, 0.3106171, 1)
ambient_light_energy = 16.0
ssao_enabled = true
ssao_radius = 1.17
ssao_intensity = 0.0
glow_intensity = 0.34
glow_strength = 0.29
glow_bloom = 0.1
fog_light_color = Color(2.211, 2.211, 2.211, 1)
fog_light_energy = 0.01
fog_density = 0.0399
volumetric_fog_enabled = true
volumetric_fog_density = 0.0005
volumetric_fog_emission = Color(1, 1, 1, 1)
volumetric_fog_emission_energy = 7.85
volumetric_fog_anisotropy = 0.9
volumetric_fog_length = 69.07
[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_5jr0i"]
dof_blur_far_enabled = true
dof_blur_far_distance = 26.01
dof_blur_near_enabled = true
dof_blur_near_distance = 2.6
dof_blur_near_transition = 5.0
[node name="IntroMenu" type="Node3D" unique_id=2130618263]
[node name="Matador" parent="." unique_id=166852612 instance=ExtResource("1_eicjn")]
transform = Transform3D(-0.56715536, 0, -0.8236109, 0, 1, 0, 0.8236109, 0, -0.56715536, 5.2114463, -0.08998108, 1.8927763)
script = ExtResource("2_5jr0i")
[node name="Skeleton3D" parent="Matador/Armature" parent_id_path=PackedInt32Array(166852612, 1447304122) index="0" unique_id=357848305]
bones/0/position = Vector3(0.056660548, 0.6424767, -0.0167365)
bones/0/rotation = Quaternion(0.013179442, -0.2660563, 0.073319815, 0.9610747)
bones/1/rotation = Quaternion(0.06234612, 0.049236443, 0.08183311, 0.99347484)
bones/2/rotation = Quaternion(-0.073883414, -0.049860783, -0.17668208, 0.9802238)
bones/3/rotation = Quaternion(0.1986702, -0.17794952, -0.71790075, 0.6430262)
bones/4/rotation = Quaternion(0.34491858, -0.4473084, -0.25076818, 0.7861691)
bones/5/rotation = Quaternion(0.2577085, 0.103201896, -0.6748433, 0.68375605)
bones/6/rotation = Quaternion(1.7417646e-08, -1.0305205e-07, -0.05870078, 0.99827564)
bones/7/rotation = Quaternion(0.24033272, 0.3103031, 0.5222128, 0.7571301)
bones/8/rotation = Quaternion(5.5530215e-08, 1.2911333e-07, 0.055464897, 0.99846065)
bones/9/rotation = Quaternion(-6.3051346e-09, -3.6333955e-07, 0.005667881, 0.999984)
bones/10/rotation = Quaternion(2.5839595e-08, 9.468444e-08, 0.058700778, 0.99827564)
bones/11/rotation = Quaternion(0.39202607, 0.47060946, 0.57993996, 0.53713304)
bones/12/rotation = Quaternion(0.8712108, 0.008231261, 0.48523128, 0.073990606)
bones/13/rotation = Quaternion(-0.056263044, 0.0027001738, 0.3080972, 0.9496859)
bones/14/rotation = Quaternion(0.016082464, 0.024660494, -0.86586916, 0.4994036)
bones/15/rotation = Quaternion(0.6067664, -0.3062479, -0.7163194, 0.15790276)
bones/16/rotation = Quaternion(-0.0731876, -0.0023153822, -0.47496143, 0.87695485)
bones/17/rotation = Quaternion(-0.11824294, -0.17776872, 0.80557114, 0.55269533)
bones/18/rotation = Quaternion(0.5305965, -0.28927496, 0.76720744, -0.21489605)
bones/20/position = Vector3(0.22012731, 0.38421977, 0.36399037)
bones/21/position = Vector3(-0.23671798, 0.052281797, -0.027087089)
bones/21/rotation = Quaternion(0.5078295, -0.4920459, -0.4920459, 0.50782955)
bones/22/position = Vector3(-0.39721552, 0.31719273, 0.3595722)
bones/23/position = Vector3(-0.9167187, 1.3206767, 0.42621902)
bones/23/rotation = Quaternion(0.9993525, -0.0021175682, 0.03502641, -0.00795782)
bones/24/rotation = Quaternion(0.08874816, -0.018719967, -0.04671622, 0.99478185)
bones/25/rotation = Quaternion(0.09634846, -0.0268489, -0.04050248, 0.9941608)
[node name="matador" parent="Matador/Armature/Skeleton3D" index="0" unique_id=593562242]
transform = Transform3D(0.8642424, 0, 0.50307554, 0, 1, 0, -0.50307554, 0, 0.8642424, 0, 0, 0)
[node name="Muleta" parent="Matador/Armature/Skeleton3D" index="1" unique_id=978680467]
cast_shadow = 0
[node name="Camera3D" type="Camera3D" parent="." unique_id=1531255459]
transform = Transform3D(0.42176014, 0.2362673, 0.8753835, -0.10687317, 0.97167695, -0.21076548, -0.900387, -0.0046625203, 0.4350652, 8.41945, 0.17132203, 2.0652685)
fov = 41.6
near = 0.001
[node name="arena model2026" parent="." unique_id=179544183 instance=ExtResource("3_5jr0i")]
transform = Transform3D(-0.83746713, 0, 0.54648757, 0, 0.99999994, 0, -0.54648757, 0, -0.83746713, 3.8733478, -0.6, -1.1080065)
[node name="arena_placeholder_v01" parent="." unique_id=1343590504 instance=ExtResource("3_1v6n4")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.3344436, 0, -1.5401263)
visible = false
[node name="StaticBody3D" type="StaticBody3D" parent="arena_placeholder_v01" unique_id=340133176]
[node name="CollisionShape3D" type="CollisionShape3D" parent="arena_placeholder_v01/StaticBody3D" unique_id=201484167]
transform = Transform3D(-33.265, 4.9526625e-07, -2.9081186e-06, 5.0228755e-06, 3.28, 0, -2.9081186e-06, 4.329755e-14, 33.265, 0, -3.3065948, 0)
shape = SubResource("CylinderShape3D_eicjn")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=660229295]
transform = Transform3D(0.9491592, 0.31479403, -0.0014368258, -0.28033537, 0.84731936, 0.45106864, 0.14321098, -0.4277331, 0.89248836, 1.1162033, 7.3956842, -4.480528)
light_energy = 1.32
shadow_enabled = true
shadow_blur = 8.689
[node name="DirectionalLight3D2" type="DirectionalLight3D" parent="." unique_id=498871251]
transform = Transform3D(0.835524, -0.5376153, 0.11344351, -0.48260456, -0.6193575, 0.6192651, -0.26266432, -0.572159, -0.7769435, 1.1162033, 7.3956842, -4.480528)
visible = false
light_energy = 0.415
light_indirect_energy = 16.0
light_volumetric_fog_energy = 1.11
shadow_blur = 10.0
[node name="Player" parent="." unique_id=165510044 instance=ExtResource("4_eicjn")]
transform = Transform3D(0.9563367, 0, 0.29226705, 0, 1, 0, -0.29226705, 0, 0.9563367, 3.0920272, 0.39692497, -4.302477)
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=114793752]
environment = SubResource("Environment_5jr0i")
camera_attributes = SubResource("CameraAttributesPractical_5jr0i")
[node name="SpotLight3D" type="SpotLight3D" parent="." unique_id=1428020323]
transform = Transform3D(0.94930077, -0.05846006, -0.30888584, 0.21308771, 0.8420559, 0.4955155, 0.23113126, -0.53621286, 0.81182146, -20.807917, 10.690277, 20.135067)
visible = false
light_energy = 16.0
light_volumetric_fog_energy = 16.0
shadow_enabled = true
spot_range = 84.316696
[editable path="Matador"]
+7 -8
View File
@@ -1,6 +1,6 @@
[gd_scene format=3 uid="uid://matador_scene_v1"]
[gd_scene format=3 uid="uid://d0te4mwbh33ag"]
[ext_resource type="Script" path="res://matador.gd" id="1_matgd"]
[ext_resource type="Script" uid="uid://bvfa7xi0luysk" path="res://matador.gd" id="1_matgd"]
[ext_resource type="PackedScene" uid="uid://eu2lqjhowj4t" path="res://Assets/Matador.glb" id="2_matfbx"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_body"]
@@ -11,19 +11,18 @@ height = 1.2
radius = 0.45
height = 1.4
[node name="Matador" type="CharacterBody3D"]
[node name="Matador" type="CharacterBody3D" unique_id=1781857630]
script = ExtResource("1_matgd")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=2101651042]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0)
shape = SubResource("CapsuleShape3D_body")
[node name="HitArea" type="Area3D" parent="."]
monitoring = true
[node name="HitArea" type="Area3D" parent="." unique_id=745037545]
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="HitArea"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="HitArea" unique_id=1497356275]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0)
shape = SubResource("CapsuleShape3D_hit")
[node name="matador2" parent="." instance=ExtResource("2_matfbx")]
[node name="matador2" parent="." unique_id=1487256381 instance=ExtResource("2_matfbx")]
+5
View File
@@ -0,0 +1,5 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://b73nb47y8ppt"]
[resource]
albedo_color = Color(0.26098922, 0.27367952, 0.27059656, 1)
metallic = 1.0
+14
View File
@@ -0,0 +1,14 @@
shader_type spatial;
void vertex() {
// Called for every vertex the material is visible on.
}
void fragment() {
// Called for every pixel the material is visible on.
}
//void light() {
// // Called for every pixel for every light affecting the material.
// // Uncomment to replace the default light processing function with this one.
//}
+1
View File
@@ -0,0 +1 @@
uid://bme1rkldtyrhu
+4
View File
@@ -0,0 +1,4 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://isrp2y47xs5x"]
[resource]
albedo_color = Color(0.49425018, 0.31969637, 0.21259204, 1)
+5
View File
@@ -0,0 +1,5 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://blpkmyikjnhbo"]
[resource]
emission_enabled = true
emission = Color(0.4627451, 0.8117647, 0.9490196, 1)
+5
View File
@@ -0,0 +1,5 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://dgmk764033feq"]
[resource]
emission_enabled = true
emission = Color(0.7096375, 0.3347874, 0.09943161, 1)
+2 -1
View File
@@ -9,7 +9,8 @@ radius = 0.7495117
height = 1.845398
[node name="Player" type="CharacterBody3D" unique_id=165510044]
collision_layer = 3
collision_layer = 2
collision_mask = 9
script = ExtResource("1_xhfnw")
[node name="CollisionBull" type="CollisionShape3D" parent="." unique_id=571780801]
+52
View File
@@ -0,0 +1,52 @@
[gd_scene format=3 uid="uid://crtm0xtiql3r8"]
[ext_resource type="Script" uid="uid://bn777gguclud5" path="res://player.gd" id="1_xhfnw"]
[ext_resource type="Script" uid="uid://cpyq2r5cq653g" path="res://camera_iso.gd" id="2_camera_iso"]
[ext_resource type="PackedScene" uid="uid://bun14xmk20pcj" path="res://Assets/bull.fbx" id="4_e80uo"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_kne1u"]
radius = 0.7495117
height = 1.845398
[node name="Player" type="CharacterBody3D" unique_id=165510044]
collision_layer = 2
collision_mask = 9
script = ExtResource("1_xhfnw")
[node name="CollisionBull" type="CollisionShape3D" parent="." unique_id=571780801]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.29183745, 0.3197594)
shape = SubResource("CapsuleShape3D_kne1u")
[node name="Camera3D" type="Camera3D" parent="." unique_id=1120161087]
script = ExtResource("2_camera_iso")
[node name="bull" parent="." unique_id=1386495166 instance=ExtResource("4_e80uo")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.655, 0.23)
[node name="Skeleton3D" parent="bull/Armature" parent_id_path=PackedInt32Array(1386495166, 1942410469) index="0" unique_id=550138996]
bones/0/position = Vector3(0, 0, 0.009963839)
bones/0/rotation = Quaternion(0.7071068, 0, 0, 0.7071067)
bones/0/scale = Vector3(1, 1, 1)
bones/1/position = Vector3(0.003526625, -0.0043296535, 0.0040827994)
bones/1/rotation = Quaternion(-0.00038647873, 0.06909673, 0.9868542, -0.14609687)
bones/2/rotation = Quaternion(-0.06929122, 3.2175163e-07, -0.112670615, 0.99121344)
bones/4/position = Vector3(0.0045358227, -0.002137695, -0.004238624)
bones/4/rotation = Quaternion(-0.24948503, 0.19590352, 0.9416978, -0.11217985)
bones/4/scale = Vector3(1.0000001, 0.9999999, 1.0000001)
bones/5/rotation = Quaternion(-0.58943665, -0.3660725, -0.22564478, 0.683842)
bones/5/scale = Vector3(1, 1.0000001, 0.99999994)
bones/6/rotation = Quaternion(0.52910197, 0.15997827, 0.120245, 0.8246207)
bones/6/scale = Vector3(1, 1, 1.0000001)
bones/17/position = Vector3(0, 0.0009373814, 0.007552617)
bones/17/rotation = Quaternion(-9.4156974e-08, 0.7071068, 0.7071067, -9.4156974e-08)
bones/19/position = Vector3(-0.003526625, -0.0043296535, 0.0040827994)
bones/19/rotation = Quaternion(0.00038647873, 0.06909673, 0.9868542, 0.14609687)
bones/20/rotation = Quaternion(-0.06929122, -3.2227587e-07, 0.11267061, 0.99121344)
bones/22/position = Vector3(-0.0045358227, -0.002137695, -0.004238624)
bones/22/rotation = Quaternion(0.24948503, 0.19590352, 0.9416978, 0.11217985)
bones/23/rotation = Quaternion(-0.58943665, 0.3660725, 0.22564478, 0.683842)
bones/23/scale = Vector3(1, 1.0000001, 1)
bones/24/rotation = Quaternion(0.529102, -0.15997836, -0.120245025, 0.82462066)
bones/24/scale = Vector3(1, 1.0000001, 1)
[editable path="bull"]
+52
View File
@@ -0,0 +1,52 @@
[gd_scene format=3 uid="uid://crtm0xtiql3r8"]
[ext_resource type="Script" uid="uid://bn777gguclud5" path="res://player.gd" id="1_xhfnw"]
[ext_resource type="Script" uid="uid://cpyq2r5cq653g" path="res://camera_iso.gd" id="2_camera_iso"]
[ext_resource type="PackedScene" uid="uid://bun14xmk20pcj" path="res://Assets/bull.fbx" id="4_e80uo"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_kne1u"]
radius = 0.7495117
height = 1.845398
[node name="Player" type="CharacterBody3D" unique_id=165510044]
collision_layer = 2
collision_mask = 9
script = ExtResource("1_xhfnw")
[node name="CollisionBull" type="CollisionShape3D" parent="." unique_id=571780801]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.29183745, 0.3197594)
shape = SubResource("CapsuleShape3D_kne1u")
[node name="Camera3D" type="Camera3D" parent="." unique_id=1120161087]
script = ExtResource("2_camera_iso")
[node name="bull" parent="." unique_id=1386495166 instance=ExtResource("4_e80uo")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.655, 0.23)
[node name="Skeleton3D" parent="bull/Armature" parent_id_path=PackedInt32Array(1386495166, 1942410469) index="0" unique_id=550138996]
bones/0/position = Vector3(0, 0, 0.009963839)
bones/0/rotation = Quaternion(0.7071068, 0, 0, 0.7071067)
bones/0/scale = Vector3(1, 1, 1)
bones/1/position = Vector3(0.003526625, -0.0043296535, 0.0040827994)
bones/1/rotation = Quaternion(-0.00038647873, 0.06909673, 0.9868542, -0.14609687)
bones/2/rotation = Quaternion(-0.06929122, 3.2175163e-07, -0.112670615, 0.99121344)
bones/4/position = Vector3(0.0045358227, -0.002137695, -0.004238624)
bones/4/rotation = Quaternion(-0.24948503, 0.19590352, 0.9416978, -0.11217985)
bones/4/scale = Vector3(1.0000001, 0.9999999, 1.0000001)
bones/5/rotation = Quaternion(-0.58943665, -0.3660725, -0.22564478, 0.683842)
bones/5/scale = Vector3(1, 1.0000001, 0.99999994)
bones/6/rotation = Quaternion(0.52910197, 0.15997827, 0.120245, 0.8246207)
bones/6/scale = Vector3(1, 1, 1.0000001)
bones/17/position = Vector3(0, 0.0009373814, 0.007552617)
bones/17/rotation = Quaternion(-9.4156974e-08, 0.7071068, 0.7071067, -9.4156974e-08)
bones/19/position = Vector3(-0.003526625, -0.0043296535, 0.0040827994)
bones/19/rotation = Quaternion(0.00038647873, 0.06909673, 0.9868542, 0.14609687)
bones/20/rotation = Quaternion(-0.06929122, -3.2227587e-07, 0.11267061, 0.99121344)
bones/22/position = Vector3(-0.0045358227, -0.002137695, -0.004238624)
bones/22/rotation = Quaternion(0.24948503, 0.19590352, 0.9416978, 0.11217985)
bones/23/rotation = Quaternion(-0.58943665, 0.3660725, 0.22564478, 0.683842)
bones/23/scale = Vector3(1, 1.0000001, 1)
bones/24/rotation = Quaternion(0.529102, -0.15997836, -0.120245025, 0.82462066)
bones/24/scale = Vector3(1, 1.0000001, 1)
[editable path="bull"]
+52
View File
@@ -0,0 +1,52 @@
[gd_scene format=3 uid="uid://crtm0xtiql3r8"]
[ext_resource type="Script" uid="uid://bn777gguclud5" path="res://player.gd" id="1_xhfnw"]
[ext_resource type="Script" uid="uid://cpyq2r5cq653g" path="res://camera_iso.gd" id="2_camera_iso"]
[ext_resource type="PackedScene" uid="uid://bun14xmk20pcj" path="res://Assets/bull.fbx" id="4_e80uo"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_kne1u"]
radius = 0.7495117
height = 1.845398
[node name="Player" type="CharacterBody3D" unique_id=165510044]
collision_layer = 2
collision_mask = 9
script = ExtResource("1_xhfnw")
[node name="CollisionBull" type="CollisionShape3D" parent="." unique_id=571780801]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.29183745, 0.3197594)
shape = SubResource("CapsuleShape3D_kne1u")
[node name="Camera3D" type="Camera3D" parent="." unique_id=1120161087]
script = ExtResource("2_camera_iso")
[node name="bull" parent="." unique_id=1386495166 instance=ExtResource("4_e80uo")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.655, 0.23)
[node name="Skeleton3D" parent="bull/Armature" parent_id_path=PackedInt32Array(1386495166, 1942410469) index="0" unique_id=550138996]
bones/0/position = Vector3(0, 0, 0.009963839)
bones/0/rotation = Quaternion(0.7071068, 0, 0, 0.7071067)
bones/0/scale = Vector3(1, 1, 1)
bones/1/position = Vector3(0.003526625, -0.0043296535, 0.0040827994)
bones/1/rotation = Quaternion(-0.00038647873, 0.06909673, 0.9868542, -0.14609687)
bones/2/rotation = Quaternion(-0.06929122, 3.2175163e-07, -0.112670615, 0.99121344)
bones/4/position = Vector3(0.0045358227, -0.002137695, -0.004238624)
bones/4/rotation = Quaternion(-0.24948503, 0.19590352, 0.9416978, -0.11217985)
bones/4/scale = Vector3(1.0000001, 0.9999999, 1.0000001)
bones/5/rotation = Quaternion(-0.58943665, -0.3660725, -0.22564478, 0.683842)
bones/5/scale = Vector3(1, 1.0000001, 0.99999994)
bones/6/rotation = Quaternion(0.52910197, 0.15997827, 0.120245, 0.8246207)
bones/6/scale = Vector3(1, 1, 1.0000001)
bones/17/position = Vector3(0, 0.0009373814, 0.007552617)
bones/17/rotation = Quaternion(-9.4156974e-08, 0.7071068, 0.7071067, -9.4156974e-08)
bones/19/position = Vector3(-0.003526625, -0.0043296535, 0.0040827994)
bones/19/rotation = Quaternion(0.00038647873, 0.06909673, 0.9868542, 0.14609687)
bones/20/rotation = Quaternion(-0.06929122, -3.2227587e-07, 0.11267061, 0.99121344)
bones/22/position = Vector3(-0.0045358227, -0.002137695, -0.004238624)
bones/22/rotation = Quaternion(0.24948503, 0.19590352, 0.9416978, 0.11217985)
bones/23/rotation = Quaternion(-0.58943665, 0.3660725, 0.22564478, 0.683842)
bones/23/scale = Vector3(1, 1.0000001, 1)
bones/24/rotation = Quaternion(0.529102, -0.15997836, -0.120245025, 0.82462066)
bones/24/scale = Vector3(1, 1.0000001, 1)
[editable path="bull"]
+52
View File
@@ -0,0 +1,52 @@
[gd_scene format=3 uid="uid://crtm0xtiql3r8"]
[ext_resource type="Script" uid="uid://bn777gguclud5" path="res://player.gd" id="1_xhfnw"]
[ext_resource type="Script" uid="uid://cpyq2r5cq653g" path="res://camera_iso.gd" id="2_camera_iso"]
[ext_resource type="PackedScene" uid="uid://bun14xmk20pcj" path="res://Assets/bull.fbx" id="4_e80uo"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_kne1u"]
radius = 0.7495117
height = 1.845398
[node name="Player" type="CharacterBody3D" unique_id=165510044]
collision_layer = 2
collision_mask = 9
script = ExtResource("1_xhfnw")
[node name="CollisionBull" type="CollisionShape3D" parent="." unique_id=571780801]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.29183745, 0.3197594)
shape = SubResource("CapsuleShape3D_kne1u")
[node name="Camera3D" type="Camera3D" parent="." unique_id=1120161087]
script = ExtResource("2_camera_iso")
[node name="bull" parent="." unique_id=1386495166 instance=ExtResource("4_e80uo")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.655, 0.23)
[node name="Skeleton3D" parent="bull/Armature" parent_id_path=PackedInt32Array(1386495166, 1942410469) index="0" unique_id=550138996]
bones/0/position = Vector3(0, 0, 0.009963839)
bones/0/rotation = Quaternion(0.7071068, 0, 0, 0.7071067)
bones/0/scale = Vector3(1, 1, 1)
bones/1/position = Vector3(0.003526625, -0.0043296535, 0.0040827994)
bones/1/rotation = Quaternion(-0.00038647873, 0.06909673, 0.9868542, -0.14609687)
bones/2/rotation = Quaternion(-0.06929122, 3.2175163e-07, -0.112670615, 0.99121344)
bones/4/position = Vector3(0.0045358227, -0.002137695, -0.004238624)
bones/4/rotation = Quaternion(-0.24948503, 0.19590352, 0.9416978, -0.11217985)
bones/4/scale = Vector3(1.0000001, 0.9999999, 1.0000001)
bones/5/rotation = Quaternion(-0.58943665, -0.3660725, -0.22564478, 0.683842)
bones/5/scale = Vector3(1, 1.0000001, 0.99999994)
bones/6/rotation = Quaternion(0.52910197, 0.15997827, 0.120245, 0.8246207)
bones/6/scale = Vector3(1, 1, 1.0000001)
bones/17/position = Vector3(0, 0.0009373814, 0.007552617)
bones/17/rotation = Quaternion(-9.4156974e-08, 0.7071068, 0.7071067, -9.4156974e-08)
bones/19/position = Vector3(-0.003526625, -0.0043296535, 0.0040827994)
bones/19/rotation = Quaternion(0.00038647873, 0.06909673, 0.9868542, 0.14609687)
bones/20/rotation = Quaternion(-0.06929122, -3.2227587e-07, 0.11267061, 0.99121344)
bones/22/position = Vector3(-0.0045358227, -0.002137695, -0.004238624)
bones/22/rotation = Quaternion(0.24948503, 0.19590352, 0.9416978, 0.11217985)
bones/23/rotation = Quaternion(-0.58943665, 0.3660725, 0.22564478, 0.683842)
bones/23/scale = Vector3(1, 1.0000001, 1)
bones/24/rotation = Quaternion(0.529102, -0.15997836, -0.120245025, 0.82462066)
bones/24/scale = Vector3(1, 1.0000001, 1)
[editable path="bull"]
+52
View File
@@ -0,0 +1,52 @@
[gd_scene format=3 uid="uid://crtm0xtiql3r8"]
[ext_resource type="Script" uid="uid://bn777gguclud5" path="res://player.gd" id="1_xhfnw"]
[ext_resource type="Script" uid="uid://cpyq2r5cq653g" path="res://camera_iso.gd" id="2_camera_iso"]
[ext_resource type="PackedScene" uid="uid://bun14xmk20pcj" path="res://Assets/bull.fbx" id="4_e80uo"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_kne1u"]
radius = 0.7495117
height = 1.845398
[node name="Player" type="CharacterBody3D" unique_id=165510044]
collision_layer = 2
collision_mask = 9
script = ExtResource("1_xhfnw")
[node name="CollisionBull" type="CollisionShape3D" parent="." unique_id=571780801]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.29183745, 0.3197594)
shape = SubResource("CapsuleShape3D_kne1u")
[node name="Camera3D" type="Camera3D" parent="." unique_id=1120161087]
script = ExtResource("2_camera_iso")
[node name="bull" parent="." unique_id=1386495166 instance=ExtResource("4_e80uo")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.655, 0.23)
[node name="Skeleton3D" parent="bull/Armature" parent_id_path=PackedInt32Array(1386495166, 1942410469) index="0" unique_id=550138996]
bones/0/position = Vector3(0, 0, 0.009963839)
bones/0/rotation = Quaternion(0.7071068, 0, 0, 0.7071067)
bones/0/scale = Vector3(1, 1, 1)
bones/1/position = Vector3(0.003526625, -0.0043296535, 0.0040827994)
bones/1/rotation = Quaternion(-0.00038647873, 0.06909673, 0.9868542, -0.14609687)
bones/2/rotation = Quaternion(-0.06929122, 3.2175163e-07, -0.112670615, 0.99121344)
bones/4/position = Vector3(0.0045358227, -0.002137695, -0.004238624)
bones/4/rotation = Quaternion(-0.24948503, 0.19590352, 0.9416978, -0.11217985)
bones/4/scale = Vector3(1.0000001, 0.9999999, 1.0000001)
bones/5/rotation = Quaternion(-0.58943665, -0.3660725, -0.22564478, 0.683842)
bones/5/scale = Vector3(1, 1.0000001, 0.99999994)
bones/6/rotation = Quaternion(0.52910197, 0.15997827, 0.120245, 0.8246207)
bones/6/scale = Vector3(1, 1, 1.0000001)
bones/17/position = Vector3(0, 0.0009373814, 0.007552617)
bones/17/rotation = Quaternion(-9.4156974e-08, 0.7071068, 0.7071067, -9.4156974e-08)
bones/19/position = Vector3(-0.003526625, -0.0043296535, 0.0040827994)
bones/19/rotation = Quaternion(0.00038647873, 0.06909673, 0.9868542, 0.14609687)
bones/20/rotation = Quaternion(-0.06929122, -3.2227587e-07, 0.11267061, 0.99121344)
bones/22/position = Vector3(-0.0045358227, -0.002137695, -0.004238624)
bones/22/rotation = Quaternion(0.24948503, 0.19590352, 0.9416978, 0.11217985)
bones/23/rotation = Quaternion(-0.58943665, 0.3660725, 0.22564478, 0.683842)
bones/23/scale = Vector3(1, 1.0000001, 1)
bones/24/rotation = Quaternion(0.529102, -0.15997836, -0.120245025, 0.82462066)
bones/24/scale = Vector3(1, 1.0000001, 1)
[editable path="bull"]
+52
View File
@@ -0,0 +1,52 @@
[gd_scene format=3 uid="uid://crtm0xtiql3r8"]
[ext_resource type="Script" uid="uid://bn777gguclud5" path="res://player.gd" id="1_xhfnw"]
[ext_resource type="Script" uid="uid://cpyq2r5cq653g" path="res://camera_iso.gd" id="2_camera_iso"]
[ext_resource type="PackedScene" uid="uid://bun14xmk20pcj" path="res://Assets/bull.fbx" id="4_e80uo"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_kne1u"]
radius = 0.7495117
height = 1.845398
[node name="Player" type="CharacterBody3D" unique_id=165510044]
collision_layer = 2
collision_mask = 9
script = ExtResource("1_xhfnw")
[node name="CollisionBull" type="CollisionShape3D" parent="." unique_id=571780801]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.29183745, 0.3197594)
shape = SubResource("CapsuleShape3D_kne1u")
[node name="Camera3D" type="Camera3D" parent="." unique_id=1120161087]
script = ExtResource("2_camera_iso")
[node name="bull" parent="." unique_id=1386495166 instance=ExtResource("4_e80uo")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.655, 0.23)
[node name="Skeleton3D" parent="bull/Armature" parent_id_path=PackedInt32Array(1386495166, 1942410469) index="0" unique_id=550138996]
bones/0/position = Vector3(0, 0, 0.009963839)
bones/0/rotation = Quaternion(0.7071068, 0, 0, 0.7071067)
bones/0/scale = Vector3(1, 1, 1)
bones/1/position = Vector3(0.003526625, -0.0043296535, 0.0040827994)
bones/1/rotation = Quaternion(-0.00038647873, 0.06909673, 0.9868542, -0.14609687)
bones/2/rotation = Quaternion(-0.06929122, 3.2175163e-07, -0.112670615, 0.99121344)
bones/4/position = Vector3(0.0045358227, -0.002137695, -0.004238624)
bones/4/rotation = Quaternion(-0.24948503, 0.19590352, 0.9416978, -0.11217985)
bones/4/scale = Vector3(1.0000001, 0.9999999, 1.0000001)
bones/5/rotation = Quaternion(-0.58943665, -0.3660725, -0.22564478, 0.683842)
bones/5/scale = Vector3(1, 1.0000001, 0.99999994)
bones/6/rotation = Quaternion(0.52910197, 0.15997827, 0.120245, 0.8246207)
bones/6/scale = Vector3(1, 1, 1.0000001)
bones/17/position = Vector3(0, 0.0009373814, 0.007552617)
bones/17/rotation = Quaternion(-9.4156974e-08, 0.7071068, 0.7071067, -9.4156974e-08)
bones/19/position = Vector3(-0.003526625, -0.0043296535, 0.0040827994)
bones/19/rotation = Quaternion(0.00038647873, 0.06909673, 0.9868542, 0.14609687)
bones/20/rotation = Quaternion(-0.06929122, -3.2227587e-07, 0.11267061, 0.99121344)
bones/22/position = Vector3(-0.0045358227, -0.002137695, -0.004238624)
bones/22/rotation = Quaternion(0.24948503, 0.19590352, 0.9416978, 0.11217985)
bones/23/rotation = Quaternion(-0.58943665, 0.3660725, 0.22564478, 0.683842)
bones/23/scale = Vector3(1, 1.0000001, 1)
bones/24/rotation = Quaternion(0.529102, -0.15997836, -0.120245025, 0.82462066)
bones/24/scale = Vector3(1, 1.0000001, 1)
[editable path="bull"]
+52
View File
@@ -0,0 +1,52 @@
[gd_scene format=3 uid="uid://crtm0xtiql3r8"]
[ext_resource type="Script" uid="uid://bn777gguclud5" path="res://player.gd" id="1_xhfnw"]
[ext_resource type="Script" uid="uid://cpyq2r5cq653g" path="res://camera_iso.gd" id="2_camera_iso"]
[ext_resource type="PackedScene" uid="uid://bun14xmk20pcj" path="res://Assets/bull.fbx" id="4_e80uo"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_kne1u"]
radius = 0.7495117
height = 1.845398
[node name="Player" type="CharacterBody3D" unique_id=165510044]
collision_layer = 2
collision_mask = 9
script = ExtResource("1_xhfnw")
[node name="CollisionBull" type="CollisionShape3D" parent="." unique_id=571780801]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.29183745, 0.3197594)
shape = SubResource("CapsuleShape3D_kne1u")
[node name="Camera3D" type="Camera3D" parent="." unique_id=1120161087]
script = ExtResource("2_camera_iso")
[node name="bull" parent="." unique_id=1386495166 instance=ExtResource("4_e80uo")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.655, 0.23)
[node name="Skeleton3D" parent="bull/Armature" parent_id_path=PackedInt32Array(1386495166, 1942410469) index="0" unique_id=550138996]
bones/0/position = Vector3(0, 0, 0.009963839)
bones/0/rotation = Quaternion(0.7071068, 0, 0, 0.7071067)
bones/0/scale = Vector3(1, 1, 1)
bones/1/position = Vector3(0.003526625, -0.0043296535, 0.0040827994)
bones/1/rotation = Quaternion(-0.00038647873, 0.06909673, 0.9868542, -0.14609687)
bones/2/rotation = Quaternion(-0.06929122, 3.2175163e-07, -0.112670615, 0.99121344)
bones/4/position = Vector3(0.0045358227, -0.002137695, -0.004238624)
bones/4/rotation = Quaternion(-0.24948503, 0.19590352, 0.9416978, -0.11217985)
bones/4/scale = Vector3(1.0000001, 0.9999999, 1.0000001)
bones/5/rotation = Quaternion(-0.58943665, -0.3660725, -0.22564478, 0.683842)
bones/5/scale = Vector3(1, 1.0000001, 0.99999994)
bones/6/rotation = Quaternion(0.52910197, 0.15997827, 0.120245, 0.8246207)
bones/6/scale = Vector3(1, 1, 1.0000001)
bones/17/position = Vector3(0, 0.0009373814, 0.007552617)
bones/17/rotation = Quaternion(-9.4156974e-08, 0.7071068, 0.7071067, -9.4156974e-08)
bones/19/position = Vector3(-0.003526625, -0.0043296535, 0.0040827994)
bones/19/rotation = Quaternion(0.00038647873, 0.06909673, 0.9868542, 0.14609687)
bones/20/rotation = Quaternion(-0.06929122, -3.2227587e-07, 0.11267061, 0.99121344)
bones/22/position = Vector3(-0.0045358227, -0.002137695, -0.004238624)
bones/22/rotation = Quaternion(0.24948503, 0.19590352, 0.9416978, 0.11217985)
bones/23/rotation = Quaternion(-0.58943665, 0.3660725, 0.22564478, 0.683842)
bones/23/scale = Vector3(1, 1.0000001, 1)
bones/24/rotation = Quaternion(0.529102, -0.15997836, -0.120245025, 0.82462066)
bones/24/scale = Vector3(1, 1.0000001, 1)
[editable path="bull"]
+52
View File
@@ -0,0 +1,52 @@
[gd_scene format=3 uid="uid://crtm0xtiql3r8"]
[ext_resource type="Script" uid="uid://bn777gguclud5" path="res://player.gd" id="1_xhfnw"]
[ext_resource type="Script" uid="uid://cpyq2r5cq653g" path="res://camera_iso.gd" id="2_camera_iso"]
[ext_resource type="PackedScene" uid="uid://bun14xmk20pcj" path="res://Assets/bull.fbx" id="4_e80uo"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_kne1u"]
radius = 0.7495117
height = 1.845398
[node name="Player" type="CharacterBody3D" unique_id=165510044]
collision_layer = 2
collision_mask = 9
script = ExtResource("1_xhfnw")
[node name="CollisionBull" type="CollisionShape3D" parent="." unique_id=571780801]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.29183745, 0.3197594)
shape = SubResource("CapsuleShape3D_kne1u")
[node name="Camera3D" type="Camera3D" parent="." unique_id=1120161087]
script = ExtResource("2_camera_iso")
[node name="bull" parent="." unique_id=1386495166 instance=ExtResource("4_e80uo")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.655, 0.23)
[node name="Skeleton3D" parent="bull/Armature" parent_id_path=PackedInt32Array(1386495166, 1942410469) index="0" unique_id=550138996]
bones/0/position = Vector3(0, 0, 0.009963839)
bones/0/rotation = Quaternion(0.7071068, 0, 0, 0.7071067)
bones/0/scale = Vector3(1, 1, 1)
bones/1/position = Vector3(0.003526625, -0.0043296535, 0.0040827994)
bones/1/rotation = Quaternion(-0.00038647873, 0.06909673, 0.9868542, -0.14609687)
bones/2/rotation = Quaternion(-0.06929122, 3.2175163e-07, -0.112670615, 0.99121344)
bones/4/position = Vector3(0.0045358227, -0.002137695, -0.004238624)
bones/4/rotation = Quaternion(-0.24948503, 0.19590352, 0.9416978, -0.11217985)
bones/4/scale = Vector3(1.0000001, 0.9999999, 1.0000001)
bones/5/rotation = Quaternion(-0.58943665, -0.3660725, -0.22564478, 0.683842)
bones/5/scale = Vector3(1, 1.0000001, 0.99999994)
bones/6/rotation = Quaternion(0.52910197, 0.15997827, 0.120245, 0.8246207)
bones/6/scale = Vector3(1, 1, 1.0000001)
bones/17/position = Vector3(0, 0.0009373814, 0.007552617)
bones/17/rotation = Quaternion(-9.4156974e-08, 0.7071068, 0.7071067, -9.4156974e-08)
bones/19/position = Vector3(-0.003526625, -0.0043296535, 0.0040827994)
bones/19/rotation = Quaternion(0.00038647873, 0.06909673, 0.9868542, 0.14609687)
bones/20/rotation = Quaternion(-0.06929122, -3.2227587e-07, 0.11267061, 0.99121344)
bones/22/position = Vector3(-0.0045358227, -0.002137695, -0.004238624)
bones/22/rotation = Quaternion(0.24948503, 0.19590352, 0.9416978, 0.11217985)
bones/23/rotation = Quaternion(-0.58943665, 0.3660725, 0.22564478, 0.683842)
bones/23/scale = Vector3(1, 1.0000001, 1)
bones/24/rotation = Quaternion(0.529102, -0.15997836, -0.120245025, 0.82462066)
bones/24/scale = Vector3(1, 1.0000001, 1)
[editable path="bull"]
+15
View File
@@ -0,0 +1,15 @@
[gd_scene format=3 uid="uid://c8spearwrap01"]
[ext_resource type="PackedScene" uid="uid://jepc74w8opbu" path="res://Assets/spear.glb" id="1_spearglb"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_shaft"]
radius = 0.13
height = 2.2
[node name="Spear" type="Node3D"]
[node name="spear" parent="." instance=ExtResource("1_spearglb")]
[node name="HitShape" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, 0.79)
shape = SubResource("CapsuleShape3D_shaft")
+20
View File
@@ -0,0 +1,20 @@
[gd_scene format=3 uid="uid://c8swordwrap01"]
[ext_resource type="PackedScene" uid="uid://xyvank512l5n" path="res://Assets/sword.glb" id="1_swordglb"]
[ext_resource type="Script" path="res://hitbox.gd" id="2_hitbox"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_blade"]
radius = 0.18
height = 1.3
[node name="Sword" type="Node3D"]
[node name="sword" parent="." instance=ExtResource("1_swordglb")]
[node name="BladeHitbox" type="Area3D" parent="."]
script = ExtResource("2_hitbox")
damage_cause = "gored"
[node name="CollisionShape3D" type="CollisionShape3D" parent="BladeHitbox"]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, 0.8)
shape = SubResource("CapsuleShape3D_blade")
+226 -52
View File
@@ -26,7 +26,25 @@ var _phase: Phase = Phase.WINDUP
var _bull: CharacterBody3D = null
var _skeleton: Skeleton3D = null
var _anim_player: AnimationPlayer = null
# Separate player baked into Assets/fx/Bear_FX.glb: each clip scales one FX mesh up from 0
# and back at its strike frame (self-hiding), so bear.gd just fires the matching clip.
var _fx_player: AnimationPlayer = null
var _fx_root: Node = null
# Shaped attack colliders live in BearAttackHitboxes.tscn (under bear_model, so they track the
# bear's facing): a ground-circle cylinder for the leap slam and a forward box lane for the smash.
# Their sizes AND their travel/pop motion are authored in that scene's AnimationPlayer (clips
# "leap_slam" / "smash_travel") — scrub them there to tweak. bear.gd only fires the clip, sets the
# knock-up shaping, activates monitoring, and sweeps for overlaps while the clip runs.
var _leap_hitbox: Hitbox = null
var _smash_hitbox: Hitbox = null
var _hitbox_anim: AnimationPlayer = null
var _active_hitbox: Hitbox = null
var _blood_burst: CPUParticles3D = null
# Bull-ram tracking: the bull's position last frame (to sweep its travel) and whether it was mid-ram
# last frame (edge-trigger so one charge = one wound, re-arming when the bull breaks off).
var _bull_prev_pos: Vector3 = Vector3.ZERO
var _bull_prev_seen: bool = false
var _bull_ramming: bool = false
var _hp: int = 10
var _enraged: bool = false
@@ -78,9 +96,7 @@ const _BULL_STANDOFF: float = 1.9
@onready var _mesh: Node3D = $bear_model
@onready var _hit_area: Area3D = $HitArea
var _dust: CPUParticles3D = null
# Claw-slash bursts bound to the paw bones, fired one per hit of the 1-2 punch.
var _claw_l: CPUParticles3D = null
var _claw_r: CPUParticles3D = null
const RigidSkin = preload("res://rigid_skin.gd")
@@ -93,6 +109,13 @@ func _ready() -> void:
health_changed.emit(_hp, _hp)
_skeleton = _find_skeleton(_mesh)
_anim_player = _find_anim_player(_mesh)
_fx_root = _mesh.get_node_or_null("Bear_FX")
if _fx_root:
_fx_player = _fx_root.get_node_or_null("AnimationPlayer") as AnimationPlayer
if _fx_player:
# The smash/leap clips end held at full scale (Siim only ramped the claw clips back
# down), so snap each effect back to 0 when its clip finishes — keeps them one-shot.
_fx_player.animation_finished.connect(_on_fx_finished)
# Web (Mali/ANGLE) can't run Compatibility vertex-skinning; rebuild the bear as
# non-skinned bone-attached pieces there. Desktop keeps smooth GPU skinning.
if OS.has_feature("web"):
@@ -113,12 +136,11 @@ func _ready() -> void:
for a in [_anim_swipe, _anim_smash, _anim_leap, _anim_death]:
_set_no_loop(a)
_anim_player.playback_default_blend_time = 0.12
_hit_area.body_entered.connect(_on_body_entered)
_blood_burst = preload("res://blood_burst.gd").new()
add_child(_blood_burst)
_dust = _make_slam_dust()
add_child(_dust)
_setup_claws()
_setup_attack_hitboxes()
_enter_neutral()
#take hit flashing
@@ -141,7 +163,7 @@ func _hit_flash() -> void:
_hit_flash_tween = create_tween()
_hit_flash_tween.tween_interval(0.10)
_hit_flash_tween.tween_callback(_clear_hit_flash)
func _make_hit_overlay() -> StandardMaterial3D:
var mat := StandardMaterial3D.new()
mat.albedo_color = Color(1.0, 0.05, 0.05, 1.0)
@@ -166,8 +188,6 @@ func _clear_hit_flash() -> void:
func _setup_claws() -> void:
if _skeleton == null:
return
_claw_r = _attach_claw("hand_r")
_claw_l = _attach_claw("hand_l")
func _attach_claw(bone: String) -> CPUParticles3D:
@@ -216,6 +236,9 @@ func _physics_process(delta: float) -> void:
_acquire_bull()
_update_enrage()
_stagger_cd = maxf(0.0, _stagger_cd - delta)
_tick_attack_hitbox()
if _bull != null:
_sweep_bull_ram()
match _state:
State.NEUTRAL: _tick_neutral(delta)
@@ -285,15 +308,19 @@ func _decide() -> void:
var dist := _flat_dist_to_bull()
var options: Array
if dist <= DP.f("bear_close_range"):
# In strike range: punch or overhead (both step in during the swing).
options = [[State.SWIPE, 3.0], [State.SMASH, 3.0 if _enraged else 2.5]]
elif dist <= DP.f("bear_mid_range"):
# Mid: mostly walk the bull down on two legs; occasionally leap the gap.
options = [[State.STALK, 3.0], [State.LEAP, 2.0 if _enraged else 1.5]]
# Short range: claw attack
options = [[State.SWIPE, 3.0]]
else:
# Far: lope in on all fours, or spring across with a leap.
options = [[State.PROWL, 3.0], [State.LEAP, 1.5]]
# At distance: overhead smash 1/3 of the time, jump smash 2/3 — both close the gap as
# they land, so the bear slams its way in rather than walking (stalk/prowl).
options = [
[State.SMASH, 1.0],
[State.LEAP, 2.0]
]
_start_routine(_weighted_pick(options))
@@ -302,12 +329,21 @@ func _decide() -> void:
func _range_allows(routine: State) -> bool:
if _bull == null:
return routine == State.PROWL
var dist := _flat_dist_to_bull()
match routine:
State.SWIPE, State.SMASH:
State.SWIPE:
return dist <= DP.f("bear_close_range") * 1.4
State.LEAP:
return dist <= DP.f("bear_mid_range") * 1.5
State.SMASH:
# Smash can be started from any distance.
# The attack itself will move toward the bull.
return true
return true
@@ -394,12 +430,12 @@ func _tick_swipe(delta: float) -> void:
var frac := 1.0 - _phase_timer / maxf(_active_len, 0.001)
if _hits_done == 0 and frac >= 0.25:
_hits_done = 1
_play_fx(_claw_fx_clip(0))
_try_hit(DP.f("bear_swipe_reach"))
_claw_slash(true) # first paw (right) rakes across
elif _hits_done == 1 and frac >= 0.65:
_hits_done = 2
_play_fx(_claw_fx_clip(1))
_try_hit(DP.f("bear_swipe_reach"))
_claw_slash(false) # back-hand with the left paw
if _phase_timer <= 0.0:
_begin_recover(DP.f("bear_swipe_recover"))
Phase.RECOVER:
@@ -426,13 +462,16 @@ func _tick_smash(delta: float) -> void:
if _phase_timer <= 0.0:
_begin_attack_active(_anim_smash, 0.9)
Phase.ACTIVE:
# The overhead steps in less than the swipe — it's a commitment, not a rush.
_lunge_and_track(DP.f("bear_lunge_speed") * 0.5, delta)
# The overhead steps in less than the swipe — it's a commitment, not a rush. no rotation
_lunge_and_track_no_rotation(DP.f("bear_lunge_speed") * 0.5, delta)
_phase_timer -= delta
var frac := 1.0 - _phase_timer / maxf(_active_len, 0.001)
if _hits_done == 0 and frac >= 0.4:
_hits_done = 1
_slam(DP.f("bear_smash_radius"), 0.8)
_play_fx(&"Bear_fx_smash_hit")
_slam_dust()
_shake(0.8)
_begin_smash_hitbox() # plays the scene's "smash_travel" clip; swept in _tick_attack_hitbox
if _phase_timer <= 0.0:
_begin_recover(DP.f("bear_smash_recover"))
Phase.RECOVER:
@@ -483,7 +522,8 @@ func _tick_leap(delta: float) -> void:
elif _leap_airborne or _phase_timer <= 0.0:
velocity.x = 0.0
velocity.z = 0.0
_slam(DP.f("bear_slam_radius"), 0.7)
_play_fx(&"Bear_fx_jump_smash")
_fire_leap_hitbox()
_phase = Phase.RECOVER
_phase_timer = _scaled(DP.f("bear_leap_recover"))
Phase.RECOVER:
@@ -561,6 +601,20 @@ func _lunge_and_track(speed: float, delta: float) -> void:
_decelerate(_PLANT_DECEL, delta)
func _lunge_and_track_no_rotation(speed: float, delta: float) -> void:
if _bull == null:
_decelerate(_PLANT_DECEL, delta)
return
var to_bull := _flat_to_bull()
var dist := to_bull.length()
if speed > 0.0 and dist > _BULL_STANDOFF:
_accelerate(to_bull / dist, speed, delta)
else:
_decelerate(_PLANT_DECEL, delta)
# ── Hitting the bull ───────────────────────────────────────────────────────────────
# Directional strike: the bull is mauled inside `reach` of the bear that's facing it
@@ -580,17 +634,83 @@ func _try_hit(reach: float) -> bool:
return true
# Radial slam (smash / leap landing): hits any way the bull is, within `radius`, with a
# ground-pound shake and a burst of dust kicked up at the paws. No facing arc — you're
# caught if you're near where it comes down.
func _slam(radius: float, shake: float) -> void:
_slam_dust()
if _bull == null:
_shake(shake)
# Grab the designer-authored collider sub-scene (BearAttackHitboxes.tscn instanced under
# bear_model) and park both hitboxes deactivated. Shapes + travel are authored in that scene.
func _setup_attack_hitboxes() -> void:
var root := _mesh.get_node_or_null("AttackHitboxes") if _mesh else null
if root == null:
return
if _flat_dist_to_bull() <= radius:
_bull.call(&"take_sword_hit", "mauled")
_shake(shake)
_leap_hitbox = root.get_node_or_null("LeapSlamHitbox") as Hitbox
_smash_hitbox = root.get_node_or_null("SmashHitbox") as Hitbox
_hitbox_anim = root.get_node_or_null("AnimationPlayer") as AnimationPlayer
if _hitbox_anim != null:
# Advance the shape's travel in the physics step so it stays in lockstep with the sweep.
_hitbox_anim.callback_mode_process = AnimationMixer.ANIMATION_CALLBACK_MODE_PROCESS_PHYSICS
if _leap_hitbox != null:
_leap_hitbox.deactivate()
if _smash_hitbox != null:
_smash_hitbox.deactivate()
# Leap landing: kick up dust + shake, launch the ground-circle collider clip, and arm it so the bull
# is launched from ANYWHERE in the circle (bear_leap_ring_frac 0). Raise ring_frac to restore a
# grounded inner zone that only mauls; the launch zone then starts at that fraction of the radius.
func _fire_leap_hitbox() -> void:
_slam_dust()
_shake(0.7)
if _leap_hitbox == null:
return
_leap_hitbox.knock_up = DP.f("bear_leap_knockup")
_leap_hitbox.knock_up_min_dist = DP.f("bear_leap_ring_frac") * _shape_extent(_leap_hitbox, true)
_leap_hitbox.knock_up_max_dist = 0.0 # binary: full-height launch everywhere it launches
_start_attack_hitbox(_leap_hitbox, &"leap_slam")
# Overhead smash: launch the lane clip; knock-up ramps 0→full with distance (further = higher),
# maxing at the lane's authored full length so the shape and the launch curve stay in sync.
func _begin_smash_hitbox() -> void:
if _smash_hitbox == null:
return
_smash_hitbox.knock_up = DP.f("bear_smash_knockup")
_smash_hitbox.knock_up_min_dist = 0.0
_smash_hitbox.knock_up_max_dist = _shape_extent(_smash_hitbox, false)
_start_attack_hitbox(_smash_hitbox, &"smash_travel")
# Activate the hitbox and play its authored motion clip; _tick_attack_hitbox sweeps for overlaps
# each frame while the clip runs, then deactivates when it ends.
func _start_attack_hitbox(hb: Hitbox, clip: StringName) -> void:
if _active_hitbox != null and _active_hitbox != hb:
_active_hitbox.deactivate()
hb.activate()
_active_hitbox = hb
if _hitbox_anim != null and _hitbox_anim.has_animation(clip):
_hitbox_anim.play(clip)
_hitbox_anim.seek(0.0, true)
func _tick_attack_hitbox() -> void:
if _active_hitbox == null:
return
_active_hitbox.sweep()
# The clip drives the shape's travel; when it stops, the swing is over — close the hitbox.
if _hitbox_anim == null or not _hitbox_anim.is_playing():
_active_hitbox.deactivate()
_active_hitbox = null
# Full extent (planar) of a hitbox's authored shape, for the knock-up distance math: the circle's
# radius (cylinder) or the lane's length (box half-size along local +Z, forward from the bear).
func _shape_extent(hb: Hitbox, radial: bool) -> float:
var cs := hb.get_node_or_null("CollisionShape3D") as CollisionShape3D
if cs == null:
return 0.0
if radial and cs.shape is CylinderShape3D:
return (cs.shape as CylinderShape3D).radius
if not radial and cs.shape is BoxShape3D:
# Box spans [0, size.z] because it's offset forward by half its length.
return (cs.shape as BoxShape3D).size.z
return 0.0
# Kick up a one-shot ring of dust at the bear's feet where the slam lands.
@@ -651,15 +771,6 @@ func _make_slam_dust() -> CPUParticles3D:
return p
# Fire the claw-slash burst on one paw for a swipe hit (right paw first, then left).
func _claw_slash(right: bool) -> void:
var claw := _claw_r if right else _claw_l
if claw == null:
return
claw.restart()
claw.emitting = true
# A short fan of pale streaks raked from a paw — thin boxes aligned to their velocity so
# they read as claw marks slashing outward. Built in code and parented to a hand bone.
func _make_claw_slash() -> CPUParticles3D:
@@ -723,18 +834,44 @@ func apply_ability_hit(hit_dir: Vector3, strength: float, _up_boost: float = 0.0
_take_hit(hit_dir, strength)
# Ramming: only a real charge from the bull wounds the bear; a gentle nudge is shrugged
# off. The bear never damages the bull by colliding — only its swings/slams do.
func _on_body_entered(body: Node3D) -> void:
if _state == State.DEAD or not body.is_in_group(&"player"):
# Only a horns-first charge wounds the bear. Swept (prev → now) so a tunnelling or point-blank charge
# still lands where body_entered wouldn't; edge-triggered (_bull_ramming) so one charge = one wound.
func _sweep_bull_ram() -> void:
var now := _bull.global_position
var seg_from := _bull_prev_pos if _bull_prev_seen else now
_bull_prev_pos = now
_bull_prev_seen = true
if _state == State.DEAD:
_bull_ramming = false
return
var player := body as CharacterBody3D
if player.velocity.length() < DP.f("bear_hit_threshold"):
return
var flat := Vector3(player.velocity.x, 0.0, player.velocity.z)
var dir := flat.normalized() if flat.length() > 0.5 else \
(global_position - player.global_position).normalized()
_take_hit(dir, player.velocity.length())
var vel := Vector3(_bull.velocity.x, 0.0, _bull.velocity.z)
var speed := vel.length()
var ramming := false
if speed >= DP.f("bear_hit_threshold") and _horns_first(seg_from):
var a := Vector3(seg_from.x, 0.0, seg_from.z)
var b := Vector3(now.x, 0.0, now.z)
var p := Vector3(global_position.x, 0.0, global_position.z)
if p.distance_to(Geometry3D.get_closest_point_to_segment(p, a, b)) <= DP.f("bear_ram_reach"):
ramming = true
if ramming and not _bull_ramming:
var dir := vel.normalized() if speed > 0.5 else (global_position - now).normalized()
_take_hit(dir, speed)
_bull_ramming = ramming
# Horns-first gate: wound only when the bull's velocity points within bull_gore_arc of the direction
# from `from` to the bear. The dash ability skips the gate.
func _horns_first(from: Vector3) -> bool:
if _bull.has_method(&"is_dashing") and _bull.call(&"is_dashing"):
return true # the dash ability is a committed lunge — it rams on contact, no angle gate
var vel := Vector3(_bull.velocity.x, 0.0, _bull.velocity.z)
if vel.length() < 0.5:
return false
var to_bear := global_position - from
to_bear.y = 0.0
if to_bear.length() < 0.01:
return true
return vel.normalized().dot(to_bear.normalized()) > cos(deg_to_rad(DP.f("bull_gore_arc")))
func _take_hit(hit_dir: Vector3, strength: float) -> void:
@@ -907,6 +1044,43 @@ func _play(anim_name: StringName) -> void:
_anim_player.play(anim_name)
# The two swipe hits map to the L/R claw-slash clips; bear_fx_claw_swap flips the order in
# case the baked left/right clips read reversed in-game. hit 0 = first swing, 1 = second.
func _claw_fx_clip(hit: int) -> StringName:
var swap := DP.f("bear_fx_claw_swap") >= 0.5
var first_left := not swap
if (hit == 0) == first_left:
return &"Bear_fx_claw_attack_L"
return &"Bear_fx_claw_attack_R"
# Fire a one-shot FX clip from the Bear_FX glb (crater / slash / debris). Each clip scales
# its mesh up at the strike and back to 0 on its own, so this is a plain fire-and-forget.
func _play_fx(clip: StringName) -> void:
if _fx_player == null or not _fx_player.has_animation(clip):
return
if _fx_root is Node3D:
(_fx_root as Node3D).rotation.y = deg_to_rad(DP.f("bear_fx_yaw"))
_fx_player.play(clip)
_fx_player.seek(0.0, true)
func _on_fx_finished(anim: StringName) -> void:
if _fx_root == null:
return
var mesh := _fx_root.get_node_or_null(NodePath(anim)) as Node3D
if mesh == null:
return
# The crater clip only ramps up (it ends held at full scale with no shrink), so leave it on
# the ground for a beat after the slam, then hide it. The others self-clear immediately.
if anim == &"Bear_fx_jump_smash":
var linger := DP.f("bear_fx_crater_linger")
if linger > 0.0:
get_tree().create_timer(linger).timeout.connect(func() -> void: mesh.scale = Vector3.ZERO)
return
mesh.scale = Vector3.ZERO
# Restart a one-shot attack clip from its first frame at `speed` (even if already current).
func _play_attack(anim_name: StringName, speed: float) -> void:
if _anim_player == null or anim_name == &"":
-8
View File
@@ -1,8 +0,0 @@
extends Node3D
func mesh_on():
visible = true
func mesh_off():
visible = false
-1
View File
@@ -1 +0,0 @@
uid://bsbed05ifr18s
-9
View File
@@ -1,9 +0,0 @@
extends Camera3D
@export var spring_arm: Node3D
func _process(delta: float) -> void:
var lerp_power: float = DP.f("cam_lerp_power")
position = position.lerp(spring_arm.position, delta * lerp_power)
-1
View File
@@ -1 +0,0 @@
uid://b720l6m0ehrj3
+15 -3
View File
@@ -1,3 +1,4 @@
class_name IsoCamera
extends Camera3D
@export var height: float = 25.0
@@ -16,6 +17,11 @@ var _shake_amount: float = 0.0
var _shake_decay: float = 0.0
var _user_fov: float = 0.0
# Per-level framing multiplier: 1.0 = the designer's base shot, >1 dollies the camera
# back for a wider view (the lobby uses this). Set by game_shell when a level loads;
# kept separate from the scroll-wheel FOV zoom so the two don't fight.
var _framing_scale: float = 1.0
# Trailing-camera state: _focus is the smoothed point the camera frames (it lags
# the bull), _drag_offset is the velocity-driven trail that slides it behind.
var _focus: Vector3 = Vector3.ZERO
@@ -51,15 +57,21 @@ func adjust_zoom(ratio: float) -> void:
_user_fov = clampf(_user_fov / ratio, fov_min, fov_max)
## Dolly the camera in/out for the level being loaded. 1.0 is the base framing; >1 pulls
## back for a wider shot (the lobby hub uses this). Independent of the scroll-wheel zoom.
func set_framing_scale(scale: float) -> void:
_framing_scale = maxf(scale, 0.1)
func _process(delta: float) -> void:
fov = lerpf(fov, _user_fov, delta * 8.0)
var angle_rad := deg_to_rad(horizontal_angle_deg)
var offset := Vector3(
sin(angle_rad) * horizontal_distance,
height,
cos(angle_rad) * horizontal_distance
sin(angle_rad) * horizontal_distance * _framing_scale,
height * _framing_scale,
cos(angle_rad) * horizontal_distance * _framing_scale
)
var target := get_parent() as Node3D
-39
View File
@@ -1,39 +0,0 @@
extends Node3D
@onready var spring_arm: SpringArm3D = $SpringArm3D
var _desired_length: float = 7.0
func _ready() -> void:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
_desired_length = DP.f("cam_spring_length")
spring_arm.spring_length = _desired_length
func _unhandled_input(event: InputEvent) -> void:
var sensitivity: float = DP.f("cam_sensitivity")
var min_vert: float = deg_to_rad(DP.f("cam_min_vert_angle"))
var max_vert: float = deg_to_rad(DP.f("cam_max_vert_angle"))
var min_zoom: float = DP.f("cam_min_zoom")
var max_zoom: float = DP.f("cam_max_zoom")
if event is InputEventMouseMotion:
rotation.y -= event.relative.x * sensitivity
rotation.y = wrapf(rotation.y, 0.0, TAU)
rotation.x -= event.relative.y * sensitivity
rotation.x = clamp(rotation.x, min_vert, max_vert)
if event.is_action_pressed("zoom_in"):
_desired_length = clamp(_desired_length / 1.2, min_zoom, max_zoom)
if event.is_action_pressed("zoom_out"):
_desired_length = clamp(_desired_length * 1.2, min_zoom, max_zoom)
if event.is_action_pressed("toggle_mouse_capture"):
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _process(_delta: float) -> void:
spring_arm.spring_length = _desired_length
-1
View File
@@ -1 +0,0 @@
uid://b4td4k8yo5y78
+63 -35
View File
@@ -9,7 +9,11 @@ extends Node
## bodies get picked up within one interval.
##
## Toggle from the console:
## show_collisions · show_hitboxes · show_bones · show_raycasts (true / false)
## show_hitboxes · show_attacks · show_bones · show_raycasts (true / false)
## show_hitboxes — the combatants' hurt volumes: each HitArea + the player/enemy body
## capsules, drawn as calm translucent-blue volumes (what abilities/blades hit)
## show_attacks — the attack hitboxes (bear claw/smash/leap, matador blade, thrown
## spear), filled translucent red and shown ONLY while the swing is actually live
## show_states — floating AI-state tags + velocity vectors over each matador
## show_animation_name — floating current-clip tag over every AnimationPlayer host
## show_stats — 2D corner readout: fps / frame ms / draw calls / matador tally
@@ -20,13 +24,14 @@ extends Node
const REBUILD_INTERVAL := 0.5
const STATS_INTERVAL := 0.2 # stats text is re-composed 5×/sec, not every frame
const COLOR_BODY := Color(0.30, 1.0, 0.45) # collision wireframes (green)
const COLOR_AREA := Color(0.0, 0.9, 1.0) # hit-area volumes (cyan, translucent)
const COLOR_AREA := Color(0.0, 0.9, 1.0) # combatant hurt volumes (cyan, translucent)
const COLOR_ATTACK := Color(1.0, 0.30, 0.15) # attack hitboxes (red, translucent, overlaid)
const COLOR_BONE := Color(1.0, 0.35, 0.9) # skeleton bones (magenta)
const COLOR_VEL := Color(1.0, 0.85, 0.2) # matador velocity vectors (amber)
const COLOR_ANIM := Color(0.55, 0.85, 1.0) # animation-name tags (sky blue)
const COLOR_GRID := Color(0.45, 0.45, 0.45, 0.5)
const AREA_ALPHA := 0.25
const AREA_ALPHA := 0.25
const ATTACK_ALPHA := 0.32
const GRID_HALF := 20 # grid extends ±GRID_HALF cells from the origin
const GRID_STEP := 1.0 # metres between grid lines
@@ -80,6 +85,7 @@ func ray(from: Vector3, to: Vector3, color: Color = Color.YELLOW) -> void:
func _process(delta: float) -> void:
_reconcile(delta)
_pulse_attacks()
if DP.b("show_bones"):
_draw_bones()
if DP.b("show_states"):
@@ -359,11 +365,11 @@ func _si(n: int) -> String:
# ── Collision / hit-area overlays (incremental) ────────────────────────────────
func _reconcile(delta: float) -> void:
var col := DP.b("show_collisions")
var hit := DP.b("show_hitboxes")
var atk := DP.b("show_attacks")
var bone := DP.b("show_bones")
var anim := DP.b("show_animation_name")
if not (col or hit or bone or anim):
if not (hit or atk or bone or anim):
if not _overlays.is_empty():
_clear_overlays()
_skeletons.clear()
@@ -371,7 +377,7 @@ func _reconcile(delta: float) -> void:
_prev_flags = ""
return
var flags := "%d%d%d%d" % [int(col), int(hit), int(bone), int(anim)]
var flags := "%d%d%d%d" % [int(hit), int(atk), int(bone), int(anim)]
_reconcile_t -= delta
if flags != _prev_flags: # a toggle just changed — refresh immediately
_prev_flags = flags
@@ -385,7 +391,7 @@ func _reconcile(delta: float) -> void:
var wanted: Dictionary = {}
var scene := get_tree().current_scene
if scene != null:
_collect(scene, col, hit, bone, anim, wanted)
_collect(scene, hit, atk, bone, anim, wanted)
# Drop overlays whose shape is gone or no longer wanted. The overlay is a child of
# the collision shape, so it's freed with it — hold it as Variant, since assigning a
@@ -401,10 +407,11 @@ func _reconcile(delta: float) -> void:
for id: int in wanted:
if not _overlays.has(id):
var entry: Array = wanted[id]
_overlays[id] = _attach(entry[0] as CollisionShape3D, entry[1] as bool)
_overlays[id] = _attach(entry[0] as CollisionShape3D, entry[1] as String)
func _collect(node: Node, col: bool, hit: bool, bone: bool, anim: bool, wanted: Dictionary) -> void:
func _collect(node: Node, hit: bool, atk: bool, bone: bool, anim: bool,
wanted: Dictionary) -> void:
# The audience ("public") is ambient decoration, not a debug target — skip the whole
# crowd subtree so its clapping AnimationPlayers/skeletons don't flood the overlays.
if node.is_in_group(&"public"):
@@ -416,15 +423,28 @@ func _collect(node: Node, col: bool, hit: bool, bone: bool, anim: bool, wanted:
if node is CollisionShape3D:
var cs := node as CollisionShape3D
if cs.shape != null and not cs.disabled and _drawable(cs.shape):
var parent := cs.get_parent()
var is_area := parent is Area3D
# Ragdoll bone colliders (PhysicalBone3D) are excluded — use show_bones for
# the skeleton; otherwise every corpse floods the view with capsules.
var is_body := parent is PhysicsBody3D and not (parent is PhysicalBone3D)
if (is_area and hit) or (is_body and col):
wanted[cs.get_instance_id()] = [cs, is_area]
var kind := _classify(cs.get_parent())
var show := (kind == "attack" and atk) or (kind == "hitbox" and hit)
if show:
wanted[cs.get_instance_id()] = [cs, kind]
for child in node.get_children():
_collect(child, col, hit, bone, anim, wanted)
_collect(child, hit, atk, bone, anim, wanted)
# Sort a shape's owning body/area into an overlay bucket, or "" to skip.
# attack — a swing volume (a Hitbox area, or a thrown-spear projectile body)
# hitbox — a combatant's hurt volume: its HitArea, or its own body capsule
func _classify(parent: Node) -> String:
if parent is Hitbox or parent is SpearProjectile:
return "attack"
if parent is Area3D:
return "hitbox"
# Ragdoll bone colliders (PhysicalBone3D) are excluded — use show_bones for the
# skeleton; otherwise every corpse floods the view with capsules.
if parent is PhysicsBody3D and not (parent is PhysicalBone3D):
if parent.is_in_group(&"player") or parent.is_in_group(&"matador"):
return "hitbox"
return ""
# Skip only the unbounded shapes whose debug mesh is meaningless/huge; concave arena
@@ -433,20 +453,35 @@ func _drawable(shape: Shape3D) -> bool:
return not (shape is WorldBoundaryShape3D or shape is HeightMapShape3D)
func _attach(cs: CollisionShape3D, is_area: bool) -> MeshInstance3D:
func _attach(cs: CollisionShape3D, kind: String) -> MeshInstance3D:
var mi := MeshInstance3D.new()
if is_area:
var solid := _solid_mesh(cs.shape)
mi.mesh = solid if solid != null else cs.shape.get_debug_mesh()
mi.material_override = _translucent_material(COLOR_AREA)
var solid := _solid_mesh(cs.shape)
mi.mesh = solid if solid != null else cs.shape.get_debug_mesh()
if kind == "attack":
# Overlaid so a brief swing volume reads clearly on top of the action; its
# visibility is pulsed per-frame in _pulse_attacks so it only shows while live.
mi.material_override = _translucent_material(COLOR_ATTACK, ATTACK_ALPHA, true)
else:
mi.mesh = cs.shape.get_debug_mesh()
mi.material_override = _wire_material(COLOR_BODY)
# The calm translucent-blue volume — depth-tested so it sits in the world.
mi.material_override = _translucent_material(COLOR_AREA, AREA_ALPHA, false)
mi.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
cs.add_child(mi)
return mi
# Attack overlays exist for as long as show_attacks is on, but a swing hitbox is only a
# hazard while its Hitbox is monitoring — so show each attack volume only when it's live.
# (A thrown spear has no monitoring gate; it stays visible for its whole flight.)
func _pulse_attacks() -> void:
for id: int in _overlays:
var mi: Variant = _overlays[id]
if not is_instance_valid(mi):
continue
var owner := (mi as Node).get_parent().get_parent()
if owner is Hitbox:
(mi as MeshInstance3D).visible = (owner as Area3D).monitoring
func _clear_overlays() -> void:
for id: int in _overlays:
var mi: Variant = _overlays[id]
@@ -491,19 +526,12 @@ func _line_material() -> StandardMaterial3D:
return mat
func _wire_material(color: Color) -> StandardMaterial3D:
var mat := StandardMaterial3D.new()
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
mat.albedo_color = color
mat.no_depth_test = true
return mat
func _translucent_material(color: Color) -> StandardMaterial3D:
func _translucent_material(color: Color, alpha: float, overlay: bool) -> StandardMaterial3D:
var mat := StandardMaterial3D.new()
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
mat.albedo_color = Color(color.r, color.g, color.b, AREA_ALPHA)
mat.albedo_color = Color(color.r, color.g, color.b, alpha)
mat.cull_mode = BaseMaterial3D.CULL_DISABLED
mat.depth_draw_mode = BaseMaterial3D.DEPTH_DRAW_DISABLED
mat.no_depth_test = overlay
return mat
+84 -18
View File
@@ -20,6 +20,10 @@ func _ready() -> void:
func _register_all() -> void:
#Gamepad vibration
_reg_b("Gamepad", "gamepad_vibration", true)
#Level Unlocking
_reg_b("Gate", "gate_unlocked_bear", false)
# ── Movement ──────────────────────────────────────────────────────────────
# WASD/arrows drive the bull: move_accel ramps flat velocity toward max_speed in
# the input direction; move_friction bleeds it off when no direction is held.
@@ -37,6 +41,10 @@ func _register_all() -> void:
# bull_hit_iframes seconds of invulnerability so a single pass can't drain it.
_reg_f("Bull", "bull_max_hp", 10.0, 1.0, 100.0, 1.0)
_reg_f("Bull", "bull_hit_iframes", 0.8, 0.0, 3.0, 0.1)
# Half-angle (deg) of the bull's horns-first cone: running into an enemy only wounds it when the
# bull's velocity points within this of the enemy (not a sideways brush). 90 = any contact at speed.
# (The dash ability bypasses this.)
_reg_f("Bull", "bull_gore_arc", 75.0, 10.0, 180.0, 5.0)
# ── Dust speed thresholds ─────────────────────────────────────────────────
_reg_f("Dust", "dust_walk_spd", 1.5, 0.1, 10.0)
_reg_f("Dust", "dust_charge_spd", 7.0, 1.0, 20.0)
@@ -101,6 +109,7 @@ func _register_all() -> void:
# Wave system: matadors enter the arena in escalating waves (1 → 2 → … → N where N
# is the number of placed spawn points). mat_spawn_stagger is the delay between each
# matador leaping in within a wave; mat_wave_pause is the breather after a wave clears.
_reg_f("Matador", "mat_wave_size", 8.0, 1, 50)
_reg_f("Matador", "mat_spawn_stagger", 0.4, 0.0, 3.0, 0.05)
_reg_f("Matador", "mat_wave_pause", 2.0, 0.0, 8.0, 0.25)
_reg_f("Matador", "mat_walk_speed", 5.5, 0.5, 10.0)
@@ -111,6 +120,9 @@ func _register_all() -> void:
_reg_f("Matador", "mat_idle_min", 1.2, 0.0, 5.0, 0.1)
_reg_f("Matador", "mat_idle_max", 4.0, 0.5, 10.0, 0.1)
_reg_f("Matador", "mat_hit_threshold", 4.0, 1.0, 30.0)
# Planar reach at which the bull's swept charge path gores a matador (~bull + HitArea radii).
# Raise for a more forgiving charge, lower for a more precise one.
_reg_f("Matador", "mat_charge_gore_radius", 1.2, 0.5, 3.0, 0.05)
_reg_f("Matador", "mat_ragdoll_impulse", 6.0, 0.5, 20.0)
# Ragdoll joint limits — lower swing/twist = stiffer corpse that keeps its
# shape; higher angular damp settles the flail instead of flopping flat.
@@ -133,21 +145,42 @@ func _register_all() -> void:
_reg_f("Matador", "mat_attack_range", 8.0, 2.0, 20.0)
_reg_f("Matador", "mat_attack_speed", 7.5, 1.0, 12.0)
_reg_f("Matador", "mat_attack_duration", 1.8, 0.5, 5.0, 0.1)
_reg_f("Matador", "mat_attack_min_dist", 4.2, 0.5, 6.0, 0.1)
# Forward drive during the opening of a melee swing — turns the stationary stab
# into an estocada lunge so the blade covers ground toward the bull.
_reg_f("Matador", "mat_lunge_speed", 13.0, 0.0, 20.0)
_reg_f("Matador", "mat_lunge_time", 0.22, 0.0, 0.6, 0.01)
# Reach of the reach-based stab (the reliable melee hit) and its re-strike gap.
# The bull dies if it comes inside mat_stab_reach of a matador that's attacking,
# bracing, or passing with a drawn blade — closing in is genuinely deadly.
_reg_f("Matador", "mat_stab_reach", 1.7, 0.5, 4.0, 0.1)
# Reach of the reach-based melee hit and its re-strike gap. This now governs ONLY the sidestep
# PASS (mat charges the bull past with the blade out): a fast lateral sweep where the thin blade
# Area would tunnel, so a center-to-center distance check is the reliable gore. The stationary
# ATTACK stab no longer uses this — it drives off the sword's BladeHitbox collider (see below).
_reg_f("Matador", "mat_stab_reach", 2.0, 0.5, 4.0, 0.1)
# Distance the matador plants at to swing. The ATTACK stab damages off the animated BladeHitbox,
# whose thrust reaches ~3.75 m at full extension — so this MUST stay under that or the blade never
# touches the bull and the stab whiffs. 3.5 m keeps the matador clear of the bull's ~1.8 m-long
# body while the thrust still lands. Raise toward 3.75 for more gap, lower to stab from closer.
_reg_f("Matador", "mat_stab_standoff", 3.5, 0.5, 4.0, 0.1)
# Fraction through the Attack clip at which the blade's collider is armed. The clip is guard →
# wind-up (blade pulled back, phase ~0.3-0.5) → thrust (blade drives out to ~3.5 m, phase ~0.55+).
# Arming at the thrust keeps the bull from being gored during the wind-up (blade not yet extended)
# or the guard pose. The BladeHitbox overlap still decides the exact hit; this just gates timing.
_reg_f("Matador", "mat_stab_strike_at", 0.5, 0.0, 1.0, 0.05)
# Chance, each time a stab finishes, that the matador breaks off into something else (give ground,
# circle, or throw) instead of immediately stabbing again — keeps it from drilling the same thrust
# on repeat. 0 = always re-stab if in range, 1 = always break off after every stab.
_reg_f("Matador", "mat_stab_followup_chance", 0.6, 0.0, 1.0, 0.05)
# Beat after every stab where the brain won't re-commit to ATTACK, so it can't machine-gun the
# bull — it circles/gives ground instead. 0 = stab as fast as range allows.
_reg_f("Matador", "mat_stab_recovery", 0.9, 0.0, 3.0, 0.1)
# Chance, when a stab actually CONNECTS, that the matador breaks into a crowd-pleasing taunt and
# gives ground instead of pressing — milking the hit rather than spamming. High by design.
_reg_f("Matador", "mat_taunt_after_hit", 0.85, 0.0, 1.0, 0.05)
_reg_f("Matador", "mat_stab_cooldown", 0.6, 0.1, 3.0, 0.1)
# Half-angle (deg) the matador must be facing the bull within for a stab to land.
# Stops "sword's off to the side but I still died" — you're only gored when the
# blade is actually presented at you.
_reg_f("Matador", "mat_stab_arc", 55.0, 5.0, 180.0, 5.0)
_reg_f("Matador", "mat_roll_chance", 0.35, 0.0, 1.0, 0.05)
# Chance a matador rolls clear (survives) instead of ragdolling when the bull's charge connects.
_reg_f("Matador", "mat_roll_chance", 0.8, 0.0, 1.0, 0.05)
# How much a committed charge pierces the survival roll: roll chance fades toward
# mat_roll_chance*(1-this) as bull speed climbs to mat_charge_speed. 1 = full-speed charge always
# gores. (A dash connect ignores the roll entirely.)
_reg_f("Matador", "mat_charge_pierce", 0.8, 0.0, 1.0, 0.05)
_reg_f("Matador", "mat_roll_duration", 0.45, 0.1, 1.5, 0.05)
# Playback rate of the Draw_weapon clip used for both drawing and sheathing —
# higher = snappier unholster/holster.
@@ -191,7 +224,7 @@ func _register_all() -> void:
# routine (wind-up → active → recovery); each routine plays to the end (the recovery
# is the player's punish window). Below bear_enrage_frac HP it enters phase 2: faster
# tells and recovery (× bear_enrage_scale) and longer combo chains.
_reg_f("Bear", "bear_max_hp", 20.0, 1.0, 100.0, 1.0)
_reg_f("Bear", "bear_max_hp", 30.0, 1.0, 100.0, 1.0)
# HP fraction at which phase 2 ("Fury") triggers, and how much it multiplies every
# wind-up / recovery timer (lower = snappier, more dangerous).
_reg_f("Bear", "bear_enrage_frac", 0.4, 0.0, 1.0, 0.05)
@@ -201,7 +234,8 @@ func _register_all() -> void:
# close is deliberately generous — the bear commits to melee "from a bit further" and
# steps in during the swing (see bear_lunge_speed) rather than needing to be on top.
_reg_f("Bear", "bear_close_range", 5.0, 1.0, 12.0, 0.1)
_reg_f("Bear", "bear_mid_range", 9.0, 3.0, 20.0, 0.5)
_reg_f("Bear", "bear_mid_range", 10.0, 3.0, 20.0, 0.5)
_reg_f("Bear", "bear_long_range", 15.0, 3.0, 100.0, 0.5)
# Beat spent in NEUTRAL sizing up the bull between routines — kept short so the bear
# flows straight from one action into the next instead of pausing (raise for a more
# hesitant, readable boss; near-0 for relentless pressure). Shrinks again in phase 2.
@@ -225,10 +259,22 @@ func _register_all() -> void:
_reg_f("Bear", "bear_swipe_windup", 0.3, 0.05, 2.0, 0.05)
_reg_f("Bear", "bear_swipe_recover", 0.35, 0.05, 3.0, 0.05)
_reg_f("Bear", "bear_swipe_reach", 4.2, 1.0, 8.0, 0.1)
# Which claw-slash FX plays on the first vs second swipe hit — the L/R clips are easy to
# mix up, so 0 = first hit L then R, 1 = swap them. Purely cosmetic (no gameplay effect).
_reg_f("Bear", "bear_fx_claw_swap", 0.0, 0.0, 1.0, 1.0)
# Live yaw (deg) applied to the whole Bear_FX node before each effect fires, so the claw
# rake / debris can be spun to line up with the bear's facing by eye. Bake the good value.
_reg_f("Bear", "bear_fx_yaw", 0.0, -180.0, 180.0, 5.0)
# The baked crater clip only pops up (no shrink), so hold it on the ground this long after a
# leap slam before hiding it — otherwise it flashes for a single frame and reads as invisible.
_reg_f("Bear", "bear_fx_crater_linger", 0.8, 0.0, 3.0, 0.1)
# Overhead Smash (SMASH_HIT) — slower tell, biggest punish window, AoE on impact.
_reg_f("Bear", "bear_smash_windup", 0.6, 0.1, 3.0, 0.05)
_reg_f("Bear", "bear_smash_recover", 0.75, 0.1, 4.0, 0.05)
_reg_f("Bear", "bear_smash_radius", 4.2, 1.0, 8.0, 0.1)
# The overhead smash's hitbox is a forward box lane whose size + travel are authored in
# BearAttackHitboxes.tscn's AnimationPlayer ("smash_travel"). Here we only set the upward
# pop the bull takes off its feet at the far end (it ramps 0→this with hit distance).
_reg_f("Bear", "bear_smash_knockup", 6.0, 0.0, 16.0, 0.5)
# Leap Slam (JUMP_SMASH, 47 frames @30fps) — timed to the clip by FRAME: it plays the
# crouch grounded, springs at the takeoff frame, and the arc is solved so the paws hit
# ground exactly on the impact frame (25), leaving the tail frames to settle on the
@@ -239,7 +285,10 @@ func _register_all() -> void:
_reg_f("Bear", "bear_leap_height", 2.6, 0.5, 8.0, 0.1)
_reg_f("Bear", "bear_leap_recover", 0.35, 0.0, 4.0, 0.05)
_reg_f("Bear", "bear_leap_speed", 14.0, 4.0, 30.0, 0.5)
_reg_f("Bear", "bear_slam_radius", 4.0, 1.0, 8.0, 0.1)
# Where the leap-slam launch zone starts, as a fraction of the circle radius. 0 = launch anywhere
# inside; raise to carve a grounded inner zone that only mauls (0.75 = only the outer quarter ring).
_reg_f("Bear", "bear_leap_ring_frac", 0.0, 0.0, 1.0, 0.05)
_reg_f("Bear", "bear_leap_knockup", 7.0, 0.0, 16.0, 0.5)
# Stalk (WALK_ON2LEGS) — how long it will keep walking the bull down before re-deciding.
_reg_f("Bear", "bear_stalk_time", 2.5, 0.0, 6.0, 0.1)
# Odds a close combo chains a follow-up smash after the swipe (phase 2 always chains).
@@ -248,6 +297,9 @@ func _register_all() -> void:
# shrugged off, only a real charge or an ability wounds it. (The bear itself never
# damages the bull by colliding — only its swings and slams hurt.)
_reg_f("Bear", "bear_hit_threshold", 6.0, 1.0, 30.0, 0.5)
# Planar reach at which a horns-first bull charge wounds the bear (~bear body radius + bull reach).
# The bull's swept path is tested against this, so a tunnelling or point-blank charge still lands.
_reg_f("Bear", "bear_ram_reach", 2.1, 0.5, 5.0, 0.1)
# How long (s) the bear is rocked back and can't act after taking a hit.
_reg_f("Bear", "bear_stagger_time", 0.5, 0.0, 2.0, 0.05)
# Poise: after a stagger the bear shrugs off staggers for this long (hits still wound
@@ -341,7 +393,6 @@ func _register_all() -> void:
_reg_f("Roll", "roll_hit_strength", 22.0, 1.0, 40.0) # horizontal launch on the pop
_reg_f("Roll", "roll_knockup", 11.0, 0.0, 25.0) # vertical knock-up on the pop
# ── Debug overlays (see debug_draw.gd) ───────────────────────────────────
_reg_b("Debug", "show_collisions", false)
# PS1 post-process filter (see ps1_filter.gd on the fullscreen ColorRect):
# screen-covering CRT/PS1 shader — pixelation, colour-banding + dither, and a
# rolling scanline. Keys map 1:1 onto the shader uniforms; show_ps1 toggles the
@@ -355,6 +406,7 @@ func _register_all() -> void:
_reg_f("PS1", "ps1_roll_speed", 3.0, 0.0, 10.0, 0.1)
_reg_f("PS1", "ps1_roll_strength", 1.0, 0.0, 1.0, 0.05)
_reg_b("Debug", "show_hitboxes", false)
_reg_b("Debug", "show_attacks", false)
_reg_b("Debug", "show_bones", false)
_reg_b("Debug", "show_raycasts", false)
_reg_b("Debug", "show_tail", false)
@@ -433,12 +485,22 @@ func save() -> void:
if p["value"] == p["default"]:
continue
var re := RegEx.new()
var literal := ""
if p["type"] == TYPE_FLOAT:
re.compile('(_reg_f\\("[^"]+",\\s*"%s",\\s*)([-\\d.e]+)' % key)
src = re.sub(src, "$1" + _fmt_float(p["value"] as float))
literal = _fmt_float(p["value"] as float)
else:
re.compile('(_reg_b\\("[^"]+",\\s*"%s",\\s*)(true|false)' % key)
src = re.sub(src, "$1" + ("true" if bool(p["value"]) else "false"))
literal = "true" if bool(p["value"]) else "false"
var m := re.search(src)
if m == null:
push_warning("DP.save: no _reg_ line found for '%s' — skipped" % key)
continue
# Splice the value in by index rather than RegEx.sub(): sub()'s replacement
# string parses "$n" as a backreference, so "$1"+"12.5" becomes "$112.5"
# (group 112 → PCRE2 error → mangled output). Indexed splice inserts the
# literal verbatim, exactly the value the user entered.
src = src.substr(0, m.get_start(2)) + literal + src.substr(m.get_end(2))
p["default"] = p["value"]
var wfile := FileAccess.open(path, FileAccess.WRITE)
@@ -449,8 +511,12 @@ func save() -> void:
wfile.close()
# Godot's String % operator has no "g" conversion — "%.6g" % v slips past the
# compiler (v is not const) but emits the literal "%.6g" at runtime, which would be
# written straight into the source. "%s" gives the shortest round-tripping form,
# matching the value the user entered; the guard keeps it a float literal.
func _fmt_float(v: float) -> String:
var s := "%.6g" % v
var s := "%s" % v
if not ("." in s or "e" in s):
s += ".0"
return s
+101
View File
@@ -0,0 +1,101 @@
@tool
extends Area3D
class_name Hitbox
## A designer-placeable attack hitbox: drop this into a scene, give it a CollisionShape3D
## child, and drag the shape to size/position the attack's reach in the editor. The shape
## itself decides what got hit — no distance/facing math in code.
##
## Inactive by default; the owning script calls activate() for the swing's active window and
## deactivate() when it ends. Each activation only hits a given body once (the bull's own
## i-frames also collapse a flurry, but this keeps a single swing from re-triggering).
const PhysicsLayers = preload("res://physics_layers.gd")
## How the hit is tagged on the bull's take_sword_hit ("mauled" / "gored" / …).
@export var damage_cause: String = "mauled"
## Upward launch (m/s) applied to the bull on hit — e.g. an overhead smash that pops it up.
@export var knock_up: float = 0.0
## Knock-up distance shaping, measured planar (XZ) from this hitbox's own origin to the body:
## below `knock_up_min_dist` no pop is applied (leap slam: only the outer ring launches). If
## `knock_up_max_dist` > min, the pop ramps 0→`knock_up` from min to max (overhead smash: the
## further out the hit lands, the higher the bull flies); at/again 0 it's full past the min.
@export var knock_up_min_dist: float = 0.0
@export var knock_up_max_dist: float = 0.0
var _active: bool = false
var _hit_this_swing: Dictionary = {}
# Whether the most recent active window connected. Cleared on activate(), NOT deactivate(), so the
# owner can read it after the window closes (e.g. a landed stab breaks off to taunt).
var _did_hit: bool = false
func _ready() -> void:
# Detect the bull's body (layer BULL) only; never collide or push physics.
collision_layer = 0
collision_mask = PhysicsLayers.BULL
monitorable = false
monitoring = false
if Engine.is_editor_hint():
return
body_entered.connect(_on_body_entered)
func activate() -> void:
if _active:
return
_active = true
_hit_this_swing.clear()
_did_hit = false
monitoring = true
func deactivate() -> void:
_active = false
monitoring = false
# Did the window that just closed connect? Valid until the next activate() clears it.
func did_hit() -> bool:
return _did_hit
func _on_body_entered(body: Node3D) -> void:
_apply_hit(body)
# For AoE slams the bull is usually already standing inside the shape when it activates, so
# body_entered never fires. The owner calls sweep() each active frame to catch current overlaps
# (still deduped per activation, so the bull is only hit once per slam).
func sweep() -> void:
if not _active:
return
for body in get_overlapping_bodies():
_apply_hit(body)
func _apply_hit(body: Node3D) -> void:
if not _active or not body.is_in_group(&"player"):
return
if _hit_this_swing.has(body):
return
_hit_this_swing[body] = true
_did_hit = true
body.call(&"take_sword_hit", damage_cause)
if knock_up > 0.0:
var v := _knock_up_for(body)
if v > 0.0:
body.call(&"apply_knock_up", v)
# Scale the pop by how far the body is from this hitbox's origin (planar). See the export docs.
func _knock_up_for(body: Node3D) -> float:
if knock_up_min_dist <= 0.0 and knock_up_max_dist <= 0.0:
return knock_up
var to := body.global_position - global_position
var d := Vector2(to.x, to.z).length()
if d < knock_up_min_dist:
return 0.0
if knock_up_max_dist > knock_up_min_dist:
var t := clampf((d - knock_up_min_dist) / (knock_up_max_dist - knock_up_min_dist), 0.0, 1.0)
return knock_up * t
return knock_up
+1
View File
@@ -0,0 +1 @@
uid://dlwjiw42q6b5f
+123 -8
View File
@@ -42,6 +42,13 @@ var _ability_bar: HBoxContainer
var _ability_panels: Array[PanelContainer] = []
var _bull_bg: TextureRect
# Lobby barrel-smash reward — tally the barrels present on load; when the last one bursts,
# throw confetti + a "WOooOoW!" and grant the bull two yellow bonus pips. Latched so it
# fires once per lobby visit.
var _barrels_remaining: int = 0
var _barrel_reward_given: bool = false
const _BARREL_BONUS_HP: int = 2
# Red damage vignette — a full-screen shader ColorRect flashed on every hit.
const _VIGNETTE_SHADER := "res://damage_vignette.gdshader"
var _vignette: ColorRect
@@ -90,6 +97,7 @@ func _ready() -> void:
_build_touch_controls()
_update_control_hints()
_find_spawner.call_deferred()
_watch_barrels.call_deferred()
# On-screen joystick + ability buttons for touch devices. Self-gating: the overlay
@@ -213,11 +221,109 @@ func _find_spawner() -> void:
_spawner.all_defeated.connect(_on_all_defeated)
# ── Lobby barrel-smash reward ───────────────────────────────────────────────────
# Tally the barrels the current level loaded with and listen for each one bursting. Only
# the lobby has barrels, so on every other level this simply finds none and stands down.
func _watch_barrels() -> void:
var barrels := get_tree().get_nodes_in_group(&"barrel")
_barrels_remaining = barrels.size()
if _barrels_remaining == 0:
return
for barrel: Node in barrels:
barrel.destroyed.connect(_on_barrel_destroyed)
func _on_barrel_destroyed() -> void:
_barrels_remaining -= 1
if _barrels_remaining > 0 or _barrel_reward_given:
return
_barrel_reward_given = true
# Bank the reward run-wide (capped at +2). Only heal the bull for the pips that were
# actually added — if it already carried the cap over from an earlier lobby, it keeps
# the cheer but no new health.
var granted := Run.add_bonus_hp(_BARREL_BONUS_HP)
if granted > 0 and _player != null and _player.has_method(&"grant_bonus_hp"):
_player.call(&"grant_bonus_hp", granted)
_celebrate()
# The "cleared the lobby" flourish: a burst of confetti and a big springy "WOooOoW!".
func _celebrate() -> void:
_spawn_confetti()
_show_wow()
func _show_wow() -> void:
var wow := Label.new()
wow.text = "WOooOoW!"
wow.set_anchors_preset(Control.PRESET_CENTER)
wow.grow_horizontal = Control.GROW_DIRECTION_BOTH
wow.grow_vertical = Control.GROW_DIRECTION_BOTH
wow.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
wow.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
wow.mouse_filter = Control.MOUSE_FILTER_IGNORE
wow.add_theme_font_override("font", UiFonts.title())
wow.add_theme_font_size_override("font_size", 96)
wow.add_theme_color_override("font_color", _HP_BONUS)
wow.add_theme_color_override("font_outline_color", Color(0.0, 0.0, 0.0, 0.9))
wow.add_theme_constant_override("outline_size", 8)
wow.pivot_offset = Vector2.ZERO
wow.scale = Vector2(0.2, 0.2)
add_child(wow)
# Keep the pop growing from the label's centre once it has a real size.
await get_tree().process_frame
wow.pivot_offset = wow.size * 0.5
var tw := create_tween()
tw.tween_property(wow, "scale", Vector2.ONE, 0.35).set_trans(Tween.TRANS_BACK).set_ease(
Tween.EASE_OUT)
tw.tween_interval(1.1)
tw.parallel().tween_property(wow, "modulate:a", 0.0, 0.6)
tw.parallel().tween_property(wow, "position:y", wow.position.y - 40.0, 0.6)
tw.tween_callback(wow.queue_free)
func _spawn_confetti() -> void:
const _CONFETTI_COLORS: Array[Color] = [
Color(0.98, 0.24, 0.28), # red
Color(1.00, 0.78, 0.20), # gold
Color(0.30, 0.80, 0.40), # green
Color(0.30, 0.62, 1.00), # blue
Color(0.85, 0.40, 0.95), # violet
Color(1.00, 1.00, 1.00), # white
]
var vp := get_viewport().get_visible_rect().size
# One emitter per colour, raining down across the top of the screen.
for col: Color in _CONFETTI_COLORS:
var p := CPUParticles2D.new()
p.position = Vector2(vp.x * 0.5, -20.0)
p.emission_shape = CPUParticles2D.EMISSION_SHAPE_RECTANGLE
p.emission_rect_extents = Vector2(vp.x * 0.5, 6.0)
p.amount = 40
p.lifetime = 2.6
p.one_shot = true
p.explosiveness = 0.35
p.direction = Vector2(0.0, 1.0)
p.spread = 25.0
p.gravity = Vector2(0.0, 420.0)
p.initial_velocity_min = 120.0
p.initial_velocity_max = 260.0
p.angular_velocity_min = -360.0
p.angular_velocity_max = 360.0
p.scale_amount_min = 4.0
p.scale_amount_max = 8.0
p.color = col
add_child(p)
# Self-clean once the burst has fully fallen.
get_tree().create_timer(p.lifetime + 0.5).timeout.connect(p.queue_free)
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventKey and event.pressed and not event.echo:
if _game_over and event.physical_keycode in [KEY_ENTER, KEY_KP_ENTER]:
if _result_win:
_continue_to_map()
_continue_to_lobby()
else:
_restart()
elif event.physical_keycode == KEY_TAB and not _game_over:
@@ -238,12 +344,13 @@ func _restart() -> void:
get_tree().reload_current_scene()
# A cleared arena advances the run: commit the win and open the map to pick the next node.
func _continue_to_map() -> void:
# A cleared level drops the player back into the lobby hub: bank the win (which opens the
# gates it unlocks) and reload the shell so it rebuilds the lobby.
func _continue_to_lobby() -> void:
get_tree().paused = false
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
Run.complete_current_level()
get_tree().change_scene_to_file("res://levels/MapScreen.tscn")
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
Run.return_to_lobby()
get_tree().change_scene_to_file(Run.active_level().scene_path)
func _toggle_controls() -> void:
@@ -400,7 +507,7 @@ func _build_game_over() -> void:
# Win → Continue to the run map; loss → Go Again from the top. Shown per-result in
# _show_game_over; both share the Enter shortcut.
_over_continue = _make_button("Continue (Enter)")
_over_continue.pressed.connect(_continue_to_map)
_over_continue.pressed.connect(_continue_to_lobby)
row.add_child(_over_continue)
_over_again = _make_button("Go Again (Enter)")
@@ -419,6 +526,9 @@ func _build_game_over() -> void:
const _HP_FULL: Color = Color(0.82, 0.16, 0.12)
const _HP_EMPTY: Color = Color(0.35, 0.05, 0.05)
const _HP_SOCKET: Color = Color(0.05, 0.02, 0.02, 0.92)
# Bonus pips (barrel-smash reward) read as bright gold-yellow so they stand apart from the
# red life bar.
const _HP_BONUS: Color = Color(1.00, 0.84, 0.18)
const _HP_PIP_W: float = 22.0
const _HP_PIP_H: float = 14.0
@@ -497,10 +607,15 @@ func _on_health_changed(current: int, max_hp: int) -> void:
var cur := maxi(current, 0)
var frac := 0.0 if max_hp <= 0 else clampf(float(cur) / float(max_hp), 0.0, 1.0)
var lit := _HP_FULL.lerp(_HP_EMPTY, 1.0 - frac)
# Bonus pips sit at the high end of the bar; paint those top pips yellow when lit.
var bonus := 0
if _player != null and _player.has_method(&"get_bonus_hp"):
bonus = _player.call(&"get_bonus_hp")
var base_max := max_hp - bonus
for i: int in _hp_seg_fills.size():
var fill := _hp_seg_fills[i]
fill.visible = i < cur
fill.color = lit
fill.color = _HP_BONUS if i >= base_max else lit
const _SLOT_SEPARATION: int = 10
+681 -15
View File
@@ -22,13 +22,13 @@ shape = SubResource("BoxShape3D_ulcgi")
[node name="arena_placeholder_v01" parent="Node3D" unique_id=173047470 instance=ExtResource("2_nxogm")]
[node name="Arena_draft" parent="Node3D/arena_placeholder_v01" index="0" unique_id=727602018]
[node name="Arena_draft" parent="Node3D/arena_placeholder_v01" index="0" unique_id=603097973]
visible = false
[node name="Wall" parent="Node3D/arena_placeholder_v01" index="1" unique_id=1457821831]
[node name="Wall" parent="Node3D/arena_placeholder_v01" index="1" unique_id=171701243]
visible = false
[node name="CollisionShape3D" parent="Node3D/arena_placeholder_v01/Wall/StaticBody3D" parent_id_path=PackedInt32Array(173047470, 1904923047) index="0" unique_id=1063849009]
[node name="CollisionShape3D" parent="Node3D/arena_placeholder_v01/Wall/StaticBody3D" parent_id_path=PackedInt32Array(173047470, 1793167121) index="0" unique_id=404958985]
transform = Transform3D(0.98309773, 0, 0, 0, 0.9558868, 0, 0, 0, 4.061706, 0.13596812, -0.091219574, -5.4371103e-09)
[node name="Arena2" parent="Node3D/arena_placeholder_v01" unique_id=1270130903 instance=ExtResource("3_fy5k1")]
@@ -79,34 +79,700 @@ light_energy = 0.106
shadow_enabled = true
shadow_blur = 10.0
[node name="DirectionalLight3D2" type="DirectionalLight3D" parent="Lights" unique_id=1111896461]
transform = Transform3D(0.6177694, 0, 0.7863593, 0, 1, 0, -0.7863593, 0, 0.6177694, 0, 26.991016, 0)
light_color = Color(0.80501384, 0.8787135, 1, 1)
light_energy = 0.157
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1750284504]
environment = SubResource("Environment_73fnb")
[node name="CrowdBillboards" type="MultiMeshInstance3D" parent="." unique_id=106730614]
[node name="Crowd" type="Node3D" parent="." unique_id=2013004589]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, 14)
[node name="CrowdBillboards" type="MultiMeshInstance3D" parent="Crowd" unique_id=106730614]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -5, -14)
script = ExtResource("11_crowd")
[node name="CrowdMarker1" type="Node3D" parent="." unique_id=2100000001]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, 14)
[node name="Left" type="Node3D" parent="Crowd" unique_id=1621845484]
[node name="L_Step3" type="Node3D" parent="Crowd/Left" unique_id=623102737]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.592416, -1.045898, -23.088398)
[node name="CrowdMarker9" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=578926054]
script = ExtResource("9_agtuu")
orientation = 3
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker2" type="Node3D" parent="." unique_id=2100000002]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 5, 0)
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=1610777090]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.2258072, 0.14058113, -2.5608063)
script = ExtResource("9_agtuu")
orientation = 5
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker3" type="Node3D" parent="." unique_id=2100000003]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, -14)
[node name="CrowdMarker11" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=1861343773]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.809, 0.14058208, 1.755331)
script = ExtResource("9_agtuu")
orientation = 0
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker4" type="Node3D" parent="." unique_id=2100000004]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14, 5, 0)
[node name="CrowdMarker12" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=1555035931]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8979845, 0.14058113, 4.362587)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker13" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=1750314761]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.0180187, 0.14058161, -4.3905067)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker14" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=691141866]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.9175544, 0.14058161, -5.9128)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker15" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=1664612281]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -1.0940075, 0, -1.355114)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker16" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=1677355487]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -3.6482267, 0.14058113, -3.5884771)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker18" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=63826938]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, 1.3811512, 0.14058113, 2.7079024)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker19" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=972576799]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -6.663862, 0.14058161, -5.0203266)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker20" type="Node3D" parent="Crowd/Left/L_Step3" unique_id=1082256967]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -9.743899, 0.14058161, -6.133005)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="L_Step4" type="Node3D" parent="Crowd/Left" unique_id=2012797300]
[node name="CrowdMarker2" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=2100000002]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14, -0.0132164955, -23.088398)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker3" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=563466125]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.533139, -0.0132164955, -24.70021)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker4" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=1529541292]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.021559, -0.013215542, -21.333067)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker5" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=10514539]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.887294, -0.0132164955, -18.725811)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker6" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=1864581651]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.740928, -0.013216019, -28.157803)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker7" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=937874303]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.6115, -0.013216019, -29.924221)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker8" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=1255677084]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.2360125, -0.0132164955, -30.806953)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker9" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=2072287774]
transform = Transform3D(0.9725945, 0, 0.232508, 0, 1, 0, -0.232508, 0, 0.9725945, 13.294765, -0.0132164955, -24.4567)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=1158540011]
transform = Transform3D(0.9725945, 0, 0.232508, 0, 1, 0, -0.232508, 0, 0.9725945, 11.827905, -0.0132164955, -26.068512)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker11" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=1862689569]
transform = Transform3D(0.9725945, 0, 0.232508, 0, 1, 0, -0.232508, 0, 0.9725945, 14.316324, -0.013215542, -22.701368)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker12" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=494798769]
transform = Transform3D(0.9725945, 0, 0.232508, 0, 1, 0, -0.232508, 0, 0.9725945, 15.182059, -0.0132164955, -20.094112)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker13" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=1508360812]
transform = Transform3D(0.9725945, 0, 0.232508, 0, 1, 0, -0.232508, 0, 0.9725945, 9.035693, -0.013216019, -29.526104)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker14" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=1811163868]
transform = Transform3D(0.9725945, 0, 0.232508, 0, 1, 0, -0.232508, 0, 0.9725945, 4.9062653, -0.013216019, -31.292522)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker15" type="Node3D" parent="Crowd/Left/L_Step4" unique_id=1866931486]
transform = Transform3D(0.9725945, 0, 0.232508, 0, 1, 0, -0.232508, 0, 0.9725945, 7.489478, -0.0132164955, -29.721859)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="L_Step1" type="Node3D" parent="Crowd/Left" unique_id=1744694409]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 11.379745, -2.091795, -22.703432)
[node name="CrowdMarker9" type="Node3D" parent="Crowd/Left/L_Step1" unique_id=1620001578]
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Left/L_Step1" unique_id=1055150056]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.2258072, 0.14058113, -2.5608063)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker11" type="Node3D" parent="Crowd/Left/L_Step1" unique_id=717131032]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.2287855, 0.14058208, 1.9909182)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker12" type="Node3D" parent="Crowd/Left/L_Step1" unique_id=1781479729]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8979845, 0.14058113, 4.362587)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker13" type="Node3D" parent="Crowd/Left/L_Step1" unique_id=1352193990]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.0180187, 0.14058161, -4.3905067)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker14" type="Node3D" parent="Crowd/Left/L_Step1" unique_id=743385499]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.9175544, 0.14058161, -5.9128)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="L_Step5" type="Node3D" parent="Crowd/Left" unique_id=670288549]
transform = Transform3D(0.9967379, 0, -0.08070645, 0, 1, 0, 0.08070645, 0, 0.9967379, 11.637655, -3.0939364, -20.899355)
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=274558473]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.2258072, 0.14058113, -2.5608063)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker11" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=516605334]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.809, 0.14058208, 1.755331)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker12" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=1577172273]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8979845, 0.14058113, 4.362587)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker13" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=1757843488]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.0180187, 0.14058161, -4.3905067)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker14" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=1120424592]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.9175544, 0.14058161, -5.9128)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker15" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=1819323657]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -1.0940075, 0, -1.355114)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker16" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=538915422]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -3.6482267, 0.14058113, -3.5884771)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker17" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=1328913359]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -0.053198814, 0.14058208, 0.27350044)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker18" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=878163668]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, 1.3811512, 0.14058113, 2.7079024)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker19" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=1568364605]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -6.663862, 0.14058161, -5.0203266)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker20" type="Node3D" parent="Crowd/Left/L_Step5" unique_id=1367833604]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -9.743899, 0.14058161, -6.133005)
script = ExtResource("9_agtuu")
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="Back" type="Node3D" parent="Crowd" unique_id=638158299]
[node name="B_Step3" type="Node3D" parent="Crowd/Back" unique_id=174422561]
transform = Transform3D(0.098605186, 0, 0.99512655, 0, 1, 0, -0.99512655, 0, 0.098605186, -8.350439, -1.045898, -26.733604)
[node name="CrowdMarker9" type="Node3D" parent="Crowd/Back/B_Step3" unique_id=1376565490]
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Back/B_Step3" unique_id=2134315249]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.2258072, 0.14058113, -2.5608063)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker11" type="Node3D" parent="Crowd/Back/B_Step3" unique_id=434884711]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.809, 0.14058208, 1.755331)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker12" type="Node3D" parent="Crowd/Back/B_Step3" unique_id=1901106701]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8979845, 0.14058113, 4.362587)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker13" type="Node3D" parent="Crowd/Back/B_Step3" unique_id=1659701219]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.0180187, 0.14058161, -4.3905067)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker14" type="Node3D" parent="Crowd/Back/B_Step3" unique_id=469584679]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, -7.9328146, 0.14058161, -5.5702662)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="B_Step4" type="Node3D" parent="Crowd/Back" unique_id=792967648]
transform = Transform3D(0.09860524, 0, 0.9951266, 0, 1, 0, -0.9951266, 0, 0.09860524, 13.383762, 0, -11.9259205)
[node name="CrowdMarker2" type="Node3D" parent="Crowd/Back/B_Step4" unique_id=409183135]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14, -0.0132164955, -23.088398)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker3" type="Node3D" parent="Crowd/Back/B_Step4" unique_id=1443859159]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.533139, -0.0132164955, -24.70021)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker4" type="Node3D" parent="Crowd/Back/B_Step4" unique_id=1737861319]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.021559, -0.013215542, -21.333067)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker5" type="Node3D" parent="Crowd/Back/B_Step4" unique_id=1991036767]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.887294, -0.0132164955, -18.725811)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker6" type="Node3D" parent="Crowd/Back/B_Step4" unique_id=1075095199]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.740928, -0.013216019, -28.157803)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker7" type="Node3D" parent="Crowd/Back/B_Step4" unique_id=1699892650]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.6115, -0.013216019, -29.924221)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker8" type="Node3D" parent="Crowd/Back/B_Step4" unique_id=565692575]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.2360125, -0.0132164955, -30.806953)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="B_Step" type="Node3D" parent="Crowd/Back" unique_id=414907102]
transform = Transform3D(-0.04323627, 0, 0.99906486, 0, 1, 0, -0.99906486, 0, -0.04323627, -8.380329, -1.827393, -25.818556)
[node name="CrowdMarker9" type="Node3D" parent="Crowd/Back/B_Step" unique_id=1943968269]
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Back/B_Step" unique_id=2061244199]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.2258072, 0.14058113, -2.5608063)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker11" type="Node3D" parent="Crowd/Back/B_Step" unique_id=977400271]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.2287855, 0.14058208, 1.9909182)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker12" type="Node3D" parent="Crowd/Back/B_Step" unique_id=1522748404]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8979845, 0.14058113, 4.362587)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker13" type="Node3D" parent="Crowd/Back/B_Step" unique_id=791374389]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.0180187, 0.14058161, -4.3905067)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker14" type="Node3D" parent="Crowd/Back/B_Step" unique_id=1457299400]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.9175544, 0.14058161, -5.9128)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="L_Step5" type="Node3D" parent="Crowd/Back" unique_id=1665844535]
transform = Transform3D(0.022304952, 0, 0.99975127, 0, 1, 0, -0.99975127, 0, 0.022304952, -6.9624662, -3.0939345, -25.679592)
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Back/L_Step5" unique_id=1629480429]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.2258072, 0.3974409, -2.5608063)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker11" type="Node3D" parent="Crowd/Back/L_Step5" unique_id=1506450411]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.809, 0.39744186, 1.755331)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker12" type="Node3D" parent="Crowd/Back/L_Step5" unique_id=622605512]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8979845, 0.3974409, 4.362587)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker13" type="Node3D" parent="Crowd/Back/L_Step5" unique_id=257326812]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.0180187, 0.3974414, -4.3905067)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker14" type="Node3D" parent="Crowd/Back/L_Step5" unique_id=1211459457]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.9175544, 0.3974414, -5.9128)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker15" type="Node3D" parent="Crowd/Back/L_Step5" unique_id=155390702]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -1.0940075, 0.25685978, -1.355114)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker16" type="Node3D" parent="Crowd/Back/L_Step5" unique_id=34227892]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -3.6482267, 0.3974409, -3.5884771)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker17" type="Node3D" parent="Crowd/Back/L_Step5" unique_id=1904591453]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -0.053198814, 0.39744186, 0.27350044)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker18" type="Node3D" parent="Crowd/Back/L_Step5" unique_id=687360614]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, 1.3811512, 0.3974409, 2.7079024)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker19" type="Node3D" parent="Crowd/Back/L_Step5" unique_id=1751401910]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -6.663862, 0.3974414, -5.0203266)
script = ExtResource("9_agtuu")
orientation = 1
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="Right" type="Node3D" parent="Crowd" unique_id=1277806052]
[node name="R_Step3" type="Node3D" parent="Crowd/Right" unique_id=1092390193]
transform = Transform3D(-0.9993231, 0, -0.036786973, 0, 1, 0, 0.036786973, 0, -0.9993231, -12.105062, -1.045898, -5.1461663)
[node name="CrowdMarker9" type="Node3D" parent="Crowd/Right/R_Step3" unique_id=550527812]
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Right/R_Step3" unique_id=417838082]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.2258072, 0.14058113, -2.5608063)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker11" type="Node3D" parent="Crowd/Right/R_Step3" unique_id=562183345]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.809, 0.14058208, 1.755331)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker12" type="Node3D" parent="Crowd/Right/R_Step3" unique_id=59142166]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8979845, 0.14058113, 4.362587)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker13" type="Node3D" parent="Crowd/Right/R_Step3" unique_id=1970971214]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.0180187, 0.14058161, -4.3905067)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker14" type="Node3D" parent="Crowd/Right/R_Step3" unique_id=622146302]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.9175544, 0.14058161, -5.9128)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="R_Step4" type="Node3D" parent="Crowd/Right" unique_id=1081871135]
transform = Transform3D(-0.99684, 0, 0.07943541, 0, 1, 0, -0.07943541, 0, -0.99684, 2.0997996, 0, -28.147049)
[node name="CrowdMarker2" type="Node3D" parent="Crowd/Right/R_Step4" unique_id=384688095]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14, -0.0132164955, -23.088398)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker3" type="Node3D" parent="Crowd/Right/R_Step4" unique_id=794438773]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.533139, -0.0132164955, -24.70021)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker4" type="Node3D" parent="Crowd/Right/R_Step4" unique_id=318354120]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.021559, -0.013215542, -21.333067)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker5" type="Node3D" parent="Crowd/Right/R_Step4" unique_id=1139375927]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.887294, -0.0132164955, -18.725811)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker6" type="Node3D" parent="Crowd/Right/R_Step4" unique_id=468384482]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.740928, -0.013216019, -28.157803)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker7" type="Node3D" parent="Crowd/Right/R_Step4" unique_id=1219838852]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.6115, -0.013216019, -29.924221)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker8" type="Node3D" parent="Crowd/Right/R_Step4" unique_id=876634044]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.2360125, -0.0132164955, -30.806953)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="R_Step1" type="Node3D" parent="Crowd/Right" unique_id=1804391941]
transform = Transform3D(-0.9983546, 0, -0.05734154, 0, 1, 0, 0.05734154, 0, -0.9983546, -11.76964, -2.091795, -5.703799)
[node name="CrowdMarker9" type="Node3D" parent="Crowd/Right/R_Step1" unique_id=1122311940]
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Right/R_Step1" unique_id=107523420]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.2258072, 0.14058113, -2.5608063)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker11" type="Node3D" parent="Crowd/Right/R_Step1" unique_id=265148663]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.2287855, 0.14058208, 1.9909182)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker12" type="Node3D" parent="Crowd/Right/R_Step1" unique_id=592546407]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8979845, 0.14058113, 4.362587)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker13" type="Node3D" parent="Crowd/Right/R_Step1" unique_id=514985832]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.0180187, 0.14058161, -4.3905067)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker14" type="Node3D" parent="Crowd/Right/R_Step1" unique_id=416317204]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.9175544, 0.14058161, -5.9128)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="L_Step5" type="Node3D" parent="Crowd/Right" unique_id=1434949087]
transform = Transform3D(-0.99935067, 0, -0.036034077, 0, 1, 0, 0.036034077, 0, -0.99935067, -10.943644, -3.0939355, -6.015876)
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Right/L_Step5" unique_id=1951969393]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.2258072, 0.3974409, -2.5608063)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker11" type="Node3D" parent="Crowd/Right/L_Step5" unique_id=1614578381]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.809, 0.39744186, 1.755331)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker12" type="Node3D" parent="Crowd/Right/L_Step5" unique_id=2079795403]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8979845, 0.3974409, 4.362587)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker13" type="Node3D" parent="Crowd/Right/L_Step5" unique_id=18703002]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.0180187, 0.3974414, -4.3905067)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker14" type="Node3D" parent="Crowd/Right/L_Step5" unique_id=619627641]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.9175544, 0.3974414, -5.9128)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker15" type="Node3D" parent="Crowd/Right/L_Step5" unique_id=46013841]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -1.0940075, 0.25685978, -1.355114)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker16" type="Node3D" parent="Crowd/Right/L_Step5" unique_id=1130198232]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -3.6482267, 0.3974409, -3.5884771)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker17" type="Node3D" parent="Crowd/Right/L_Step5" unique_id=744258528]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -0.053198814, 0.39744186, 0.27350044)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker18" type="Node3D" parent="Crowd/Right/L_Step5" unique_id=774368922]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, 1.3811512, 0.3974409, 2.7079024)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker19" type="Node3D" parent="Crowd/Right/L_Step5" unique_id=545323927]
transform = Transform3D(0.9906587, 0, 0.13636485, 0, 1, 0, -0.13636485, 0, 0.9906587, -6.663862, 0.3974414, -5.0203266)
script = ExtResource("9_agtuu")
orientation = 2
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="Front_Right" type="Node3D" parent="Crowd" unique_id=1683981332]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16.440575, 0, -11.451455)
[node name="CrowdMarker3" type="Node3D" parent="Crowd/Front_Right" unique_id=943299423]
script = ExtResource("9_agtuu")
orientation = 4
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker4" type="Node3D" parent="Crowd/Front_Right" unique_id=1123847296]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.05489731, 0, 1.3246164)
script = ExtResource("9_agtuu")
orientation = 4
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker5" type="Node3D" parent="Crowd/Front_Right" unique_id=640400607]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.7841702, -0.93699646, 0)
script = ExtResource("9_agtuu")
orientation = 4
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker6" type="Node3D" parent="Crowd/Front_Right" unique_id=603945551]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.8390675, -0.93699646, 1.3246164)
script = ExtResource("9_agtuu")
orientation = 4
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker7" type="Node3D" parent="Crowd/Front_Right" unique_id=26053676]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.6784592, -2.0288038, 0.21630049)
script = ExtResource("9_agtuu")
orientation = 4
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker8" type="Node3D" parent="Crowd/Front_Right" unique_id=983869769]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.7333565, -2.0288038, 1.5409169)
script = ExtResource("9_agtuu")
orientation = 4
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker9" type="Node3D" parent="Crowd/Front_Right" unique_id=2131633869]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.7693996, -2.7652984, 0)
script = ExtResource("9_agtuu")
orientation = 4
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker10" type="Node3D" parent="Crowd/Front_Right" unique_id=393732717]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.824297, -2.7652984, 1.3246164)
script = ExtResource("9_agtuu")
orientation = 4
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="Front_Left" type="Node3D" parent="Crowd" unique_id=1426987879]
[node name="CrowdMarker" type="Node3D" parent="Crowd/Front_Left" unique_id=884656972]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.1676445, 0, 1.5733547)
script = ExtResource("9_agtuu")
orientation = 3
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker2" type="Node3D" parent="Crowd/Front_Left" unique_id=1281756834]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.1122522, 0, 1.5733547)
script = ExtResource("9_agtuu")
orientation = 3
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker3" type="Node3D" parent="Crowd/Front_Left" unique_id=287020937]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.483545, -1.8461189, -0.5833006)
script = ExtResource("9_agtuu")
orientation = 3
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker4" type="Node3D" parent="Crowd/Front_Left" unique_id=1628869900]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.7205377, -1.8461189, -0.36581516)
script = ExtResource("9_agtuu")
orientation = 3
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker5" type="Node3D" parent="Crowd/Front_Left" unique_id=375235166]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.245149, -0.9629531, 0.27452564)
script = ExtResource("9_agtuu")
orientation = 3
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[node name="CrowdMarker6" type="Node3D" parent="Crowd/Front_Left" unique_id=1951144178]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.7495923, -0.9629531, 0.48515797)
script = ExtResource("9_agtuu")
orientation = 3
metadata/_custom_type_script = "uid://70j3ks1emhkd"
[editable path="Node3D/arena_placeholder_v01"]
+17 -1
View File
@@ -4,7 +4,10 @@ extends Node3D
## spawners, lighting, colliders) into LevelRoot. Switching levels frees the whole
## previous module first, so no old mesh or collider can survive into the next fight.
const PhysicsLayers = preload("res://physics_layers.gd")
@onready var _level_root: Node3D = $LevelRoot
@onready var _camera: IsoCamera = $Player/Camera3D
func _ready() -> void:
@@ -23,4 +26,17 @@ func load_active_level() -> void:
if level == null or level.level_scene == null:
push_warning("game_shell: active level has no level_scene")
return
_level_root.add_child(level.level_scene.instantiate())
_camera.set_framing_scale(level.camera_zoom)
var module := level.level_scene.instantiate()
_tag_environment_for_corpses(module)
_level_root.add_child(module)
## Ground and walls stay on WORLD so the bull and live matadors collide with them; here
## we add CORPSE too. A killed matador's ragdoll is masked to CORPSE alone, so it rests
## on the arena while the bull — which only collides with WORLD — passes through the body
## instead of spazzing out on it. Done at load so it also reaches colliders baked into
## the instanced GLB arenas, not just the level module's own floor box.
func _tag_environment_for_corpses(module: Node) -> void:
for body: StaticBody3D in module.find_children("*", "StaticBody3D", true, false):
body.collision_layer |= PhysicsLayers.CORPSE
+4
View File
@@ -17,6 +17,10 @@ extends Resource
@export var level_scene: PackedScene = null
## Placeholder pip tint on the map until per-level icon art exists.
@export var color: Color = Color(0.80, 0.62, 0.24)
## Camera framing multiplier when this level loads — 1.0 is the shell camera's default
## shot; >1 dollies the camera back for a wider view (the lobby pulls out so the whole
## hub reads). Applied by game_shell; independent of the player's scroll-wheel zoom.
@export var camera_zoom: float = 1.0
## A boss level caps a run — its node is drawn larger and clearing it ends the map.
@export var is_boss: bool = false
## The enemy this level pits the bull against. Null → the usual matador wave (the
+267
View File
@@ -0,0 +1,267 @@
[gd_scene format=3 uid="uid://32nyipcwrab5"]
[ext_resource type="PackedScene" uid="uid://bbfvwolhomilp" path="res://tscn_s/torch.tscn" id="1_w7uyf"]
[ext_resource type="PackedScene" uid="uid://bd56iuttyiypv" path="res://tscn_s/BarrelSimple.tscn" id="2_3o0md"]
[ext_resource type="PackedScene" uid="uid://dctmlh4hnuux1" path="res://Assets/Lobby_underground.glb" id="2_w7uyf"]
[ext_resource type="Script" uid="uid://cwbf7jfkr8j10" path="res://Assets/lobby_underground.gd" id="4_73452"]
[ext_resource type="Script" uid="uid://dn77mjyxllgl6" path="res://levels/to_the_bear_level.gd" id="5_6j2sa"]
[ext_resource type="Script" uid="uid://cgwliuslwfmbk" path="res://levels/to_the_arena_level.gd" id="6_jmi3x"]
[sub_resource type="Environment" id="Environment_lobby"]
[sub_resource type="Animation" id="Animation_w7uyf"]
resource_name = "Gate_opening"
length = 7.5
tracks/0/type = "position_3d"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Lobby_underground/Locked_grid")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, 0, 0, 0, 0.033333335, 1, 0.032444477, 0, 0, 0.06666667, 1, -0.033060133, 0, 0, 0.10934577, 1, 0.032444477, 0, 0, 0.14267911, 1, -0.033060133, 0, 0, 0.17731747, 1, 0.032444477, 0, 0, 0.2106508, 1, -0.033060133, 0, 0, 0.24085623, 1, 0.032444477, 0, 0, 0.27418956, 1, -0.033060133, 0, 0, 0.29700676, 1, 0.032444477, 0, 0, 0.3303401, 1, -0.033060133, 0, 0, 0.36350083, 1, 0.032444477, 0, 0, 0.39683416, 1, -0.033060133, 0, 0, 0.42408428, 1, 0.032444477, 0, 0, 0.4574176, 1, -0.033060133, 0, 0, 0.48153976, 1, 0, 0, 0, 0.5148731, 1, 0.032444477, 0, 0, 0.54402214, 1, 0.032444477, 0, 0, 0.54820645, 1, -0.033060133, 0, 0, 0.57735544, 1, -0.033060133, 0, 0, 0.5908855, 1, 0.032444477, 0, 0, 0.60017264, 1, 0.032444477, 0, 0, 0.6242189, 1, -0.033060133, 0, 0, 0.633506, 1, -0.033060133, 0, 0, 0.6588572, 1, 0.032444477, 0, 0, 0.6666667, 1, 0.032444477, 0, 0, 0.6921905, 1, -0.033060133, 0, 0, 0.70000005, 1, -0.033060133, 0, 0, 0.72725016, 1, 0.032444477, 0, 0, 0.75179356, 1, 0, 0, 0, 0.76058346, 1, -0.033060133, 0, 0, 0.7851269, 1, 0.032444477, 0, 0, 0.8184602, 1, -0.033060133, 0, 0, 0.86113936, 1, 0.032444477, 0, 0, 0.8944727, 1, -0.033060133, 0, 0, 0.929111, 1, 0.032444477, 0, 0, 0.9624443, 1, -0.033060133, 0, 0, 0.9926498, 1, 0.032444477, 0, 0, 1.0259831, 1, -0.033060133, 0, 0, 1.0488003, 1, 0.032444477, 0, 0, 1.0821337, 1, -0.033060133, 0, 0, 1.1152945, 1, 0.032444477, 0, 0, 1.1486278, 1, -0.033060133, 0, 0, 1.1758778, 1, 0.032444477, 0, 0, 1.2092111, 1, -0.033060133, 0, 0, 1.2333333, 1, 0, 0, 0, 1.2666667, 1, 0.032444477, 0, 0, 1.2958157, 1, 0.032444477, 0, 0, 1.3, 1, -0.033060133, 0, 0, 1.329149, 1, -0.033060133, 0, 0, 1.342679, 1, 0.032444477, 0, 0, 1.3519661, 1, 0.032444477, 0, 0, 1.3760124, 1, -0.033060133, 0, 0, 1.3852996, 1, -0.033060133, 0, 0, 1.4106507, 1, 0.032444477, 0, 0, 1.4184602, 1, 0.032444477, 0, 0, 1.443984, 1, -0.033060133, 0, 0, 1.4517937, 1, -0.033060133, 0, 0, 1.4790437, 1, 0.032444477, 0, 0, 1.512377, 1, -0.033060133, 0, 0, 1.6, 1, 0, 0, 0, 7.4666667, 1, 0, 6.938447, 0)
[sub_resource type="Animation" id="Animation_73452"]
length = 0.001
tracks/0/type = "position_3d"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Lobby_underground/Locked_grid")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, 0, 0, 0)
[sub_resource type="AnimationLibrary" id="AnimationLibrary_6j2sa"]
_data = {
&"Gate_opening": SubResource("Animation_w7uyf"),
&"RESET": SubResource("Animation_73452")
}
[sub_resource type="BoxShape3D" id="BoxShape3D_73452"]
size = Vector3(4.1274414, 8.299622, 6.9958496)
[node name="lobby_level" type="Node3D" unique_id=1511255302]
[node name="Lights" type="Node3D" parent="." unique_id=562527333]
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Lights" unique_id=955995990]
transform = Transform3D(-0.502238, -0.82287306, 0.26577574, 0.36594617, 0.07621761, 0.9275096, -0.78347975, 0.5630903, 0.26284787, 0, 0, 0)
light_color = Color(0.78431374, 0.8117647, 1, 1)
light_energy = 0.228
shadow_enabled = true
[node name="SpotLight3D" type="SpotLight3D" parent="Lights" unique_id=1783040386]
transform = Transform3D(-0.9926004, -0.101570696, 0.06654498, -0.08617279, 0.9753173, 0.20329961, -0.08555172, 0.19606102, -0.9768528, -2.86597, 1.7488484, -31.233114)
light_color = Color(0.51629305, 0.20273978, 0.034483083, 1)
light_energy = 1000.0
shadow_enabled = true
shadow_reverse_cull_face = true
spot_range = 22.312231
[node name="SpotLight3D3" type="SpotLight3D" parent="Lights" unique_id=30670834]
transform = Transform3D(-0.94000536, -0.14085309, 0.31072634, 0.3218794, -0.064308055, 0.94459444, -0.11306689, 0.9879399, 0.105787426, 11.072751, 38.325985, 6.519638)
light_color = Color(0.31635508, 0.2876817, 0.44758296, 1)
light_energy = 17.27
shadow_enabled = true
shadow_reverse_cull_face = true
spot_range = 4095.795
[node name="SpotLight3D2" type="SpotLight3D" parent="Lights" unique_id=748351326]
transform = Transform3D(-0.0064023333, 0.48097554, -0.8767107, 0.0041269795, 0.87673384, 0.48095813, 0.99997103, -0.00053891214, -0.0075981184, -30.750355, 6.77676, -0.61776364)
light_color = Color(0.1254902, 0.37254903, 0.16078432, 1)
light_energy = 1000.0
shadow_enabled = true
shadow_reverse_cull_face = true
spot_range = 22.312231
[node name="Torches" type="Node3D" parent="Lights" unique_id=1105190110]
[node name="Torch" parent="Lights/Torches" unique_id=1280811583 instance=ExtResource("1_w7uyf")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -19.966858, -0.26246262, 0)
[node name="Torch2" parent="Lights/Torches" unique_id=472577842 instance=ExtResource("1_w7uyf")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.3695145, 0, 0)
[node name="Torch3" parent="Lights/Torches" unique_id=207127049 instance=ExtResource("1_w7uyf")]
transform = Transform3D(0.0026565322, 0, 0.9999965, 0, 1, 0, -0.9999965, 0, 0.0026565322, -0.38332775, 1.9073486e-06, 16.218426)
[node name="Torch4" parent="Lights/Torches" unique_id=601493997 instance=ExtResource("1_w7uyf")]
transform = Transform3D(0.0026565322, 0, 0.9999965, 0, 1, 0, -0.9999965, 0, 0.0026565322, -0.3482311, 1.9073486e-06, 3.0070276)
[node name="Torch5" parent="Lights/Torches" unique_id=1952598831 instance=ExtResource("1_w7uyf")]
transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 0.09400132, 1.9073486e-06, -0.31505296)
[node name="Torch6" parent="Lights/Torches" unique_id=830103133 instance=ExtResource("1_w7uyf")]
transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 16.002838, 1.9073486e-06, -0.31505156)
[node name="Torch7" parent="Lights/Torches" unique_id=1842073656 instance=ExtResource("1_w7uyf")]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -0.349617, 1.9073486e-06, -0.31505227)
[node name="Torch8" parent="Lights/Torches" unique_id=987701581 instance=ExtResource("1_w7uyf")]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -0.349617, 1.9073486e-06, -0.31505227)
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=939963056]
environment = SubResource("Environment_lobby")
[node name="Barrels" type="Node3D" parent="." unique_id=1740830546]
[node name="BarrelSimple" parent="Barrels" unique_id=771860903 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.276957, 0.056278944, -13.151918)
[node name="BarrelSimple2" parent="Barrels" unique_id=609563864 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.8753104, 0.11255789, -14.810173)
[node name="BarrelSimple3" parent="Barrels" unique_id=2089803156 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.758999, 0.11255789, -14.810173)
[node name="BarrelSimple4" parent="Barrels" unique_id=223671996 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.40292, 0.11255789, -14.810173)
[node name="BarrelSimple5" parent="Barrels" unique_id=1643056602 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.8811536, 0.11255789, -10.928238)
[node name="BarrelSimple6" parent="Barrels" unique_id=1861324204 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.764843, 0.11255789, -10.928238)
[node name="BarrelSimple7" parent="Barrels" unique_id=1662505485 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.597986, 0.11255789, -11.120108)
[node name="BarrelSimple8" parent="Barrels" unique_id=711949884 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.686088, 0.11255789, -6.599861)
[node name="BarrelSimple9" parent="Barrels" unique_id=633001295 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.569777, 0.11255789, -6.599861)
[node name="BarrelSimple10" parent="Barrels" unique_id=1460426434 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.40292, 0.11255789, -6.791731)
[node name="BarrelSimple11" parent="Barrels" unique_id=1660531493 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.210243, 0.056278944, 12.913824)
[node name="BarrelSimple12" parent="Barrels" unique_id=1652485637 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.8753104, 0.11255789, 6.3396435)
[node name="BarrelSimple13" parent="Barrels" unique_id=590613985 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.758999, 0.11255789, 6.3396435)
[node name="BarrelSimple14" parent="Barrels" unique_id=176616372 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.40292, 0.11255789, 6.3396435)
[node name="BarrelSimple15" parent="Barrels" unique_id=465036756 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.070376, 0.11255789, 10.029709)
[node name="BarrelSimple16" parent="Barrels" unique_id=224566162 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.954065, 0.11255789, 10.029709)
[node name="BarrelSimple17" parent="Barrels" unique_id=1512161234 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.597986, 0.11255789, 10.029709)
[node name="BarrelSimple18" parent="Barrels" unique_id=1113697629 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.8753104, 0.11255789, 14.358086)
[node name="BarrelSimple19" parent="Barrels" unique_id=1224035347 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.758999, 0.11255789, 14.358086)
[node name="BarrelSimple20" parent="Barrels" unique_id=249931770 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.40292, 0.11255789, 14.358086)
[node name="BarrelSimple21" parent="Barrels" unique_id=1893459330 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.3384705, 0.056278944, 15.129177)
[node name="BarrelSimple22" parent="Barrels" unique_id=1386374345 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.883017, 0.11255789, 6.7661877)
[node name="BarrelSimple23" parent="Barrels" unique_id=1508934681 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.999329, 0.11255789, 6.7661877)
[node name="BarrelSimple24" parent="Barrels" unique_id=1567182843 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.3554077, 0.11255789, 6.7661877)
[node name="BarrelSimple25" parent="Barrels" unique_id=2023488949 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.687952, 0.11255789, 10.456253)
[node name="BarrelSimple26" parent="Barrels" unique_id=918952214 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.804262, 0.11255789, 10.456253)
[node name="BarrelSimple27" parent="Barrels" unique_id=1651601809 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.1603413, 0.11255789, 10.456253)
[node name="BarrelSimple28" parent="Barrels" unique_id=1526224674 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.883017, 0.11255789, 14.78463)
[node name="BarrelSimple29" parent="Barrels" unique_id=212191494 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.999329, 0.11255789, 14.78463)
[node name="BarrelSimple30" parent="Barrels" unique_id=625425940 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.3554077, 0.11255789, 14.78463)
[node name="BarrelSimple31" parent="Barrels" unique_id=1216255698 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.165121, 0.056277037, -13.43729)
[node name="BarrelSimple32" parent="Barrels" unique_id=1511816190 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.938013, 0.11255789, -14.810173)
[node name="BarrelSimple33" parent="Barrels" unique_id=592677866 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.054325, 0.11255789, -14.810173)
[node name="BarrelSimple34" parent="Barrels" unique_id=855289598 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.410404, 0.11255789, -14.810173)
[node name="BarrelSimple35" parent="Barrels" unique_id=521586989 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.742949, 0.11255789, -11.120108)
[node name="BarrelSimple36" parent="Barrels" unique_id=841067379 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.859259, 0.11255789, -11.120108)
[node name="BarrelSimple37" parent="Barrels" unique_id=1167528508 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.215338, 0.11255789, -11.120108)
[node name="BarrelSimple38" parent="Barrels" unique_id=2081881340 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.938013, 0.11255789, -6.791731)
[node name="BarrelSimple39" parent="Barrels" unique_id=716196812 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.054325, 0.11255789, -6.791731)
[node name="BarrelSimple40" parent="Barrels" unique_id=1689907554 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.410404, 0.11255789, -6.791731)
[node name="BarrelSimple41" parent="Barrels" unique_id=1885522518 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.4957442, 0.11255789, -1.522007)
[node name="BarrelSimple42" parent="Barrels" unique_id=138543996 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.3879452, 0.11255789, -1.522007)
[node name="BarrelSimple43" parent="Barrels" unique_id=1456059567 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.6908097, 0.11255789, 2.8063698)
[node name="BarrelSimple44" parent="Barrels" unique_id=1888973294 instance=ExtResource("2_3o0md")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.1928787, 0.11255789, 2.8063698)
[node name="Lobby_underground" parent="." unique_id=1313381882 instance=ExtResource("2_w7uyf")]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 0, 0, 0)
script = ExtResource("4_73452")
[node name="Plane" parent="Lobby_underground" index="1" unique_id=1962555538]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2352347, 0)
[node name="AnimationPlayer" type="AnimationPlayer" parent="Lobby_underground" unique_id=2070502042]
root_node = NodePath("../..")
libraries/ = SubResource("AnimationLibrary_6j2sa")
[node name="to_the_bear_level" type="Area3D" parent="." unique_id=267572930]
collision_mask = 3
script = ExtResource("5_6j2sa")
[node name="CollisionShape3D" type="CollisionShape3D" parent="to_the_bear_level" unique_id=2080871641]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -24.975298, 3.6498108, 0.59606934)
shape = SubResource("BoxShape3D_73452")
[node name="to_the_arena_level" type="Area3D" parent="." unique_id=293174522]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -2.7537346, 0, -1.2036956e-07)
collision_mask = 3
script = ExtResource("6_jmi3x")
[node name="CollisionShape3D" type="CollisionShape3D" parent="to_the_arena_level" unique_id=409491377]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -23.561888, 2.767395, 0.59606934)
shape = SubResource("BoxShape3D_73452")
[editable path="Lobby_underground"]
+21 -6
View File
@@ -34,15 +34,29 @@ func _spawn() -> void:
# Matadors are assigned to a random subset of spawn points each wave and enter staggered.
func _start_next_wave() -> void:
_wave += 1
var count := mini(_wave, _spawn_points.size())
var points: Array = _spawn_points.duplicate()
# 8 waves total.
if _wave > DP.f("mat_wave_size"):
return
# Wave 1 = 1 matador, Wave 2 = 2, ... Wave 8 = 8.
var count := _wave
# Shuffle the spawn points so the spawn locations are random.
var points: Array[Node3D] = _spawn_points.duplicate()
points.shuffle()
for i: int in count:
var sp := points[i] as Node3D
for i in range(count):
# Reuse spawn points when we have more matadors than points.
var sp: Node3D = points[i % points.size()]
var m := _spawn_at(sp.global_position)
m.call_deferred(&"enter_spawn_roll", Vector3.ZERO)
if i < count - 1:
await get_tree().create_timer(DP.f("mat_spawn_stagger")).timeout
await get_tree().create_timer(
DP.f("mat_spawn_stagger")
).timeout
func _place_bull(angle: float, arena_r: float) -> void:
@@ -68,7 +82,8 @@ func _on_matador_killed() -> void:
_alive -= 1
if _alive > 0 or _resolved:
return
if _wave >= _spawn_points.size():
if _wave >= DP.f("mat_wave_size"):
DP.set_value("gate_unlocked_bear", true)
_resolved = true
all_defeated.emit()
else:
+71 -1
View File
@@ -15,6 +15,7 @@ signal run_started
const _SHELL_SCENE := "res://scene.tscn"
const _ARENA_LEVEL := preload("res://levels/arena_level.tscn")
const _BEAR_LEVEL := preload("res://levels/bear_level.tscn")
const _LOBBY_LEVEL := preload("res://levels/lobby_level.tscn")
# Map shape. Small + placeholder for now; the final row is a single boss node.
const _ROWS := 5
@@ -33,6 +34,20 @@ var pending_col: int = -1
## Debug override — when set, active_level() returns this regardless of map state.
## Set via the console `level` command; cleared on start_new_run().
var debug_level_override: LevelDef = null
## The lobby is the hub the run starts and returns to: a walk-around room whose gates lead
## into the fights. While set, active_level() serves the lobby; cleared once a gate is
## entered (choose_level) and set again on a win (return_to_lobby).
var enter_lobby: bool = false
## Level picked at a lobby gate and being fought now — active_level() serves it while
## enter_lobby is false. Null in the lobby itself.
var lobby_choice: LevelDef = null
## Ids of levels the player has cleared this run (StringName -> true). Drives which lobby
## gates are open: the bear gate stays shut until the arena is beaten.
var cleared: Dictionary = {}
## Run-long bonus health (yellow pips) earned from lobby rewards. Persists across level
## loads — the player reads it on spawn — and is capped so it can't stack past BONUS_HP_CAP.
var bonus_hp: int = 0
const BONUS_HP_CAP: int = 2
# Level catalog. Every level shares the shell scene; what changes is the level module
# (its geometry + spawners) and the opponent. The arena (matador wave, normal + boss
@@ -43,6 +58,7 @@ const _BEAR_SCENE := preload("res://Bear.tscn")
var _arena: LevelDef
var _arena_boss: LevelDef
var _bear: LevelDef
var _lobby: LevelDef
func _ready() -> void:
@@ -52,6 +68,10 @@ func _ready() -> void:
)
_bear = _make_level(&"bear", "Bear's Den", _BEAR_LEVEL, Color(0.55, 0.38, 0.22), false)
_bear.enemy_scene = _BEAR_SCENE
# The lobby is a fightless hub — no enemy_scene, so no wave spawns and no win/lose.
_lobby = _make_level(&"lobby", "Lobby", _LOBBY_LEVEL, Color(0.62, 0.66, 0.72), false)
# It's a roomy hub with nothing to fight — pull the camera back so more of it reads.
_lobby.camera_zoom = 1.6
func _make_level(
@@ -72,6 +92,10 @@ func _make_level(
func active_level() -> LevelDef:
if debug_level_override != null:
return debug_level_override
if enter_lobby:
return _lobby
if lobby_choice != null:
return lobby_choice
var n := node_at(pending_row, pending_col)
if n == null:
n = current_node()
@@ -84,12 +108,13 @@ func get_level(id: StringName) -> LevelDef:
&"arena": return _arena
&"arena_boss": return _arena_boss
&"bear": return _bear
&"lobby": return _lobby
return null
## All known level ids — shown by `level` in the console.
func level_ids() -> Array[StringName]:
return [&"arena", &"arena_boss", &"bear"]
return [&"arena", &"arena_boss", &"bear", &"lobby"]
## Begin a fresh run: build a new map and place the player at the start gate. Called from
@@ -101,6 +126,11 @@ func start_new_run() -> void:
pending_row = -1
pending_col = -1
debug_level_override = null
# The run opens in the lobby hub; its gates lead into the fights.
enter_lobby = true
lobby_choice = null
cleared = {}
bonus_hp = 0
run_started.emit()
@@ -156,10 +186,50 @@ func run_complete() -> bool:
func select_node(node: MapNode) -> void:
if node == null:
return
enter_lobby = false
pending_row = node.row
pending_col = node.col
## Send the player to the lobby hub instead of a fight — active_level() serves the lobby
## until a gate is entered.
func go_to_lobby() -> void:
enter_lobby = true
lobby_choice = null
## Enter the fight behind a lobby gate: active_level() serves it until the player wins and
## returns to the lobby. Ignored for an unknown id.
func choose_level(id: StringName) -> void:
var l := get_level(id)
if l == null:
return
enter_lobby = false
lobby_choice = l
## Land back in the lobby after a win, banking the cleared level so its follow-on gates
## open (clearing the arena unlocks the bear gate).
func return_to_lobby() -> void:
if lobby_choice != null:
cleared[lobby_choice.id] = true
go_to_lobby()
## Whether the bear gate should be open — the arena must be cleared first.
func bear_gate_open() -> bool:
return cleared.has(&"arena")
## Bank bonus health for the rest of the run, clamped to BONUS_HP_CAP. Returns how many
## pips were actually added (0 once the cap is reached) so the HUD only heals the bull when
## there's headroom — a repeat barrel clear still cheers but grants nothing.
func add_bonus_hp(amount: int) -> int:
var before := bonus_hp
bonus_hp = clampi(bonus_hp + amount, 0, BONUS_HP_CAP)
return bonus_hp - before
## Commit the level just won: move the player onto the pending node (or leave them at the
## start gate after the intro fight, which has no pending node).
func complete_current_level() -> void:
+12
View File
@@ -0,0 +1,12 @@
extends Area3D
## Lobby gate into the arena fight. Always open — the arena is the run's first door.
func _ready() -> void:
body_entered.connect(_on_body_entered)
func _on_body_entered(body: Node3D) -> void:
if not body.is_in_group("player"):
return
Run.choose_level(&"arena")
get_tree().change_scene_to_file(Run.active_level().scene_path)
+1
View File
@@ -0,0 +1 @@
uid://cgwliuslwfmbk
+16
View File
@@ -0,0 +1,16 @@
extends Area3D
## Lobby gate into the Bear's Den. Shut until the arena is cleared (Run.bear_gate_open()),
## which is also what plays the grid-opening animation — so the trigger only fires once the
## gate has actually risen.
func _ready() -> void:
body_entered.connect(_on_body_entered)
func _on_body_entered(body: Node3D) -> void:
if not body.is_in_group("player"):
return
#if not Run.bear_gate_open():
# return
Run.choose_level(&"bear")
get_tree().change_scene_to_file(Run.active_level().scene_path)
+1
View File
@@ -0,0 +1 @@
uid://dn77mjyxllgl6
+218 -86
View File
@@ -1,13 +1,9 @@
extends CharacterBody3D
# WANDER bull outside flee range, roaming freely
# FLEE → bull within range, matador backs away (raycast-steered around walls)
# BRACE → charge detected: plant feet, face the bull (cite phase)
# SIDESTEP→ bull commits: sharp lateral step to let it pass (pase phase)
# ATTACK → post-dodge or mid-range: chase and strike
# ROLL → hit by bull but roll chance fires: survive and recover
# THROW → planted, winding up an overhand throw, then releasing the sword
# RAGDOLL → hit by bull, no roll chance
# WANDER → roam/taunt outside flee range. FLEE → bull close: back away (raycast-steered).
# BRACE → charge detected: plant + face (cite). SIDESTEP → bull commits: lateral pass (pase).
# ATTACK → chase and strike. ROLL → hit but rolled: survive. THROW → wind up + hurl the spear.
# RAGDOLL → hit, no roll.
enum State { WANDER, FLEE, BRACE, SIDESTEP, ATTACK, ROLL, THROW, RAGDOLL }
# The matador's high-level *want*, chosen by a weighted utility vote (see
@@ -32,7 +28,9 @@ var _dodge_cd: float = 0.0
var _will_dodge: bool = true
var _attack_timer: float = 0.0
var _swing_timer: float = 0.0
var _lunge_timer: float = 0.0
var _attack_cd: float = 0.0
var _bull_prev_pos: Vector3 = Vector3.ZERO
var _bull_prev_seen: bool = false
var _roll_timer: float = 0.0
var _roll_dir: Vector3 = Vector3.ZERO
var _is_spawning: bool = false
@@ -52,7 +50,7 @@ var _drawing: bool = false
var _sheathing: bool = false
var _draw_timer: float = 0.0
var _draw_len: float = 0.0
var _sword_blade_area: Area3D = null
var _sword_blade_area: Hitbox = null
var _spear_node: Node3D = null
var _blade_hit_cd: float = 0.0
var _death_player: AudioStreamPlayer = null
@@ -76,8 +74,9 @@ const _ANIM_TAUNTS: Array[StringName] = [&"Taunt", &"Taunt_B", &"Taunt_C"]
# reparents from holster to hand at this point in the animation.
const _DRAW_GRAB_AT: float = 0.55
const _SWORD_SCENE: PackedScene = preload("res://Assets/sword.glb")
const _SPEAR_SCENE: PackedScene = preload("res://Assets/spear.glb")
# Wrapper scenes (glb + an editor-tweakable hitbox / collider) — see Sword.tscn / Spear.tscn.
const _SWORD_SCENE: PackedScene = preload("res://Sword.tscn")
const _SPEAR_SCENE: PackedScene = preload("res://Spear.tscn")
const _GRAVITY: float = 9.8 # arena gravity, for the spear's ballistic arc
@@ -168,6 +167,9 @@ func _physics_process(delta: float) -> void:
_dodge_cd = maxf(0.0, _dodge_cd - delta)
_blade_hit_cd = maxf(0.0, _blade_hit_cd - delta)
_throw_aim_cd = maxf(0.0, _throw_aim_cd - delta)
_attack_cd = maxf(0.0, _attack_cd - delta)
if _bull != null:
_sweep_bull_gore()
if _state != State.RAGDOLL and _bull != null:
_update_ai_state(delta)
@@ -185,9 +187,8 @@ func _physics_process(delta: float) -> void:
_advance_draw(delta)
# Utility-driven brain. The physically committed states (a brace, a pass, a roll, a
# throw wind-up) run to completion on their own timers; from the free states the
# matador re-scores its options every mat_decide_interval and acts on the winner.
# Utility-driven brain. Committed states (brace / pass / roll / throw wind-up) run to completion on
# their own timers; from the free states the matador re-scores every mat_decide_interval.
func _update_ai_state(delta: float) -> void:
if _state == State.BRACE or _state == State.SIDESTEP \
or _state == State.ROLL or _state == State.THROW:
@@ -204,9 +205,8 @@ func _update_ai_state(delta: float) -> void:
_enter_intent(intent)
# Score each intent from weighted heuristics and return the winner. Weights (the
# mat_w_* params) shape the personality; a small commit bonus on the current intent
# stops it flip-flopping between two near-tied options.
# Score each intent from weighted mat_w_* heuristics and return the winner; a small commit bonus on
# the current intent stops it flip-flopping between two near-tied options.
func _choose_intent() -> Intent:
var dist := global_position.distance_to(_bull.global_position)
var bull_flat := Vector3(_bull.velocity.x, 0.0, _bull.velocity.z)
@@ -227,6 +227,9 @@ func _choose_intent() -> Intent:
# A matador won't commit to a strike it can't bail out of, so a spent dodge
# cooldown makes attacking (and dodging outright) less attractive.
var dodge_ready := 1.0 if _dodge_cd <= 0.0 else 0.35
# The post-stab recovery beat (mat_stab_recovery) kills ATTACK outright — the matador circles
# or gives ground between thrusts rather than machine-gunning the bull; DODGE/FLEE stay live.
var attack_ready := 0.0 if _attack_cd > 0.0 else 1.0
var throw_ok := _throw_aim_cd <= 0.0 and is_instance_valid(_sword_node) \
and dist >= DP.f("mat_throw_min_dist") and dist <= DP.f("mat_throw_range")
@@ -247,7 +250,7 @@ func _choose_intent() -> Intent:
# Press the attack; ease off a touch when a charge is barrelling in. Supporting
# matadors barely press — they yield the pass to whoever's engaging.
Intent.ATTACK: DP.f("mat_w_aggression") * (0.45 + 0.55 * close) \
* (1.0 - 0.55 * danger) * dodge_ready * engage_mult,
* (1.0 - 0.55 * danger) * dodge_ready * engage_mult * attack_ready,
# Sidestep / plant against an incoming charge.
Intent.DODGE: DP.f("mat_w_caution") * danger * (1.0 if _dodge_cd <= 0.0 else 0.0),
# Hurl the blade — an occasional ranged flourish from an engaging matador when
@@ -255,7 +258,10 @@ func _choose_intent() -> Intent:
Intent.THROW: (DP.f("mat_w_throw") * (0.35 + 0.65 * (1.0 - close))) \
if (throw_ok and is_engager) else -1.0,
}
score[_intent] = float(score[_intent]) + DP.f("mat_w_commit")
# Commit bonus keeps a near-tied choice from flip-flopping — but don't re-reinforce a
# just-swung ATTACK we're recovering from, or the matador clings to it and spams the bull.
if not (_intent == Intent.ATTACK and _attack_cd > 0.0):
score[_intent] = float(score[_intent]) + DP.f("mat_w_commit")
var best: Intent = Intent.WANDER
var best_score := -INF
@@ -301,9 +307,8 @@ func _enter_intent(intent: Intent) -> void:
_start_throw()
# How many other live matadors are closer to the bull than this one. 0 = the
# closest (the natural lead engager); the utility brain gives the nearest
# mat_engage_slots the go-ahead to press while the rest spread out and taunt.
# How many other live matadors are closer to the bull than this one (0 = the lead engager); the
# brain lets the nearest mat_engage_slots press while the rest spread out and taunt.
func _engagement_rank() -> int:
if _bull == null:
return 0
@@ -347,6 +352,19 @@ func _is_charge_incoming() -> bool:
return bull_flat.normalized().dot(to_me.normalized()) > 0.85
# Bull charging fast and aimed straight at the matador, at ANY range (unlike _is_charge_incoming,
# which is capped to brace range) — so a taunting matador can answer a charge from across the arena.
func _charge_aimed_at_me() -> bool:
var bull_flat := Vector3(_bull.velocity.x, 0.0, _bull.velocity.z)
if bull_flat.length() < DP.f("mat_charge_speed"):
return false
var to_me := global_position - _bull.global_position
to_me.y = 0.0
if to_me.length() < 0.1:
return true
return bull_flat.normalized().dot(to_me.normalized()) > 0.9
# Returns a wall-clear direction, recomputed at most every _STEER_INTERVAL seconds.
# Randomises among available clear angles so juke direction is unpredictable.
func _steer_clear(desired_dir: Vector3, delta: float) -> Vector3:
@@ -407,6 +425,19 @@ func _face_point(point: Vector3, delta: float, rate: float) -> void:
func _tick_wander(delta: float) -> void:
# Plant the feet while drawing / sheathing instead of sliding through the clip.
if _drawing or _sheathing or _idle_timer > 0.0:
# A charge aimed at a taunting matador snaps it out of the pose: hurl a spear at a bull
# barrelling in from range, or switch to the sword (brace/cite) to meet a closer rush.
if _idle_timer > 0.0 and not _drawing and not _sheathing \
and _bull != null and _charge_aimed_at_me():
var dist := global_position.distance_to(_bull.global_position)
var throw_ok := _throw_aim_cd <= 0.0 and is_instance_valid(_sword_node) \
and dist >= DP.f("mat_throw_min_dist") and dist <= DP.f("mat_throw_range")
if dist > DP.f("mat_brace_range") and throw_ok:
_start_throw() # far charge — get the spear off before it arrives
return
if dist <= DP.f("mat_brace_range"):
_start_brace() # closer rush — draw the sword and cite the charge
return
_idle_timer = maxf(0.0, _idle_timer - delta)
_decelerate(10.0, delta)
# Taunt toward the bull so the posturing plays to it, not off into space.
@@ -531,6 +562,7 @@ func _start_attack() -> void:
func _tick_attack(delta: float) -> void:
_attack_timer -= delta
var was_swinging := _swing_timer > 0.0
_swing_timer = maxf(0.0, _swing_timer - delta)
# Plant the feet while drawing instead of sliding toward the bull mid-clip.
if _drawing or _sheathing:
@@ -543,22 +575,41 @@ func _tick_attack(delta: float) -> void:
to_bull.y = 0.0
var dist := to_bull.length()
# Commit to a full swing once in range instead of flipping Run/Attack at the
# distance boundary every frame (the old foot-slide jitter). When the swing
# ends the matador re-closes if the bull slipped away, or stabs again if not.
if _swing_timer <= 0.0 and dist <= DP.f("mat_attack_min_dist") and _sword_in_hand:
# A finished stab enforces a recovery beat (no re-commit for mat_stab_recovery), then decides
# what's next: a landed hit very likely breaks into a taunt/retreat, otherwise the usual roll
# to give ground / circle / throw — anything but instantly drilling the same thrust again.
if was_swinging and _swing_timer <= 0.0:
_attack_cd = DP.f("mat_stab_recovery")
var landed := _sword_blade_area != null and _sword_blade_area.did_hit()
if landed and randf() < DP.f("mat_taunt_after_hit"):
_do_taunt_retreat()
return
if randf() < DP.f("mat_stab_followup_chance"):
_do_stab_followup()
return
# Run in (Run clip) to mat_stab_standoff, then plant and swing on the spot — the standoff sits
# inside the sword's ~3.75 m thrust reach; killing velocity on commit stops the feet sliding.
# The recovery beat gates the next commit so back-to-back stabs can't machine-gun the bull.
if _swing_timer <= 0.0 and _attack_cd <= 0.0 and dist <= DP.f("mat_stab_standoff") and _sword_in_hand:
_swing_timer = _anim_length(_ANIM_ATTACK, 0.9)
_lunge_timer = DP.f("mat_lunge_time")
velocity.x = 0.0
velocity.z = 0.0
# Re-arm fresh each swing — back-to-back stabs commit before the else-branch deactivate runs.
if _sword_blade_area != null:
_sword_blade_area.deactivate()
if _swing_timer > 0.0:
_lunge_timer = maxf(0.0, _lunge_timer - delta)
if _lunge_timer > 0.0 and dist > DP.f("mat_attack_min_dist"):
_accelerate(to_bull.normalized(), DP.f("mat_lunge_speed"), delta)
else:
_decelerate(22.0, delta)
_decelerate(22.0, delta)
_play_anim(_ANIM_ATTACK)
_try_melee_hit(DP.f("mat_stab_reach"))
# Damage off the sword's own BladeHitbox (Sword.tscn), riding the animated blade — gored only
# when the thrust reaches it. Arm at the thrust (mat_stab_strike_at) and sweep for the overlap.
if _sword_blade_area != null and _swing_phase() >= DP.f("mat_stab_strike_at"):
_sword_blade_area.activate()
_sword_blade_area.sweep()
else:
if _sword_blade_area != null:
_sword_blade_area.deactivate()
var dir := _steer_clear(to_bull.normalized(), delta)
_accelerate(dir, DP.f("mat_attack_speed"), delta)
_play_anim(_ANIM_RUN)
@@ -566,6 +617,50 @@ func _tick_attack(delta: float) -> void:
move_and_slide()
# How far through the attack swing: 0 (just committed) → 1 (finished), tracking the clip's progress.
func _swing_phase() -> float:
var length := _anim_length(_ANIM_ATTACK, 0.9)
if length <= 0.0:
return 1.0
return clampf(1.0 - _swing_timer / length, 0.0, 1.0)
# Break off after a stab instead of drilling the same thrust: give ground, hurl a spear, or circle.
# The brain re-engages after; _decide_cd is reset so the pick plays out before it re-scores.
func _do_stab_followup() -> void:
_decide_cd = DP.f("mat_decide_interval")
_dodge_cd = DP.f("mat_dodge_cooldown")
_steer_cd = 0.0
var roll := randf()
if roll < 0.2 and _throw_aim_cd <= 0.0 and is_instance_valid(_sword_node):
_start_throw() # ranged flourish
elif roll < 0.6:
_state = State.FLEE # give ground after the thrust
_intent = Intent.FLEE
else:
_state = State.WANDER # circle to a fresh angle before pressing again
_intent = Intent.WANDER
_pick_wander_target()
# A stab that LANDED: milk it. Break into a long taunt held toward the bull, then drift out to the
# showmanship ring — and lock ATTACK out for the whole hold (_attack_cd) so the brain can't drag the
# matador straight back into another thrust. DODGE/FLEE stay live, so a charging bull is still
# answered. This is what stops the "stab, stab, stab" spam after the matador connects.
func _do_taunt_retreat() -> void:
_state = State.WANDER
_intent = Intent.WANDER
_idle_timer = randf_range(DP.f("mat_taunt_hold") * 0.7, DP.f("mat_taunt_hold") * 1.3)
_idle_anim = _pick_taunt()
_taunt_swap = randf_range(1.5, 3.0)
_attack_cd = maxf(_attack_cd, _idle_timer)
_dodge_cd = DP.f("mat_dodge_cooldown")
_steer_cd = 0.0
_pick_wander_target()
if _sword_blade_area != null:
_sword_blade_area.deactivate()
func _enter_roll(hit_dir: Vector3) -> void:
_state = State.ROLL
# Match the state to the actual clip so the roll plays through once instead of
@@ -579,9 +674,8 @@ func _enter_roll(hit_dir: Vector3) -> void:
_anim_player.seek(0.0, true)
# Called by the spawner (deferred) to make the matador leap-roll toward a target
# point on entry — the cinematic arena entrance. After the roll it transitions to
# normal AI via the standard ROLL → FLEE path.
# Called (deferred) by the spawner to make the matador leap-roll toward a target on entry — the
# cinematic arena entrance. After the roll it transitions to normal AI via the ROLL → FLEE path.
func enter_spawn_roll(toward: Vector3) -> void:
var dir := toward - global_position
dir.y = 0.0
@@ -770,34 +864,84 @@ func _on_body_entered(body: Node3D) -> void:
if not body.is_in_group(&"player"):
return
var player := body as CharacterBody3D
if player.velocity.length() < DP.f("mat_hit_threshold"):
var bull_speed := player.velocity.length()
if bull_speed < DP.f("mat_hit_threshold"):
return
if not _horns_first(player.global_position):
return
var flat_vel := Vector3(player.velocity.x, 0.0, player.velocity.z)
var hit_dir := flat_vel.normalized() if flat_vel.length() > 0.5 else \
(global_position - player.global_position).normalized()
_take_bull_charge(bull_speed, hit_dir)
if randf() < DP.f("mat_roll_chance"):
# Tunnel-proof charge detection: at dash speed the bull skips clean over the thin HitArea between
# ticks, so body_entered never fires. Sweep its actual travel (prev → now) and gore on any pass within
# mat_charge_gore_radius. Runs every frame (even ragdolled) to keep the segment fresh.
func _sweep_bull_gore() -> void:
var now := _bull.global_position
var seg_from := _bull_prev_pos if _bull_prev_seen else now
_bull_prev_pos = now
_bull_prev_seen = true
if _state == State.RAGDOLL or _state == State.ROLL:
return
var flat_vel := Vector3(_bull.velocity.x, 0.0, _bull.velocity.z)
var bull_speed := flat_vel.length()
if bull_speed < DP.f("mat_hit_threshold"):
return
var a := Vector3(seg_from.x, 0.0, seg_from.z)
var b := Vector3(now.x, 0.0, now.z)
var p := Vector3(global_position.x, 0.0, global_position.z)
var closest := Geometry3D.get_closest_point_to_segment(p, a, b)
if p.distance_to(closest) > DP.f("mat_charge_gore_radius"):
return
if not _horns_first(seg_from):
return
var hit_dir := flat_vel.normalized() if bull_speed > 0.5 \
else (global_position - now).normalized()
_take_bull_charge(bull_speed, hit_dir)
# Horns-first gate: gore only when the bull's velocity points within bull_gore_arc of the direction
# from `from` to the matador — not a sideways brush or backing in. The dash ability skips the gate.
func _horns_first(from: Vector3) -> bool:
if _bull == null:
return false
if _bull.has_method(&"is_dashing") and _bull.call(&"is_dashing"):
return true # the dash ability is a committed lunge — it gores on contact, no angle gate
var vel := Vector3(_bull.velocity.x, 0.0, _bull.velocity.z)
if vel.length() < 0.5:
return false
var to_me := global_position - from
to_me.y = 0.0
if to_me.length() < 0.01:
return true
return vel.normalized().dot(to_me.normalized()) > cos(deg_to_rad(DP.f("bull_gore_arc")))
# Resolve a connected charge: the survival roll fades as bull speed climbs (mat_charge_pierce), so a
# committed charge gores rather than getting shrugged off.
func _take_bull_charge(bull_speed: float, hit_dir: Vector3) -> void:
# The boulder roll bowls matadors over with its own launch + chain (player._roll_try_pop); don't
# pre-empt that with a quiet gore, or the ball rolls straight through without popping.
if _bull.has_method(&"is_rolling") and _bull.call(&"is_rolling"):
return
# The dash is a committed lunge — a connect is a guaranteed kill, no survival roll (it already
# bypasses the horns cone). A passive cruise-charge still leaves a roll chance that fades with speed.
var roll_chance := 0.0
if not (_bull.has_method(&"is_dashing") and _bull.call(&"is_dashing")):
var floor_spd := DP.f("mat_hit_threshold")
var full_spd := maxf(DP.f("mat_charge_speed"), floor_spd + 0.1)
var commit := clampf((bull_speed - floor_spd) / (full_spd - floor_spd), 0.0, 1.0)
roll_chance = DP.f("mat_roll_chance") * (1.0 - commit * DP.f("mat_charge_pierce"))
if randf() < roll_chance:
_enter_roll(hit_dir)
else:
_enter_ragdoll(hit_dir, player.velocity.length())
_enter_ragdoll(hit_dir, bull_speed)
func _on_blade_hit(body: Node3D) -> void:
if _state != State.ATTACK and _state != State.SIDESTEP and _state != State.BRACE:
return
if not body.is_in_group(&"player"):
return
if _blade_hit_cd > 0.0:
return
_blade_hit_cd = DP.f("mat_stab_cooldown")
body.call(&"take_sword_hit", "gored")
# Reach-based stab. A charging bull crosses metres per physics frame, so it easily
# tunnels through the thin blade Area between frames — this distance check is the
# reliable hit. Called from the offensive ticks (active swing / pass) whenever the
# blade is drawn: if the bull is inside reach AND the matador is facing it — the
# blade actually presented, not held off to the side — it's gored.
# Reach-based hit for the sidestep PASS (fast lateral sweep — the thin blade Area tunnels, so a
# distance+facing check is the reliable gore; the ATTACK stab uses the blade collider instead).
func _try_melee_hit(reach: float) -> void:
if _blade_hit_cd > 0.0 or not _sword_in_hand or _bull == null:
return
@@ -806,8 +950,6 @@ func _try_melee_hit(reach: float) -> void:
var dist := to_bull.length()
if dist > reach or dist < 0.01:
return
# Only lands within the frontal arc — you're gored on a presented blade, not by
# brushing a matador whose sword is pointing elsewhere.
var facing := Vector3(sin(_mesh.rotation.y), 0.0, cos(_mesh.rotation.y))
if facing.dot(to_bull / dist) < cos(deg_to_rad(DP.f("mat_stab_arc"))):
return
@@ -817,8 +959,8 @@ func _try_melee_hit(reach: float) -> void:
func _enter_ragdoll(hit_dir: Vector3, bull_speed: float, up_boost: float = 0.0) -> void:
_state = State.RAGDOLL
if _sword_blade_area:
_sword_blade_area.monitoring = false
if _sword_blade_area != null:
_sword_blade_area.deactivate()
_clear_spear() # a spear mid-wind-up dies with the matador, not in the air
killed.emit()
var cleanup_timer := get_tree().create_timer(4.0)
@@ -1011,10 +1153,9 @@ func _pick_wander_target() -> void:
# ── Sword attachment ──────────────────────────────────────────────────────────
# The rig (matador_v03) carries two purpose-built bones: weapon_bone (right-hand
# grip) and weapon_rest_bone (hip holster). The sword rides in the holster and is
# carried to the hand in combat (see _carry_sword); each bone has its own DP-tunable
# local offset/rotation (sword_* / sword_rest_*) so the poses seat independently.
# The rig (matador_v03) carries two bones: weapon_bone (right-hand grip) and weapon_rest_bone (hip
# holster). The sword rides in the holster, carried to the hand in combat (_carry_sword); each bone
# has its own DP-tunable offset/rotation (sword_* / sword_rest_*) so the poses seat independently.
func _setup_sword() -> void:
if not _skeleton:
return
@@ -1047,28 +1188,15 @@ func _spawn_sword() -> void:
_drawing = false
_apply_sword_grip()
# Blade collider along +Z (hilt at origin), tipped from the capsule's default Y.
# Only monitors while the sword is in hand (see _carry_sword).
var blade_cap := CapsuleShape3D.new()
blade_cap.radius = 0.18
blade_cap.height = 1.30
var blade_cs := CollisionShape3D.new()
blade_cs.shape = blade_cap
blade_cs.position = Vector3(0.0, 0.0, 0.8)
blade_cs.rotation_degrees = Vector3(90.0, 0.0, 0.0)
_sword_blade_area = Area3D.new()
_sword_blade_area.collision_layer = 0
_sword_blade_area.collision_mask = 1
_sword_blade_area.monitoring = _sword_in_hand
_sword_blade_area.add_child(blade_cs)
_sword_node.add_child(_sword_blade_area)
_sword_blade_area.body_entered.connect(_on_blade_hit)
# The blade hitbox (Sword.tscn, hitbox.gd) is armed only during the ATTACK thrust (see
# _tick_attack); off while merely carried, so brushing a drawn matador never gores the bull.
_sword_blade_area = _sword_node.get_node_or_null("BladeHitbox") as Hitbox
if _sword_blade_area != null:
_sword_blade_area.deactivate()
# The sword is MELEE-only: drawn while fighting up close (ATTACK) or guarding
# (BRACE / SIDESTEP), holstered otherwise. Ranged throws use a spear instead
# (see _spawn_spear_in_hand), so THROW keeps the sword holstered.
# The sword is MELEE-only: drawn for ATTACK / BRACE / SIDESTEP, holstered otherwise. Ranged throws
# use a spear (_spawn_spear_in_hand), so THROW keeps the sword holstered.
func _wants_sword_drawn() -> bool:
return _state == State.ATTACK \
or _state == State.BRACE or _state == State.SIDESTEP
@@ -1077,6 +1205,9 @@ func _wants_sword_drawn() -> bool:
func _update_sword_carry() -> void:
if not is_instance_valid(_sword_node) or _state == State.RAGDOLL:
return
# The blade collider lives only during the ATTACK thrust; leaving ATTACK disarms it.
if _state != State.ATTACK and _sword_blade_area != null:
_sword_blade_area.deactivate()
if _wants_sword_drawn():
if not _sword_in_hand and not _drawing:
_begin_draw()
@@ -1156,8 +1287,9 @@ func _carry_sword(in_hand: bool) -> void:
_sword_in_hand = in_hand
_sword_node.reparent(target, false)
_apply_sword_grip()
if _sword_blade_area:
_sword_blade_area.monitoring = in_hand
# Carrying never arms the blade — only the ATTACK thrust does (see _tick_attack).
if _sword_blade_area != null:
_sword_blade_area.deactivate()
func _apply_sword_grip() -> void:
+10 -3
View File
@@ -4,6 +4,8 @@ extends RefCounted
## limited swing/twist (DP-tunable) so the corpse keeps its silhouette instead of
## folding into a flat "deflated" pile; the cape stays free (PIN) so it drapes.
const PhysicsLayers = preload("res://physics_layers.gd")
# [bone, radius] → sphere collider; [bone, radius, height] → capsule.
const _BONES: Array = [
["matador", 0.18],
@@ -53,10 +55,15 @@ static func build(skeleton: Skeleton3D) -> PhysicalBoneSimulator3D:
pb.bone_name = bname
pb.mass = 0.4
pb.linear_damp = 0.1
pb.collision_layer = 1
pb.collision_mask = 1
# The ragdoll only simulates once the matador is dead, so it lives on the CORPSE
# layer and masks to CORPSE alone: it rests on the ground/walls (which also carry
# CORPSE) but the bull — which collides only with WORLD — passes straight through
# the bodies instead of tripping over them.
pb.collision_layer = PhysicsLayers.CORPSE
pb.collision_mask = PhysicsLayers.CORPSE
if bname.begins_with("Bone"):
# Cape: floppy cloth — free swing, light, draggy, one-way collision.
# Cape: floppy cloth — free swing, light, draggy, one-way collision (layer 0
# so nothing collides with it; it still drapes on the CORPSE-masked ground).
pb.joint_type = PhysicalBone3D.JOINT_TYPE_PIN
pb.mass = 0.15
pb.linear_damp = 0.5
+11
View File
@@ -0,0 +1,11 @@
## Central registry of the 3D physics collision-layer bits. These mirror the
## layer_names in project.godot so the editor's layer picker reads the same words.
##
## The bull only collides with WORLD, so a killed matador is lifted off WORLD onto
## CORPSE alone (see matador_ragdoll.gd). The ground and walls carry WORLD | CORPSE
## (tagged at level load in game_shell.gd), so the ragdoll still rests on the arena
## while the bull passes through the bodies instead of tripping over them.
const WORLD: int = 1 # layer 1 — environment + live actors (bull, matadors, spears)
const BULL: int = 2 # layer 2 — the bull's own body
const CORPSE: int = 4 # layer 3 — ragdolled matadors; ground/walls also carry this
+1
View File
@@ -0,0 +1 @@
uid://d01o2ul83waw5
+111 -15
View File
@@ -67,6 +67,9 @@ signal health_changed(current: int, max_hp: int)
signal hit_taken(cause: String)
var _max_hp: int = 10
var _hp: int = 10
# Bonus pips granted by lobby rewards (e.g. smashing every barrel). Tacked on top of the
# base bar; the HUD paints these top pips yellow instead of red.
var _bonus_hp: int = 0
var _hit_iframes: float = 0.0
var _huff_player: AudioStreamPlayer = null
@@ -93,6 +96,11 @@ func _ready() -> void:
RigidSkin.convert_tree(self)
_max_hp = maxi(1, int(DP.f("bull_max_hp")))
_hp = _max_hp
# Carry any run-long bonus pips (barrel reward) into this level so they survive the
# scene reload between fights; the HUD paints these top pips yellow.
_bonus_hp = Run.bonus_hp
_max_hp += _bonus_hp
_hp += _bonus_hp
_cube_scale = cube_guy.scale
_setup_hoof_dust()
_setup_legs()
@@ -511,6 +519,7 @@ func _tick_roll(delta: float, _steer: Vector3) -> void:
move_and_slide()
_was_on_floor = is_on_floor()
_smash_barrels_in_radius(DP.f("roll_hit_radius"))
_roll_try_pop(speed)
@@ -549,22 +558,37 @@ func _roll_try_pop(speed: float) -> bool:
return false
# Closest active matador we haven't already popped this roll, or null if none left.
# Closest thing the roll should home on — an active matador (arena) or an intact barrel
# (lobby) we haven't already smashed this roll. Null if nothing is left to hit.
func _roll_pick_target() -> Node3D:
var best: Node3D = null
var best_d := INF
for mat: Node in get_tree().get_nodes_in_group(&"matador"):
if _roll_hit.has(mat) or not _mat_active(mat):
continue
var d: float = (mat as Node3D).global_position.distance_squared_to(global_position)
for cand: Node3D in _roll_targets():
var d: float = cand.global_position.distance_squared_to(global_position)
if d < best_d:
best_d = d
best = mat as Node3D
best = cand
return best
# Live roll targets: active matadors plus standing barrels, minus anything already popped.
func _roll_targets() -> Array[Node3D]:
var out: Array[Node3D] = []
for mat: Node in get_tree().get_nodes_in_group(&"matador"):
if not _roll_hit.has(mat) and _mat_active(mat):
out.append(mat as Node3D)
for barrel: Node in get_tree().get_nodes_in_group(&"barrel"):
if _barrel_alive(barrel):
out.append(barrel as Node3D)
return out
func _roll_target_valid() -> bool:
return is_instance_valid(_roll_target) and _mat_active(_roll_target)
if not is_instance_valid(_roll_target):
return false
if _roll_target.is_in_group(&"barrel"):
return _barrel_alive(_roll_target)
return _mat_active(_roll_target)
# A matador still in play — valid, not ragdolled/consumed. Ragdolled bodies report
@@ -573,8 +597,39 @@ func _mat_active(mat: Node) -> bool:
return is_instance_valid(mat) and mat.has_method(&"is_active") and mat.call(&"is_active")
# End the Powerball early: brake hard (the ball "pops" and unrolls) and drop back to
# the normal locomotion path next frame.
# A lobby barrel still standing — valid and not already queued for removal by an earlier hit.
func _barrel_alive(barrel: Node) -> bool:
return is_instance_valid(barrel) and not barrel.is_queued_for_deletion()
# Burst every barrel whose centre sits within range_m on the ground plane. Shared by the
# boulder roll (which ploughs straight through them) and the slam shockwave. Each barrel
# self-removes and leaves the &"barrel" group, so the HUD's clear-the-lobby tally counts it
# exactly once.
func _smash_barrels_in_radius(range_m: float) -> void:
for barrel: Node in get_tree().get_nodes_in_group(&"barrel"):
if not _barrel_alive(barrel):
continue
var to_b: Vector3 = (barrel as Node3D).global_position - global_position
to_b.y = 0.0
if to_b.length() <= range_m:
barrel.call(&"destroy_barrel")
# True while the boulder roll is live — matadors defer their charge-gore to the roll's own pop
# (is_rolling guard in matador._take_bull_charge) so the ball pops instead of quietly goring.
func is_rolling() -> bool:
return _active_ability == 3 and _ability_active
# True while the dash ability is live. A dash is a committed lunge — it gores/rams on contact
# regardless of angle (enemies bypass their horns-first cone while it's set).
func is_dashing() -> bool:
return _active_ability == 1 and _ability_active
# End the Powerball early: brake hard (the ball "pops" and unrolls) and drop back to the normal
# locomotion path next frame.
func _end_roll() -> void:
_ability_active = false
_active_ability = -1
@@ -1019,13 +1074,15 @@ func _physics_process(delta: float) -> void:
cube_guy.rotation.y = lerp_angle(
cube_guy.rotation.y, target_angle, delta * DP.f("visual_turn_speed"))
# Looping DASH clip while genuinely moving on the ground, idle otherwise.
# Looping WALK clip while genuinely moving on the ground, idle otherwise.
_update_locomotion_anim(on_floor and flat_speed > 1.0)
_pre_slide_vel_y = velocity.y
var pre_wall_vel := Vector3(velocity.x, 0.0, velocity.z)
move_and_slide()
# ── Wall bounce — no sliding, guaranteed exit ────────────────────────────
# pre_wall_vel is captured before move_and_slide strips the into-wall component,
# so into_spd correctly reflects how hard the bull hit the wall even when stationary.
@@ -1041,11 +1098,23 @@ func _physics_process(delta: float) -> void:
velocity.z = flat_n.z * exit_spd
pre_wall_vel = Vector3(velocity.x, 0.0, velocity.z)
# ── Bounce on landing ─────────────────────────────────────────────────────
# --- ADD THIS BREAKABLE BARREL DETECTION CODE ---
var collision = get_slide_collision(i)
var collider = collision.get_collider()
# Check if the object we hit has the "destroy_barrel" function
if collider and collider.has_method("destroy_barrel"):
# Optional: Only break if moving fast (e.g., sprinting or dashing)
# if velocity.length() > 5.0:
collider.destroy_barrel()
# ── Landing. Don't bounce ─────────────────────────────────────────────────────
if is_on_floor() and not _was_on_floor:
var impact := -_pre_slide_vel_y
if impact > DP.f("bounce_min_impact") and not _slam_pending:
velocity.y = impact * DP.f("bounce_restitution")
velocity.y = 0.0
#Bouncing landing below
#var impact := -_pre_slide_vel_y
#if impact > DP.f("bounce_min_impact") and not _slam_pending:
#velocity.y = impact * DP.f("bounce_restitution")
# ── Slam landing ──────────────────────────────────────────────────────────
if _slam_pending and is_on_floor() and not _was_on_floor:
@@ -1058,6 +1127,7 @@ func _physics_process(delta: float) -> void:
_play_idle()
_spawn_slam_fx()
_hit_matadors_radius(DP.f("slam_range"), DP.f("slam_strength"), DP.f("slam_launch_up"))
_smash_barrels_in_radius(DP.f("slam_range"))
# ── Dust ──────────────────────────────────────────────────────────────────
if flat_speed > DP.f("dust_charge_spd") and on_floor:
@@ -1084,6 +1154,22 @@ func get_max_hp() -> int:
return _max_hp
# Bonus pips currently on the bar — the HUD colours this many top pips yellow.
func get_bonus_hp() -> int:
return _bonus_hp
# Award extra health (from a lobby reward): grows both the cap and the current bar so the
# new pips arrive full, and marks them as bonus so the HUD paints them yellow.
func grant_bonus_hp(amount: int) -> void:
if amount <= 0:
return
_bonus_hp += amount
_max_hp += amount
_hp += amount
health_changed.emit(_hp, _max_hp)
# A clean hit — thrown or swung blade — costs the bull one HP pip; the run ends only
# when the last pip is gone. `cause` ("gored" / "thrown") tags how it happened for the
# death notice. I-frames absorb a flurry so several blades in one pass drop one pip,
@@ -1097,6 +1183,10 @@ func take_sword_hit(cause: String = "", hit_pos: Vector3 = Vector3.ZERO) -> void
health_changed.emit(_hp, _max_hp)
hit_taken.emit(cause)
camera_pivot.call(&"trigger_hit", 0.7)
# Vibrate controller 0 with half weak strength, full strong strength, for 0.5 seconds
if DP.b("gamepad_vibration"):
Input.start_joy_vibration(0, 0.5, 1, 0.2)
# A spear gores a spot — blood spurts from the entry wound (where it struck the
# bull). Melee gores pass no position and skip the spurt; gore can be turned off.
if cause == "thrown" and Settings.gore:
@@ -1112,6 +1202,12 @@ func take_sword_hit(cause: String = "", hit_pos: Vector3 = Vector3.ZERO) -> void
died.emit(cause)
# Pop the bull upward — a smash hitbox knocks it off its feet. Only ever raises the
# vertical speed so a downward-moving bull still gets launched.
func apply_knock_up(v: float) -> void:
velocity.y = maxf(velocity.y, v)
# Blood spurt from a spear wound: a short-lived spray of dark-red gobs flung out of the
# entry point, biased outward from the bull's centre (so it reads as bursting from the
# hide) with a touch of lift before gravity drags it down.
@@ -1153,7 +1249,7 @@ func _spawn_blood(hit_pos: Vector3) -> void:
p.global_position = hit_pos
p.restart()
_free_after(p, 1.5)
#hit flashing
func _hit_flash() -> void:
+11 -3
View File
@@ -12,7 +12,7 @@ config_version=5
config/name="Bullosseum"
config/version="0.2.0"
run/main_scene="res://MainMenu.tscn"
run/main_scene="uid://bmnmenu0intr1"
config/features=PackedStringArray("4.7", "GL Compatibility")
boot_splash/bg_color=Color(0, 0, 0, 1)
boot_splash/image="res://Assets/loading_screen.png"
@@ -75,13 +75,13 @@ move_right={
zoom_in={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":8,"position":Vector2(726, 8),"global_position":Vector2(735, 56),"factor":1.0,"button_index":4,"canceled":false,"pressed":true,"double_click":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":6,"pressure":0.0,"pressed":false,"script":null)
]
}
zoom_out={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":16,"position":Vector2(400, 21),"global_position":Vector2(409, 69),"factor":1.0,"button_index":5,"canceled":false,"pressed":true,"double_click":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":4,"pressure":0.0,"pressed":false,"script":null)
]
}
toggle_mouse_capture={
@@ -118,6 +118,13 @@ ability_roll={
pointing/emulate_touch_from_mouse=true
[layer_names]
3d_physics/layer_1="world"
3d_physics/layer_2="bull"
3d_physics/layer_3="corpse"
3d_physics/layer_4="bear_FX"
[physics]
3d/physics_engine="Jolt Physics"
@@ -128,3 +135,4 @@ rendering_device/driver.windows="opengl3"
renderer/rendering_method="gl_compatibility"
textures/vram_compression/import_s3tc_bptc=true
textures/vram_compression/import_etc2_astc=true
environment/defaults/default_clear_color=Color(0, 0, 0, 1)
+1 -1
View File
@@ -30,7 +30,7 @@ script = ExtResource("13_shell")
[node name="Player" parent="." unique_id=332720469 instance=ExtResource("1_ulcgi")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.2416196, 5.1711025, -4.841382)
[node name="Camera3D" parent="Player" index="3" unique_id=1120161087]
[node name="Camera3D" parent="Player" index="1" unique_id=1120161087]
attributes = SubResource("CameraAttributesPractical_73fnb")
fov = 50.0
near = 2.636
+25 -2
View File
@@ -10,6 +10,8 @@ extends RigidBody3D
# (see shed_all, which the bull's slam calls to fling them all off); other hits pin
# it in place until the despawn timer clears it.
const PhysicsLayers = preload("res://physics_layers.gd")
const _DESPAWN_SEC: float = 8.0
const _STUCK_GROUP: StringName = &"stuck_spear"
# Shaft geometry in spear.glb local space: tip at +Z, butt behind the origin.
@@ -34,16 +36,25 @@ static func launch(parent: Node, mesh: Node3D, origin: Vector3, velocity: Vector
var s := SpearProjectile.new()
s.gravity_scale = gravity
s.collision_layer = 0
s.collision_mask = 1
# Mask WORLD so a miss sticks in the arena, and BULL so it can actually hit the
# bull — the bull's body is on layer BULL, not WORLD, so a WORLD-only mask flew
# straight through it (every throw whiffed, even against a stationary bull).
s.collision_mask = PhysicsLayers.WORLD | PhysicsLayers.BULL
s.contact_monitor = true
s.max_contacts_reported = 6
parent.add_child(s)
# Seat the body so its local +Z (the shaft, see spear.glb) points along the throw.
s.global_transform = Transform3D(_aim_basis(velocity), origin)
# Take the editor-tweakable collider from the spear wrapper (Spear.tscn's HitShape)
# before reparenting, then drop the now-nested template.
var collider := _collider_from(mesh)
mesh.reparent(s, false)
mesh.transform = Transform3D.IDENTITY
s._mesh = mesh
s.add_child(_shaft_collider())
var tmpl := mesh.get_node_or_null("HitShape")
if tmpl != null:
tmpl.queue_free()
s.add_child(collider)
s.linear_velocity = velocity
_despawn(s)
return s
@@ -84,6 +95,18 @@ static func shed_all(bull: Node) -> void:
_despawn(rb)
# Clone the wrapper's editor-tweakable HitShape (Spear.tscn) into a fresh CollisionShape3D
# for the projectile body; falls back to the built-in shaft collider if it's missing.
static func _collider_from(source: Node) -> CollisionShape3D:
var tmpl := source.get_node_or_null("HitShape") as CollisionShape3D
if tmpl != null and tmpl.shape != null:
var cs := CollisionShape3D.new()
cs.shape = tmpl.shape
cs.transform = tmpl.transform
return cs
return _shaft_collider()
static func _shaft_collider() -> CollisionShape3D:
# Collider along local +Z (mesh runs z≈-0.34 … 1.92), fattened so a fast throw
# can't tunnel past the bull's collision spheres.
+25
View File
@@ -0,0 +1,25 @@
extends CharacterBody3D
## Stand-in bull for the combat tests. As a TARGET it records hitbox callbacks (hits / knock-up);
## as an ATTACKER it exposes the ability-state interface (is_dashing / is_rolling) the matador and
## bear query. Ability flags default off = an ordinary charge.
var hits: int = 0
var knocked_up: float = 0.0
var dashing: bool = false
var rolling: bool = false
func take_sword_hit(_cause: String = "", _hit_pos: Vector3 = Vector3.ZERO) -> void:
hits += 1
func apply_knock_up(v: float) -> void:
knocked_up = maxf(knocked_up, v)
func is_dashing() -> bool:
return dashing
func is_rolling() -> bool:
return rolling
+1
View File
@@ -0,0 +1 @@
uid://bamw0bnk3bfvs
+98
View File
@@ -0,0 +1,98 @@
extends SceneTree
## Bear attack-FX test. The four attack effects (crater, smash debris, left/right claw slash)
## live in Assets/fx/Bear_FX.glb as meshes that rest at scale 0 at Siim's baked positions. The
## GLB carries its own AnimationPlayer whose clips scale one mesh up at its strike frame and
## back to 0 (self-hiding) while pinning the others at 0. bear.gd fires the matching clip on
## each strike (see _play_fx). This asserts each clip pops its own mesh, self-hides by the end,
## and never leaves another effect on-screen — so a mis-wired trigger or a broken clip is caught
## headlessly. Run: godot --headless --script res://tests/bear_fx_test.gd
var _pass := 0
var _fail := 0
var _fx_player: AnimationPlayer = null
var _fx: Dictionary = {} # short name -> Node3D
func _init() -> void:
_run.call_deferred()
func _ok(c: bool, m: String) -> void:
if c:
_pass += 1
print(" PASS: ", m)
else:
_fail += 1
print(" FAIL: ", m)
func _run() -> void:
var bear := (load("res://Bear.tscn") as PackedScene).instantiate()
root.add_child(bear)
await physics_frame
var fx_root := bear.find_child("Bear_FX", true, false)
_ok(fx_root != null, "Bear_FX instanced in the scene")
if fx_root == null:
_finish()
return
_fx_player = fx_root.get_node_or_null("AnimationPlayer") as AnimationPlayer
_ok(_fx_player != null, "found the Bear_FX AnimationPlayer")
if _fx_player == null:
_finish()
return
for n: String in ["jump_smash", "smash_hit", "claw_attack_R", "claw_attack_L"]:
_fx[n] = bear.find_child("Bear_fx_" + n, true, false)
_ok(_fx[n] != null, "found Bear_fx_" + n)
if _fx.values().has(null):
_finish()
return
_ok(not _vis("jump_smash") and not _vis("smash_hit")
and not _vis("claw_attack_R") and not _vis("claw_attack_L"),
"all FX hidden at rest (scale 0)")
# Each clip pops only its own mesh at the strike, then self-hides, leaving nothing stale.
await _check_clip("Bear_fx_claw_attack_L", "claw_attack_L")
await _check_clip("Bear_fx_claw_attack_R", "claw_attack_R")
await _check_clip("Bear_fx_smash_hit", "smash_hit")
await _check_clip("Bear_fx_jump_smash", "jump_smash")
_finish()
# Play a clip to completion in real process mode (so bear.gd's animation_finished hide runs):
# the clip's own mesh scales up somewhere in the middle, every other mesh stays hidden, and the
# mesh is back to scale 0 once the clip has finished.
func _check_clip(clip: String, owner_key: String) -> void:
_fx_player.play(clip)
_fx_player.seek(0.0, true)
var peak := 0.0
var others_clean := true
var frames := 0
while _fx_player.is_playing() and frames < 600:
await process_frame
frames += 1
peak = maxf(peak, (_fx[owner_key] as Node3D).scale.length())
for k: String in _fx.keys():
if k != owner_key and _vis(k):
others_clean = false
# Hide happens on animation_finished (immediately for most, after a linger for the crater),
# so poll a bounded window rather than assume it's gone on the very next frame.
var settle := 0
while _vis(owner_key) and settle < 600:
await process_frame
settle += 1
_ok(peak > 0.05, clip + ": its mesh pops during the clip")
_ok(others_clean, clip + ": no other effect shows while it plays")
_ok(not _vis(owner_key), clip + ": hidden again after the clip ends")
func _vis(n: String) -> bool:
return (_fx[n] as Node3D).scale.length() > 0.05
func _finish() -> void:
print("Results: %d passed, %d failed" % [_pass, _fail])
quit(1 if _fail > 0 else 0)
+1
View File
@@ -0,0 +1 @@
uid://duyfxhca4np78
+121
View File
@@ -0,0 +1,121 @@
extends SceneTree
## Bear attack-collider test. The colliders + their motion live in BearAttackHitboxes.tscn: the
## leap slam is a ground circle (cylinder) whose "leap_slam" clip pops it open; the overhead smash
## is a forward box lane whose "smash_travel" clip grows it out from the bear. bear.gd fires the
## clip, arms the knock-up shaping, and sweeps while it runs. This asserts: a bull anywhere in the
## leap circle is mauled AND launched by default (bear_leap_ring_frac 0), while raising ring_frac
## carves a grounded inner zone; the smash lane catches bulls near AND far as the front travels,
## throws the further one higher, and spares anything off the lane.
## Run: godot --headless --script res://tests/bear_hitbox_test.gd
var _pass := 0
var _fail := 0
func _init() -> void:
_run.call_deferred()
func _ok(c: bool, m: String) -> void:
if c:
_pass += 1
print(" PASS: ", m)
else:
_fail += 1
print(" FAIL: ", m)
func _make_bull(pos: Vector3) -> CharacterBody3D:
var b := CharacterBody3D.new()
b.collision_layer = 2 # PhysicsLayers.BULL — what the hitboxes mask
b.collision_mask = 0
b.add_to_group(&"player")
b.set_script(load("res://tests/_fake_bull.gd"))
var cs := CollisionShape3D.new()
var shape := SphereShape3D.new()
shape.radius = 0.6
cs.shape = shape
b.add_child(cs)
root.add_child(b)
b.global_position = pos
return b
# Drive one attack collider clip to completion, sweeping each physics frame like _physics_process.
func _drive(bear: Node, fire: String) -> void:
bear.call(fire)
for i in 60:
bear.call("_tick_attack_hitbox")
await physics_frame
if bear.get("_active_hitbox") == null:
break
func _run() -> void:
var bear := (load("res://Bear.tscn") as PackedScene).instantiate() as Node3D
root.add_child(bear)
bear.set_physics_process(false) # freeze the AI; we fire the colliders ourselves
await physics_frame
var leap_hb := bear.find_child("LeapSlamHitbox", true, false) as Area3D
var smash_hb := bear.find_child("SmashHitbox", true, false) as Area3D
_ok(leap_hb != null, "leap slam cylinder hitbox exists (from BearAttackHitboxes.tscn)")
_ok(smash_hb != null, "overhead smash lane hitbox exists (from BearAttackHitboxes.tscn)")
if leap_hb == null or smash_hb == null:
_finish()
return
var dp := root.get_node("/root/DP")
var slam_r: float = (leap_hb.get_node("CollisionShape3D").shape as CylinderShape3D).radius
var lane: float = (smash_hb.get_node("CollisionShape3D").shape as BoxShape3D).size.z
# ── Leap slam: by default (bear_leap_ring_frac 0) the bull is launched from ANYWHERE in the
# circle — no safe inner spot. Off the circle is still spared.
dp.call("set_value", "bear_leap_ring_frac", 0.0)
var center := _make_bull(Vector3(0.0, 0.5, 0.0))
var midring := _make_bull(Vector3(slam_r * 0.5, 0.5, 0.0))
var outside := _make_bull(Vector3(slam_r + 3.0, 0.5, 0.0))
await physics_frame
await _drive(bear, "_fire_leap_hitbox")
_ok(center.hits >= 1 and center.knocked_up > 0.0, "bull at the circle center is mauled AND launched")
_ok(midring.hits >= 1 and midring.knocked_up > 0.0, "bull mid-circle is mauled AND launched")
_ok(outside.hits == 0, "bull outside the slam radius is spared")
center.queue_free()
midring.queue_free()
outside.queue_free()
await physics_frame
# Raising ring_frac restores a grounded inner zone that only mauls (the slider still works).
dp.call("set_value", "bear_leap_ring_frac", 0.75)
var frac: float = dp.f("bear_leap_ring_frac")
var inner := _make_bull(Vector3(slam_r * (frac * 0.5), 0.5, 0.0))
var ring := _make_bull(Vector3(slam_r * (frac + (1.0 - frac) * 0.5), 0.5, 0.0))
await physics_frame
await _drive(bear, "_fire_leap_hitbox")
_ok(inner.hits >= 1 and inner.knocked_up == 0.0, "raised ring_frac keeps the inner circle grounded")
_ok(ring.knocked_up > 0.0, "raised ring_frac still launches the outer ring")
inner.queue_free()
ring.queue_free()
dp.call("set_value", "bear_leap_ring_frac", 0.0)
await physics_frame
# ── Overhead smash: the lane's leading edge travels the whole way, so bulls near AND far are
# both caught as the front passes; the further one is thrown higher. Off-lane is spared.
var near := _make_bull(Vector3(0.0, 0.5, lane * 0.2))
var far := _make_bull(Vector3(0.0, 0.5, lane * 0.8))
var beside := _make_bull(Vector3(lane * 0.5, 0.5, lane * 0.5))
var behind := _make_bull(Vector3(0.0, 0.5, -3.0))
await physics_frame
await _drive(bear, "_begin_smash_hitbox")
_ok(near.hits >= 1, "bull near the bear is caught as the shockwave starts")
_ok(far.hits >= 1, "bull far down the lane is caught when the front reaches it")
_ok(far.knocked_up > near.knocked_up, "the further hit is thrown higher")
_ok(beside.hits == 0, "bull beside the lane is spared (a lane, not a circle)")
_ok(behind.hits == 0, "bull behind the bear is spared")
_finish()
func _finish() -> void:
print("Results: %d passed, %d failed" % [_pass, _fail])
quit(1 if _fail > 0 else 0)
+1
View File
@@ -0,0 +1 @@
uid://cvweb2dnv23s
+112
View File
@@ -0,0 +1,112 @@
extends SceneTree
## Bear ram test. Running the bull HORNS-FIRST into the bear should wound it. The bear detects this by
## sweeping the bull's actual travel (prev → now) against its body each frame (bear._sweep_bull_ram),
## gated by speed (bear_hit_threshold), reach (bear_ram_reach) and a horns-first cone (bull_gore_arc),
## and edge-triggered so one charge = one wound. This drives passes against a frozen bear and asserts:
## a horns-first charge (even one that tunnels / starts close) wounds it once; a charge moving AWAY
## (bear behind the horns), a pass out of reach, and a too-slow nudge all leave it unharmed.
## Run: godot --headless --script res://tests/bear_ram_test.gd
var _pass := 0
var _fail := 0
func _init() -> void:
_run.call_deferred()
func _ok(c: bool, m: String) -> void:
if c:
_pass += 1
print(" PASS: ", m)
else:
_fail += 1
print(" FAIL: ", m)
func _make_bull() -> CharacterBody3D:
var b := CharacterBody3D.new()
b.set_script(load("res://tests/_fake_bull.gd")) # exposes is_dashing()/is_rolling()
b.collision_layer = 2
b.collision_mask = 0
b.add_to_group(&"player")
var cs := CollisionShape3D.new()
var shape := CapsuleShape3D.new()
shape.radius = 0.75
shape.height = 1.845
cs.shape = shape
b.add_child(cs)
root.add_child(b)
return b
# Sweep the bull from `from` to `to` at `speed` (velocity along the travel), reseting the bear's ram
# edge-state first so each pass is isolated. The prev → now segment is what the bear tests against.
func _ram_pass(bear: Node, bull: CharacterBody3D, speed: float, from: Vector3, to: Vector3) -> void:
bear.set("_bull_prev_seen", false)
bear.set("_bull_ramming", false)
var dir := to - from
dir.y = 0.0
bull.velocity = dir.normalized() * speed if dir.length() > 0.01 else Vector3.ZERO
bull.global_position = from
bear.call("_sweep_bull_ram")
bull.global_position = to
bear.call("_sweep_bull_ram")
func _run() -> void:
var bull := _make_bull()
var bear := (load("res://Bear.tscn") as PackedScene).instantiate() as Node3D
root.add_child(bear)
bear.global_position = Vector3.ZERO
bear.set_physics_process(false) # freeze the AI; we drive the ram sweep ourselves
await physics_frame
bear.call("_acquire_bull")
var dp := root.get_node("/root/DP")
var reach: float = dp.f("bear_ram_reach")
var thr: float = dp.f("bear_hit_threshold")
_ok(bear.get("_bull") == bull, "bear acquired the bull")
# (a) Horns-first charge straight through the bear — endpoints (3 m) sit outside the reach, so
# only the swept test catches the pass-through.
var hp0: int = bear.get("_hp")
_ok(3.0 > reach, "test pass tunnels: endpoints (3 m) exceed the ram reach (%.2f m)" % reach)
_ram_pass(bear, bull, 66.0, Vector3(-3, 0, 0), Vector3(3, 0, 0))
_ok(bear.get("_hp") == hp0 - 1, "a horns-first charge wounds the bear once")
# (b) One charge = one wound: sweeping the same charge again without disengaging doesn't re-hit
# mid-contact (edge-triggered). Re-seed as if the bull never left the ram — no reset.
var hp1: int = bear.get("_hp")
bull.velocity = Vector3(66, 0, 0)
bull.global_position = Vector3(0.2, 0, 0) # still on top of the bear, still charging
bear.call("_sweep_bull_ram")
_ok(bear.get("_hp") == hp1, "a sustained charge doesn't drain the bear frame-by-frame")
# (c) Charging AWAY (bear behind the horns) is not a horns-first ram, even up close.
var hp2: int = bear.get("_hp")
_ram_pass(bear, bull, 66.0, Vector3(0.5, 0, 0), Vector3(4, 0, 0))
_ok(bear.get("_hp") == hp2, "a charge moving away from the bear leaves it unharmed")
# (d) A fast pass wide of the bear (out of reach) is spared.
_ram_pass(bear, bull, 66.0, Vector3(-3, 0, 3), Vector3(3, 0, 3))
_ok(bear.get("_hp") == hp2, "a charge that passes wide of the bear is spared")
# (e) A slow nudge below the hit threshold is shrugged off.
_ram_pass(bear, bull, thr - 1.0, Vector3(-3, 0, 0), Vector3(3, 0, 0))
_ok(bear.get("_hp") == hp2, "a nudge below the hit threshold doesn't wound the bear")
# (f) The DASH ability bypasses the horns-first cone: the same charge-away pass that (c) shrugged
# off DOES wound the bear while dashing (a committed lunge rams on contact).
var hp3: int = bear.get("_hp")
bull.set("dashing", true)
_ram_pass(bear, bull, 66.0, Vector3(0.5, 0, 0), Vector3(4, 0, 0))
_ok(bear.get("_hp") == hp3 - 1, "the dash ability rams the bear on contact even when not horns-first")
bull.set("dashing", false)
_finish()
func _finish() -> void:
print("Results: %d passed, %d failed" % [_pass, _fail])
quit(1 if _fail > 0 else 0)
+1
View File
@@ -0,0 +1 @@
uid://o2cdiyq77u8k
+8 -1
View File
@@ -46,6 +46,13 @@ func _run() -> void:
quit(1)
return
# The run now opens in the fightless lobby; force the matador arena so the scene loads
# with live matadors for the checks below.
var run: Node = root.get_node_or_null("/root/Run")
if run != null:
run.ensure_run() # build the run first — the shell's own ensure_run would wipe the override
run.debug_level_override = run.get_level(&"arena")
var scene: Node = scene_res.instantiate()
root.add_child(scene)
current_scene = scene # match runtime: game code (sword throw, overlays) uses current_scene
@@ -283,7 +290,7 @@ func _check_overlays() -> void:
_note("overlay check: DP / DebugDraw autoload missing")
return
var flags := [
"show_states", "show_stats", "show_collisions", "show_hitboxes", "show_bones",
"show_states", "show_stats", "show_attacks", "show_hitboxes", "show_bones",
"show_animation_name", "show_wireframe", "show_grid", "show_axes",
]
for flag: String in flags:
+118
View File
@@ -0,0 +1,118 @@
extends SceneTree
## Charge-reliability test. A fast bull (dash ≈ 66 m/s ≈ 1.1 m/frame) moves far enough per physics
## frame to tunnel clean through the matador's thin HitArea, so the Area's body_entered never fires
## — "my charge goes right through them." matador.gd now sweeps the bull's actual travel (prev → now)
## each frame and gores any matador on the path (_sweep_bull_gore), and a committed charge pierces the
## survival roll (mat_charge_pierce). This drives a tunnelling pass whose endpoints both sit OUTSIDE
## the gore radius — so only the swept test can catch it — and asserts: (a) the charge still connects,
## (b) a full-speed charge gores (kills) rather than being rolled off, and (c) a slow bump at the hit
## threshold still lets the matador roll clear.
## Run: godot --headless --script res://tests/matador_charge_test.gd
var _pass := 0
var _fail := 0
func _init() -> void:
_run.call_deferred()
func _ok(c: bool, m: String) -> void:
if c:
_pass += 1
print(" PASS: ", m)
else:
_fail += 1
print(" FAIL: ", m)
func _make_bull() -> CharacterBody3D:
var bull := CharacterBody3D.new()
bull.set_script(load("res://tests/_fake_bull.gd")) # exposes is_dashing()/is_rolling()
bull.collision_layer = 2
bull.collision_mask = 0
bull.add_to_group(&"player")
var cs := CollisionShape3D.new()
var shape := CapsuleShape3D.new()
shape.radius = 0.75
shape.height = 1.845
cs.shape = shape
bull.add_child(cs)
root.add_child(bull)
return bull
func _make_matador(_bull: CharacterBody3D) -> CharacterBody3D:
var mat := (load("res://Matador.tscn") as PackedScene).instantiate() as CharacterBody3D
root.add_child(mat)
mat.global_position = Vector3.ZERO
mat.set_physics_process(false) # we drive the swept gore ourselves, isolated from the AI
await physics_frame
mat.call("_acquire_bull")
return mat
# Sweep the bull straight across the matador at `speed`: seed the previous position at from_x (too
# far to gore), then teleport to to_x so the prev → now segment passes through the matador at x=0.
func _charge_pass(mat: CharacterBody3D, bull: CharacterBody3D, speed: float, from_x: float, to_x: float) -> void:
bull.global_position = Vector3(from_x, 0.0, 0.0)
bull.velocity = Vector3(speed, 0.0, 0.0)
mat.call("_sweep_bull_gore")
bull.global_position = Vector3(to_x, 0.0, 0.0)
mat.call("_sweep_bull_gore")
func _run() -> void:
var dp := root.get_node("/root/DP")
var gore_r: float = dp.f("mat_charge_gore_radius")
var thr: float = dp.f("mat_hit_threshold")
_ok(2.0 > gore_r, "test pass tunnels: endpoints (2 m) sit outside the gore radius (%.2f m)" % gore_r)
# One shared bull — matadors acquire the sole node in the "player" group, so every scenario
# sweeps the same body (a second bull would leave later matadors reading the wrong, stale one).
var bull := _make_bull()
# (a) A dash-speed pass that leaps clean over the HitArea must still connect. Force the roll so
# the reaction is a clean, ragdoll-free state change proving detection.
dp.call("set_value", "mat_charge_pierce", 0.0)
dp.call("set_value", "mat_roll_chance", 1.0)
var mat_a: CharacterBody3D = await _make_matador(bull)
_charge_pass(mat_a, bull, 66.0, -2.0, 2.0)
_ok(mat_a.call("ai_state_name") == "ROLL", "a dash that tunnels the HitArea still connects (matador reacts)")
# (b) A full-speed charge pierces the survival roll and gores — even forced roll_chance can't save it.
dp.call("set_value", "mat_charge_pierce", 1.0)
dp.call("set_value", "mat_roll_chance", 1.0)
var mat_b: CharacterBody3D = await _make_matador(bull)
_charge_pass(mat_b, bull, 66.0, -2.0, 2.0)
_ok(mat_b.call("ai_state_name") == "RAGDOLL", "a full-speed charge pierces the roll and gores the matador")
# (c) The pierce only bites at speed: a slow bump at the hit threshold still lets them roll clear.
var mat_c: CharacterBody3D = await _make_matador(bull)
_charge_pass(mat_c, bull, thr, -2.0, 2.0)
_ok(mat_c.call("ai_state_name") == "ROLL", "a slow bump at the threshold still rolls clear")
# (d) Horns-first only: a fast pass with the matador BEHIND the bull's heading (it charges away,
# 0.5 → 3, matador at 0) doesn't gore, even though the swept path passes within reach.
dp.call("set_value", "mat_charge_pierce", 0.0)
dp.call("set_value", "mat_roll_chance", 1.0)
var mat_d: CharacterBody3D = await _make_matador(bull)
_charge_pass(mat_d, bull, 66.0, 0.5, 3.0)
_ok(mat_d.call("ai_state_name") == "WANDER", "a charge moving away from the matador doesn't gore (horns-first)")
# (e) The DASH ability is a committed lunge: even the not-horns-first pass connects (is_dashing
# bypasses the cone) AND is a guaranteed kill — roll_chance forced to 1.0 still RAGDOLLS, not rolls.
dp.call("set_value", "mat_roll_chance", 1.0)
dp.call("set_value", "mat_charge_pierce", 0.0)
bull.set("dashing", true)
var mat_e: CharacterBody3D = await _make_matador(bull)
_charge_pass(mat_e, bull, 66.0, 0.5, 3.0)
_ok(mat_e.call("ai_state_name") == "RAGDOLL", "a dash connect is a guaranteed kill (no survival roll)")
bull.set("dashing", false)
_finish()
func _finish() -> void:
print("Results: %d passed, %d failed" % [_pass, _fail])
quit(1 if _fail > 0 else 0)
+1
View File
@@ -0,0 +1 @@
uid://wplxv71pxkrl
+67
View File
@@ -0,0 +1,67 @@
extends SceneTree
## Thrown-spear hit test. The bull's body sits on collision layer BULL, so a spear whose mask
## only covered WORLD flew straight through it — every throw whiffed, even against a stationary
## bull. This launches a spear dead-on at a still fake bull and asserts the projectile masks BULL
## and actually lands the hit. Run: godot --headless --script res://tests/matador_spear_test.gd
# physics_layers.gd is pure constants (safe to preload); spear_projectile.gd references the
# Settings autoload, whose global identifier isn't registered when a --script entry compiles its
# preloads — so it's loaded at runtime inside _run instead, once the autoloads exist.
const PhysicsLayers = preload("res://physics_layers.gd")
var _pass := 0
var _fail := 0
func _init() -> void:
_run.call_deferred()
func _ok(c: bool, m: String) -> void:
if c:
_pass += 1
print(" PASS: ", m)
else:
_fail += 1
print(" FAIL: ", m)
func _run() -> void:
# Stationary fake bull at the origin, on the BULL layer like the real one.
var bull := CharacterBody3D.new()
bull.collision_layer = PhysicsLayers.BULL
bull.collision_mask = 0
bull.add_to_group(&"player")
bull.set_script(load("res://tests/_fake_bull.gd"))
var bcs := CollisionShape3D.new()
var bshape := CapsuleShape3D.new()
bshape.radius = 0.6
bshape.height = 1.4
bcs.shape = bshape
bull.add_child(bcs)
root.add_child(bull)
bull.global_position = Vector3.ZERO
await physics_frame
# Launch a spear flat, dead-on from 3 m out; low gravity so the short flight stays level.
var spear_script := load("res://spear_projectile.gd")
var mesh := (load("res://Spear.tscn") as PackedScene).instantiate() as Node3D
root.add_child(mesh)
var origin := Vector3(0.0, 0.0, -3.0)
var spear := spear_script.launch(root, mesh, origin, Vector3(0.0, 0.0, 12.0), 0.05) as RigidBody3D
_ok(spear.collision_mask & PhysicsLayers.BULL != 0, "spear masks the BULL layer (can collide with the bull)")
for i in 90:
await physics_frame
if bull.hits >= 1:
break
_ok(bull.hits >= 1, "thrown spear hits a stationary bull")
_finish()
func _finish() -> void:
print("Results: %d passed, %d failed" % [_pass, _fail])
quit(1 if _fail > 0 else 0)
+1
View File
@@ -0,0 +1 @@
uid://dcwtku2xvxswa
+101
View File
@@ -0,0 +1,101 @@
extends SceneTree
## Matador stab-reliability test. The matador runs in, plants at mat_stab_standoff, and its stab
## damages off the sword's own BladeHitbox collider (armed only during the thrust) — NOT a distance
## check. This drives the attack tick against a STATIONARY, real-sized bull placed beyond the
## standoff and asserts it (a) gores the bull when the thrust physically reaches it, (b) lands the
## hit during the thrust and not the wind-up/walk-up, and (c) plants at the standoff, not inside the
## bull, and (d) keeps landing on repeat stabs from the same spot (the blade re-arms each swing).
## Run: godot --headless --script res://tests/matador_stab_test.gd
var _pass := 0
var _fail := 0
func _init() -> void:
_run.call_deferred()
func _ok(c: bool, m: String) -> void:
if c:
_pass += 1
print(" PASS: ", m)
else:
_fail += 1
print(" FAIL: ", m)
func _run() -> void:
var dp := root.get_node("/root/DP")
var standoff: float = dp.f("mat_stab_standoff")
var strike_at: float = dp.f("mat_stab_strike_at")
# Stationary, real-sized bull beyond the standoff — the matador runs in, plants at the standoff,
# and its THRUST (not the walk-up) has to reach across the gap to gore it.
var bull := CharacterBody3D.new()
bull.collision_layer = 2
bull.collision_mask = 0
bull.add_to_group(&"player")
bull.set_script(load("res://tests/_fake_bull.gd"))
var bcs := CollisionShape3D.new()
var bshape := CapsuleShape3D.new()
bshape.radius = 0.75
bshape.height = 1.845
bcs.shape = bshape
bull.add_child(bcs)
root.add_child(bull)
bull.global_position = Vector3(0.0, 0.0, standoff + 3.0)
var mat := (load("res://Matador.tscn") as PackedScene).instantiate() as CharacterBody3D
root.add_child(mat) # _ready acquires the bull from the "player" group
mat.global_position = Vector3.ZERO
mat.set_physics_process(false) # we drive the attack tick ourselves, isolated from the AI
await physics_frame
mat.call("_acquire_bull") # normally done in _physics_process, which we disabled
_ok(mat.get("_bull") == bull, "matador acquired the bull")
mat.call("_carry_sword", true) # actually draw into the hand so the BladeHitbox rides the thrust
mat.call("_start_attack")
dp.call("set_value", "mat_stab_followup_chance", 0.0) # isolate repeat stabs from the break-off roll
dp.call("set_value", "mat_stab_recovery", 0.0) # no recovery beat gating back-to-back stabs
dp.call("set_value", "mat_taunt_after_hit", 0.0) # don't break off to taunt after a landed hit
var min_dist := 999.0
var first_hit_phase := -1.0
var last_hits := 0
for i in 300: # several swings' worth of ticks (approach + repeated stabs)
mat.call("_tick_attack", 1.0 / 60.0)
var d := mat.global_position.distance_to(bull.global_position)
min_dist = minf(min_dist, d)
if bull.hits > last_hits:
if first_hit_phase < 0.0:
first_hit_phase = mat.call("_swing_phase") # phase on the frame the first hit landed
last_hits = bull.hits
await physics_frame
_ok(bull.hits >= 1, "the sword's thrust reaches across the standoff and gores the bull")
_ok(first_hit_phase >= strike_at - 0.1, "hit lands in the thrust, not the wind-up (phase %.2f)" % first_hit_phase)
_ok(bull.hits >= 2, "repeat stabs from the same spot keep landing (%d hits)" % bull.hits)
_ok(min_dist >= standoff - 0.5, "matador plants at the standoff, not inside the bull (closest %.2f m)" % min_dist)
# Anti-spam: once a stab CONNECTS, a high mat_taunt_after_hit must break the matador off ATTACK
# (into a taunt/retreat) instead of drilling the bull again. Force the roll and confirm it leaves.
dp.call("set_value", "mat_taunt_after_hit", 1.0)
bull.hits = 0
mat.call("_start_attack")
var broke_off := false
for i in 200:
mat.call("_tick_attack", 1.0 / 60.0)
if mat.call("ai_state_name") != "ATTACK":
broke_off = true
break
await physics_frame
_ok(broke_off, "a landed stab breaks the matador off ATTACK (taunt/retreat), not another thrust")
_ok(bull.hits >= 1, "the break-off only fires after the stab actually connected (%d hits)" % bull.hits)
_finish()
func _finish() -> void:
print("Results: %d passed, %d failed" % [_pass, _fail])
quit(1 if _fail > 0 else 0)
+1
View File
@@ -0,0 +1 @@
uid://deueaav5qscnc
+91
View File
@@ -0,0 +1,91 @@
extends SceneTree
## A taunting matador must answer a charge instead of posing through it: hurl a spear at a bull
## barrelling in from range, or switch to the sword (brace/cite) to meet a closer rush. Drives
## _tick_wander on a matador mid-taunt (_idle_timer > 0) against a bull charging straight at it and
## asserts the state it breaks into by range; a slow / non-aimed bull leaves it taunting.
## Run: godot --headless --script res://tests/matador_taunt_react_test.gd
var _pass := 0
var _fail := 0
func _init() -> void:
_run.call_deferred()
func _ok(c: bool, m: String) -> void:
if c:
_pass += 1
print(" PASS: ", m)
else:
_fail += 1
print(" FAIL: ", m)
func _make_bull() -> CharacterBody3D:
var b := CharacterBody3D.new()
b.collision_layer = 2
b.collision_mask = 0
b.add_to_group(&"player")
var cs := CollisionShape3D.new()
var shape := CapsuleShape3D.new()
shape.radius = 0.75
shape.height = 1.845
cs.shape = shape
b.add_child(cs)
root.add_child(b)
return b
func _make_taunting_matador(_bull: CharacterBody3D) -> CharacterBody3D:
var mat := (load("res://Matador.tscn") as PackedScene).instantiate() as CharacterBody3D
root.add_child(mat)
mat.global_position = Vector3.ZERO
mat.set_physics_process(false) # we drive _tick_wander ourselves, no brain
await physics_frame
mat.call("_acquire_bull")
mat.set("_idle_timer", 5.0) # mid-taunt: standing and posturing
mat.set("_throw_aim_cd", 0.0) # spear ready
return mat
# Park the bull at `dist` straight ahead (+Z) of the matador, charging back toward it at `speed`.
func _charge_from(bull: CharacterBody3D, dist: float, speed: float) -> void:
bull.global_position = Vector3(0.0, 0.0, dist)
bull.velocity = Vector3(0.0, 0.0, -speed)
func _run() -> void:
var bull := _make_bull()
# (a) Far charge (10 m, past brace range but within throw range) → get the spear off.
var mat_a: CharacterBody3D = await _make_taunting_matador(bull)
_charge_from(bull, 10.0, 30.0)
mat_a.call("_tick_wander", 1.0 / 60.0)
_ok(mat_a.call("ai_state_name") == "THROW", "a taunting matador hurls a spear at a charge from range")
# (b) Closer rush (3 m, inside brace range) → switch to the sword and cite it.
var mat_b: CharacterBody3D = await _make_taunting_matador(bull)
_charge_from(bull, 3.0, 30.0)
mat_b.call("_tick_wander", 1.0 / 60.0)
_ok(mat_b.call("ai_state_name") == "BRACE", "a taunting matador switches to the sword for a closer rush")
# (c) A slow bull (below charge speed) isn't a charge — keep taunting.
var mat_c: CharacterBody3D = await _make_taunting_matador(bull)
_charge_from(bull, 10.0, 3.0)
mat_c.call("_tick_wander", 1.0 / 60.0)
_ok(mat_c.call("ai_state_name") == "WANDER", "a taunting matador ignores a slow (non-charging) bull")
# (d) A fast bull aimed AWAY from the matador isn't charging at it — keep taunting.
var mat_d: CharacterBody3D = await _make_taunting_matador(bull)
bull.global_position = Vector3(0.0, 0.0, 10.0)
bull.velocity = Vector3(0.0, 0.0, 30.0) # heading further away, not at the matador
mat_d.call("_tick_wander", 1.0 / 60.0)
_ok(mat_d.call("ai_state_name") == "WANDER", "a taunting matador ignores a charge not aimed at it")
_finish()
func _finish() -> void:
print("Results: %d passed, %d failed" % [_pass, _fail])
quit(1 if _fail > 0 else 0)
+1
View File
@@ -0,0 +1 @@
uid://c1r546ktiw2ka

Some files were not shown because too many files have changed in this diff Show More