gfolf2/src/equipment/balls/physics_ball/game_ball.gd

66 lines
1.6 KiB
GDScript3
Raw Normal View History

2024-11-11 18:39:12 +00:00
class_name GameBall extends RigidBody3D
## Base class for all gfolf balls
signal entered_water
2024-11-13 01:16:30 +00:00
2024-11-13 03:03:05 +00:00
const TERRAIN_DAMPING_EPSILON := 1e-6
const IRON_DAMPING := 9999.0
2024-11-13 01:16:30 +00:00
## Angular damping while in air
@export var air_damping := 0.0
## Angular damping while in collision with rough terrain
@export var rough_damping := 8.0
2024-11-13 03:03:05 +00:00
## Angular damping for iron balls
@export var iron_damping := 9999.0
## Causes the ball to act more like a brick
@export var iron_ball := false:
set(value):
if value:
physics_material_override = iron_physics
else:
physics_material_override = normal_physics
iron_ball = value
var _zones: Array[BallZone] = []
2024-11-17 21:07:28 +00:00
@onready var normal_physics: PhysicsMaterial = preload(
"res://src/equipment/balls/physics_ball/normal_physics.tres"
)
@onready var iron_physics: PhysicsMaterial = preload(
"res://src/equipment/balls/physics_ball/iron_physics.tres"
)
2024-11-13 03:03:05 +00:00
## Called by a water area when this ball enters it
func enter_water() -> void:
entered_water.emit()
func _total_terrain_angular_damping() -> float:
return _zones.reduce(
func(a: float, b: BallZone) -> float: return a + b.terrain_angular_damping, 0.0
)
2024-11-13 01:16:30 +00:00
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
2024-11-13 03:03:05 +00:00
var damping := air_damping
if iron_ball:
damping = iron_damping
elif state.get_contact_count():
damping = _total_terrain_angular_damping()
if damping <= TERRAIN_DAMPING_EPSILON:
damping = rough_damping
angular_damp = damping
func enter_zone(zone: BallZone) -> void:
_zones.push_back(zone)
if zone.water_hazard:
entered_water.emit()
func exit_zone(zone: BallZone) -> void:
_zones.erase(zone)