Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ build/
bin/
.sconsign.dblite
*.obj
*.obj.import
*.tmp
*.log

Expand Down
38 changes: 29 additions & 9 deletions actors/bosses/town/emperor_boss.gd
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,17 @@ var burst_center: Vector2 = Vector2.ZERO
var shadow_reposition_point: Vector2 = Vector2.ZERO
var body_sprite: Sprite2D = null
var weapon_sprite: Sprite2D = null
var weapon_angle_offset: float = deg_to_rad(64.0)
var weapon_angle_offset: float = 0.0
var visual_last_position: Vector2 = Vector2.ZERO
var visual_bob_time: float = 0.0

func _ready() -> void:
add_to_group("damageable")
health_component.setup(max_hp, defense_value)
health_component.damaged.connect(_on_damaged)
health_component.died.connect(_on_died)
hp = max_hp
visual_last_position = global_position
_setup_body_visual()
_setup_weapon_visual()
burst_ring.visible = false
Expand Down Expand Up @@ -158,7 +161,7 @@ func _start_basic_attack() -> void:
state_time = 0.0
action_committed = false
attack_cooldown = attack_interval
_animate_weapon_swing(-112.0, 38.0, 0.26)
_animate_weapon_swing(-42.0, 20.0, 0.26)

func _process_basic_attack() -> void:
if not action_committed and state_time >= 0.24:
Expand Down Expand Up @@ -187,7 +190,7 @@ func _start_skill_cast() -> void:
charge_direction = (target.global_position - global_position).normalized() if target != null else line_direction
if charge_direction == Vector2.ZERO:
charge_direction = Vector2.RIGHT
_animate_weapon_swing(-124.0, -18.0, 0.32)
_animate_weapon_swing(-46.0, 12.0, 0.32)
&"burst":
state = &"skill_burst"
burst_center = target.global_position if target != null else global_position
Expand All @@ -197,7 +200,7 @@ func _start_skill_cast() -> void:
burst_ring.modulate = Color(0.82, 0.9, 1.0, 0.92)
&"volley":
state = &"skill_volley"
_animate_weapon_swing(-44.0, 18.0, 0.24)
_animate_weapon_swing(-28.0, 12.0, 0.24)

func _pick_skill() -> StringName:
var pool: Array[StringName] = [&"shadow", &"charge", &"burst", &"volley"]
Expand All @@ -213,7 +216,7 @@ func _process_skill_shadow() -> void:
line_direction = (target.global_position - global_position).normalized()
if line_direction == Vector2.ZERO:
line_direction = Vector2.RIGHT
_animate_weapon_swing(-138.0, 46.0, 0.18)
_animate_weapon_swing(-44.0, 18.0, 0.18)
_hit_target_in_arc(112.0, shadow_step_slash_damage, 145.0)
_spawn_slash_effect(112.0, Color(0.8, 0.9, 1.0, 0.95))
if state_time >= shadow_step_duration:
Expand Down Expand Up @@ -349,7 +352,7 @@ func _setup_body_visual() -> void:
body_sprite.texture = TEXTURE_LOADER.load_texture(EMPEROR_BODY_TEXTURE_PATH)
body_sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
body_sprite.centered = true
body_sprite.scale = Vector2.ONE * 0.40
body_sprite.scale = Vector2.ONE * 0.34
body.add_child(body_sprite)
body.color = Color(1.0, 1.0, 1.0, 0.0)

Expand All @@ -364,8 +367,8 @@ func _setup_weapon_visual() -> void:
weapon_sprite.texture = TEXTURE_LOADER.load_texture(EMPEROR_WEAPON_TEXTURE_PATH)
weapon_sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
weapon_sprite.centered = true
weapon_sprite.scale = Vector2.ONE * 0.42
weapon_sprite.position = Vector2(-40.0, 8.0)
weapon_sprite.scale = Vector2.ONE * 0.70
weapon_sprite.position = Vector2(-64.0, 8.0)
weapon.add_child(weapon_sprite)

