Fix casting beneath overhangs
This commit is contained in:
parent
40696b6bd9
commit
deab51a18a
4 changed files with 46 additions and 8 deletions
|
|
@ -56,6 +56,7 @@ var _rod: Node3D
|
|||
var _rod_tip: Marker3D
|
||||
var _rod_neutral_rotation: Vector3
|
||||
var _cast_arrival_position: Vector3
|
||||
var _active_cast_arc_height: float = 0.0
|
||||
var _cast_tracks_water_surface: bool = false
|
||||
var _bobber_surface_position: Vector3
|
||||
var _bobber_idle_elapsed: float = 0.0
|
||||
|
|
@ -153,6 +154,7 @@ func begin_cast(
|
|||
target: Vector3,
|
||||
blocked_landing_position: Vector3 = Vector3.ZERO,
|
||||
cast_is_blocked: bool = false,
|
||||
resolved_arc_height: float = -1.0,
|
||||
) -> void:
|
||||
if _mode != VisualMode.AIMING or _rod_tip == null:
|
||||
return
|
||||
|
|
@ -165,6 +167,11 @@ func begin_cast(
|
|||
_cast_arrival_position = (
|
||||
blocked_landing_position if cast_is_blocked else target
|
||||
)
|
||||
_active_cast_arc_height = (
|
||||
maxf(resolved_arc_height, 0.0)
|
||||
if resolved_arc_height >= 0.0
|
||||
else cast_arc_height
|
||||
)
|
||||
_cast_tracks_water_surface = not cast_is_blocked
|
||||
|
||||
var cast_start: Vector3 = _rod_tip.global_position
|
||||
|
|
@ -302,6 +309,7 @@ func cleanup() -> void:
|
|||
_bobber_base_scale = Vector3.ONE
|
||||
_bobber.rotation = Vector3.ZERO
|
||||
_cast_arrival_position = Vector3.ZERO
|
||||
_active_cast_arc_height = 0.0
|
||||
_cast_tracks_water_surface = false
|
||||
_bobber_surface_position = Vector3.ZERO
|
||||
_bobber_idle_elapsed = 0.0
|
||||
|
|
@ -319,7 +327,7 @@ func _set_cast_sample(
|
|||
target: Vector3,
|
||||
) -> void:
|
||||
var sample: Vector3 = start.lerp(target, progress)
|
||||
sample.y += sin(progress * PI) * cast_arc_height
|
||||
sample.y += sin(progress * PI) * _active_cast_arc_height
|
||||
if _cast_tracks_water_surface:
|
||||
sample.y += (
|
||||
WaterSurfaceMotionType.get_default_height_offset()
|
||||
|
|
|
|||
|
|
@ -783,19 +783,31 @@ func _confirm_cast() -> void:
|
|||
return
|
||||
|
||||
var cast_launch_position := _get_cast_launch_position()
|
||||
_cast_path_is_clear = is_cast_path_clear(
|
||||
var resolved_cast_arc: Dictionary = _surface_resolver.resolve_cast_arc(
|
||||
get_world_3d().direct_space_state,
|
||||
cast_launch_position,
|
||||
_cast_target,
|
||||
_presentation.cast_arc_height,
|
||||
)
|
||||
var resolved_arc_height: float = float(
|
||||
resolved_cast_arc.get("arc_height", _presentation.cast_arc_height)
|
||||
)
|
||||
var resolved_cast_collision: Dictionary = resolved_cast_arc.get(
|
||||
"collision",
|
||||
{},
|
||||
)
|
||||
_cast_path_is_clear = resolved_cast_collision.is_empty()
|
||||
var cast_is_invalid: bool = (
|
||||
not _aim_surface_sample.is_fishable() or not _cast_path_is_clear
|
||||
)
|
||||
var arrival_position: Vector3 = _cast_target
|
||||
if not _cast_path_is_clear:
|
||||
arrival_position = _resolve_cast_impact_position(
|
||||
cast_launch_position,
|
||||
var collision_position: Variant = resolved_cast_collision.get(
|
||||
"position",
|
||||
_cast_target,
|
||||
)
|
||||
if typeof(collision_position) == TYPE_VECTOR3:
|
||||
arrival_position = collision_position
|
||||
if _active_player != null:
|
||||
# Movement is available while aiming, then locks once the cast is
|
||||
# released so the active bobber/fishing event remains anchored.
|
||||
|
|
@ -806,6 +818,7 @@ func _confirm_cast() -> void:
|
|||
_cast_target,
|
||||
arrival_position,
|
||||
cast_is_invalid,
|
||||
resolved_arc_height,
|
||||
)
|
||||
_presentation.set_line_mode(FishingPresentationType.LineMode.TAUT)
|
||||
|
||||
|
|
@ -1410,6 +1423,7 @@ func resolve_fishing_surface(
|
|||
get_world_3d().direct_space_state,
|
||||
target,
|
||||
resolved_reference_y,
|
||||
water_occlusion_tolerance,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ func resolve_surface(
|
|||
space_state: PhysicsDirectSpaceState3D,
|
||||
query_position: Vector3,
|
||||
reference_y: float,
|
||||
maximum_solid_rise: float = INF,
|
||||
) -> FishingSurfaceSampleType:
|
||||
var sample := FishingSurfaceSampleType.new()
|
||||
var ray_top: float = maxf(query_position.y, reference_y) + ray_start_height
|
||||
|
|
@ -33,10 +34,16 @@ func resolve_surface(
|
|||
ray_top,
|
||||
ray_bottom,
|
||||
)
|
||||
var solid_hit: Dictionary = _find_top_solid_surface(
|
||||
var solid_ray_top: float = minf(
|
||||
ray_top,
|
||||
reference_y + maximum_solid_rise,
|
||||
)
|
||||
var solid_hit: Dictionary = {}
|
||||
if solid_ray_top > ray_bottom:
|
||||
solid_hit = _find_top_solid_surface(
|
||||
space_state,
|
||||
query_position,
|
||||
ray_top,
|
||||
solid_ray_top,
|
||||
ray_bottom,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ func _validate_resolver_layers() -> void:
|
|||
_add_solid_box(world, Vector3(40.0, 2.0, 12.0), Vector3(10.0, -1.0, 0.0))
|
||||
_add_water_region(world, Vector3(0.0, 2.0, 0.0), Vector2(8.0, 8.0), PondPool)
|
||||
_add_solid_box(world, Vector3(1.0, 1.0, 1.0), Vector3(2.0, 2.25, 0.0))
|
||||
_add_solid_box(world, Vector3(1.0, 1.0, 1.0), Vector3(-2.0, 6.0, 0.0))
|
||||
_add_water_region(world, Vector3(10.0, 5.0, 0.0), Vector2(6.0, 6.0), PondPool)
|
||||
_add_water_region(world, Vector3(20.0, 3.0, 0.0), Vector2(6.0, 6.0), null)
|
||||
await physics_frame
|
||||
|
|
@ -64,6 +65,14 @@ func _validate_resolver_layers() -> void:
|
|||
)
|
||||
assert(water.is_fishable())
|
||||
assert(is_equal_approx(water.position.y, 2.0))
|
||||
var water_under_overhang: FishingSurfaceSampleType = resolver.resolve_surface(
|
||||
space_state,
|
||||
Vector3(-2.0, 4.0, 0.0),
|
||||
4.0,
|
||||
0.08,
|
||||
)
|
||||
assert(water_under_overhang.is_fishable())
|
||||
assert(is_equal_approx(water_under_overhang.position.y, 2.0))
|
||||
|
||||
var covered_water: FishingSurfaceSampleType = resolver.resolve_surface(
|
||||
space_state,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue