Win, lose screen. Game version info. Matador a lot more aggressive/wins easier (tweaks needed). No more score/combo/waves
This commit is contained in:
@@ -38,6 +38,7 @@ var _ability_timer: float = 0.0
|
||||
var _active_ability: int = -1
|
||||
var _dash_dir: Vector3 = Vector3.ZERO
|
||||
var _roll_dir: Vector3 = Vector3.ZERO
|
||||
var _roll_ramp: float = 0.0
|
||||
var _bull_anim: AnimationPlayer = null
|
||||
|
||||
var _charge_ready_emitter: CPUParticles3D = null
|
||||
@@ -54,9 +55,11 @@ var _charge_bar_ramp: Gradient = null
|
||||
var _charge_bar_time: float = 0.0
|
||||
var _charge_bar_shown: float = 0.0
|
||||
|
||||
const MAX_HEALTH: int = 10
|
||||
var health: int = MAX_HEALTH
|
||||
signal health_changed(new_health: int)
|
||||
# One clean hit ends the run — see take_sword_hit(). The HUD listens for `died`
|
||||
# to raise the lose screen (the `cause` tags how it happened, for the death notice);
|
||||
# _dead latches so a flurry of hits fires it only once.
|
||||
signal died(cause: String)
|
||||
var _dead: bool = false
|
||||
|
||||
var _huff_player: AudioStreamPlayer = null
|
||||
var _crowd_player: AudioStreamPlayer = null
|
||||
@@ -460,15 +463,16 @@ func _activate_roll() -> void:
|
||||
_ability_active = true
|
||||
_active_ability = 3
|
||||
_ability_timer = DP.f("roll_duration")
|
||||
# Combine with any charge already underway: keep the current heading + speed,
|
||||
# floored to a launch minimum so even a standing roll shoves off like a boulder.
|
||||
_roll_ramp = 0.0
|
||||
# Curl into the ball along the current heading (or facing when standing still)
|
||||
# and launch at the base speed — it ramps up from here the longer you roll.
|
||||
var flat := Vector3(velocity.x, 0.0, velocity.z)
|
||||
if flat.length() > 1.0:
|
||||
_roll_dir = flat.normalized()
|
||||
else:
|
||||
var f := cube_guy.global_transform.basis.z
|
||||
_roll_dir = Vector3(f.x, 0.0, f.z).normalized()
|
||||
var launch := maxf(flat.length(), DP.f("roll_min_speed"))
|
||||
var launch := DP.f("roll_base_speed")
|
||||
velocity.x = _roll_dir.x * launch
|
||||
velocity.z = _roll_dir.z * launch
|
||||
if _bull_anim and _bull_anim.has_animation(_ANIM_ROLL):
|
||||
@@ -483,23 +487,21 @@ func _activate_roll() -> void:
|
||||
_huff_player.play()
|
||||
|
||||
|
||||
# One rolling frame: steer, ramp/retain speed, move, then ricochet off walls and
|
||||
# bowl through matadors. Fully replaces the normal locomotion path while active.
|
||||
# One rolling frame (Rammus Powerball): steer with momentum, accelerate the longer
|
||||
# the roll lasts, move (walls just slide), then pop the ball on the first matador we
|
||||
# ram. Fully replaces the normal locomotion path while active.
|
||||
func _tick_roll(delta: float, steer: Vector3) -> void:
|
||||
var steer_flat := Vector3(steer.x, 0.0, steer.z)
|
||||
if steer_flat.length() > 0.1:
|
||||
var t := clampf(DP.f("roll_turn") * delta, 0.0, 1.0)
|
||||
_roll_dir = _roll_dir.slerp(steer_flat.normalized(), t).normalized()
|
||||
|
||||
# Ramp toward the cruise top speed; anything above it (from wall boosts) bleeds
|
||||
# off slowly via roll_momentum instead of snapping back — that's the fun carry.
|
||||
var speed := Vector2(velocity.x, velocity.z).length()
|
||||
# Speed builds over time: base → max across roll_rampup_time, so a long roll
|
||||
# winds up into a runaway boulder while a quick tap barely gets going.
|
||||
_roll_ramp += delta
|
||||
var ramp := clampf(_roll_ramp / maxf(DP.f("roll_rampup_time"), 0.01), 0.0, 1.0)
|
||||
var top := DP.f("roll_max_speed")
|
||||
if speed < top:
|
||||
speed = move_toward(speed, top, DP.f("roll_accel") * delta)
|
||||
else:
|
||||
speed = maxf(top, speed * pow(DP.f("roll_momentum"), delta))
|
||||
speed = minf(speed, DP.f("roll_wall_cap"))
|
||||
var speed := lerpf(DP.f("roll_base_speed"), top, ramp)
|
||||
velocity.x = _roll_dir.x * speed
|
||||
velocity.z = _roll_dir.z * speed
|
||||
|
||||
@@ -511,40 +513,43 @@ func _tick_roll(delta: float, steer: Vector3) -> void:
|
||||
if _charge_trail_emitter:
|
||||
_charge_trail_emitter.direction = (-_roll_dir + Vector3(0.0, 0.25, 0.0)).normalized()
|
||||
|
||||
var pre_wall := Vector3(velocity.x, 0.0, velocity.z)
|
||||
move_and_slide()
|
||||
_was_on_floor = is_on_floor()
|
||||
_roll_wall_ricochet(pre_wall)
|
||||
# Bowling strike: fling matadors we plow into up and outward like pins (and the
|
||||
# resulting kills feed the HUD combo meter).
|
||||
_hit_matadors_radius(DP.f("roll_hit_radius"), DP.f("roll_hit_strength"), DP.f("roll_hit_up"))
|
||||
_roll_try_pop(speed)
|
||||
|
||||
|
||||
# On hitting a wall mid-roll, mirror the heading and BOOST speed (capped) instead of
|
||||
# bleeding it — banking off walls is how you build ludicrous momentum.
|
||||
func _roll_wall_ricochet(pre_wall: Vector3) -> void:
|
||||
for i in get_slide_collision_count():
|
||||
var col := get_slide_collision(i)
|
||||
var normal := col.get_normal()
|
||||
if absf(normal.y) >= 0.5:
|
||||
# Pop the ball on ramming a matador: launch every matador in the hit radius up and
|
||||
# outward, then end the roll (Rammus stops when Powerball connects). Returns true if
|
||||
# it popped so the caller can stop touching roll state this frame.
|
||||
func _roll_try_pop(speed: float) -> bool:
|
||||
var radius := DP.f("roll_hit_radius")
|
||||
for mat: Node in get_tree().get_nodes_in_group(&"matador"):
|
||||
var to_mat: Vector3 = (mat as Node3D).global_position - global_position
|
||||
to_mat.y = 0.0
|
||||
if to_mat.length() > radius:
|
||||
continue
|
||||
var flat_n := Vector3(normal.x, 0.0, normal.z).normalized()
|
||||
var refl := pre_wall - 2.0 * pre_wall.dot(flat_n) * flat_n
|
||||
refl.y = 0.0
|
||||
if refl.length() < 0.01:
|
||||
return
|
||||
_roll_dir = refl.normalized()
|
||||
var boosted := minf(pre_wall.length() * DP.f("roll_wall_boost"), DP.f("roll_wall_cap"))
|
||||
velocity.x = _roll_dir.x * boosted
|
||||
velocity.z = _roll_dir.z * boosted
|
||||
var hit := col.get_position()
|
||||
_spawn_kick_sparks(hit, flat_n)
|
||||
_spawn_kick_flash(hit)
|
||||
camera_pivot.call(&"trigger_hit", clampf(boosted / 90.0, 0.25, 1.0))
|
||||
_hit_matadors_radius(radius, DP.f("roll_hit_strength"), DP.f("roll_knockup"))
|
||||
camera_pivot.call(&"trigger_hit", clampf(speed / 90.0, 0.35, 1.0))
|
||||
if _huff_player:
|
||||
_huff_player.pitch_scale = randf_range(1.05, 1.35)
|
||||
_huff_player.play()
|
||||
return
|
||||
_end_roll()
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
# 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
|
||||
_ability_timer = 0.0
|
||||
_roll_ramp = 0.0
|
||||
_legs.set(&"charge_pitch_target", 0.0)
|
||||
_legs.set(&"tail_ragdoll", false)
|
||||
velocity.x *= 0.15
|
||||
velocity.z *= 0.15
|
||||
_play_idle()
|
||||
|
||||
|
||||
func _hit_matadors_cone(range_m: float, half_angle_rad: float, strength: float,
|
||||
@@ -1065,6 +1070,11 @@ func _physics_process(delta: float) -> void:
|
||||
# ── Hoof sounds ───────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
func take_sword_hit() -> void:
|
||||
health = maxi(0, health - 1)
|
||||
health_changed.emit(health)
|
||||
# A single clean hit — thrown or swung blade — ends the run. `cause` ("gored" /
|
||||
# "thrown") tags how it happened for the death notice. Latches so the lose screen is
|
||||
# raised exactly once even if several blades land on the same frame.
|
||||
func take_sword_hit(cause: String = "") -> void:
|
||||
if _dead:
|
||||
return
|
||||
_dead = true
|
||||
died.emit(cause)
|
||||
|
||||
Reference in New Issue
Block a user