func _animate_weapon_swing(start_degrees: float, end_degrees: float, duration: float) -> void:
Expand All @@ -383,10 +386,27 @@ func _update_visuals() -> void:
body.modulate = Color(1.0, 1.0, 1.0, 0.8)
else:
body.modulate = Color.WHITE
_apply_body_motion(0.9, 0.025, 0.012)
phase_ring.default_color = Color(1.0, 0.84, 0.52, 0.88)
weapon.position = line_direction * 22.0 + Vector2(0.0, 0.0)
weapon.rotation = line_direction.angle() + weapon_angle_offset
weapon.rotation = _weapon_guard_rotation(line_direction, -48.0) + weapon_angle_offset
projectile_spawner.position = line_direction * 24.0
visual_last_position = global_position

func _weapon_guard_rotation(direction: Vector2, guard_degrees: float) -> float:
var facing := direction.normalized() if direction.length_squared() > 0.0001 else Vector2.RIGHT
var side_sign := -1.0 if facing.x < -0.05 else 1.0
return facing.angle() + deg_to_rad(guard_degrees * side_sign)

func _apply_body_motion(bob_scale: float, sway_scale: float, idle_sway: float) -> void:
var movement := global_position - visual_last_position
var motion_ratio := clampf(movement.length() / maxf(move_speed * get_physics_process_delta_time(), 1.0), 0.0, 1.0)
visual_bob_time += 0.08 + motion_ratio * 0.12
var facing := -1.0 if line_direction.x < -0.05 else 1.0
if body_sprite != null:
body_sprite.flip_h = facing < 0.0
body.position = Vector2(0.0, sin(visual_bob_time) * (1.0 + motion_ratio * 3.0) * bob_scale)
body.rotation = sin(visual_bob_time * 0.55) * (idle_sway + motion_ratio * sway_scale) * facing

func _spawn_damage_number(amount: float, is_critical: bool) -> void:
var damage_number := DAMAGE_NUMBER_SCENE.instantiate()
Expand Down
18 changes: 17 additions & 1 deletion actors/bosses/town/guard_unit.gd
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func _process_idle(delta: float) -> void:
var to_target := target.global_position - global_position
var distance := to_target.length()
if distance > 0.0:
sword.rotation = to_target.angle()
sword.rotation = _sword_visual_rotation(to_target)
if _can_use_skills() and skill2_cooldown_remaining <= 0.0 and distance <= 190.0:
_start_sweep()
return
Expand Down Expand Up @@ -240,6 +240,22 @@ func _update_visuals() -> void:
body.color = base_color
aura_ring.visible = immune
aura_ring.default_color = Color(0.8, 0.92, 1.0, 0.75) if immune else Color(1.0, 0.84, 0.5, 0.0)
if target != null and is_instance_valid(target):
var to_target := target.global_position - global_position
if to_target.length_squared() > 0.0001:
sword.rotation = _sword_visual_rotation(to_target)

func _sword_visual_rotation(direction: Vector2) -> float:
var facing := direction.normalized() if direction.length_squared() > 0.0001 else Vector2.RIGHT
var side_sign := -1.0 if facing.x < -0.05 else 1.0
var guard_degrees := -44.0
if state == &"basic_attack":
var attack_progress := clampf(state_time / 0.42, 0.0, 1.0)
guard_degrees = lerpf(-52.0, 18.0, attack_progress)
elif state == &"skill_2_sweep":
var sweep_progress := clampf(state_time / 2.0, 0.0, 1.0)
guard_degrees = lerpf(-60.0, 24.0, sweep_progress)
return facing.angle() + deg_to_rad(guard_degrees * side_sign)

func _spawn_damage_number(amount: float, is_critical: bool) -> void:
var damage_number := DAMAGE_NUMBER_SCENE.instantiate()
Expand Down
32 changes: 27 additions & 5 deletions actors/bosses/town/judicator_boss.gd
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,13 @@ var slow_time_remaining: float = 0.0
var slow_factor: float = 1.0
var body_sprite: Sprite2D = null
var sword_sprite: Sprite2D = null
var sword_angle_offset: float = deg_to_rad(56.0)
var sword_angle_offset: float = 0.0
var enraged: bool = false
var slam_aftershock_committed: bool = false
var barrage_wave_index: int = 0
var barrage_next_wave_time: float = 0.0
var visual_last_position: Vector2 = Vector2.ZERO
var visual_bob_time: float = 0.0

