Compare commits

...

4 Commits

25 changed files with 713 additions and 40 deletions

View File

@ -134,3 +134,11 @@ Asset credits
*** Author: lulyc
*** License CC0
** fireball.wav
*** Retrieved from https://freesound.org/people/LiamG_SFX/sounds/334237/
*** Author: LiamG_SFX
*** License: CC BY 4.0

BIN
asset_dev/balls/powerball/fireball.blend (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
asset_dev/particles/smoke.blend (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,104 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v4.2.60",
"version":"2.0"
},
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
0
]
}
],
"nodes":[
{
"mesh":0,
"name":"Fireball"
}
],
"meshes":[
{
"name":"Sphere.001",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3
}
]
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":84,
"max":[
0.17320509254932404,
0.20000000298023224,
0.20000001788139343
],
"min":[
-0.17320507764816284,
0,
-0.18961560726165771
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":84,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":84,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":108,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":1008,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":1008,
"byteOffset":1008,
"target":34962
},
{
"buffer":0,
"byteLength":672,
"byteOffset":2016,
"target":34962
},
{
"buffer":0,
"byteLength":216,
"byteOffset":2688,
"target":34963
}
],
"buffers":[
{
"byteLength":2904,
"uri":"fireball.bin"
}
]
}

View File

@ -0,0 +1,36 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://dd2nxbfssd4hh"
path="res://.godot/imported/fireball.gltf-97c966d8efae6c02cddcd5d037fee594.scn"
[deps]
source_file="res://assets/models/balls/powerball/fireball.gltf"
dest_files=["res://.godot/imported/fireball.gltf-97c966d8efae6c02cddcd5d037fee594.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
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=""
_subresources={}
gltf/naming_version=1
gltf/embedded_image_handling=1

Binary file not shown.

View File

@ -0,0 +1,104 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v4.2.60",
"version":"2.0"
},
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
0
]
}
],
"nodes":[
{
"mesh":0,
"name":"SmokeCloud"
}
],
"meshes":[
{
"name":"Sphere",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3
}
]
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":153,
"max":[
0.20304334163665771,
0.14592236280441284,
0.14660561084747314
],
"min":[
-0.2416081726551056,
-0.14180392026901245,
-0.15602463483810425
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":153,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":153,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":720,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":1836,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":1836,
"byteOffset":1836,
"target":34962
},
{
"buffer":0,
"byteLength":1224,
"byteOffset":3672,
"target":34962
},
{
"buffer":0,
"byteLength":1440,
"byteOffset":4896,
"target":34963
}
],
"buffers":[
{
"byteLength":6336,
"uri":"smoke.bin"
}
]
}

View File

