generated from krampus/template-godot4
64 lines
1.6 KiB
GDScript
64 lines
1.6 KiB
GDScript
class_name GameBall extends RigidBody3D
|
|
## Base class for all gfolf balls
|
|
|
|
signal entered_water
|
|
|
|
const TERRAIN_DAMPING_EPSILON := 1e-6
|
|
const IRON_DAMPING := 9999.0
|
|
|
|
## 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
|
|
## 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] = []
|
|
|
|
@onready
|
|
var normal_physics: PhysicsMaterial = preload("res://src/player/physics_ball/normal_physics.tres")
|
|
@onready
|
|
var iron_physics: PhysicsMaterial = preload("res://src/player/physics_ball/iron_physics.tres")
|
|
|
|
|
|
## 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
|
|
)
|
|
|
|
|
|
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
|
|
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)
|