func _ready() -> void:
add_to_group("damageable")
Expand All @@ -79,6 +81,7 @@ func _ready() -> void:
health_component.defense_changed.connect(_on_defense_changed)
health_component.died.connect(_on_died)
hp = max_hp
visual_last_position = global_position
_setup_body_visual()
_setup_weapon_visual()
landing_ring.visible = false
Expand Down Expand Up @@ -413,7 +416,7 @@ func _setup_body_visual() -> void:
body_sprite.texture = TEXTURE_LOADER.load_texture(JUDICATOR_BODY_TEXTURE_PATH)
body_sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
body_sprite.centered = true
body_sprite.scale = Vector2.ONE * 0.40
body_sprite.scale = Vector2.ONE * 0.36
body.add_child(body_sprite)
body.color = Color(1.0, 1.0, 1.0, 0.0)

Expand All @@ -428,8 +431,8 @@ func _setup_weapon_visual() -> void:
sword_sprite.texture = TEXTURE_LOADER.load_texture(JUDICATOR_WEAPON_TEXTURE_PATH)
sword_sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
sword_sprite.centered = true
sword_sprite.scale = Vector2.ONE * 0.44
sword_sprite.position = Vector2(-36.0, 4.0)
sword_sprite.scale = Vector2.ONE * 0.68
sword_sprite.position = Vector2(-62.0, 4.0)
sword.add_child(sword_sprite)
sword.color = Color(1.0, 1.0, 1.0, 0.0)

Expand All @@ -452,7 +455,8 @@ func _update_visuals() -> void:
if to_target != Vector2.ZERO:
sword_direction = to_target.normalized()
sword.position = sword_direction * 18.0 + Vector2(0.0, 2.0)
sword.rotation = sword_direction.angle() + sword_angle_offset
sword.rotation = _weapon_guard_rotation(sword_direction, -46.0) + sword_angle_offset
_apply_heavy_body_motion()
var pulse := 0.82 + 0.18 * sin(Time.get_ticks_msec() * 0.01)
if landing_ring.visible:
landing_ring.scale = Vector2.ONE * (0.94 + 0.08 * pulse)
Expand All @@ -461,6 +465,24 @@ func _update_visuals() -> void:
if slash_line.visible:
slash_line.width = 4.0 + 1.2 * pulse
slash_line.modulate = Color(1.0, 1.0, 1.0, 0.74 + 0.16 * pulse)
visual_last_position = global_position

func _weapon_guard_rotation(direction: Vector2, guard_degrees: float) -> float:
var facing := direction.normalized() if direction.length_squared() > 0.0001 else Vector2.RIGHT
var side_sign := -1.0 if facing.x < -0.05 else 1.0
return facing.angle() + deg_to_rad(guard_degrees * side_sign)

func _apply_heavy_body_motion() -> void:
var movement := global_position - visual_last_position
var motion_ratio := clampf(movement.length() / maxf(move_speed * get_physics_process_delta_time(), 1.0), 0.0, 1.0)
visual_bob_time += 0.06 + motion_ratio * 0.17
var facing := -1.0 if line_direction.x < -0.05 else 1.0
if body_sprite != null:
body_sprite.flip_h = facing < 0.0
var stomp := absf(sin(visual_bob_time))
body.position = Vector2(0.0, stomp * (1.2 + motion_ratio * 3.8))
body.rotation = sin(visual_bob_time * 0.5) * (0.01 + motion_ratio * 0.018) * facing
body.scale = Vector2(1.0 + stomp * motion_ratio * 0.018, 1.0 - stomp * motion_ratio * 0.012)

func _spawn_aftershock() -> void:
var ring := Line2D.new()
Expand Down
23 changes: 20 additions & 3 deletions actors/bosses/town/mage_boss.gd
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ var body_sprite: Sprite2D = null
var weapon_sprite: Sprite2D = null
var weapon_angle_offset: float = deg_to_rad(98.0)
var orbit_direction: float = 1.0
var visual_last_position: Vector2 = Vector2.ZERO
var visual_bob_time: float = 0.0