@ -0,0 +1,48 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://bkrb4rxwjaxba"
path="res://.godot/imported/smoke.gltf-923367b79e5b097f0bc224e276b9686d.scn"
[deps]
source_file="res://assets/models/particles/smoke.gltf"
dest_files=["res://.godot/imported/smoke.gltf-923367b79e5b097f0bc224e276b9686d.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
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=""
_subresources={
"meshes": {
"smoke_Sphere": {
"generate/lightmap_uv": 0,
"generate/lods": 0,
"generate/shadow_meshes": 0,
"lods/normal_merge_angle": 60.0,
"lods/normal_split_angle": 25.0,
"save_to_file/enabled": true,
"save_to_file/path": "res://assets/models/particles/smoke_mesh.res"
}
}
}
gltf/naming_version=1
gltf/embedded_image_handling=1

BIN
assets/models/particles/smoke_mesh.res (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/sound/sfx/ball/effects/fireball.wav (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://tqr7u7vb2r0f"
path="res://.godot/imported/fireball.wav-e9a4a19e43ae33c51b6ba6e788266ca3.sample"
[deps]
source_file="res://assets/sound/sfx/ball/effects/fireball.wav"
dest_files=["res://.godot/imported/fireball.wav-e9a4a19e43ae33c51b6ba6e788266ca3.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=0

View File

@ -230,7 +230,7 @@ locale/translations=PackedStringArray("res://assets/text/text.en.translation")
[layer_names]
3d_physics/layer_1="Collision Geometry"
3d_physics/layer_2="Layer 2"
3d_physics/layer_2="Water"
3d_physics/layer_27="Glass Material"
3d_physics/layer_28="Metal Material"
3d_physics/layer_29="Rock Material"

View File

@ -29,7 +29,8 @@ mass = 0.1
physics_material_override = SubResource("PhysicsMaterial_867vn")
linear_damp = 0.1
script = ExtResource("2_ay78j")
radius = 0.1
base_damage = 5.0
radius = 0.5
[node name="BallMesh" parent="." index="0"]
mesh = SubResource("SphereMesh_iqcc5")

View File

@ -17,6 +17,9 @@ enum Type {
const TERRAIN_DAMPING_EPSILON := 1e-6
const MAGNUS_EPSILON := 1e-3
## If enabled, ball ability cooldown is only reset at end of shot.
@export var once_per_shot_ability := false
## Angular damping while in air
@export var air_damping := 0.0
## Angular damping while in collision with rough terrain
@ -29,8 +32,10 @@ const MAGNUS_EPSILON := 1e-3
## This is approximately 1/2 * rho * C_L * pi * r^2
## where `rho` is the fluid density of the medium, or 1.225 for air at sea level,
## and `C_L` is the lift coefficient which for our purposes is 0.05,
## and `r` is the radius of the ball, which is 5cm.
@export var magnus_coefficient := 0.00024
## and `r` is the radius of the ball, which is variable.
## NOTE: Rather than use r^2 we use r * a constant 0.05
#@export var magnus_coefficient := 0.00024
@export var magnus_coefficient := 0.00481056
## Causes the ball to stick to surfaces
@export var magnetic := false
@ -41,7 +46,7 @@ const MAGNUS_EPSILON := 1e-3
## Scaling factor for additional force-based damage
@export var damage_force_scale := 0.01
## Approximate average radius, for physics purposes
## Approximate average radius, for physics & positioning purposes
@export var radius := 0.05
var current_gravity: Vector3
@ -51,6 +56,7 @@ var player: WorldPlayer
var _last_contact_normal: Vector3 = Vector3.UP
var _position_on_last_wake: Vector3
var _awake := false
var _ability_triggered := false
var _zones: Array[BallZone] = []
@onready var ability_cooldown: Timer = %AbilityCooldown
@ -75,10 +81,15 @@ func enter_water() -> void:
## Activate this ball's ability, if there is one.
func activate_ability() -> void:
if ability_cooldown.is_stopped():
if once_per_shot_ability:
if not _ability_triggered:
_ability_triggered = true
_activate_ability()
# TODO bonk
elif ability_cooldown.is_stopped():
_activate_ability()
ability_cooldown.start()
# TODO: bonk
# TODO bonk
func _activate_ability() -> void:
@ -98,7 +109,7 @@ func _total_terrain_angular_damping() -> float:
func _magnus_force() -> Vector3:
return magnus_coefficient * angular_velocity.cross(linear_velocity)
return magnus_coefficient * radius * angular_velocity.cross(linear_velocity)
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
@ -106,6 +117,7 @@ func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
if not _awake:
# Triggered on first frame after waking
_awake = true
_ability_triggered = false
_position_on_last_wake = global_position
_last_contact_normal = Vector3.UP
# TODO something's fucky here... I think this gets called once after the ball sleeps

View File

@ -1,11 +1,18 @@
extends GameBall
const ABILITY_MAGNITUDE := 5.0
const ABILITY_MAGNITUDE := 2.0
const SCREENSHAKE_INTENSITY := 8.0
const SCREENSHAKE_LENGTH := 3.0
var _ability_impulse := Vector3.ZERO
@onready var fireball_pivot: Node3D = %FireballPivot
@onready var powerball_animation: AnimationPlayer = %PowerballAnimation
@onready var game: Game = get_tree().get_first_node_in_group(Game.group)
func _activate_ability() -> void:
_ability_impulse = linear_velocity.normalized() * ABILITY_MAGNITUDE
@ -17,5 +24,16 @@ func _activate_ability() -> void:
func _finish_ability() -> void:
can_sleep = true
freeze = false
linear_velocity = Vector3.ZERO
apply_central_impulse(_ability_impulse)
game.viewport.screen_shake(SCREENSHAKE_INTENSITY, SCREENSHAKE_LENGTH)
func _process(_delta: float) -> void:
# Rotate fireball to direction of travel
var y := linear_velocity.normalized()
if y.length_squared() <= 1e-9:
y = -global_basis.z.normalized()
var x := Vector3(y.y, -y.x, 0)
var z := y.cross(x).normalized()
x = z.cross(y).normalized() # orthonormalize
fireball_pivot.global_basis = Basis(x, y, z)

View File

@ -1,9 +1,11 @@
[gd_scene load_steps=18 format=3 uid="uid://deuytmxw2lc62"]
[gd_scene load_steps=37 format=4 uid="uid://deuytmxw2lc62"]
[ext_resource type="PackedScene" uid="uid://dfttci386ohip" path="res://src/equipment/balls/physics_ball/physics_ball.tscn" id="1_14gld"]
[ext_resource type="Texture2D" uid="uid://ckhiq6rfjv63u" path="res://assets/textures/gfolfball/gfolfball.png" id="2_a2gtg"]
[ext_resource type="Script" path="res://src/equipment/balls/power_ball/power_ball.gd" id="2_hy51e"]
[ext_resource type="Texture2D" uid="uid://btntjs7mbdigu" path="res://assets/textures/gfolfball/gfolfball_normal.png" id="3_60i75"]
[ext_resource type="PackedScene" uid="uid://dd2nxbfssd4hh" path="res://assets/models/balls/powerball/fireball.gltf" id="5_i8vmm"]
[ext_resource type="AudioStream" uid="uid://tqr7u7vb2r0f" path="res://assets/sound/sfx/ball/effects/fireball.wav" id="6_uwolu"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_c4cm7"]
albedo_color = Color(2, 0.266, 0.266, 1)
@ -25,6 +27,91 @@ height = 0.1
radial_segments = 6
rings = 6
[sub_resource type="Gradient" id="Gradient_b68qa"]
offsets = PackedFloat32Array(0.291939, 1)
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 0, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_sr8jb"]
gradient = SubResource("Gradient_b68qa")
fill = 1
fill_from = Vector2(0.5, 0.5)
metadata/_snap_enabled = true
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_aqmuo"]
transparency = 1
cull_mode = 2
shading_mode = 0
vertex_color_use_as_albedo = true
albedo_color = Color(2, 1.98431, 1.6, 0.156863)
albedo_texture = SubResource("GradientTexture2D_sr8jb")
[sub_resource type="Animation" id="Animation_5t74j"]
resource_name = "flicker"
length = 2.0
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("FireballScaleRoot:scale")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0.00610052, 0.1, 0.206101, 0.3, 0.40305, 0.5, 0.60305, 0.7, 0.80305, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9),
"transitions": PackedFloat32Array(0.618, 1, 0.618, 1, 0.618, 1, 0.618, 1, 0.618, 1, 0.618, 1, 0.618, 1, 0.618, 1, 0.618, 1, 0.618, 1),
"update": 0,
"values": [Vector3(1, 1, 1), Vector3(1, 1.2, 1), Vector3(1, 1, 1), Vector3(1, 1.2, 1), Vector3(1, 1, 1), Vector3(1, 1.2, 1), Vector3(1, 1, 1), Vector3(1, 1.2, 1), Vector3(1, 1, 1), Vector3(1, 1.2, 1), Vector3(1, 1, 1), Vector3(1, 1.2, 1), Vector3(1, 1, 1), Vector3(1, 1.2, 1), Vector3(1, 1, 1), Vector3(1, 1.2, 1), Vector3(1, 1, 1), Vector3(1, 1.2, 1), Vector3(1, 1, 1), Vector3(1, 1.2, 1)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("FireballScaleRoot:rotation")
tracks/1/interp = 1
tracks/1/loop_wrap = false
tracks/1/keys = {
"times": PackedFloat32Array(0, 2),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(0, 0, 0), Vector3(0, 2.0944, 0)]
}
[sub_resource type="Animation" id="Animation_2co83"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("FireballScaleRoot:scale")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(1, 1, 1)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("FireballScaleRoot:rotation")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0, 0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_hmunj"]
_data = {
"RESET": SubResource("Animation_2co83"),
"flicker": SubResource("Animation_5t74j")
}
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_jvq4v"]
random_pitch = 1.1
streams_count = 1
stream_0/stream = ExtResource("6_uwolu")
[sub_resource type="Curve" id="Curve_ai354"]
max_value = 100.0
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(0.115, 100), 0.0, 0.0, 0, 0]
@ -70,9 +157,86 @@ sections = 3
section_length = 0.1
curve = SubResource("Curve_p1ob2")
[sub_resource type="Gradient" id="Gradient_ljxg5"]
offsets = PackedFloat32Array(0, 0.01566, 0.237136, 0.760626)
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 0.3, 1, 1, 0.0623333, 0.03, 1, 0, 0, 0, 1)
[sub_resource type="GradientTexture1D" id="GradientTexture1D_3g0ul"]
gradient = SubResource("Gradient_ljxg5")
[sub_resource type="Curve" id="Curve_ux8et"]
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.298, 0.484), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="CurveTexture" id="CurveTexture_m3urn"]
curve = SubResource("Curve_ux8et")
[sub_resource type="Curve" id="Curve_odpml"]
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.122105, 1), 0.0, 0.0, 0, 0, Vector2(0.787368, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), -15.6101, 0.0, 0, 0]
point_count = 4
[sub_resource type="CurveTexture" id="CurveTexture_gkytq"]
curve = SubResource("Curve_odpml")
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_6n6nm"]
lifetime_randomness = 0.24
angle_min = -720.0
angle_max = 720.0
angular_velocity_min = -15.0
angular_velocity_max = 15.0
gravity = Vector3(0, 1, 0)
damping_min = 3.0
damping_max = 3.0
damping_curve = SubResource("CurveTexture_m3urn")
scale_min = 0.3
scale_max = 3.0
scale_curve = SubResource("CurveTexture_gkytq")
color_ramp = SubResource("GradientTexture1D_3g0ul")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1upti"]
transparency = 1
vertex_color_use_as_albedo = true
billboard_mode = 3
billboard_keep_scale = true
particles_anim_h_frames = 1
particles_anim_v_frames = 1
particles_anim_loop = false
[sub_resource type="ArrayMesh" id="ArrayMesh_r0r4b"]
_surfaces = [{
"aabb": AABB(-0.241608, -0.141804, -0.156025, 0.444652, 0.287726, 0.30263),
"format": 34896613377,
"index_count": 720,
"index_data": PackedByteArray("eQAIACkAeQAnAAgAeAAGACsAeAAlAAYAAAAsAFMAHwBWAFQAdwAHACoAdwAmAAcAdgAFACwAdgAkAAUAHwBYAFYAdQAMADMAdQAvAAwAdAAKADUAdAAtAAoAcwANADIAcwAwAA0AcgALADQAcgAuAAsABQA1AFUAHwBaAFgAcQARADwAcQA4ABEAcAAPAD4AcAA2AA8AbwASADsAbwA5ABIAbgAQAD0AbgA3ABAACgA+AFcAHwBbAFoAbQAXAEYAbQBCABcAbAAVAEgAbABAABUAawAYAEUAawBDABgAagAWAEcAagBBABYADwBIAFkAaQAcAE8AaQBLABwAaAAaAFEAaABJABoAZwAdAE4AZwBMAB0AZgAbAFAAZgBKABsAFQBRAD8AHwBNAFsAZQAAAF4AZQAgAAAAZAADAGAAZAAjAAMAYwABAF0AYwAhAAEAGgBeAFwAHwBUAE0AYgACAGEAYgAiAAIAYAAiAGIAYAADACIAHQBiAEsAHQBgAGIASwBhABwASwBiAGEAVAAEAF8AVABfAE0ATQBfAB4AXgAAAFMAXgBTAFwAXABTABQAYQAhAGMAYQACACEAHABjAEoAHABhAGMASgBdABsASgBjAF0AXwAjAGQAXwAEACMAHgBkAEwAHgBfAGQATABgAB0ATABkAGAAXQAgAGUAXQABACAAGwBlAEkAGwBdAGUASQBeABoASQBlAF4ATQAeAFIATQBSAFsAWwBSABkAUQAaAFwAUQBcAD8APwBcABQATwBKAGYATwAcAEoAFwBmAEEAFwBPAGYAQQBQABYAQQBmAFAAUgBMAGcAUgAeAEwAGQBnAEMAGQBSAGcAQwBOABgAQwBnAE4AUABJAGgAUAAbAEkAFgBoAEAAFgBQAGgAQABRABUAQABoAFEATgBLAGkATgAdAEsAGABpAEIAGABOAGkAQgBPABcAQgBpAE8ASAAVAD8ASAA/AFkAWQA/ABQARgBBAGoARgAXAEEAEQBqADcAEQBGAGoANwBHABAANwBqAEcARABDAGsARAAZAEMAEwBrADkAEwBEAGsAOQBFABIAOQBrAEUARwBAAGwARwAWAEAAEABsADYAEABHAGwANgBIAA8ANgBsAEgARQBCAG0ARQAYAEIAEgBtADgAEgBFAG0AOABGABEAOABtAEYAWwAZAEQAWwBEAFoAWgBEABMAPgAPAFkAPgBZAFcAVwBZABQAPAA3AG4APAARADcADABuAC4ADAA8AG4ALgA9AAsALgBuAD0AOgA5AG8AOgATADkADgBvADAADgA6AG8AMAA7AA0AMABvADsAPQA2AHAAPQAQADYACwBwAC0ACwA9AHAALQA+AAoALQBwAD4AOwA4AHEAOwASADgADQBxAC8ADQA7AHEALwA8AAwALwBxADwAWgATADoAWgA6AFgAWAA6AA4ANQAKAFcANQBXAFUAVQBXABQAMwAuAHIAMwAMAC4ABwByACUABwAzAHIAJQA0AAYAJQByADQAMQAwAHMAMQAOADAACQBzACcACQAxAHMAJwAyAAgAJwBzADIANAAtAHQANAALAC0ABgB0ACQABgA0AHQAJAA1AAUAJAB0ADUAMgAvAHUAMgANAC8ACAB1ACYACAAyAHUAJgAzAAcAJgB1ADMAWAAOADEAWAAxAFYAVgAxAAkAKwAkAHYAKwAGACQAAQB2ACAAAQArAHYAIAAsAAAAIAB2ACwAKQAmAHcAKQAIACYAAwB3ACIAAwApAHcAIgAqAAIAIgB3ACoAVgAJACgAVgAoAFQAVAAoAAQALAAFAFUALABVAFMAUwBVABQAKgAlAHgAKgAHACUAAgB4ACEAAgAqAHgAIQArAAEAIQB4ACsAKAAnAHkAKAAJACcABAB5ACMABAAoAHkAIwApAAMAIwB5ACkA"),
"lods": [0.0297894, PackedByteArray("KAAIAHcAKAAnAAgAJwANAAgAKAAJACcACQBzACcAJwBzAA0AVgAJACgAVgAoAFQAHwBWAFQAVAAoAAQACQAxAHMAVgAxAAkAWAAxAFYAHwBYAFYAWAAOADEAMQAwAHMAMQAOADAAcwAwAA0ADgA6ADAAWAA6AA4AMABxAA0AMAA6AHEAWgA6AFgAHwBaAFgAWgATADoAOgATADkAOgA5AHEADQBxAC8ALwBuAC4ADQAvADMACAANADMAMwAvAC4ACAAzAAcABwAzAC4AdwAIAAcALwBxADwALwA8AG4AcQARADwAcQA5ABEAPAAQAG4APAARABAAbgAQAD0ALgBuAD0ALgA9AAsACwA9AD4APQAQAD4ALgALAHQAEQBHABAAPgAQAA8AEABsAA8AEABHAGwAPgAPAFkAPgBZAFcAVwBZABQACgA+AFcACwA+AAoAdAALAAoADwBsAFkAbAA/AFkAWQA/ABQAbAAVAD8AbAAWABUARwAWAGwARwBBABYARgBBAEcARgAXAEEAEQBGAEcAbQAXAEYAEQBtAEYAbQBCABcAOQBtABEAGABCAG0AOQAYAG0AOQBrABgAawBDABgAEwBrADkARABDAGsAEwBEAGsARAAZAEMAWgBEABMAWwAZAEQAWwBEAFoAHwBbAFoAAAAsAFMAUwBVABQALABVAFMALAAFAFUAIAAsAAAAIAB2ACwAdgAFACwAXQAgAAAAIQB2ACAAXQAhACAAIQArAHYAXQAAAF4AXgAAAFMAXgBTAFwAXABTABQAGgBeAFwAGgBdAF4AYQAhAF0AGwBdABoAGwBhAF0AUAAbABoATwAbAFAAHABhABsATwAcABsAYQACACEAAgArACEASwBhABwAaQAcAE8AaQBLABwAQgBpAE8AQgBPABcAFwBPAFAAGABpAEIAFwBQAEEAQQBQABYAGABOAGkATgBLAGkAQwBOABgAFgBQAFEAUAAaAFEAFgBRABUAUQAaAFwAFQBRAD8AUQBcAD8APwBcABQAGQBOAEMAGQAdAE4ATgAdAEsAHQBiAEsASwBiAGEAYgACAGEAHQBgAGIAYAACAGIAGQAeAB0AHgBgAB0ATQAeABkATQAZAFsAHwBNAFsAHgAEAGAATQAEAB4AVAAEAE0AHwBUAE0ABAAjAGAABAAoACMAYAAjAAMAYAADAAIAIwAoAHcAIwB3AAMAAwB3AAIAAgB3ACoAdwAHACoAAgAqACsAKgAHACUAKgAlACsABwAuACUAJQAuAHQAKwAlACQAJQB0ACQAKwAkAHYAdgAkAAUAJAB0AAUAdAAKAAUABQAKAFcABQBXAFUAVQBXABQA"), 0.0626595, PackedByteArray("HwBWAFQAVgAJAFQAVAAJAAQAVAAEAE0AHwBUAE0ATQAEAB4AHgAEAAMABAAJAAMATQAeABkAHwBNABkAGQAeAB0AHgADAB0AGQAdAEMAQwAdABcAHQBLABcAHQADAGIAHQBiAEsAAwACAGIAAwB3AAIAAwAJAHcAdwAlAAIAdwAJACUACQAvACUAYgACAGEASwBiAGEAAgAlACsAYQACACsASwBhABsAYQArABsAFwBLABsAFwAbABYAKwAlAAUAGwArAAAAKwAFAAAAFgAbABoAGwAAABoAFgAaAD8AGgBcAD8APwBcABQAGgAAAFMAGgBTAFwAXABTABQAAAAFAFUAAABVAFMAUwBVABQABQBXAFUAVQBXABQABQAKAFcAJQAKAAUAJQAuAAoAJQAvAC4ACgBZAFcAVwBZABQACgAPAFkALwBuAC4ALgBuAAoACgAQAA8AbgAQAAoAEAAWAA8ARgAWABAADwAWAD8ADwA/AFkAWQA/ABQAbgBGABAARgAXABYADQBGAG4ALwANAG4ACQANAC8ADQA5AEYAOQAXAEYAQwAXADkAGQBDADkADgA5AA0AEwAZADkADgATADkAWgAZABMAHwAZAFoAWgATAA4AWgAOAFgAHwBaAFgACQAOAA0AWAAOAAkAWAAJAFYAHwBYAFYA"), 0.112059, PackedByteArray("HwBWAFQAVgAJAFQAVAAJAAQAHgAEABoABAAJABoAGgAJAAUAWAAJAFYAHwBYAFYAWAAOAAkACQAOAAUAWgATAA4AHwBaAFgAWgAOAFgAQQATAFoAHwBBAFoADgATAEEADgBBAA8ADgAPAAoADwBBAFkAWQBBABQACgAPAFkACgBZAFcAVwBZABQABQAKAFcABQBXAFUAVQBXABQABQAOAAoAAAAFAFUAAABVAFMAUwBVABQAGgAFAAAAGgAAAFMAGgBTAFwAXABTABQAGgBcAEEAQQBcABQAHwBNAEEATQAeAEEATQAEAB4AVAAEAE0AHwBUAE0AQQAeABoA")],
"primitive": 3,
"uv_scale": Vector4(0, 0, 0, 0),
"vertex_count": 122,
"vertex_data": PackedByteArray("P4da5E85AAAZi0+ryw8AADKZ0m8oGgAAv5qxa18bAAAXi+IxP0EAAOLHkdYwYQAALfDpqktKAAD//yp+dUEAANf3fEXxRQAAncXVLY1iAAClx/rcUKYAAJb2qrQEwgAAHv9nfIe4AACD8LZSarwAALvFXDBHpQAAGov6zB3HAAA1kJGcSewAAC6RroHD6gAAWYtcVPT2AACeinMgOtMAAOmLW+FQhAAAeUMU8VqvAAAFJqaqbb0AAK8U9H7rtgAA/SW6UWa9AAC9UB0xJaUAAJhP5M+sXwAAxyUtq0JKAAAnGbh+YEoAAIokPE+LSQAA3E/dKNhiAACNiogOsHsAAPyI6sjGHAAA5JGFh0UQAAD/maNuLxsAAEaOO0VPKQAAstpAu0ZWAABV+NCUrEUAAJP6YWYNRAAALd/QKwdVAADGqOEw1lEAAJO/ZFBLJgAAecFYeAUmAADNv/yjTyUAAJaqdu/USQAAguHl0fGzAAAo+8SUPMIAAGn5IG50sgAA0dpnQUaxAAB0xR0x+4MAAPbqJmKqiwAA6vKFc5eQAADm8HOrIoQAAHbGDtGagwAA8YsluObfAAB6kP6SP+sAAMqPnHcs7QAAGYthQZneAAAKrRcd8b4AANy951AA2wAA68eyfL7wAACyw5+9ovIAAGqoKtZWuAAABm7//7qUAAAaNabF+rUAAPUb/4/ovQAAKRs/byO7AABhO2VBSbEAACRqziTPvAAAVVYaRoLiAAAQSrd8//8AAIlVm7mb5AAArG2i7orJAABhO++6rVYAAJUbQJQJRQAAnhgrZbhBAAAWOK00AlUAAOht1ypncwAAQCI5R7SEAAAAABGBjYUAACUfCbijgwAAuEWt7Zh5AAC9UB0x+4MAAHyJuN86YgAAGYsnK9BiAAAgqUrjJ3QAAEuoLitecwAAe6gJ1saUAAB4rfATW5EAADSNC+A0qAAAhIkAAG2qAADPaiweBZQAAJZs3unjaQAA2VfPrWorAADnbVfLMVIAAOttwifnUAAAzVPRQD0bAADbSbSEwgMAAPtKCVkAAAAADlCFo14UAAD9YBkpTDUAAD1j77oGQAAALg6DqOGEAABhO2VB+4MAAJUzV8hsgQAAvAtuUo2FAAA4Tt2hAvgAADhjUEEAyAAAtV9j0VvZAAAhT5BaaPUAAPXHN5pU+QAAg7PoPs/JAADNtTfXwNYAABHCBGfH4gAA4/clj/KIAAD/2jNCO4QAAHLburzagwAA/+z/bXyOAACJuZnVgikAAKnBHGdhIQAAJ74eh1kwAACFtcgzCTkAAA==")
}]
blend_shape_mode = 0
[sub_resource type="ArrayMesh" id="ArrayMesh_x6ojl"]
resource_name = "smoke_Sphere"
_surfaces = [{
"aabb": AABB(-0.241608, -0.141804, -0.156025, 0.444652, 0.287726, 0.30263),
"attribute_data": PackedByteArray("qqqqKqqqVVWqqv9/qqqqqqqqVNX/f6oq/39VVf9//3//f6qq/39U1VVVqipVVVVVVVX/f1VVqqpVVVTVqiqqKqoqVVWqKv9/qiqqqqoqVNVVFQAA/z8AAKpqAABUlQAA/78AAKnqAAAAAKoq//+qKgAAVVX//1VVAAD/f////38AAKqq//+qqgAAVNX//1TVVNWqKlTVVVVU1f9/VNWqqlTVVNVVFf///z///6pq//9Ulf///7///6nq//+qqv8/qqqqaqqqVJWqqv+//3//P/9/qmr/f1SV/3//v1SVVNVUlaqqVJX/f1SVVVVUlaoqVVX/P1VVqmpVVVSVVVX/v6pqVNWqaqqqqmr/f6pqVVWqaqoqqir/P6oqqmqqKlSVqir/v/8/VNX/P6qq/z//f/8/VVX/P6oqqgpVFVT1VRUAAP8/////PwAAqmr//6pqAABUlf//VJUAAP+/////v1UVVNVVFaqqVRX/f1UVVVVVFaoqVNX/P1TVqmpU1VSVVNX/v6nKqer/36nqqeqqqqnq/3+p6lVVqeqqKqnqVNX/n1UVVLVVFf+fqepUtanqVHVVFaqKVRVUdanqqoqp6qpKVRX/X1UVqkqp6v9fqer/H1UVVTVVFf8fqepVNanqqgqp6lT1qeqpylUV/99VFf+/VVX/v6oq/79U1f+/qqr/v/9//79Ulf+/qmr/v/+//7//P6nqqmqp6v+/qer/P6nqVJVVFapqVRX/v1UV/z9VFVSV/z+qav8//7//P/8//z9Ulapqqmqqav+/qmr/P6pqVJVUlf8/VJVUlVSVqmpUlf+/qqpU1f9/qir/f6oq/3+qKv9/VNX/f1TVVVWqKlVVqipVVVTVVVVU1VVVVNWqKqoqqiqqKqoqVNVVFQAA/78AAKnqAABU1aoqVNWqKlTVVNVU1VTVVRX///8///+p6v//AACqagAAqmoAAKpq//+qav//qmr//6pqVLVVFf8fVRX/H6nqVTWp6v/fVRWqqqoqqqqqqv9/qir/f1TV/39U1VVVqipVVaoqVVWqqlVVqqqqKlTVAABVVf//VVUAAP9/AAD/f////3////9/VNWqKlTVVVVU1VVVVNWqqlTVVNVVFf///z///6nq////f6pq/3+qav9/qmpUlVVVVVWqalVVqmpVVapqVVVUlVVVVJWqClUVVPVVFVUV/39VFf9/VNVUlVTVVJVUtVUVqkqp6lU1qer/v/9//79Ulf8/qmr/P6pqVJVUlf9//3//f6qqVVVVVf//qir//1VV////f1TVVVVU1f9/VRX///9//z9VVapqVVWqalVVVJX/P1VV/z+qKqoKVRVU9VUV//9UlVTVVJWp6v9/qer/f6nqVVWp6qoqqkqp6v8fqepVNanq/7//f/+/VJWp6lSV/z+qav8/qmr/P1SVVJX/P1SVVJU="),
"format": 34896613399,
"index_count": 720,
"index_data": PackedByteArray("mAAIADgAmAA2AAgAlwAGADoAlwA0AAYAAAA7AGgALABvAGoAlgAHADkAlgA1AAcAlQAFADsAlQAzAAUAKwBzAG4AlAAMAEIAlAA+AAwAkwAKAEQAkwA8AAoAkgANAEEAkgA/AA0AkQALAEMAkQA9AAsABQBEAGwAKgB3AHIAkAARAEsAkABHABEAjwAPAE0AjwBFAA8AjgASAEoAjgBIABIAjQAQAEwAjQBGABAACgBNAHAAKQB4AHYAjAAeAFoAjABUAB4AiwAaAFwAiwBQABoAigAgAFkAigBWACAAiQAcAFsAiQBSABwADwBcAHQAiAAmAGQAiABfACYAhwAkAGYAhwBdACQAhgAnAGMAhgBgACcAhQAlAGUAhQBeACUAGwBmAE8ALgBiAHkAhAAAAH0AhAAvAAAAgwADAH8AgwAyAAMAggABAHwAggAwAAEAJAB9AHoALQBrAGEAgQACAIAAgQAxAAIAfwAxAIEAfwADADEAJwCBAF8AJwB/AIEAXwCAACYAXwCBAIAAawAEAH4AawB+AGEAYQB+ACgAfQAAAGkAfQBpAHoAegBpABgAgAAwAIIAgAACADAAJgCCAF4AJgCAAIIAXgB8ACUAXgCCAHwAfgAyAIMAfgAEADIAKACDAGAAKAB+AIMAYAB/ACcAYACDAH8AfAAvAIQAfAABAC8AJQCEAF0AJQB8AIQAXQB9ACQAXQCEAH0AYgAoAGcAYgBnAHkAeQBnACMAZgAkAHsAZgB7AE8ATwB7ABkAZABeAIUAZAAmAF4AHwCFAFMAHwBkAIUAUwBlAB0AUwCFAGUAZwBgAIYAZwAoAGAAIwCGAFcAIwBnAIYAVwBjACEAVwCGAGMAZQBdAIcAZQAlAF0AHQCHAFEAHQBlAIcAUQBmABsAUQCHAGYAYwBfAIgAYwAnAF8AIQCIAFUAIQBjAIgAVQBkAB8AVQCIAGQAXAAaAE4AXABOAHQAdABOABQAWgBSAIkAWgAeAFIAEQCJAEYAEQBaAIkARgBbABAARgCJAFsAWABWAIoAWAAiAFYAEwCKAEgAEwBYAIoASABZABIASACKAFkAWwBQAIsAWwAcAFAAEACLAEUAEABbAIsARQBcAA8ARQCLAFwAWQBUAIwAWQAgAFQAEgCMAEcAEgBZAIwARwBaABEARwCMAFoAeAAiAFgAeABYAHYAdgBYABMATQAPAHUATQB1AHAAcAB1ABUASwBGAI0ASwARAEYADACNAD0ADABLAI0APQBMAAsAPQCNAEwASQBIAI4ASQATAEgADgCOAD8ADgBJAI4APwBKAA0APwCOAEoATABFAI8ATAAQAEUACwCPADwACwBMAI8APABNAAoAPACPAE0ASgBHAJAASgASAEcADQCQAD4ADQBKAJAAPgBLAAwAPgCQAEsAdwATAEkAdwBJAHIAcgBJAA4ARAAKAHEARABxAGwAbABxABYAQgA9AJEAQgAMAD0ABwCRADQABwBCAJEANABDAAYANACRAEMAQAA/AJIAQAAOAD8ACQCSADYACQBAAJIANgBBAAgANgCSAEEAQwA8AJMAQwALADwABgCTADMABgBDAJMAMwBEAAUAMwCTAEQAQQA+AJQAQQANAD4ACACUADUACABBAJQANQBCAAcANQCUAEIAcwAOAEAAcwBAAG4AbgBAAAkAOgAzAJUAOgAGADMAAQCVAC8AAQA6AJUALwA7AAAALwCVADsAOAA1AJYAOAAIADUAAwCWADEAAwA4AJYAMQA5AAIAMQCWADkAbwAJADcAbwA3AGoAagA3AAQAOwAFAG0AOwBtAGgAaABtABcAOQA0AJcAOQAHADQAAgCXADAAAgA5AJcAMAA6AAEAMACXADoANwA2AJgANwAJADYABACYADIABAA3AJgAMgA4AAMAMgCYADgA"),
"lods": [0.0297894, PackedByteArray("NwDsAAwBNwA2AOwANgANAOwANwAJADYACQCSADYANgCSAA0AbwAJADcAbwA3AGoALABvAGoAagA3AAQACQBAAJIAbgBAAAkAcwBAAG4AKwBzAG4AcwAOAEAAQAA/AJIAQAAOAD8AkgA/AA0ADgBJAD8AAgFJAA4APwAKAQ0APwBJAAoBBAFJAAIBKgAEAQIBBAETAEkASQATAEgASQBIAAoBDQAKAfcA9wAJAfYADQD3AEIA7AANAEIAQgD3APUA7ABCAOsA6wBCAPUADAHsAOsA9wAKAUsA9wBLAAgBCgERAEsACgFIABEASwAQAAgBSwARABAACAEQAPgA9QAIAfgA9QD4AO0A7QD4APkA+AAQAPkA9QDtAJMAEQBbABAA+QAQAA8AEACLAA8AEABbAIsA+QAPAHUA+QB1AHAAcAB1ABUACgD5AHAA7QD5AAoAkwDtAAoADwCLAHQAiwD6AHQAdAD6ABQAiwAaAPoAiwAcABoAWwAcAIsAWwBSABwAWgBSAFsAWgAeAFIAEQBaAFsAjAAeAFoAEQCMAFoAjABUAB4ASACMABEAIABUAIwASAAgAIwASACKACAAigBWACAAEwCKAEgAWABWAIoAEwBYAIoAWAAiAFYAAwFYABMAeAAiAFgAeABYAAMB8wB4AAMBAAA7AGgAaABtABcAOwBtAGgAOwAFAG0ALwA7AAAALwALATsACwEFADsAfAAvAAAAMAALAS8AfAAwAC8AMAA6AAsBfAAAAH0AfQAAAGkAfQBpAHoAegBpABgAJAB9AHoAJAB8AH0ABQEwAHwA8QB8ACQA8QAFAXwAAAHxACQA/wDxAAAB8gAFAfEA/gDyAPEABQECADAAAgA6ADAA/QAFAfIABwHyAP4ABwH9APIA/AAHAf4A/AD+APAA8AD+AAABIQAHAfwA8AAAAVMAUwAAAe8AIQBjAAcBYwD9AAcBVwBjACEA7wAAAQEBAAEkAAEB7wABAe4AAQEkAHsA7gABAfsAAQF7APsA+wB7ABkAIwBjAFcAIwAnAGMAYwAnAP0AJwAGAf0A/QAGAQUBBgECAAUBJwB/AAYBfwACAAYBIwAoACcAKAB/ACcAYgAoACMAYgAjAHkALgBiAHkAKAAEAH8AYQAEACgAawAEAGEALQBrAGEABAAyAH8ABAA3ADIAfwAyAAMAfwADAAIAMgA3AAwBMgAMAQMAAwAMAQIAAgAMATkADAHrADkAAgA5ADoAOQDrADQAOQA0ADoA6wD1ADQANAD1AJMAOgA0APQANACTAPQAOgD0AAsBCwH0AAUA9ACTAAUAkwAKAAUABQAKAHEABQBxAGwAbABxABYA"), 0.0626595, PackedByteArray("LABvAGoAbwC/AGoAagC/AAQAawAEAGEALQBrAGEAYQAEANAA0AAEAL0ABAC/AL0AYgDQACMA0wBiACMAIwDQAM8A0AC9AM8AIwDPAFcAVwDPAMoAzwDhAMoAzwC9AOcAzwDnAF8AvQACAOcAvQDqAAIAvQC/AOoA6gDUAAIA6gDAANYAvwDbANYA5wACAOYA4gDnAOYAAgDUANcA5gACANcA4gDmAM0A5gDXAM0AywDhAM0AywDOAMcA1wDUAL4AzQDXALwA1wC+ALwAxwDNAMwAzQC8AMwAxwDMAN4AzAB7AN4A3gB7ABkAzAC8AOMAzADjAHoAegDjABgAvAC+AG0AvABtAGgAaABtABcAvgBxAGwAbABxABYAvgDBAHEA1QDBAL4A1QDaAMEA1QDcANgAwQB1AHAAcAB1ABUAwQAPAHUA2wDoANgA2QDoAMIAwgAQAA8A6AAQAMIAEADGAA8A4ADGABAADwDGAN0ADwDdAHQAdADdABQA6ADfABAA3wDJAMYAwwDfAOgA2wDDAOkAvwDDANsAwwBIAN8ASADIAN8AVgDIAEgAIgBWAEgADgBIAMMAxQAiAEgADgDFAEgAdgAiAMUA0QAiAHYA5QDFAA4A5QAOAOQA0gDlAOQAvwAOAMQAcwAOAL8AcwC/AG4AKwBzAG4A"), 0.112059, PackedByteArray("LABvAGoAbwAJAGoAagAJAAQArAAEAKoAmQCeAKoAqgCeAJwAcwAJAG4AKwBzAG4AcwCjAAkAnQCjAJsAugCmAKMArwC6AHIAugAOAHIAsQCmALkArgCxALkAoQCmALMAoQCzAKUAoQCkAJ8ApACyALgAuACyAKcACgCkAHUACgB1AHAAcAB1ABUAmgAKAHEAmgBxAGwAbABxABYAmgCiAKAAAACaAG0AAABtAGgAaABtABcAJAAFAAAAJAAAALcAJAC3AHoAegC3AKgAJAC7ALUAtQC7AKkAsABiALQAYgAoALQAYQAEACgAawAEAGEALQBrAGEAtgCtAKsA")],
"material": SubResource("StandardMaterial3D_1upti"),
"primitive": 3,
"uv_scale": Vector4(0, 0, 0, 0),
"vertex_count": 269,
"vertex_data": PackedByteArray("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")
}]
blend_shape_mode = 0
shadow_mesh = SubResource("ArrayMesh_r0r4b")
[sub_resource type="Animation" id="Animation_7yrvu"]
resource_name = "activate"
length = 0.8
length = 4.8
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
@ -99,6 +263,54 @@ tracks/1/keys = {
"method": &"_finish_ability"
}]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("BallMesh/FireballPivot:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0.8, 4.8),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [true, false]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("BallMesh/FireballPivot/FireballScaleRoot/fireball/Fireball:surface_material_override/0:albedo_color")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0.8, 0.9, 4, 4.8),
"transitions": PackedFloat32Array(1, 1, 1.618, 1),
"update": 0,
"values": [Color(1, 0.993333, 0.8, 0), Color(2, 1.98431, 1.6, 0.156863), Color(2, 1.98431, 1.6, 0.156863), Color(1, 0.993333, 0.8, 0)]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("ParticleEffects/SmokeParticles:emitting")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0.9, 4.5),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [true, false]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("SFX/PowerballSFX:playing")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0.333333),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
[sub_resource type="Animation" id="Animation_6c6mi"]
length = 0.001
@ -114,6 +326,54 @@ tracks/0/keys = {
"update": 1,
"values": [false]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("BallMesh/FireballPivot:visible")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("BallMesh/FireballPivot/FireballScaleRoot/fireball/Fireball:surface_material_override/0:albedo_color")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(2, 1.98431, 1.6, 0.156863)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("ParticleEffects/SmokeParticles:emitting")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("SFX/PowerballSFX:playing")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ospg0"]
_data = {
@ -124,10 +384,33 @@ _data = {
[node name="PowerBall" instance=ExtResource("1_14gld")]
freeze_mode = 1
script = ExtResource("2_hy51e")
once_per_shot_ability = true
[node name="BallMesh" parent="." index="0"]
mesh = SubResource("SphereMesh_0b0i7")
[node name="FireballPivot" type="Node3D" parent="BallMesh" index="0"]
unique_name_in_owner = true
visible = false
[node name="FireballScaleRoot" type="Node3D" parent="BallMesh/FireballPivot" index="0"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0)
[node name="fireball" parent="BallMesh/FireballPivot/FireballScaleRoot" index="0" instance=ExtResource("5_i8vmm")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.2, 0)
[node name="Fireball" parent="BallMesh/FireballPivot/FireballScaleRoot/fireball" index="0"]
surface_material_override/0 = SubResource("StandardMaterial3D_aqmuo")
[node name="FireballAnimation" type="AnimationPlayer" parent="BallMesh/FireballPivot" index="1"]
libraries = {
"": SubResource("AnimationLibrary_hmunj")
}
autoplay = "flicker"
[node name="PowerballSFX" type="AudioStreamPlayer3D" parent="SFX" index="3"]
stream = SubResource("AudioStreamRandomizer_jvq4v")
[node name="PowerParticles" type="GPUParticles3D" parent="ParticleEffects" index="1"]
emitting = false
amount = 32
@ -139,8 +422,20 @@ trail_lifetime = 0.4
process_material = SubResource("ParticleProcessMaterial_k07ua")
draw_pass_1 = SubResource("RibbonTrailMesh_elifs")
[node name="SmokeParticles" type="GPUParticles3D" parent="ParticleEffects" index="2"]
emitting = false
amount = 128
lifetime = 4.0
randomness = 0.5
fixed_fps = 60
visibility_aabb = AABB(-50, -50, -50, 100, 100, 100)
process_material = SubResource("ParticleProcessMaterial_6n6nm")
draw_pass_1 = SubResource("ArrayMesh_x6ojl")
[node name="PowerballAnimation" type="AnimationPlayer" parent="." index="7"]
unique_name_in_owner = true
libraries = {
"": SubResource("AnimationLibrary_ospg0")
}
[editable path="BallMesh/FireballPivot/FireballScaleRoot/fireball"]

View File

@ -18,6 +18,8 @@ const SCENE_MAP: Dictionary = {
ball = value
ball_changed.emit(ball)
@export var height_offset := 0.08
@onready var shot_setup: ShotSetup = $".."
@ -41,6 +43,7 @@ func spawn_ball(type: GameBall.Type) -> void:
ball = get_instance(type)
if is_instance_valid(ball):
add_child(ball)
position.y = height_offset + ball.radius
snap()

View File

@ -41,6 +41,7 @@ const WATER_DAMAGE := 10.0
const CURVE_INFLUENCE := PI / 16
## Just enough to make things interesting!
const SHOT_OFFSET_X_FACTOR := 20.0
const SHOT_OFFSET_Z_FACTOR := 2.0 / 45.0
## Impulse offset multiplier due to curve, in meters
@ -135,8 +136,9 @@ var _tracking_camera: OrbitalCamera
@onready var camera: Camera3D = %Camera
@onready var player_pivot: Node3D = %PlayerPivot
@onready var player_offset: Node3D = %PlayerOffset
# TODO: genericize for selectable characters
@onready var character: CharacterController = $PlayerPivot/GfolfGirl
@onready var character: CharacterController = $PlayerPivot/PlayerOffset/GfolfGirl
@onready var shot_animation: AnimationPlayer = %ShotAnimation
@onready var shot_sfx: ShotSFX = %ShotSFX
@ -282,7 +284,10 @@ func take_shot() -> void:
var curve := shot_curve * absf(shot_curve) * CURVE_FACTOR
# Position where the ball is hit (imparts spin)
var offset := direction.global_basis.x.normalized() * -curve
var offset := (
direction.global_basis.x.normalized() * -curve * game_ball.radius * SHOT_OFFSET_X_FACTOR
)
print_debug("Curve offset magnitude: ", offset.length())
offset += (
direction.global_basis.z.normalized()
* game_ball.radius
@ -311,6 +316,7 @@ func _show_shot_projection() -> void:
if not game_ball:
return
shot_projection.set_ball(game_ball)
shot_projection.putt_projection = club_type == Club.Type.PUTTER
shot_projection.initial_speed = 1
shot_projection.basis = Basis.from_euler(Vector3(club.angle, 0, 0))
@ -319,7 +325,6 @@ func _show_shot_projection() -> void:
tween.tween_property(shot_projection, "initial_speed", shot_speed, CAMERA_SNAP_TIME).set_trans(
Tween.TRANS_QUAD
)
shot_projection.linear_damp = game_ball.linear_damp
shot_projection.show()
@ -383,6 +388,9 @@ func travel_to_ball() -> void:
_target_rotation.y = 0
global_basis = game_ball.get_reoriented_basis()
# Adjust position downward to account for ball radius
global_position -= global_basis.y.normalized() * game_ball.radius
ball_point.snap()
@ -507,9 +515,12 @@ func _on_phase_change(new_phase: Phase) -> void:
func _on_game_ball_changed(ball: GameBall) -> void:
var z_offset := 0.0
if ball:
ball.entered_water.connect(_on_ball_entered_water)
ball.sleeping_state_changed.connect(_on_ball_sleeping_state_changed)
z_offset = ball.radius
player_offset.position.z = z_offset
func _process(delta: float) -> void:

View File

@ -456,36 +456,39 @@ bus = &"SFX"
[node name="PlayerPivot" type="Node3D" parent="."]
unique_name_in_owner = true
[node name="GfolfGirl" parent="PlayerPivot" instance=ExtResource("3_e4aur")]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -0.555968, 0, 0.0999683)
[node name="PlayerOffset" type="Node3D" parent="PlayerPivot"]
unique_name_in_owner = true
[node name="DemoCamera" type="Camera3D" parent="PlayerPivot" groups=["DemoCamera"]]
[node name="GfolfGirl" parent="PlayerPivot/PlayerOffset" instance=ExtResource("3_e4aur")]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -0.556, 0, 0.05)
[node name="DemoCamera" type="Camera3D" parent="PlayerPivot/PlayerOffset" groups=["DemoCamera"]]
transform = Transform3D(-0.311543, -0.0687373, 0.947743, 0, 0.99738, 0.0723374, -0.950232, 0.0225362, -0.310727, 0.845792, 0.706621, -0.383459)
[node name="DeathSequence" type="Node3D" parent="PlayerPivot"]
[node name="DeathSequence" type="Node3D" parent="PlayerPivot/PlayerOffset"]
process_mode = 3
script = ExtResource("10_vakjm")
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer" parent="PlayerPivot/DeathSequence"]
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer" parent="PlayerPivot/PlayerOffset/DeathSequence"]
stream = SubResource("AudioStreamRandomizer_7seum")
volume_db = -4.0
bus = &"SFX"
[node name="DeathAnimation" type="AnimationPlayer" parent="PlayerPivot/DeathSequence"]
[node name="DeathAnimation" type="AnimationPlayer" parent="PlayerPivot/PlayerOffset/DeathSequence"]
unique_name_in_owner = true
libraries = {
"": SubResource("AnimationLibrary_kc803")
}
[node name="Camera3D1" type="Camera3D" parent="PlayerPivot/DeathSequence"]
[node name="Camera3D1" type="Camera3D" parent="PlayerPivot/PlayerOffset/DeathSequence"]
transform = Transform3D(-0.00257592, 0.0226116, 0.999741, 0, 0.999744, -0.0226116, -0.999997, -5.82457e-05, -0.00257526, 1.6905, 0.831287, 0.0668699)
far = 8192.0
[node name="Camera3D2" type="Camera3D" parent="PlayerPivot/DeathSequence"]
[node name="Camera3D2" type="Camera3D" parent="PlayerPivot/PlayerOffset/DeathSequence"]
transform = Transform3D(0.864734, -0.175509, 0.470564, 0, 0.936951, 0.349461, -0.502229, -0.302191, 0.810214, 0.386249, 1.16999, 0.906541)
far = 8192.0
[node name="Camera3D3" type="Camera3D" parent="PlayerPivot/DeathSequence"]
[node name="Camera3D3" type="Camera3D" parent="PlayerPivot/PlayerOffset/DeathSequence"]
transform = Transform3D(0.00178714, 0.559853, 0.82859, 0, 0.828592, -0.559853, -0.999998, 0.00100054, 0.00148081, 0.334412, 0.629604, 0.136928)
far = 8192.0
@ -571,7 +574,7 @@ loop_animation = 1
[node name="ShotProjection" parent="ArrowPivot" instance=ExtResource("4_ry2ho")]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 0.707107, -0.707107, 0, 0.707107, 0.707107, 0, -0.02, 0)
transform = Transform3D(1, 0, 0, 0, 0.707107, -0.707107, 0, 0.707107, 0.707107, 0, 0, 0)
visible = false
initial_speed = 50.0
time_step = 0.1

View File

@ -27,7 +27,7 @@ const PUTT_ATTRITION := 0.8325 # green?
## Uses continuous collision detection.
@export var check_collision := true
## Mask for collision checking.
@export_flags_3d_physics var collision_mask := 1
@export_flags_3d_physics var collision_mask := 1 | 2
## Bodies excluded from collision checking.
## This should probably include the ball!
@export var excluded_bodies: Array[CollisionObject3D] = []
@ -61,6 +61,11 @@ var _cached_vel: Vector3
@onready var debug_draw: Control = %DebugDraw
func set_ball(ball: GameBall) -> void:
global_position = ball.global_position
linear_damp = ball.linear_damp
func _process(_delta: float) -> void:
if not visible:
# Don't bother if we're not visible

View File

@ -7,6 +7,7 @@
[node name="FreeCamera" type="CharacterBody3D"]
process_mode = 3
collision_layer = 0
collision_mask = 3
script = ExtResource("1_3gm3q")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=10 format=3 uid="uid://cwnwcd8kushl3"]
[gd_scene load_steps=8 format=3 uid="uid://cwnwcd8kushl3"]
[ext_resource type="Script" path="res://src/world/world.gd" id="1_ybjyx"]
[ext_resource type="PackedScene" uid="uid://bm2o3mex10v11" path="res://levels/debug_level/debug_level.tscn" id="2_0xu5a"]
@ -6,22 +6,10 @@
[ext_resource type="Script" path="res://src/ui/world_ui.gd" id="2_imewa"]
[ext_resource type="Resource" uid="uid://crock3revdn73" path="res://src/player/debug_player.tres" id="3_pyw81"]
[ext_resource type="Script" path="res://src/world/play_manager/round_robin_manager.gd" id="5_h6mje"]
[ext_resource type="Resource" uid="uid://c1pnqsddvey3m" path="res://src/equipment/clubs/drivers/debug_driver.tres" id="5_u5ok3"]
[sub_resource type="Resource" id="Resource_njyo4"]
script = ExtResource("2_e743i")
life = 4.0
name = "Gfolfer2"
color = Color(1, 0.439216, 0.439216, 1)
driver = ExtResource("5_u5ok3")
_balls = {
1: -1,
2: -1
}
[sub_resource type="Resource" id="Resource_rdjhi"]
script = ExtResource("5_h6mje")
players = Array[ExtResource("2_e743i")]([ExtResource("3_pyw81"), SubResource("Resource_njyo4")])
players = Array[ExtResource("2_e743i")]([ExtResource("3_pyw81")])
[node name="World" type="Node" groups=["WorldGroup"]]
script = ExtResource("1_ybjyx")