func _ready() -> void:
add_to_group("damageable")
Expand All @@ -78,6 +80,7 @@ func _ready() -> void:
health_component.shield_changed.connect(_on_shield_changed)
health_component.died.connect(_on_died)
hp = max_hp
visual_last_position = global_position
_setup_body_visual()
_setup_weapon_visual()
for child in blade_orbit.get_children():
Expand Down Expand Up @@ -404,7 +407,7 @@ func _setup_body_visual() -> void:
body_sprite.texture = TEXTURE_LOADER.load_texture(MAGE_BODY_TEXTURE_PATH)
body_sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
body_sprite.centered = true
body_sprite.scale = Vector2.ONE * 0.38
body_sprite.scale = Vector2.ONE * 0.32
body.add_child(body_sprite)
body.color = Color(1.0, 1.0, 1.0, 0.0)

Expand All @@ -419,8 +422,8 @@ func _setup_weapon_visual() -> void:
weapon_sprite.texture = TEXTURE_LOADER.load_texture(MAGE_WEAPON_TEXTURE_PATH)
weapon_sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
weapon_sprite.centered = true
weapon_sprite.scale = Vector2.ONE * 0.42
weapon_sprite.position = Vector2(-34.0, 4.0)
weapon_sprite.scale = Vector2.ONE * 0.62
weapon_sprite.position = Vector2(-40.0, 4.0)
weapon.add_child(weapon_sprite)

func _animate_weapon_swing(start_degrees: float, end_degrees: float, duration: float) -> void:
Expand Down Expand Up @@ -450,9 +453,23 @@ func _update_visuals() -> void:
if enchant_sigil.visible:
enchant_sigil.rotation += 0.08
enchant_sigil.scale = Vector2.ONE * (0.96 + 0.08 * sin(Time.get_ticks_msec() * 0.008))
_apply_float_body_motion(1.45, 0.055)
weapon.position = line_direction * 18.0 + Vector2(0.0, -4.0)
weapon.rotation = line_direction.angle() + weapon_angle_offset
projectile_spawner.position = line_direction * 26.0
visual_last_position = global_position

func _apply_float_body_motion(float_scale: float, sway_scale: float) -> void:
var movement := global_position - visual_last_position
var motion_ratio := clampf(movement.length() / maxf(move_speed * get_physics_process_delta_time(), 1.0), 0.0, 1.0)
visual_bob_time += 0.075 + motion_ratio * 0.11
var facing := -1.0 if line_direction.x < -0.05 else 1.0
if body_sprite != null:
body_sprite.flip_h = facing < 0.0
body_sprite.position.x = sin(visual_bob_time * 0.7) * (1.2 + motion_ratio * 2.4) * facing
body_sprite.scale = Vector2(0.32 + sin(visual_bob_time * 0.9) * 0.008, 0.32 + cos(visual_bob_time * 0.75) * 0.018)
body.position = Vector2(0.0, sin(visual_bob_time) * (2.0 + motion_ratio * 3.4) * float_scale)
body.rotation = sin(visual_bob_time * 0.6) * (0.018 + motion_ratio * sway_scale) * facing

func _build_ring_points(radius: float, steps: int = 16) -> PackedVector2Array:
var points := PackedVector2Array()
Expand Down
37 changes: 29 additions & 8 deletions actors/bosses/town/ranger_boss.gd
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ var slow_time_remaining: float = 0.0
var slow_factor: float = 1.0
var body_sprite: Sprite2D = null
var weapon_sprite: Sprite2D = null
var weapon_angle_offset: float = deg_to_rad(56.0)
var weapon_angle_offset: float = 0.0
var visual_last_position: Vector2 = Vector2.ZERO
var visual_bob_time: float = 0.0

func _ready() -> void:
add_to_group("damageable")
Expand All @@ -79,6 +81,7 @@ func _ready() -> void:
health_component.healed.connect(_on_healed)
health_component.died.connect(_on_died)
hp = max_hp
visual_last_position = global_position
_setup_body_visual()
_setup_weapon_visual()
aim_ring.visible = false
Expand Down Expand Up @@ -220,7 +223,7 @@ func _start_basic_attack() -> void:
state_time = 0.0
action_committed = false
attack_cooldown = _get_attack_interval()
_animate_weapon_swing(-94.0, 34.0, 0.2)
_animate_weapon_swing(-32.0, 14.0, 0.2)
Sfx.play_event(&"ranger_attack", global_position)

func _process_basic_attack() -> void:
Expand All @@ -239,7 +242,7 @@ func _start_skill1() -> void:
aim_ring.visible = true
aim_ring.scale = Vector2.ONE * 0.42
aim_ring.modulate = Color(0.72, 1.0, 0.86, 0.88)
_animate_weapon_swing(-74.0, 24.0, skill1_cast_duration)
_animate_weapon_swing(-28.0, 10.0, skill1_cast_duration)

func _process_skill1_cast() -> void:
if not action_committed and state_time >= skill1_cast_duration * 0.65:
Expand Down Expand Up @@ -309,7 +312,7 @@ func _start_skill3() -> void:
skill3_cooldown_remaining = skill3_cooldown
assassination_mark.visible = true
assassination_mark.scale = Vector2.ONE * 0.76
_animate_weapon_swing(-104.0, 12.0, 0.18)
_animate_weapon_swing(-34.0, 12.0, 0.18)
Sfx.play_event(&"ranger_skill3_assassinate", global_position)

func _process_skill3_dash(delta: float) -> void:
Expand Down Expand Up @@ -446,7 +449,7 @@ func _setup_body_visual() -> void:
body_sprite.texture = TEXTURE_LOADER.load_texture(RANGER_BODY_TEXTURE_PATH)
body_sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
body_sprite.centered = true
body_sprite.scale = Vector2.ONE * 0.38
body_sprite.scale = Vector2.ONE * 0.33
body.add_child(body_sprite)
body.color = Color(1.0, 1.0, 1.0, 0.0)

Expand All @@ -461,8 +464,8 @@ func _setup_weapon_visual() -> void:
weapon_sprite.texture = TEXTURE_LOADER.load_texture(RANGER_WEAPON_TEXTURE_PATH)
weapon_sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
weapon_sprite.centered = true
weapon_sprite.scale = Vector2.ONE * 0.46
weapon_sprite.position = Vector2(-32.0, 5.0)
weapon_sprite.scale = Vector2.ONE * 0.66
weapon_sprite.position = Vector2(-60.0, 5.0)
weapon.add_child(weapon_sprite)

func _animate_weapon_swing(start_degrees: float, end_degrees: float, duration: float) -> void:
Expand Down Expand Up @@ -493,8 +496,26 @@ func _update_visuals() -> void:
assassination_mark.rotation += 0.16
assassination_mark.modulate = Color(1.0, 0.48, 0.42, 0.9)
weapon.position = line_direction * 18.0 + Vector2(0.0, -2.0)
weapon.rotation = line_direction.angle() + weapon_angle_offset
weapon.rotation = _weapon_guard_rotation(line_direction, -38.0) + weapon_angle_offset
projectile_spawner.position = line_direction * 28.0
_apply_agile_body_motion()
visual_last_position = global_position

func _weapon_guard_rotation(direction: Vector2, guard_degrees: float) -> float:
var facing := direction.normalized() if direction.length_squared() > 0.0001 else Vector2.RIGHT
var side_sign := -1.0 if facing.x < -0.05 else 1.0
return facing.angle() + deg_to_rad(guard_degrees * side_sign)

func _apply_agile_body_motion() -> void:
var movement := global_position - visual_last_position
var motion_ratio := clampf(movement.length() / maxf(move_speed * get_physics_process_delta_time(), 1.0), 0.0, 1.0)
visual_bob_time += 0.11 + motion_ratio * 0.18
var facing := -1.0 if line_direction.x < -0.05 else 1.0
if body_sprite != null:
body_sprite.flip_h = facing < 0.0
body_sprite.position.x = sin(visual_bob_time * 0.85) * (1.0 + motion_ratio * 3.0) * facing
body.position = Vector2(sin(visual_bob_time * 0.8) * motion_ratio * 3.2 * facing, sin(visual_bob_time) * (1.5 + motion_ratio * 3.8))
body.rotation = sin(visual_bob_time * 0.7) * (0.03 + motion_ratio * 0.075) * facing

func _spawn_damage_number(amount: float, is_critical: bool) -> void:
var damage_number := DAMAGE_NUMBER_SCENE.instantiate()
Expand Down
Loading
Loading