diff --git a/CHANGELOG.md b/CHANGELOG.md index 51a077f3c0..53e5cecd06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - First version of multisalvage that allows to obtain more than one piece of material from salvage - Axe - Combat music toggle +- Spawn rtsim wyverns that travel the world, providing dragon scale loot drops ### Changed diff --git a/assets/common/abilities/ability_set_manifest.ron b/assets/common/abilities/ability_set_manifest.ron index 2745673410..428d693bc1 100644 --- a/assets/common/abilities/ability_set_manifest.ron +++ b/assets/common/abilities/ability_set_manifest.ron @@ -724,42 +724,42 @@ ), Custom("Flame Wyvern"): ( primary: Simple(None, "common.abilities.custom.flamewyvern.firebomb"), - secondary: Simple(None, "common.abilities.custom.flamewyvern.fireshockwave"), + secondary: Simple(None, "common.abilities.custom.flamewyvern.triplestrike"), abilities: [ - Simple(None, "common.abilities.custom.flamewyvern.triplestrike"), + Simple(None, "common.abilities.custom.flamewyvern.fireshockwave"), Simple(None, "common.abilities.custom.flamewyvern.flamethrower"), ], ), Custom("Frost Wyvern"): ( primary: Simple(None, "common.abilities.custom.frostwyvern.frostbomb"), - secondary: Simple(None, "common.abilities.custom.frostwyvern.iceshockwave"), + secondary: Simple(None, "common.abilities.custom.frostwyvern.triplestrike"), abilities: [ - Simple(None, "common.abilities.custom.frostwyvern.triplestrike"), + Simple(None, "common.abilities.custom.frostwyvern.iceshockwave"), Simple(None, "common.abilities.custom.frostwyvern.frostthrower"), ], ), Custom("Cloud Wyvern"): ( - primary: Simple(None, "common.abilities.custom.cloudwyvern.windbomb"), - secondary: Simple(None, "common.abilities.custom.cloudwyvern.windshockwave"), + primary: Simple(None, "common.abilities.custom.cloudwyvern.lightningbomb"), + secondary: Simple(None, "common.abilities.custom.cloudwyvern.triplestrike"), abilities: [ - Simple(None, "common.abilities.custom.cloudwyvern.triplestrike"), - Simple(None, "common.abilities.custom.cloudwyvern.windthrower"), + Simple(None, "common.abilities.custom.cloudwyvern.lightningshockwave"), + Simple(None, "common.abilities.custom.cloudwyvern.lightningthrower"), ], ), Custom("Sea Wyvern"): ( - primary: Simple(None, "common.abilities.custom.seawyvern.seabomb"), - secondary: Simple(None, "common.abilities.custom.seawyvern.seashockwave"), + primary: Simple(None, "common.abilities.custom.seawyvern.inkbomb"), + secondary: Simple(None, "common.abilities.custom.seawyvern.triplestrike"), abilities: [ - Simple(None, "common.abilities.custom.seawyvern.triplestrike"), - Simple(None, "common.abilities.custom.seawyvern.bubblethrower"), + Simple(None, "common.abilities.custom.seawyvern.inkshockwave"), + Simple(None, "common.abilities.custom.seawyvern.inkthrower"), ], ), Custom("Weald Wyvern"): ( - primary: Simple(None, "common.abilities.custom.wealdwyvern.firebomb"), - secondary: Simple(None, "common.abilities.custom.wealdwyvern.fireshockwave"), + primary: Simple(None, "common.abilities.custom.wealdwyvern.poisonbomb"), + secondary: Simple(None, "common.abilities.custom.wealdwyvern.triplestrike"), abilities: [ - Simple(None, "common.abilities.custom.wealdwyvern.triplestrike"), - Simple(None, "common.abilities.custom.wealdwyvern.flamethrower"), + Simple(None, "common.abilities.custom.wealdwyvern.poisonshockwave"), + Simple(None, "common.abilities.custom.wealdwyvern.poisonthrower"), ], ), Custom("Bird Large Basic"): ( diff --git a/assets/common/abilities/custom/arthropods/blackwidow/poisonball.ron b/assets/common/abilities/custom/arthropods/blackwidow/poisonball.ron index d93ae0899d..65418ddfd1 100644 --- a/assets/common/abilities/custom/arthropods/blackwidow/poisonball.ron +++ b/assets/common/abilities/custom/arthropods/blackwidow/poisonball.ron @@ -13,7 +13,7 @@ BasicRanged( col: (1.0, 0.75, 0.11).into(), ..Default::default() }),*/ - projectile_speed: 260.0, + projectile_speed: 25.0, num_projectiles: 1, projectile_spread: 0.3, move_efficiency: 0.3, diff --git a/assets/common/abilities/custom/birdlargebasic/triplestrike.ron b/assets/common/abilities/custom/birdlargebasic/triplestrike.ron index 3f1cd81a55..ca0ffd6eec 100644 --- a/assets/common/abilities/custom/birdlargebasic/triplestrike.ron +++ b/assets/common/abilities/custom/birdlargebasic/triplestrike.ron @@ -1,59 +1,66 @@ -ComboMelee( - stage_data: [ +ComboMelee2( + strikes: [ ( - stage: 1, - base_damage: 22.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 4.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 22, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 4.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 3.0, - damage_kind: Crushing, + recover_duration: 0.6, + movement: ( + swing: Some(Forward(3.0)), + ), + ori_modifier: 0.7, ), ( - stage: 2, - base_damage: 18.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 18, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 3.0, - damage_kind: Crushing, + recover_duration: 0.6, + movement: ( + swing: Some(Forward(3.0)), + ), + ori_modifier: 0.7, ), ( - stage: 3, - base_damage: 28.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 10.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 1.3, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 28, + poise: 0, + knockback: 10, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 1.3, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 3.5, - damage_kind: Crushing, + recover_duration: 0.6, + movement: ( + swing: Some(Forward(3.5)), + ), + ori_modifier: 0.7, ), ], - initial_energy_gain: 0, - max_energy_gain: 0, - energy_increase: 0, - speed_increase: 0.0, - max_speed_increase: 0.0, - scales_from_combo: 0, - ori_modifier: 0.7, -) + energy_cost_per_strike: 0, + auto_progress: true, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/birdlargebreathe/triplestrike.ron b/assets/common/abilities/custom/birdlargebreathe/triplestrike.ron index 1ce016e577..03bf0f68b4 100644 --- a/assets/common/abilities/custom/birdlargebreathe/triplestrike.ron +++ b/assets/common/abilities/custom/birdlargebreathe/triplestrike.ron @@ -1,77 +1,66 @@ -ComboMelee( - stage_data: [ +ComboMelee2( + strikes: [ ( - stage: 1, - base_damage: 20.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 4.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 20, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 4.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 2.0, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 2, - base_damage: 16.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 16, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 3, - base_damage: 26.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 10.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 1.3, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 26, + poise: 0, + knockback: 10, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.4, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(1.5)), + ), + ori_modifier: 0.7, ), ], - initial_energy_gain: 0, - max_energy_gain: 0, - energy_increase: 0, - speed_increase: 0.0, - max_speed_increase: 0.0, - scales_from_combo: 0, - ori_modifier: 0.7, -) + energy_cost_per_strike: 0, + auto_progress: true, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/birdlargefire/triplestrike.ron b/assets/common/abilities/custom/birdlargefire/triplestrike.ron index 085622090a..03bf0f68b4 100644 --- a/assets/common/abilities/custom/birdlargefire/triplestrike.ron +++ b/assets/common/abilities/custom/birdlargefire/triplestrike.ron @@ -1,77 +1,66 @@ -ComboMelee( - stage_data: [ +ComboMelee2( + strikes: [ ( - stage: 1, - base_damage: 20.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 4.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 20, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 4.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 2.0, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 2, - base_damage: 16.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 16, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 3, - base_damage: 26.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 10.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.375, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 26, + poise: 0, + knockback: 10, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.4, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(1.5)), + ), + ori_modifier: 0.7, ), ], - initial_energy_gain: 0, - max_energy_gain: 0, - energy_increase: 0, - speed_increase: 0.0, - max_speed_increase: 0.0, - scales_from_combo: 0, - ori_modifier: 0.7, -) + energy_cost_per_strike: 0, + auto_progress: true, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/cloudwyvern/lightningbomb.ron b/assets/common/abilities/custom/cloudwyvern/lightningbomb.ron new file mode 100644 index 0000000000..b5b6f9db50 --- /dev/null +++ b/assets/common/abilities/custom/cloudwyvern/lightningbomb.ron @@ -0,0 +1,18 @@ +BasicRanged( + energy_cost: 0, + buildup_duration: 0.5, + recover_duration: 1.5, + projectile: LaserBeam( + damage: 20.0, + radius: 5.0, + knockback: 5.0, + energy_regen: 20.0, + min_falloff: 0.1, + ), + projectile_body: Object(LightningBolt), + projectile_light: None, + projectile_speed: 100.0, + num_projectiles: 1, + projectile_spread: 0.0, + move_efficiency: 0.3, +) diff --git a/assets/common/abilities/custom/cloudwyvern/lightningshockwave.ron b/assets/common/abilities/custom/cloudwyvern/lightningshockwave.ron new file mode 100644 index 0000000000..52eaab4ac7 --- /dev/null +++ b/assets/common/abilities/custom/cloudwyvern/lightningshockwave.ron @@ -0,0 +1,24 @@ +Shockwave( + energy_cost: 0, + buildup_duration: 0.3, + swing_duration: 0.3, + recover_duration: 2.0, + damage: 20.0, + poise_damage: 10, + knockback: (strength: 18.0, direction: Away), + shockwave_angle: 360.0, + shockwave_vertical_angle: 90.0, + shockwave_speed: 15.0, + shockwave_duration: 2.0, + requires_ground: true, + move_efficiency: 0.0, + damage_kind: Crushing, + specifier: Lightning, + ori_rate: 1.0, + damage_effect: Some(Buff(( + kind: Crippled, + dur_secs: 2.0, + strength: Value(0.3), + chance: 1.0, + ))), +) diff --git a/assets/common/abilities/custom/cloudwyvern/lightningthrower.ron b/assets/common/abilities/custom/cloudwyvern/lightningthrower.ron new file mode 100644 index 0000000000..570e03461a --- /dev/null +++ b/assets/common/abilities/custom/cloudwyvern/lightningthrower.ron @@ -0,0 +1,19 @@ +BasicBeam( + buildup_duration: 0.3, + recover_duration: 1.5, + beam_duration: 2.0, + damage: 22.5, + tick_rate: 3.0, + range: 22.0, + max_angle: 22.5, + damage_effect: Some(Buff(( + kind: Crippled, + dur_secs: 3.0, + strength: Value(0.5), + chance: 1.0, + ))), + energy_regen: 2, + energy_drain: 0, + ori_rate: 0.5, + specifier: Lightning, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/cloudwyvern/triplestrike.ron b/assets/common/abilities/custom/cloudwyvern/triplestrike.ron index 085622090a..03bf0f68b4 100644 --- a/assets/common/abilities/custom/cloudwyvern/triplestrike.ron +++ b/assets/common/abilities/custom/cloudwyvern/triplestrike.ron @@ -1,77 +1,66 @@ -ComboMelee( - stage_data: [ +ComboMelee2( + strikes: [ ( - stage: 1, - base_damage: 20.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 4.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 20, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 4.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 2.0, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 2, - base_damage: 16.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 16, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 3, - base_damage: 26.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 10.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.375, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 26, + poise: 0, + knockback: 10, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.4, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(1.5)), + ), + ori_modifier: 0.7, ), ], - initial_energy_gain: 0, - max_energy_gain: 0, - energy_increase: 0, - speed_increase: 0.0, - max_speed_increase: 0.0, - scales_from_combo: 0, - ori_modifier: 0.7, -) + energy_cost_per_strike: 0, + auto_progress: true, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/cloudwyvern/windbomb.ron b/assets/common/abilities/custom/cloudwyvern/windbomb.ron deleted file mode 100644 index 544495ddf2..0000000000 --- a/assets/common/abilities/custom/cloudwyvern/windbomb.ron +++ /dev/null @@ -1,20 +0,0 @@ -BasicRanged( - energy_cost: 0, - buildup_duration: 1.0, - recover_duration: 0.7, - projectile: WindBomb( - damage: 20.0, - radius: 5.0, - energy_regen: 5.0, - min_falloff: 0.5, - ), - projectile_body: Object(BoltFire), - /*projectile_light: Some(LightEmitter { - col: (1.0, 0.75, 0.11).into(), - ..Default::default() - }),*/ - projectile_speed: 60.0, - num_projectiles: 1, - projectile_spread: 0.0, - move_efficiency: 0.3, -) diff --git a/assets/common/abilities/custom/cloudwyvern/windshockwave.ron b/assets/common/abilities/custom/cloudwyvern/windshockwave.ron deleted file mode 100644 index d99f043161..0000000000 --- a/assets/common/abilities/custom/cloudwyvern/windshockwave.ron +++ /dev/null @@ -1,18 +0,0 @@ -Shockwave( - energy_cost: 60.0, - buildup_duration: 1.4, - swing_duration: 0.1, - recover_duration: 0.4, - damage: 40.0, - poise_damage: 0, - knockback: ( strength: 25.0, direction: Away), - shockwave_angle: 360.0, - shockwave_vertical_angle: 90.0, - shockwave_speed: 20.0, - shockwave_duration: 0.5, - requires_ground: false, - move_efficiency: 0.1, - damage_kind: Energy, - specifier: Water, - ori_rate: 1.0, -) diff --git a/assets/common/abilities/custom/cloudwyvern/windthrower.ron b/assets/common/abilities/custom/cloudwyvern/windthrower.ron deleted file mode 100644 index 5f37ff1a54..0000000000 --- a/assets/common/abilities/custom/cloudwyvern/windthrower.ron +++ /dev/null @@ -1,19 +0,0 @@ -BasicBeam( - buildup_duration: 0.8, - recover_duration: 0.5, - beam_duration: 0.5, - damage: 10.0, - tick_rate: 3.0, - range: 15.0, - max_angle: 22.5, - damage_effect: Some(Buff(( - kind: Burning, - dur_secs: 10.0, - strength: DamageFraction(0.5), - chance: 0.25, - ))), - energy_regen: 0, - energy_drain: 0, - ori_rate: 0.3, - specifier: Bubbles, -) diff --git a/assets/common/abilities/custom/flamewyvern/firebomb.ron b/assets/common/abilities/custom/flamewyvern/firebomb.ron index cb309e83ec..3864707904 100644 --- a/assets/common/abilities/custom/flamewyvern/firebomb.ron +++ b/assets/common/abilities/custom/flamewyvern/firebomb.ron @@ -1,20 +1,17 @@ BasicRanged( energy_cost: 0, - buildup_duration: 1.0, - recover_duration: 0.7, + buildup_duration: 0.5, + recover_duration: 1.5, projectile: Fireball( - damage: 20.0, + damage: 32.0, radius: 5.0, energy_regen: 5.0, - min_falloff: 0.5, + min_falloff: 0.1, ), projectile_body: Object(BoltFire), - /*projectile_light: Some(LightEmitter { - col: (1.0, 0.75, 0.11).into(), - ..Default::default() - }),*/ - projectile_speed: 60.0, + projectile_light: None, + projectile_speed: 100.0, num_projectiles: 1, projectile_spread: 0.0, move_efficiency: 0.3, -) +) \ No newline at end of file diff --git a/assets/common/abilities/custom/flamewyvern/fireshockwave.ron b/assets/common/abilities/custom/flamewyvern/fireshockwave.ron index 841c443ccb..bb4ad6fd3e 100644 --- a/assets/common/abilities/custom/flamewyvern/fireshockwave.ron +++ b/assets/common/abilities/custom/flamewyvern/fireshockwave.ron @@ -1,18 +1,24 @@ Shockwave( - energy_cost: 60.0, - buildup_duration: 1.4, - swing_duration: 0.1, - recover_duration: 0.4, - damage: 40.0, - poise_damage: 0, - knockback: ( strength: 25.0, direction: Away), + energy_cost: 0, + buildup_duration: 0.3, + swing_duration: 0.3, + recover_duration: 2.0, + damage: 20.0, + poise_damage: 10, + knockback: (strength: 18.0, direction: Away), shockwave_angle: 360.0, shockwave_vertical_angle: 90.0, - shockwave_speed: 20.0, - shockwave_duration: 0.5, - requires_ground: false, - move_efficiency: 0.1, - damage_kind: Energy, + shockwave_speed: 15.0, + shockwave_duration: 2.0, + requires_ground: true, + move_efficiency: 0.0, + damage_kind: Crushing, specifier: Fire, ori_rate: 1.0, + damage_effect: Some(Buff(( + kind: Burning, + dur_secs: 2.0, + strength: DamageFraction(0.3), + chance: 1.0, + ))), ) diff --git a/assets/common/abilities/custom/flamewyvern/flamethrower.ron b/assets/common/abilities/custom/flamewyvern/flamethrower.ron index 50c9cec231..d5763bc613 100644 --- a/assets/common/abilities/custom/flamewyvern/flamethrower.ron +++ b/assets/common/abilities/custom/flamewyvern/flamethrower.ron @@ -1,19 +1,19 @@ BasicBeam( - buildup_duration: 0.8, - recover_duration: 0.5, - beam_duration: 0.5, - damage: 10.0, + buildup_duration: 0.3, + recover_duration: 1.5, + beam_duration: 2.0, + damage: 22.5, tick_rate: 3.0, - range: 15.0, + range: 22.0, max_angle: 22.5, damage_effect: Some(Buff(( kind: Burning, - dur_secs: 10.0, + dur_secs: 3.0, strength: DamageFraction(0.5), - chance: 0.25, + chance: 1.0, ))), - energy_regen: 0, + energy_regen: 2, energy_drain: 0, - ori_rate: 0.3, + ori_rate: 0.5, specifier: Flamethrower, ) diff --git a/assets/common/abilities/custom/flamewyvern/triplestrike.ron b/assets/common/abilities/custom/flamewyvern/triplestrike.ron index 085622090a..03bf0f68b4 100644 --- a/assets/common/abilities/custom/flamewyvern/triplestrike.ron +++ b/assets/common/abilities/custom/flamewyvern/triplestrike.ron @@ -1,77 +1,66 @@ -ComboMelee( - stage_data: [ +ComboMelee2( + strikes: [ ( - stage: 1, - base_damage: 20.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 4.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 20, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 4.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 2.0, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 2, - base_damage: 16.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 16, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 3, - base_damage: 26.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 10.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.375, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 26, + poise: 0, + knockback: 10, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.4, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(1.5)), + ), + ori_modifier: 0.7, ), ], - initial_energy_gain: 0, - max_energy_gain: 0, - energy_increase: 0, - speed_increase: 0.0, - max_speed_increase: 0.0, - scales_from_combo: 0, - ori_modifier: 0.7, -) + energy_cost_per_strike: 0, + auto_progress: true, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/frostwyvern/frostbomb.ron b/assets/common/abilities/custom/frostwyvern/frostbomb.ron index 5660366118..87916a6fd1 100644 --- a/assets/common/abilities/custom/frostwyvern/frostbomb.ron +++ b/assets/common/abilities/custom/frostwyvern/frostbomb.ron @@ -1,19 +1,16 @@ BasicRanged( energy_cost: 0, - buildup_duration: 1.0, - recover_duration: 0.7, + buildup_duration: 0.5, + recover_duration: 1.5, projectile: Frostball( - damage: 20.0, + damage: 32.0, radius: 5.0, energy_regen: 5.0, - min_falloff: 0.5, + min_falloff: 0.1, ), - projectile_body: Object(BoltNature), - /*projectile_light: Some(LightEmitter { - col: (1.0, 0.75, 0.11).into(), - ..Default::default() - }),*/ - projectile_speed: 60.0, + projectile_body: Object(SpearIcicle), + projectile_light: None, + projectile_speed: 100.0, num_projectiles: 1, projectile_spread: 0.0, move_efficiency: 0.3, diff --git a/assets/common/abilities/custom/frostwyvern/frostthrower.ron b/assets/common/abilities/custom/frostwyvern/frostthrower.ron index 40a1536439..3bf5464562 100644 --- a/assets/common/abilities/custom/frostwyvern/frostthrower.ron +++ b/assets/common/abilities/custom/frostwyvern/frostthrower.ron @@ -1,19 +1,19 @@ BasicBeam( - buildup_duration: 0.8, - recover_duration: 0.5, - beam_duration: 0.5, - damage: 10.0, + buildup_duration: 0.3, + recover_duration: 1.5, + beam_duration: 2.0, + damage: 22.5, tick_rate: 3.0, - range: 15.0, + range: 22.0, max_angle: 22.5, damage_effect: Some(Buff(( - kind: Burning, - dur_secs: 10.0, - strength: DamageFraction(0.5), - chance: 0.25, + kind: Frigid, + dur_secs: 3.0, + strength: Value(0.5), + chance: 1.0, ))), - energy_regen: 0, + energy_regen: 2, energy_drain: 0, - ori_rate: 0.3, + ori_rate: 0.5, specifier: Frost, ) diff --git a/assets/common/abilities/custom/frostwyvern/iceshockwave.ron b/assets/common/abilities/custom/frostwyvern/iceshockwave.ron index 3b5a5f8433..a4c1f8162c 100644 --- a/assets/common/abilities/custom/frostwyvern/iceshockwave.ron +++ b/assets/common/abilities/custom/frostwyvern/iceshockwave.ron @@ -1,18 +1,24 @@ Shockwave( - energy_cost: 60.0, - buildup_duration: 1.4, - swing_duration: 0.1, - recover_duration: 0.4, - damage: 40.0, - poise_damage: 0, - knockback: ( strength: 25.0, direction: Away), + energy_cost: 0, + buildup_duration: 0.3, + swing_duration: 0.3, + recover_duration: 2.0, + damage: 20.0, + poise_damage: 10, + knockback: (strength: 18.0, direction: Away), shockwave_angle: 360.0, shockwave_vertical_angle: 90.0, - shockwave_speed: 20.0, - shockwave_duration: 0.5, - requires_ground: false, - move_efficiency: 0.1, - damage_kind: Energy, - specifier: IceSpikes, + shockwave_speed: 15.0, + shockwave_duration: 2.0, + requires_ground: true, + move_efficiency: 0.0, + damage_kind: Crushing, + specifier: Ice, ori_rate: 1.0, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 2.0, + strength: Value(0.3), + chance: 1.0, + ))), ) diff --git a/assets/common/abilities/custom/frostwyvern/triplestrike.ron b/assets/common/abilities/custom/frostwyvern/triplestrike.ron index 085622090a..03bf0f68b4 100644 --- a/assets/common/abilities/custom/frostwyvern/triplestrike.ron +++ b/assets/common/abilities/custom/frostwyvern/triplestrike.ron @@ -1,77 +1,66 @@ -ComboMelee( - stage_data: [ +ComboMelee2( + strikes: [ ( - stage: 1, - base_damage: 20.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 4.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 20, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 4.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 2.0, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 2, - base_damage: 16.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 16, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 3, - base_damage: 26.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 10.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.375, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 26, + poise: 0, + knockback: 10, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.4, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(1.5)), + ), + ori_modifier: 0.7, ), ], - initial_energy_gain: 0, - max_energy_gain: 0, - energy_increase: 0, - speed_increase: 0.0, - max_speed_increase: 0.0, - scales_from_combo: 0, - ori_modifier: 0.7, -) + energy_cost_per_strike: 0, + auto_progress: true, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/seawyvern/bubblethrower.ron b/assets/common/abilities/custom/seawyvern/bubblethrower.ron deleted file mode 100644 index 5f37ff1a54..0000000000 --- a/assets/common/abilities/custom/seawyvern/bubblethrower.ron +++ /dev/null @@ -1,19 +0,0 @@ -BasicBeam( - buildup_duration: 0.8, - recover_duration: 0.5, - beam_duration: 0.5, - damage: 10.0, - tick_rate: 3.0, - range: 15.0, - max_angle: 22.5, - damage_effect: Some(Buff(( - kind: Burning, - dur_secs: 10.0, - strength: DamageFraction(0.5), - chance: 0.25, - ))), - energy_regen: 0, - energy_drain: 0, - ori_rate: 0.3, - specifier: Bubbles, -) diff --git a/assets/common/abilities/custom/seawyvern/inkbomb.ron b/assets/common/abilities/custom/seawyvern/inkbomb.ron new file mode 100644 index 0000000000..a557d7d7ab --- /dev/null +++ b/assets/common/abilities/custom/seawyvern/inkbomb.ron @@ -0,0 +1,17 @@ +BasicRanged( + energy_cost: 0, + buildup_duration: 0.5, + recover_duration: 1.5, + projectile: InkBomb( + damage: 32.0, + radius: 5.0, + energy_regen: 5.0, + min_falloff: 0.1, + ), + projectile_body: Object(SpitPoison), + projectile_light: None, + projectile_speed: 100.0, + num_projectiles: 1, + projectile_spread: 0.0, + move_efficiency: 0.3, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/seawyvern/inkshockwave.ron b/assets/common/abilities/custom/seawyvern/inkshockwave.ron new file mode 100644 index 0000000000..903c5e90c4 --- /dev/null +++ b/assets/common/abilities/custom/seawyvern/inkshockwave.ron @@ -0,0 +1,25 @@ +Shockwave( + energy_cost: 0, + buildup_duration: 0.3, + swing_duration: 0.3, + recover_duration: 2.0, + damage: 20.0, + poise_damage: 10, + knockback: (strength: 18.0, direction: Away), + shockwave_angle: 360.0, + shockwave_vertical_angle: 90.0, + shockwave_speed: 15.0, + shockwave_duration: 2.0, + requires_ground: true, + move_efficiency: 0.0, + damage_kind: Crushing, + specifier: Ink, + ori_rate: 1.0, + damage_effect: Some(Buff(( + kind: Wet, + dur_secs: 8.0, + strength: Value(0.3), + chance: 1.0, + ))), +) + diff --git a/assets/common/abilities/custom/seawyvern/inkthrower.ron b/assets/common/abilities/custom/seawyvern/inkthrower.ron new file mode 100644 index 0000000000..5cae603d7a --- /dev/null +++ b/assets/common/abilities/custom/seawyvern/inkthrower.ron @@ -0,0 +1,19 @@ +BasicBeam( + buildup_duration: 0.3, + recover_duration: 1.5, + beam_duration: 2.0, + damage: 22.5, + tick_rate: 3.0, + range: 22.0, + max_angle: 22.5, + damage_effect: Some(Buff(( + kind: Wet, + dur_secs: 8.0, + strength: Value(1.5), + chance: 1.0, + ))), + energy_regen: 2, + energy_drain: 0, + ori_rate: 0.5, + specifier: Ink, +) diff --git a/assets/common/abilities/custom/seawyvern/seabomb.ron b/assets/common/abilities/custom/seawyvern/seabomb.ron deleted file mode 100644 index 9bfb0a07ad..0000000000 --- a/assets/common/abilities/custom/seawyvern/seabomb.ron +++ /dev/null @@ -1,20 +0,0 @@ -BasicRanged( - energy_cost: 0, - buildup_duration: 1.0, - recover_duration: 0.7, - projectile: SeaBomb( - damage: 20.0, - radius: 5.0, - energy_regen: 5.0, - min_falloff: 0.5, - ), - projectile_body: Object(BoltFire), - /*projectile_light: Some(LightEmitter { - col: (1.0, 0.75, 0.11).into(), - ..Default::default() - }),*/ - projectile_speed: 60.0, - num_projectiles: 1, - projectile_spread: 0.0, - move_efficiency: 0.3, -) diff --git a/assets/common/abilities/custom/seawyvern/seashockwave.ron b/assets/common/abilities/custom/seawyvern/seashockwave.ron deleted file mode 100644 index d99f043161..0000000000 --- a/assets/common/abilities/custom/seawyvern/seashockwave.ron +++ /dev/null @@ -1,18 +0,0 @@ -Shockwave( - energy_cost: 60.0, - buildup_duration: 1.4, - swing_duration: 0.1, - recover_duration: 0.4, - damage: 40.0, - poise_damage: 0, - knockback: ( strength: 25.0, direction: Away), - shockwave_angle: 360.0, - shockwave_vertical_angle: 90.0, - shockwave_speed: 20.0, - shockwave_duration: 0.5, - requires_ground: false, - move_efficiency: 0.1, - damage_kind: Energy, - specifier: Water, - ori_rate: 1.0, -) diff --git a/assets/common/abilities/custom/seawyvern/triplestrike.ron b/assets/common/abilities/custom/seawyvern/triplestrike.ron index 085622090a..03bf0f68b4 100644 --- a/assets/common/abilities/custom/seawyvern/triplestrike.ron +++ b/assets/common/abilities/custom/seawyvern/triplestrike.ron @@ -1,77 +1,66 @@ -ComboMelee( - stage_data: [ +ComboMelee2( + strikes: [ ( - stage: 1, - base_damage: 20.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 4.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 20, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 4.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 2.0, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 2, - base_damage: 16.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 16, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 3, - base_damage: 26.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 10.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.375, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 26, + poise: 0, + knockback: 10, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.4, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(1.5)), + ), + ori_modifier: 0.7, ), ], - initial_energy_gain: 0, - max_energy_gain: 0, - energy_increase: 0, - speed_increase: 0.0, - max_speed_increase: 0.0, - scales_from_combo: 0, - ori_modifier: 0.7, -) + energy_cost_per_strike: 0, + auto_progress: true, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/wealdwyvern/firebomb.ron b/assets/common/abilities/custom/wealdwyvern/firebomb.ron deleted file mode 100644 index cb309e83ec..0000000000 --- a/assets/common/abilities/custom/wealdwyvern/firebomb.ron +++ /dev/null @@ -1,20 +0,0 @@ -BasicRanged( - energy_cost: 0, - buildup_duration: 1.0, - recover_duration: 0.7, - projectile: Fireball( - damage: 20.0, - radius: 5.0, - energy_regen: 5.0, - min_falloff: 0.5, - ), - projectile_body: Object(BoltFire), - /*projectile_light: Some(LightEmitter { - col: (1.0, 0.75, 0.11).into(), - ..Default::default() - }),*/ - projectile_speed: 60.0, - num_projectiles: 1, - projectile_spread: 0.0, - move_efficiency: 0.3, -) diff --git a/assets/common/abilities/custom/wealdwyvern/fireshockwave.ron b/assets/common/abilities/custom/wealdwyvern/fireshockwave.ron deleted file mode 100644 index 841c443ccb..0000000000 --- a/assets/common/abilities/custom/wealdwyvern/fireshockwave.ron +++ /dev/null @@ -1,18 +0,0 @@ -Shockwave( - energy_cost: 60.0, - buildup_duration: 1.4, - swing_duration: 0.1, - recover_duration: 0.4, - damage: 40.0, - poise_damage: 0, - knockback: ( strength: 25.0, direction: Away), - shockwave_angle: 360.0, - shockwave_vertical_angle: 90.0, - shockwave_speed: 20.0, - shockwave_duration: 0.5, - requires_ground: false, - move_efficiency: 0.1, - damage_kind: Energy, - specifier: Fire, - ori_rate: 1.0, -) diff --git a/assets/common/abilities/custom/wealdwyvern/flamethrower.ron b/assets/common/abilities/custom/wealdwyvern/flamethrower.ron deleted file mode 100644 index 50c9cec231..0000000000 --- a/assets/common/abilities/custom/wealdwyvern/flamethrower.ron +++ /dev/null @@ -1,19 +0,0 @@ -BasicBeam( - buildup_duration: 0.8, - recover_duration: 0.5, - beam_duration: 0.5, - damage: 10.0, - tick_rate: 3.0, - range: 15.0, - max_angle: 22.5, - damage_effect: Some(Buff(( - kind: Burning, - dur_secs: 10.0, - strength: DamageFraction(0.5), - chance: 0.25, - ))), - energy_regen: 0, - energy_drain: 0, - ori_rate: 0.3, - specifier: Flamethrower, -) diff --git a/assets/common/abilities/custom/wealdwyvern/poisonbomb.ron b/assets/common/abilities/custom/wealdwyvern/poisonbomb.ron new file mode 100644 index 0000000000..40161e2bde --- /dev/null +++ b/assets/common/abilities/custom/wealdwyvern/poisonbomb.ron @@ -0,0 +1,17 @@ +BasicRanged( + energy_cost: 0, + buildup_duration: 0.5, + recover_duration: 1.5, + projectile: Poisonball( + damage: 32.0, + radius: 5.0, + energy_regen: 5.0, + min_falloff: 0.1, + ), + projectile_body: Object(SpitPoison), + projectile_light: None, + projectile_speed: 100.0, + num_projectiles: 1, + projectile_spread: 0.0, + move_efficiency: 0.3, +) diff --git a/assets/common/abilities/custom/wealdwyvern/poisonshockwave.ron b/assets/common/abilities/custom/wealdwyvern/poisonshockwave.ron new file mode 100644 index 0000000000..26a148df16 --- /dev/null +++ b/assets/common/abilities/custom/wealdwyvern/poisonshockwave.ron @@ -0,0 +1,25 @@ +Shockwave( + energy_cost: 0, + buildup_duration: 0.3, + swing_duration: 0.3, + recover_duration: 2.0, + damage: 20.0, + poise_damage: 10, + knockback: (strength: 18.0, direction: Away), + shockwave_angle: 360.0, + shockwave_vertical_angle: 90.0, + shockwave_speed: 15.0, + shockwave_duration: 2.0, + requires_ground: true, + move_efficiency: 0.0, + damage_kind: Crushing, + specifier: Poison, + ori_rate: 1.0, + damage_effect: Some(Buff(( + kind: Poisoned, + dur_secs: 8.0, + strength: DamageFraction(0.3), + chance: 1.0, + ))), +) + diff --git a/assets/common/abilities/custom/wealdwyvern/poisonthrower.ron b/assets/common/abilities/custom/wealdwyvern/poisonthrower.ron new file mode 100644 index 0000000000..e9061c99ca --- /dev/null +++ b/assets/common/abilities/custom/wealdwyvern/poisonthrower.ron @@ -0,0 +1,19 @@ +BasicBeam( + buildup_duration: 0.3, + recover_duration: 1.5, + beam_duration: 2.0, + damage: 22.5, + tick_rate: 3.0, + range: 22.0, + max_angle: 22.5, + damage_effect: Some(Buff(( + kind: Poisoned, + dur_secs: 3.0, + strength: DamageFraction(0.5), + chance: 1.0, + ))), + energy_regen: 2, + energy_drain: 0, + ori_rate: 0.5, + specifier: Poison, +) diff --git a/assets/common/abilities/custom/wealdwyvern/triplestrike.ron b/assets/common/abilities/custom/wealdwyvern/triplestrike.ron index 085622090a..03bf0f68b4 100644 --- a/assets/common/abilities/custom/wealdwyvern/triplestrike.ron +++ b/assets/common/abilities/custom/wealdwyvern/triplestrike.ron @@ -1,77 +1,66 @@ -ComboMelee( - stage_data: [ +ComboMelee2( + strikes: [ ( - stage: 1, - base_damage: 20.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 4.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 20, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 4.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 2.0, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 2, - base_damage: 16.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.8, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 16, + poise: 0, + knockback: 5, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.8, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(2.0)), + ), + ori_modifier: 0.7, ), ( - stage: 3, - base_damage: 26.0, - damage_increase: 0, - base_poise_damage: 0, - poise_damage_increase: 0, - knockback: 10.0, - range: 3.5, - angle: 30.0, - base_buildup_duration: 0.375, - base_swing_duration: 0.1, + melee_constructor: ( + kind: Slash( + damage: 26, + poise: 0, + knockback: 10, + energy_regen: 0, + ), + range: 3.5, + angle: 30.0, + ), + buildup_duration: 0.4, + swing_duration: 0.1, hit_timing: 0.5, - base_recover_duration: 0.6, - forward_movement: 1.5, - damage_kind: Slashing, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10.0, - strength: DamageFraction(0.1), - chance: 0.1, - ))), + recover_duration: 0.6, + movement: ( + swing: Some(Forward(1.5)), + ), + ori_modifier: 0.7, ), ], - initial_energy_gain: 0, - max_energy_gain: 0, - energy_increase: 0, - speed_increase: 0.0, - max_speed_increase: 0.0, - scales_from_combo: 0, - ori_modifier: 0.7, -) + energy_cost_per_strike: 0, + auto_progress: true, +) \ No newline at end of file diff --git a/assets/common/entity/wild/aggressive/cloudwyvern.ron b/assets/common/entity/wild/aggressive/cloudwyvern.ron index 3126f8e18f..9448cf04e7 100644 --- a/assets/common/entity/wild/aggressive/cloudwyvern.ron +++ b/assets/common/entity/wild/aggressive/cloudwyvern.ron @@ -3,7 +3,7 @@ name: Automatic, body: RandomWith("wyvern_cloud"), alignment: Alignment(Enemy), - loot: LootTable("common.loot_tables.creature.bird_large.wyvern"), + loot: LootTable("common.loot_tables.creature.bird_large.cloudwyvern"), inventory: ( loadout: FromBody, ), diff --git a/assets/common/entity/wild/aggressive/flamewyvern.ron b/assets/common/entity/wild/aggressive/flamewyvern.ron index 77502fdb89..d150b067b2 100644 --- a/assets/common/entity/wild/aggressive/flamewyvern.ron +++ b/assets/common/entity/wild/aggressive/flamewyvern.ron @@ -3,7 +3,7 @@ name: Automatic, body: RandomWith("wyvern_flame"), alignment: Alignment(Enemy), - loot: LootTable("common.loot_tables.creature.bird_large.wyvern"), + loot: LootTable("common.loot_tables.creature.bird_large.flamewyvern"), inventory: ( loadout: FromBody, ), diff --git a/assets/common/entity/wild/aggressive/frostwyvern.ron b/assets/common/entity/wild/aggressive/frostwyvern.ron index 628fae589c..66d556240b 100644 --- a/assets/common/entity/wild/aggressive/frostwyvern.ron +++ b/assets/common/entity/wild/aggressive/frostwyvern.ron @@ -3,7 +3,7 @@ name: Automatic, body: RandomWith("wyvern_frost"), alignment: Alignment(Enemy), - loot: LootTable("common.loot_tables.creature.bird_large.wyvern"), + loot: LootTable("common.loot_tables.creature.bird_large.frostwyvern"), inventory: ( loadout: FromBody, ), diff --git a/assets/common/entity/wild/aggressive/seawyvern.ron b/assets/common/entity/wild/aggressive/seawyvern.ron index d1a07640c4..d9ad3ede28 100644 --- a/assets/common/entity/wild/aggressive/seawyvern.ron +++ b/assets/common/entity/wild/aggressive/seawyvern.ron @@ -3,7 +3,7 @@ name: Automatic, body: RandomWith("wyvern_sea"), alignment: Alignment(Enemy), - loot: LootTable("common.loot_tables.creature.bird_large.wyvern"), + loot: LootTable("common.loot_tables.creature.bird_large.seawyvern"), inventory: ( loadout: FromBody, ), diff --git a/assets/common/entity/wild/aggressive/wealdwyvern.ron b/assets/common/entity/wild/aggressive/wealdwyvern.ron index 0c81bc8d61..6e9997bb9c 100644 --- a/assets/common/entity/wild/aggressive/wealdwyvern.ron +++ b/assets/common/entity/wild/aggressive/wealdwyvern.ron @@ -3,7 +3,7 @@ name: Automatic, body: RandomWith("wyvern_weald"), alignment: Alignment(Enemy), - loot: LootTable("common.loot_tables.creature.bird_large.wyvern"), + loot: LootTable("common.loot_tables.creature.bird_large.wealdwyvern"), inventory: ( loadout: FromBody, ), diff --git a/assets/common/loot_tables/creature/bird_large/cloudwyvern.ron b/assets/common/loot_tables/creature/bird_large/cloudwyvern.ron new file mode 100644 index 0000000000..665c53c54b --- /dev/null +++ b/assets/common/loot_tables/creature/bird_large/cloudwyvern.ron @@ -0,0 +1,7 @@ +[ + (1.0, MultiDrop(Item("common.items.mineral.gem.topaz"), 1, 3)), + (5.0, MultiDrop(Item("common.items.mineral.gem.amethyst"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.elegant_crest"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.claw"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 2, 6)), +] \ No newline at end of file diff --git a/assets/common/loot_tables/creature/bird_large/flamewyvern.ron b/assets/common/loot_tables/creature/bird_large/flamewyvern.ron new file mode 100644 index 0000000000..8447f02b50 --- /dev/null +++ b/assets/common/loot_tables/creature/bird_large/flamewyvern.ron @@ -0,0 +1,7 @@ +[ + (1.0, MultiDrop(Item("common.items.mineral.gem.topaz"), 1, 3)), + (5.0, MultiDrop(Item("common.items.mineral.gem.ruby"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.large_horn"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.sharp_fang"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 2, 6)), +] \ No newline at end of file diff --git a/assets/common/loot_tables/creature/bird_large/frostwyvern.ron b/assets/common/loot_tables/creature/bird_large/frostwyvern.ron new file mode 100644 index 0000000000..ebd59ef11b --- /dev/null +++ b/assets/common/loot_tables/creature/bird_large/frostwyvern.ron @@ -0,0 +1,7 @@ +[ + (1.0, MultiDrop(Item("common.items.mineral.gem.topaz"), 1, 3)), + (5.0, MultiDrop(Item("common.items.mineral.gem.diamond"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.large_horn"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.claw"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 2, 6)), +] \ No newline at end of file diff --git a/assets/common/loot_tables/creature/bird_large/seawyvern.ron b/assets/common/loot_tables/creature/bird_large/seawyvern.ron new file mode 100644 index 0000000000..b1b6c1297e --- /dev/null +++ b/assets/common/loot_tables/creature/bird_large/seawyvern.ron @@ -0,0 +1,7 @@ +[ + (1.0, MultiDrop(Item("common.items.mineral.gem.topaz"), 1, 3)), + (5.0, MultiDrop(Item("common.items.mineral.gem.sapphire"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.sharp_fang"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.claw"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 2, 6)), +] \ No newline at end of file diff --git a/assets/common/loot_tables/creature/bird_large/wealdwyvern.ron b/assets/common/loot_tables/creature/bird_large/wealdwyvern.ron new file mode 100644 index 0000000000..6d0866c5e9 --- /dev/null +++ b/assets/common/loot_tables/creature/bird_large/wealdwyvern.ron @@ -0,0 +1,7 @@ +[ + (1.0, MultiDrop(Item("common.items.mineral.gem.topaz"), 1, 3)), + (5.0, MultiDrop(Item("common.items.mineral.gem.emerald"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.elegant_crest"), 1, 3)), + (1.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.large_horn"), 1, 3)), + (5.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 2, 6)), +] \ No newline at end of file diff --git a/assets/common/loot_tables/creature/bird_large/wyvern.ron b/assets/common/loot_tables/creature/bird_large/wyvern.ron deleted file mode 100644 index 636310cc1d..0000000000 --- a/assets/common/loot_tables/creature/bird_large/wyvern.ron +++ /dev/null @@ -1,6 +0,0 @@ -[ - (1.0, MultiDrop(Item("common.items.food.meat.bird_large_raw"), 1, 2)), - (1.0, MultiDrop(Item("common.items.food.meat.beast_large_raw"), 2, 2)), - (2.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.elegant_crest"), 1, 3)), - (1.0, MultiDrop(Item("common.items.crafting_ing.hide.scales"), 2, 6)), -] \ No newline at end of file diff --git a/assets/common/loot_tables/dungeon/dwarven_quarry/t4-mats.ron b/assets/common/loot_tables/dungeon/dwarven_quarry/t4-mats.ron index 4f4ffd0c48..c0dcf37d93 100644 --- a/assets/common/loot_tables/dungeon/dwarven_quarry/t4-mats.ron +++ b/assets/common/loot_tables/dungeon/dwarven_quarry/t4-mats.ron @@ -1,6 +1,5 @@ [ (1.0, MultiDrop(Item("common.items.crafting_ing.cloth.sunsilk"), 1, 3)), - (1.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 3, 8)), (1.0, MultiDrop(Item("common.items.mineral.ingot.orichalcum"), 1, 3)), (1.0, MultiDrop(Item("common.items.log.eldwood"), 2, 6)), ] \ No newline at end of file diff --git a/assets/common/loot_tables/dungeon/tier-4/boss.ron b/assets/common/loot_tables/dungeon/tier-4/boss.ron index ad862bc127..8418293685 100644 --- a/assets/common/loot_tables/dungeon/tier-4/boss.ron +++ b/assets/common/loot_tables/dungeon/tier-4/boss.ron @@ -8,6 +8,5 @@ (1.0, LootTable("common.loot_tables.weapons.legendary_melee")), // Crafting material // Allow for DS and Eldwood to drop till entity droppers are implemented - (1.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 3, 8)), (1.0, MultiDrop(Item("common.items.log.eldwood"), 2, 6)), ] diff --git a/assets/common/loot_tables/dungeon/tier-5/boss.ron b/assets/common/loot_tables/dungeon/tier-5/boss.ron index 0e8ae80e69..66699c60bb 100644 --- a/assets/common/loot_tables/dungeon/tier-5/boss.ron +++ b/assets/common/loot_tables/dungeon/tier-5/boss.ron @@ -13,6 +13,5 @@ // Crafting material // Allow for DS and Eldwood to drop till entity droppers are implemented (1.0, Item("common.items.crafting_ing.mindflayer_bag_damaged")), - (1.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 3, 8)), (1.0, MultiDrop(Item("common.items.log.eldwood"), 2, 6)), ] diff --git a/assets/voxygen/audio/sfx.ron b/assets/voxygen/audio/sfx.ron index ccc9aa132d..043c7c638f 100644 --- a/assets/voxygen/audio/sfx.ron +++ b/assets/voxygen/audio/sfx.ron @@ -1430,12 +1430,18 @@ threshold: 1.25, subtitle: "subtitle-attack-laser_beam", ), - Woosh: ( + Whoosh: ( files: [ - "voxygen.audio.sfx.abilities.woosh", + "voxygen.audio.sfx.abilities.whoosh", ], threshold: 0.4, ), + Swoosh: ( + files: [ + "voxygen.audio.sfx.abilities.swoosh", + ], + threshold: 1.3, + ), CyclopsCharge: ( files: [ "voxygen.audio.sfx.abilities.cyclops_charge", @@ -1518,6 +1524,13 @@ threshold: 1.0, subtitle: "subtitle-utterance-bird-angry", ), + Utterance(Angry, Wyvern): ( + files: [ + "voxygen.audio.sfx.utterance.wyvern_angry", + ], + threshold: 1.3, + subtitle: "subtitle-utterance-wyvern-angry", + ), Utterance(Angry, Adlet): ( files: [ "voxygen.audio.sfx.utterance.adlet_angry1", @@ -1719,6 +1732,13 @@ threshold: 1.0, subtitle: "subtitle-utterance-asp-hurt", ), + Utterance(Hurt, Wyvern): ( + files: [ + "voxygen.audio.sfx.utterance.wyvern_hurt", + ], + threshold: 1.2, + subtitle: "subtitle-utterance-wyvern-hurt", + ), Utterance(Angry, Wendigo): ( files: [ "voxygen.audio.sfx.utterance.wendigo_angry1", diff --git a/assets/voxygen/audio/sfx/abilities/swoosh.ogg b/assets/voxygen/audio/sfx/abilities/swoosh.ogg new file mode 100644 index 0000000000..c28fb7afd3 --- /dev/null +++ b/assets/voxygen/audio/sfx/abilities/swoosh.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9c05a669c27036748691d1bea2dc05e6f97bf0702c2151518e9e05c4ae98b7b +size 31263 diff --git a/assets/voxygen/audio/sfx/abilities/woosh.ogg b/assets/voxygen/audio/sfx/abilities/whoosh.ogg similarity index 100% rename from assets/voxygen/audio/sfx/abilities/woosh.ogg rename to assets/voxygen/audio/sfx/abilities/whoosh.ogg diff --git a/assets/voxygen/audio/sfx/utterance/wyvern_angry.ogg b/assets/voxygen/audio/sfx/utterance/wyvern_angry.ogg new file mode 100644 index 0000000000..4c90c9f4c4 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/wyvern_angry.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f66952709c7f9c91c16519f85bf28fac68ddc3a14422a6450e3b25de29309b9 +size 18645 diff --git a/assets/voxygen/audio/sfx/utterance/wyvern_hurt.ogg b/assets/voxygen/audio/sfx/utterance/wyvern_hurt.ogg new file mode 100644 index 0000000000..9f9f331f61 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/wyvern_hurt.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4689297e6c4e40186b49f5d1ea38340bda387e91b98e67d1e45ba4bcafe4faa +size 13063 diff --git a/assets/voxygen/i18n/en/hud/subtitles.ftl b/assets/voxygen/i18n/en/hud/subtitles.ftl index dbbeab8759..a48cb4031e 100644 --- a/assets/voxygen/i18n/en/hud/subtitles.ftl +++ b/assets/voxygen/i18n/en/hud/subtitles.ftl @@ -148,4 +148,6 @@ subtitle-utterance-asp-hurt = Asp hurting subtitle-utterance-wendigo-angry = Wendigo screaming subtitle-utterance-wendigo-calm = Wendigo mumbling subtitle-utterance-wolf-angry = Wolf growling -subtitle-utterance-wolf-hurt = Wolf whining \ No newline at end of file +subtitle-utterance-wolf-hurt = Wolf whining +subtitle-utterance-wyvern-angry = Wyvern roaring +subtitle-utterance-wyvern-hurt = Wyvern hurting \ No newline at end of file diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 370945eca2..6352fde4b9 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -82,6 +82,7 @@ const int POTION_SICKNESS = 41; const int GIGA_SNOW = 42; const int CYCLOPS_CHARGE = 43; const int PORTAL_FIZZ = 45; +const int INK = 46; // meters per second squared (acceleration) const float earth_gravity = 9.807; @@ -691,6 +692,17 @@ void main() { spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3 + lifetime * 5) ); break; + case INK: + f_reflect = 0.0; // Magic water doesn't reflect light, it emits it + float black_color = 0.3 + 0.2 * rand3 + 0.3 * max(floor(rand4 + 0.3), 0.0); + float ink_size = 8.0 * (1 - slow_start(0.1)) * slow_end(0.15); + attr = Attr( + (inst_dir * slow_end(1.5)) + vec3(rand0, rand1, rand2) * (percent() + 2) * 0.1, + vec3(ink_size), + vec4(0.5 * black_color, 0.75 * black_color, black_color, 1), + spin_in_axis(vec3(rand6, rand7, rand8), percent() * 10 + 3 * rand9) + ); + break; default: attr = Attr( linear_motion( diff --git a/assets/voxygen/voxel/object_manifest.ron b/assets/voxygen/voxel/object_manifest.ron index 0b13403e8d..6b220d517d 100644 --- a/assets/voxygen/voxel/object_manifest.ron +++ b/assets/voxygen/voxel/object_manifest.ron @@ -939,6 +939,26 @@ central: ("armor.empty"), ) ), + LightningBolt: ( + bone0: ( + offset: (-4.5, -80.0, -3.0), + central: ("weapon.projectile.lightning_bolt"), + ), + bone1: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), + SpearIcicle: ( + bone0: ( + offset: (-2.5, -30.0, -2.5), + central: ("weapon.projectile.icicle-spear"), + ), + bone1: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), AdletSpear: ( bone0: ( offset: (5.0, -22.0, -2.0), diff --git a/assets/voxygen/voxel/weapon/projectile/icicle-spear.vox b/assets/voxygen/voxel/weapon/projectile/icicle-spear.vox new file mode 100644 index 0000000000..b39c4fc4bd --- /dev/null +++ b/assets/voxygen/voxel/weapon/projectile/icicle-spear.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8137c3873125651d65b0648f9444c8efa86b53cadb349ece08668a7dc56832f9 +size 1924 diff --git a/assets/voxygen/voxel/weapon/projectile/lightning_bolt.vox b/assets/voxygen/voxel/weapon/projectile/lightning_bolt.vox new file mode 100644 index 0000000000..b5ffd3e8d7 --- /dev/null +++ b/assets/voxygen/voxel/weapon/projectile/lightning_bolt.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b773a91b0f2a23f38eb51f02b09472ad31f44418c6f4617db8c28da41b58a318 +size 1528 diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index 9da6d71267..5643ba06fd 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -354,7 +354,7 @@ impl<'a> From<&'a Body> for Psyche { bird_medium::Species::Puffin => 0.8, bird_medium::Species::Toucan => 0.4, }, - Body::BirdLarge(_) => 0.1, + Body::BirdLarge(_) => 0.0, Body::FishSmall(_) => 1.0, Body::FishMedium(_) => 0.75, Body::BipedLarge(_) => 0.0, @@ -380,7 +380,10 @@ impl<'a> From<&'a Body> for Psyche { arthropod::Species::Emberfly => 0.1, }, }, - sight_dist: 40.0, + sight_dist: match body { + Body::BirdLarge(_) => 80.0, + _ => 40.0, + }, listen_dist: 30.0, aggro_dist: match body { Body::Humanoid(_) => Some(20.0), diff --git a/common/src/comp/beam.rs b/common/src/comp/beam.rs index e080b8f33d..701a4b9c84 100644 --- a/common/src/comp/beam.rs +++ b/common/src/comp/beam.rs @@ -55,4 +55,7 @@ pub enum FrontendSpecifier { Steam, Frost, WebStrand, + Poison, + Ink, + Lightning, } diff --git a/common/src/comp/body/object.rs b/common/src/comp/body/object.rs index 404b35d9bc..44735011e1 100644 --- a/common/src/comp/body/object.rs +++ b/common/src/comp/body/object.rs @@ -108,6 +108,8 @@ make_case_elim!( AdletTrap = 93, Flamethrower = 94, Mine = 95, + LightningBolt = 96, + SpearIcicle = 97, } ); @@ -118,7 +120,7 @@ impl Body { } } -pub const ALL_OBJECTS: [Body; 96] = [ +pub const ALL_OBJECTS: [Body; 98] = [ Body::Arrow, Body::Bomb, Body::Scarecrow, @@ -215,6 +217,8 @@ pub const ALL_OBJECTS: [Body; 96] = [ Body::AdletTrap, Body::Flamethrower, Body::Mine, + Body::LightningBolt, + Body::SpearIcicle, ]; impl From for super::Body { @@ -320,6 +324,8 @@ impl Body { Body::AdletTrap => "adlet_trap", Body::Flamethrower => "flamethrower", Body::Mine => "mine", + Body::LightningBolt => "lightning_bolt", + Body::SpearIcicle => "spear_icicle", } } @@ -372,11 +378,8 @@ impl Body { Body::BedBlue => 50.0, Body::Bedroll => 3.0, Body::Bench => 100.0, - Body::BoltFire - | Body::BoltFireBig - | Body::BoltNature - | Body::BoltIcicle - | Body::SpitPoison => 1.0, + Body::BoltFire | Body::BoltFireBig | Body::BoltNature | Body::BoltIcicle => 1.0, + Body::SpitPoison => 100.0, Body::Bomb | Body::DagonBomb => { 0.5 * IRON_DENSITY * std::f32::consts::PI / 6.0 * self.dimensions().x.powi(3) }, @@ -446,6 +449,7 @@ impl Body { Body::AdletSpear => 1.5, Body::AdletTrap => 10.0, Body::Mine => 100.0, + Body::LightningBolt | Body::SpearIcicle => 20000.0, }; Mass(m) @@ -477,6 +481,7 @@ impl Body { Body::IceBomb => Vec3::broadcast(2.5), Body::LaserBeam => Vec3::new(8.0, 8.0, 8.0), Body::Mine => Vec3::new(0.8, 0.8, 0.5), + Body::LightningBolt | Body::SpearIcicle => Vec3::new(1.0, 1.0, 1.0), // FIXME: this *must* be exhaustive match _ => Vec3::broadcast(0.5), } diff --git a/common/src/comp/projectile.rs b/common/src/comp/projectile.rs index 016c7bc42f..c77843b8c5 100644 --- a/common/src/comp/projectile.rs +++ b/common/src/comp/projectile.rs @@ -91,12 +91,7 @@ pub enum ProjectileConstructor { knockback: f32, min_falloff: f32, }, - SeaBomb { - damage: f32, - radius: f32, - min_falloff: f32, - }, - WindBomb { + InkBomb { damage: f32, radius: f32, min_falloff: f32, @@ -527,7 +522,7 @@ impl ProjectileConstructor { is_point: true, } }, - SeaBomb { + InkBomb { damage, radius, min_falloff, @@ -541,12 +536,27 @@ impl ProjectileConstructor { Some(GroupTarget::OutOfGroup), instance, ); + let buff = AttackEffect::new( + Some(GroupTarget::OutOfGroup), + CombatEffect::Buff(CombatBuff { + kind: BuffKind::Wet, + dur_secs: 8.0, + strength: CombatBuffStrength::Value(0.5), + chance: 1.0, + }) + .adjusted_by_stats(tool_stats), + ) + .with_requirement(CombatRequirement::AnyDamage); let attack = Attack::default() .with_damage(damage) .with_crit(crit_chance, crit_mult) + .with_effect(buff) .with_combo_increment(); let explosion = Explosion { - effects: vec![RadiusEffect::Attack(attack)], + effects: vec![ + RadiusEffect::Attack(attack), + RadiusEffect::TerrainDestruction(18.0, Rgb::new(4.0, 7.0, 32.0)), + ], radius, reagent: Some(Reagent::Blue), min_falloff, @@ -561,40 +571,6 @@ impl ProjectileConstructor { is_point: true, } }, - WindBomb { - damage, - radius, - min_falloff, - } => { - let damage = AttackDamage::new( - Damage { - source: DamageSource::Explosion, - kind: DamageKind::Energy, - value: damage, - }, - Some(GroupTarget::OutOfGroup), - instance, - ); - let attack = Attack::default() - .with_damage(damage) - .with_crit(crit_chance, crit_mult) - .with_combo_increment(); - let explosion = Explosion { - effects: vec![RadiusEffect::Attack(attack)], - radius, - reagent: Some(Reagent::White), - min_falloff, - }; - Projectile { - hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish], - hit_entity: vec![Effect::Explode(explosion), Effect::Vanish], - time_left: Duration::from_secs(10), - owner, - ignore_group: true, - is_sticky: true, - is_point: true, - } - }, Snowball { damage, radius, @@ -982,15 +958,7 @@ impl ProjectileConstructor { *damage *= power; *radius *= range; }, - SeaBomb { - ref mut damage, - ref mut radius, - .. - } => { - *damage *= power; - *radius *= range; - }, - WindBomb { + InkBomb { ref mut damage, ref mut radius, .. @@ -1068,8 +1036,7 @@ impl ProjectileConstructor { Snowball { .. } => true, ExplodingPumpkin { .. } => true, DagonBomb { .. } => true, - SeaBomb { .. } => true, - WindBomb { .. } => true, + InkBomb { .. } => true, IceBomb { .. } => true, LaserBeam { .. } => true, Trap { .. } => false, diff --git a/common/src/comp/shockwave.rs b/common/src/comp/shockwave.rs index 3d6fecce76..9b5bb0d228 100644 --- a/common/src/comp/shockwave.rs +++ b/common/src/comp/shockwave.rs @@ -49,6 +49,10 @@ pub enum FrontendSpecifier { Ground, Fire, Water, + Ice, IceSpikes, Steam, + Poison, + Ink, + Lightning, } diff --git a/common/src/outcome.rs b/common/src/outcome.rs index ff2f82f84c..e7762bd955 100644 --- a/common/src/outcome.rs +++ b/common/src/outcome.rs @@ -128,7 +128,10 @@ pub enum Outcome { FailedSpriteUnlock { pos: Vec3, }, - Woosh { + Whoosh { + pos: Vec3, + }, + Swoosh { pos: Vec3, }, FireShockwave { @@ -152,7 +155,8 @@ impl Outcome { | Outcome::PoiseChange { pos, .. } | Outcome::GroundSlam { pos } | Outcome::FlashFreeze { pos } - | Outcome::Woosh { pos } + | Outcome::Whoosh { pos } + | Outcome::Swoosh { pos } | Outcome::IceSpikes { pos } | Outcome::Steam { pos } | Outcome::FireShockwave { pos } diff --git a/common/src/states/leap_melee.rs b/common/src/states/leap_melee.rs index 2e5802fd67..048e806257 100644 --- a/common/src/states/leap_melee.rs +++ b/common/src/states/leap_melee.rs @@ -75,7 +75,7 @@ impl CharacterBehavior for Data { }); if let Some(FrontendSpecifier::ElderLeap) = self.static_data.specifier { // Send local event used for frontend shenanigans - output_events.emit_local(LocalEvent::CreateOutcome(Outcome::Woosh { + output_events.emit_local(LocalEvent::CreateOutcome(Outcome::Whoosh { pos: data.pos.0 + *data.ori.look_dir() * (data.body.max_radius()), })); } diff --git a/common/src/states/shockwave.rs b/common/src/states/shockwave.rs index f7b76bff4c..a342fd3cde 100644 --- a/common/src/states/shockwave.rs +++ b/common/src/states/shockwave.rs @@ -173,7 +173,11 @@ impl CharacterBehavior for Data { }, )); }, - _ => {}, + _ => { + output_events.emit_local(LocalEvent::CreateOutcome(Outcome::Swoosh { + pos: data.pos.0 + *data.ori.look_dir() * (data.body.max_radius()), + })); + }, } } else { // Transitions to recover diff --git a/rtsim/src/data/mod.rs b/rtsim/src/data/mod.rs index a2adede9a7..0f466332d2 100644 --- a/rtsim/src/data/mod.rs +++ b/rtsim/src/data/mod.rs @@ -29,7 +29,7 @@ use std::{ /// Note that this number does *not* need incrementing on every change: most /// field removals/additions are fine. This number should only be incremented /// when we wish to perform a *hard purge* of rtsim data. -pub const CURRENT_VERSION: u32 = 3; +pub const CURRENT_VERSION: u32 = 4; #[derive(Clone, Serialize, Deserialize)] pub struct Data { diff --git a/rtsim/src/gen/mod.rs b/rtsim/src/gen/mod.rs index 1cf67c46c6..4c20b55fd5 100644 --- a/rtsim/src/gen/mod.rs +++ b/rtsim/src/gen/mod.rs @@ -218,6 +218,11 @@ impl Data { comp::body::bird_large::Species::Phoenix, comp::body::bird_large::Species::Cockatrice, comp::body::bird_large::Species::Roc, + comp::body::bird_large::Species::FlameWyvern, + comp::body::bird_large::Species::CloudWyvern, + comp::body::bird_large::Species::FrostWyvern, + comp::body::bird_large::Species::SeaWyvern, + comp::body::bird_large::Species::WealdWyvern, ] .choose(&mut rng) .unwrap(); diff --git a/rtsim/src/rule/npc_ai.rs b/rtsim/src/rule/npc_ai.rs index 5d9f2bc2d1..b877acfe29 100644 --- a/rtsim/src/rule/npc_ai.rs +++ b/rtsim/src/rule/npc_ai.rs @@ -1147,45 +1147,74 @@ fn humanoid() -> impl Action { } fn bird_large() -> impl Action { - choose(|ctx, _| { - let data = ctx.state.data(); - if let Some(home) = ctx.npc.home { - let is_home = ctx.npc.current_site.map_or(false, |site| home == site); - let goto = |wpos| { - casual(goto_2d_flying( - wpos, - 1.0, - 20.0, - 32.0, - 22.0, - ctx.npc.body.flying_height(), - )) - }; - if is_home { - if let Some((_, site)) = data - .sites - .iter() - .filter(|(id, site)| { - *id != home - && site.world_site.map_or(false, |site| { - matches!(ctx.index.sites.get(site).kind, SiteKind::Dungeon(_)) - }) - }) - .choose(&mut ctx.rng) - { - goto(site.wpos.as_::()) - } else { - casual(idle()) - } - } else if let Some(site) = data.sites.get(home) { - goto(site.wpos.as_::()) - } else { - casual(idle()) - } + now(|ctx, bearing: &mut Vec2| { + *bearing = bearing + .map(|e| e + ctx.rng.gen_range(-0.1..0.1)) + .try_normalized() + .unwrap_or_default(); + let bearing_dist = 24.0; + let mut pos = ctx.npc.wpos.xy() + *bearing * bearing_dist; + let is_deep_water = ctx + .world + .sim() + .get_interpolated(pos.as_(), |c| c.alt - c.water_alt) + .unwrap_or(f32::NEG_INFINITY) + < -120.0 + && ctx + .world + .sim() + .get(pos.as_().wpos_to_cpos()) + .map_or(false, |c| c.river.is_ocean() || c.river.is_lake()); + // when high tree_density fly high, otherwise fly low-mid + let npc_pos = ctx.npc.wpos.xy(); + let tree_density = ctx + .world + .sim() + .get_interpolated(npc_pos.as_(), |c| c.tree_density) + .unwrap_or(1.0); + let height_factor = if tree_density > 0.1 { + 2.0 } else { - casual(idle()) + ctx.rng.gen_range(0.1..0.5) + }; + if !is_deep_water { + goto_2d_flying( + pos, + 0.2, + bearing_dist, + 8.0, + 8.0, + ctx.npc.body.flying_height() * height_factor, + ) + + } else { + *bearing *= -1.0; + + pos = ctx.npc.wpos.xy() + *bearing * 24.0; + + goto_2d_flying( + pos, + 0.2, + bearing_dist, + 8.0, + 8.0, + ctx.npc.body.flying_height() * height_factor, + ) } + // If we are too far away from our goal position we can stop since we aren't going to a specific place. + .stop_if(move |ctx: &mut NpcCtx| { + ctx.npc.wpos.xy().distance_squared(pos) > (bearing_dist + 5.0).powi(2) + }) + // If goal position wasn't reached within 20 seconds we're probably stuck and need to find a new goal position. + .stop_if(timeout(10.0)) + .debug({ + let bearing = *bearing; + move || format!("Moving with a bearing of {:?}", bearing) + }) }) + .repeat() + .with_state(Vec2::::zero()) + .map(|_, _| ()) } fn monster() -> impl Action { diff --git a/server/agent/src/attack.rs b/server/agent/src/attack.rs index eb27de8df3..64cf3b92ea 100644 --- a/server/agent/src/attack.rs +++ b/server/agent/src/attack.rs @@ -106,68 +106,6 @@ impl<'a> AgentData<'a> { } } - pub fn handle_wyvern_attack( - &self, - _agent: &mut Agent, - controller: &mut Controller, - attack_data: &AttackData, - tgt_data: &TargetData, - read_data: &ReadData, - _rng: &mut impl Rng, - ) { - // Fly to target - let dir_to_target = ((tgt_data.pos.0 + Vec3::unit_z() * 1.5) - self.pos.0) - .try_normalized() - .unwrap_or_else(Vec3::zero); - let speed = 1.0; - controller.inputs.move_dir = dir_to_target.xy() * speed; - - // Always fly! If the floor can't touch you, it can't hurt you... - controller.push_basic_input(InputKind::Fly); - // Flee from the ground! The internet told me it was lava! - // If on the ground, jump with every last ounce of energy, holding onto all that - // is dear in life and straining for the wide open skies. - if self.physics_state.on_ground.is_some() { - controller.push_basic_input(InputKind::Jump); - } else { - // Only fly down if close enough to target in the xy plane - // Otherwise fly towards the target bouncing around a 5 block altitude - let mut maintain_altitude = |altitude| { - if read_data - .terrain - .ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * altitude)) - .until(Block::is_solid) - .cast() - .1 - .map_or(true, |b| b.is_some()) - { - // Fly up - controller.inputs.move_z = 1.0; - } else { - // Fly down - controller.inputs.move_z = -1.0; - } - }; - if (tgt_data.pos.0 - self.pos.0).xy().magnitude_squared() > (30.0_f32).powi(2) { - // If above 30 blocks, fly down and attack - maintain_altitude(30.0); - // Shoot bombs - controller.push_basic_input(InputKind::Primary); - } else { - maintain_altitude(2.0); - - // Attack if in range - if attack_data.dist_sqrd < 6.0_f32.powi(2) && attack_data.angle < 150.0 { - controller.push_basic_input(InputKind::Ability(0)); - } else if attack_data.dist_sqrd < 8.0_f32.powi(2) && attack_data.angle < 150.0 { - controller.push_basic_input(InputKind::Ability(1)); - } else if attack_data.dist_sqrd < 12.0_f32.powi(2) && attack_data.angle < 150.0 { - controller.push_basic_input(InputKind::Secondary); - } - } - } - } - // Intended for any agent that has one attack, that attack is a melee attack, // the agent is able to freely walk around, and the agent is trying to attack // from behind its target @@ -3034,27 +2972,26 @@ impl<'a> AgentData<'a> { attack_data: &AttackData, tgt_data: &TargetData, read_data: &ReadData, - rng: &mut impl Rng, + _rng: &mut impl Rng, ) { + enum ActionStateTimers { + AttackTimer = 0, + } + // Set fly to false + controller.push_cancel_input(InputKind::Fly); if attack_data.dist_sqrd > 30.0_f32.powi(2) { - let small_chance = rng.gen_bool(0.05); - - if small_chance - && entities_have_line_of_sight( - self.pos, - self.body, - self.scale, - tgt_data.pos, - tgt_data.body, - tgt_data.scale, - read_data, - ) - && attack_data.angle < 15.0 + if entities_have_line_of_sight( + self.pos, + self.body, + self.scale, + tgt_data.pos, + tgt_data.body, + tgt_data.scale, + read_data, + ) && attack_data.angle < 15.0 { - // Fireball controller.push_basic_input(InputKind::Primary); } - // If some target if let Some((bearing, speed)) = agent.chaser.chase( &*read_data.terrain, self.pos.0, @@ -3065,23 +3002,14 @@ impl<'a> AgentData<'a> { ..self.traversal_config }, ) { - // Walk to target controller.inputs.move_dir = bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed; - // If less than 20 blocks higher than target if (self.pos.0.z - tgt_data.pos.0.z) < 20.0 { - // Fly upward controller.push_basic_input(InputKind::Fly); controller.inputs.move_z = 1.0; - } else { - // Jump - self.jump_if(bearing.z > 1.5, controller); - controller.inputs.move_z = bearing.z; } } - } - // If higher than 2 blocks - else if !read_data + } else if !read_data .terrain .ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 2.0)) .until(Block::is_solid) @@ -3092,41 +3020,52 @@ impl<'a> AgentData<'a> { // Do not increment the timer during this movement // The next stage shouldn't trigger until the entity // is on the ground - // Fly to target controller.push_basic_input(InputKind::Fly); let move_dir = tgt_data.pos.0 - self.pos.0; controller.inputs.move_dir = move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0; controller.inputs.move_z = move_dir.z - 0.5; - // If further than 4 blocks and random chance - if rng.gen_bool(0.05) - && attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2) + if attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2) && attack_data.angle < 15.0 { - // Fireball controller.push_basic_input(InputKind::Primary); } - } - // If further than 4 blocks and random chance - else if rng.gen_bool(0.05) - && attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2) + } else if attack_data.dist_sqrd > (3.0 * attack_data.min_attack_dist).powi(2) { + self.path_toward_target( + agent, + controller, + tgt_data.pos.0, + read_data, + Path::Separate, + None, + ); + } else if self.energy.current() > 60.0 + && agent.action_state.timers[ActionStateTimers::AttackTimer as usize] < 3.0 && attack_data.angle < 15.0 { - // Fireball - controller.push_basic_input(InputKind::Primary); - } - // If random chance and less than 20 blocks higher than target and further than 4 - // blocks - else if rng.gen_bool(0.5) - && (self.pos.0.z - tgt_data.pos.0.z) < 15.0 - && attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2) + // Shockwave + controller.push_basic_input(InputKind::Ability(0)); + // Move towards the target slowly + self.path_toward_target( + agent, + controller, + tgt_data.pos.0, + read_data, + Path::Separate, + Some(0.5), + ); + agent.action_state.timers[ActionStateTimers::AttackTimer as usize] += read_data.dt.0; + } else if agent.action_state.timers[ActionStateTimers::AttackTimer as usize] < 6.0 + && attack_data.angle < 90.0 + && attack_data.in_min_range() { - controller.push_basic_input(InputKind::Fly); - controller.inputs.move_z = 1.0; - } - // If further than 2.5 blocks and random chance - else if attack_data.dist_sqrd > (2.5 * attack_data.min_attack_dist).powi(2) { - // Walk to target + // Triple strike + controller.push_basic_input(InputKind::Secondary); + agent.action_state.timers[ActionStateTimers::AttackTimer as usize] += read_data.dt.0; + } else { + // Reset timer + agent.action_state.timers[ActionStateTimers::AttackTimer as usize] = 0.0; + // Target is behind us or the timer needs to be reset. Chase target self.path_toward_target( agent, controller, @@ -3136,15 +3075,113 @@ impl<'a> AgentData<'a> { None, ); } - // If energy higher than 600 and random chance - else if self.energy.current() > 60.0 && rng.gen_bool(0.4) { - // Shockwave - controller.push_basic_input(InputKind::Ability(0)); - } else if attack_data.angle < 90.0 { + } + + pub fn handle_wyvern_attack( + &self, + agent: &mut Agent, + controller: &mut Controller, + attack_data: &AttackData, + tgt_data: &TargetData, + read_data: &ReadData, + _rng: &mut impl Rng, + ) { + enum ActionStateTimers { + AttackTimer = 0, + } + // Set fly to false + controller.push_cancel_input(InputKind::Fly); + if attack_data.dist_sqrd > 30.0_f32.powi(2) { + if entities_have_line_of_sight( + self.pos, + self.body, + self.scale, + tgt_data.pos, + tgt_data.body, + tgt_data.scale, + read_data, + ) && attack_data.angle < 15.0 + { + controller.push_basic_input(InputKind::Primary); + } + if let Some((bearing, speed)) = agent.chaser.chase( + &*read_data.terrain, + self.pos.0, + self.vel.0, + tgt_data.pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..self.traversal_config + }, + ) { + controller.inputs.move_dir = + bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed; + if (self.pos.0.z - tgt_data.pos.0.z) < 35.0 { + controller.push_basic_input(InputKind::Fly); + controller.inputs.move_z = 1.0; + } + } + } else if !read_data + .terrain + .ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 2.0)) + .until(Block::is_solid) + .cast() + .1 + .map_or(true, |b| b.is_some()) + { + // Do not increment the timer during this movement + // The next stage shouldn't trigger until the entity + // is on the ground + controller.push_basic_input(InputKind::Fly); + let move_dir = tgt_data.pos.0 - self.pos.0; + controller.inputs.move_dir = + move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0; + controller.inputs.move_z = move_dir.z - 0.5; + if attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2) + && attack_data.angle < 15.0 + { + controller.push_basic_input(InputKind::Primary); + } + } else if attack_data.dist_sqrd > (3.0 * attack_data.min_attack_dist).powi(2) { + self.path_toward_target( + agent, + controller, + tgt_data.pos.0, + read_data, + Path::Separate, + None, + ); + } else if attack_data.angle < 15.0 { + if agent.action_state.timers[ActionStateTimers::AttackTimer as usize] < 5.0 { + // beam + controller.push_basic_input(InputKind::Ability(1)); + } else if agent.action_state.timers[ActionStateTimers::AttackTimer as usize] < 9.0 { + // shockwave + controller.push_basic_input(InputKind::Ability(0)); + } else { + agent.action_state.timers[ActionStateTimers::AttackTimer as usize] = 0.0; + } + // Move towards the target slowly + self.path_toward_target( + agent, + controller, + tgt_data.pos.0, + read_data, + Path::Separate, + Some(0.5), + ); + agent.action_state.timers[ActionStateTimers::AttackTimer as usize] += read_data.dt.0; + } else if agent.action_state.timers[ActionStateTimers::AttackTimer as usize] < 9.0 + && attack_data.angle < 90.0 + && attack_data.in_min_range() + { // Triple strike controller.push_basic_input(InputKind::Secondary); + agent.action_state.timers[ActionStateTimers::AttackTimer as usize] += read_data.dt.0; } else { - // Target is behind us. Turn around and chase target + // Reset timer + agent.action_state.timers[ActionStateTimers::AttackTimer as usize] = 0.0; + // Target is behind us or the timer needs to be reset. Chase target self.path_toward_target( agent, controller, @@ -3201,9 +3238,6 @@ impl<'a> AgentData<'a> { if (self.pos.0.z - tgt_data.pos.0.z) < 20.0 { controller.push_basic_input(InputKind::Fly); controller.inputs.move_z = 1.0; - } else { - self.jump_if(bearing.z > 1.5, controller); - controller.inputs.move_z = bearing.z; } } } else if !read_data @@ -3311,22 +3345,7 @@ impl<'a> AgentData<'a> { // Increase action timer agent.action_state.timers[ActionStateTimers::TimerBirdLargeBasic as usize] += read_data.dt.0; - // If higher than 2 blocks - if !read_data - .terrain - .ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 2.0)) - .until(Block::is_solid) - .cast() - .1 - .map_or(true, |b| b.is_some()) - { - // Fly to target and land - controller.push_basic_input(InputKind::Fly); - let move_dir = tgt_data.pos.0 - self.pos.0; - controller.inputs.move_dir = - move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0; - controller.inputs.move_z = move_dir.z - 0.5; - } else if agent.action_state.timers[ActionStateTimers::TimerBirdLargeBasic as usize] > 8.0 { + if agent.action_state.timers[ActionStateTimers::TimerBirdLargeBasic as usize] > 8.0 { // If action timer higher than 8, make bird summon tornadoes controller.push_basic_input(InputKind::Secondary); if matches!(self.char_state, CharacterState::BasicSummon(c) if matches!(c.stage_section, StageSection::Recover)) diff --git a/server/src/rtsim/tick.rs b/server/src/rtsim/tick.rs index d91e40f192..613a9e2dab 100644 --- a/server/src/rtsim/tick.rs +++ b/server/src/rtsim/tick.rs @@ -165,9 +165,19 @@ fn get_npc_entity_info(npc: &Npc, sites: &Sites, index: IndexRef) -> EntityInfo comp::bird_large::Species::Phoenix => "common.entity.wild.peaceful.phoenix", comp::bird_large::Species::Cockatrice => "common.entity.wild.aggressive.cockatrice", comp::bird_large::Species::Roc => "common.entity.wild.aggressive.roc", - // Wildcard match used here as there is an array above - // which limits what species are used - _ => unimplemented!(), + comp::bird_large::Species::CloudWyvern => { + "common.entity.wild.aggressive.cloudwyvern" + }, + comp::bird_large::Species::FlameWyvern => { + "common.entity.wild.aggressive.flamewyvern" + }, + comp::bird_large::Species::FrostWyvern => { + "common.entity.wild.aggressive.frostwyvern" + }, + comp::bird_large::Species::SeaWyvern => "common.entity.wild.aggressive.seawyvern", + comp::bird_large::Species::WealdWyvern => { + "common.entity.wild.aggressive.wealdwyvern" + }, }, Body::BipedLarge(body) => match body.species { comp::biped_large::Species::Ogre => "common.entity.wild.aggressive.ogre", diff --git a/voxygen/anim/src/bird_large/combomelee.rs b/voxygen/anim/src/bird_large/combomelee.rs new file mode 100644 index 0000000000..893399b94a --- /dev/null +++ b/voxygen/anim/src/bird_large/combomelee.rs @@ -0,0 +1,149 @@ +use super::{ + super::{vek::*, Animation}, + BirdLargeSkeleton, SkeletonAttr, +}; +use common::states::utils::StageSection; + +pub struct ComboAnimation; +impl Animation for ComboAnimation { + type Dependency<'a> = ( + Option<&'a str>, + Option, + usize, + f32, + f32, + Vec3, + Vec3, + bool, + ); + type Skeleton = BirdLargeSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"bird_large_combo\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_combo")] + fn update_skeleton_inner( + skeleton: &Self::Skeleton, + ( + _ability_id, + stage_section, + current_strike, + global_time, + timer, + orientation, + last_ori, + on_ground, + ): Self::Dependency<'_>, + anim_time: f32, + rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + *rate = 1.0; + let mut next = (*skeleton).clone(); + + let multi_strike_pullback = 1.0 + - if matches!(stage_section, Some(StageSection::Recover)) { + anim_time.powi(4) + } else { + 0.0 + }; + + let (move1base, move2base, _move3) = match stage_section { + Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0), + Some(StageSection::Action) => (1.0, anim_time, 0.0), + Some(StageSection::Recover) => (1.0, 1.0, anim_time.powf(4.0)), + _ => (0.0, 0.0, 0.0), + }; + + let wave_slow_cos = (anim_time * 4.5).cos(); + + let subtract = global_time - timer; + let check = subtract - subtract.trunc(); + let mirror = (check - 0.5).signum(); + + let move1 = move1base * multi_strike_pullback; + let move2 = move2base * multi_strike_pullback; + let move1mirror = move1base * multi_strike_pullback * mirror; + let ori: Vec2 = Vec2::from(orientation); + let last_ori = Vec2::from(last_ori); + let tilt = if vek::Vec2::new(ori, last_ori) + .map(|o| o.magnitude_squared()) + .map(|m| m > 0.001 && m.is_finite()) + .reduce_and() + && ori.angle_between(last_ori).is_finite() + { + ori.angle_between(last_ori).min(0.2) + * last_ori.determine_side(Vec2::zero(), ori).signum() + } else { + 0.0 + } * 1.3; + + for strike in 0..=current_strike { + match strike { + 0..=2 => { + next.chest.position = Vec3::new( + 0.0, + s_a.chest.0, + s_a.chest.1 + wave_slow_cos * 0.06 + move2 * -6.0, + ); + next.chest.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8); + + next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); + next.neck.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.4) + * Quaternion::rotation_z(move1 * tilt * 1.5) + * Quaternion::rotation_y(move1mirror * 0.3); + + next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); + next.head.orientation = Quaternion::rotation_x(move1 * -0.2 - move2 * 0.2) + * Quaternion::rotation_y(move1mirror * 0.5); + + next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1); + next.beak.orientation = + Quaternion::rotation_x(wave_slow_cos * -0.02 + move1 * -0.5 + move2 * 0.5); + + if on_ground { + next.tail_front.position = + Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1); + next.tail_front.orientation = Quaternion::rotation_x(-move1 * 0.2); + next.tail_rear.position = Vec3::new(0.0, s_a.tail_rear.0, s_a.tail_rear.1); + next.tail_rear.orientation = Quaternion::rotation_x(0.0); + + next.wing_in_l.position = + Vec3::new(-s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2); + next.wing_in_r.position = + Vec3::new(s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2); + + next.wing_in_l.orientation = Quaternion::rotation_y( + -1.0 + wave_slow_cos * 0.06 + move1 * 1.0 + move2 * 0.5, + ) * Quaternion::rotation_z(0.2); + next.wing_in_r.orientation = Quaternion::rotation_y( + 1.0 - wave_slow_cos * 0.06 + move1 * -1.0 + move2 * -0.5, + ) * Quaternion::rotation_z(-0.2); + + next.wing_mid_l.position = + Vec3::new(-s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2); + next.wing_mid_r.position = + Vec3::new(s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2); + next.wing_mid_l.orientation = Quaternion::rotation_y(-0.1 + move1 * -0.5) + * Quaternion::rotation_z(0.7 + move1 * -0.7); + next.wing_mid_r.orientation = Quaternion::rotation_y(0.1 + move1 * 0.5) + * Quaternion::rotation_z(-0.7 + move1 * 0.7); + + next.wing_out_l.position = + Vec3::new(-s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2); + next.wing_out_r.position = + Vec3::new(s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2); + next.wing_out_l.orientation = Quaternion::rotation_y(-0.2 + move1 * -0.3) + * Quaternion::rotation_z(0.2); + next.wing_out_r.orientation = Quaternion::rotation_y(0.2 + move1 * 0.3) + * Quaternion::rotation_z(-0.2); + } else { + } + }, + _ => {}, + } + } + + next + } +} diff --git a/voxygen/anim/src/bird_large/mod.rs b/voxygen/anim/src/bird_large/mod.rs index b958c224c5..5166e78d65 100644 --- a/voxygen/anim/src/bird_large/mod.rs +++ b/voxygen/anim/src/bird_large/mod.rs @@ -1,5 +1,6 @@ pub mod alpha; pub mod breathe; +pub mod combomelee; pub mod dash; pub mod feed; pub mod fly; @@ -13,9 +14,10 @@ pub mod swim; // Reexports pub use self::{ - alpha::AlphaAnimation, breathe::BreatheAnimation, dash::DashAnimation, feed::FeedAnimation, - fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, - shoot::ShootAnimation, stunned::StunnedAnimation, summon::SummonAnimation, swim::SwimAnimation, + alpha::AlphaAnimation, breathe::BreatheAnimation, combomelee::ComboAnimation, + dash::DashAnimation, feed::FeedAnimation, fly::FlyAnimation, idle::IdleAnimation, + run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation, + stunned::StunnedAnimation, summon::SummonAnimation, swim::SwimAnimation, }; use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; diff --git a/voxygen/src/audio/sfx/mod.rs b/voxygen/src/audio/sfx/mod.rs index e73df1a884..f219a652c2 100644 --- a/voxygen/src/audio/sfx/mod.rs +++ b/voxygen/src/audio/sfx/mod.rs @@ -93,7 +93,7 @@ use client::Client; use common::{ assets::{self, AssetExt, AssetHandle}, comp::{ - beam, biped_large, biped_small, humanoid, + beam, biped_large, biped_small, bird_large, humanoid, item::{AbilitySpec, ItemDefinitionId, ItemKind, ToolKind}, object, poise::PoiseState, @@ -178,9 +178,10 @@ pub enum SfxEvent { Yeet, Klonk, SmashKlonk, - Woosh, FireShockwave, DeepLaugh, + Whoosh, + Swoosh, } #[derive(Copy, Clone, Debug, PartialEq, Deserialize, Hash, Eq)] @@ -213,6 +214,7 @@ pub enum VoiceKind { Fungome, Truffler, Wolf, + Wyvern, } fn body_to_voice(body: &Body) -> Option { @@ -261,7 +263,15 @@ fn body_to_voice(body: &Body) -> Option { quadruped_medium::Species::Antelope => VoiceKind::Antelope, _ => return None, }, - Body::BirdMedium(_) | Body::BirdLarge(_) => VoiceKind::Bird, + Body::BirdMedium(_) => VoiceKind::Bird, + Body::BirdLarge(body) => match body.species { + bird_large::Species::CloudWyvern + | bird_large::Species::FlameWyvern + | bird_large::Species::FrostWyvern + | bird_large::Species::SeaWyvern + | bird_large::Species::WealdWyvern => VoiceKind::Wyvern, + _ => VoiceKind::Bird, + }, Body::BipedSmall(body) => match body.species { biped_small::Species::Adlet => VoiceKind::Adlet, biped_small::Species::Mandragora => VoiceKind::Mandragora, @@ -510,12 +520,16 @@ impl SfxMgr { Body::Object( object::Body::BoltFire | object::Body::BoltFireBig - | object::Body::BoltNature, + | object::Body::BoltNature + | object::Body::BoltIcicle + | object::Body::SpearIcicle + | object::Body::SpitPoison, ) => { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::FireShot); audio.emit_sfx(sfx_trigger_item, *pos, None, underwater); }, - Body::Object(object::Body::LaserBeam) => { + Body::Object(object::Body::LaserBeam) + | Body::Object(object::Body::LightningBolt) => { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::LaserBeam); audio.emit_sfx(sfx_trigger_item, *pos, None, underwater); }, @@ -589,6 +603,10 @@ impl SfxMgr { Outcome::Beam { pos, specifier } => match specifier { beam::FrontendSpecifier::LifestealBeam | beam::FrontendSpecifier::Steam + | beam::FrontendSpecifier::Poison + | beam::FrontendSpecifier::Ink + | beam::FrontendSpecifier::Lightning + | beam::FrontendSpecifier::Frost | beam::FrontendSpecifier::Bubbles => { if thread_rng().gen_bool(0.5) { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::SceptreBeam); @@ -601,9 +619,7 @@ impl SfxMgr { audio.emit_sfx(sfx_trigger_item, *pos, None, underwater); } }, - beam::FrontendSpecifier::ClayGolem - | beam::FrontendSpecifier::Frost - | beam::FrontendSpecifier::WebStrand => {}, + beam::FrontendSpecifier::ClayGolem | beam::FrontendSpecifier::WebStrand => {}, }, Outcome::SpriteUnlocked { pos } => { // TODO: Dedicated sound effect! @@ -719,8 +735,17 @@ impl SfxMgr { _ => {}, }; }, - Outcome::Woosh { pos, .. } => { - let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Woosh); + Outcome::Whoosh { pos, .. } => { + let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Whoosh); + audio.emit_sfx( + sfx_trigger_item, + pos.map(|e| e + 0.5), + Some(3.0), + underwater, + ); + }, + Outcome::Swoosh { pos, .. } => { + let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Swoosh); audio.emit_sfx( sfx_trigger_item, pos.map(|e| e + 0.5), diff --git a/voxygen/src/render/pipelines/particle.rs b/voxygen/src/render/pipelines/particle.rs index 6b14e0e9e0..d5c8d6d50a 100644 --- a/voxygen/src/render/pipelines/particle.rs +++ b/voxygen/src/render/pipelines/particle.rs @@ -97,6 +97,7 @@ pub enum ParticleMode { CyclopsCharge = 43, SnowStorm = 44, PortalFizz = 45, + Ink = 46, } impl ParticleMode { diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 1fa5f9ba04..3001456c67 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -4944,38 +4944,36 @@ impl FigureMgr { skeleton_attr, ) }, - CharacterState::ComboMelee(s) => { - let stage_index = (s.stage - 1) as usize; - let stage_time = s.timer.as_secs_f32(); - let stage_progress = - if let Some(stage) = s.static_data.stage_data.get(stage_index) { - match s.stage_section { - StageSection::Buildup => { - stage_time / stage.base_buildup_duration.as_secs_f32() - }, - StageSection::Action => { - stage_time / stage.base_swing_duration.as_secs_f32() - }, - StageSection::Recover => { - stage_time / stage.base_recover_duration.as_secs_f32() - }, - _ => 0.0, - } - } else { - 0.0 - }; + CharacterState::ComboMelee2(s) => { + let timer = s.timer.as_secs_f32(); + let current_strike = s.completed_strikes % s.static_data.strikes.len(); + let strike_data = s.static_data.strikes[current_strike]; + let progress = match s.stage_section { + StageSection::Buildup => { + timer / strike_data.buildup_duration.as_secs_f32() + }, + StageSection::Action => { + timer / strike_data.swing_duration.as_secs_f32() + }, + StageSection::Recover => { + timer / strike_data.recover_duration.as_secs_f32() + }, + _ => 0.0, + }; - anim::bird_large::AlphaAnimation::update_skeleton( + anim::bird_large::ComboAnimation::update_skeleton( &target_base, ( + ability_id, Some(s.stage_section), + current_strike, time, state.state_time, ori * anim::vek::Vec3::::unit_y(), state.last_ori * anim::vek::Vec3::::unit_y(), physics.on_ground.is_some(), ), - stage_progress, + progress, &mut state_animation_rate, skeleton_attr, ) diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index 103ba8e28d..1623f6e169 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -397,7 +397,8 @@ impl ParticleMgr { | Outcome::IceSpikes { .. } | Outcome::IceCrack { .. } | Outcome::Glider { .. } - | Outcome::Woosh { .. } + | Outcome::Whoosh { .. } + | Outcome::Swoosh { .. } | Outcome::Steam { .. } | Outcome::FireShockwave { .. } | Outcome::LaserBeam { .. } => {}, @@ -1071,6 +1072,56 @@ impl ParticleMgr { }, ); }, + beam::FrontendSpecifier::Poison => { + let mut rng = thread_rng(); + let (from, to) = (Vec3::::unit_z(), *ori.look_dir()); + let m = Mat3::::rotation_from_to_3d(from, to); + self.particles.resize_with( + self.particles.len() + usize::from(beam_tick_count) / 15, + || { + let phi: f32 = rng.gen_range(0.0..beam.properties.angle); + let theta: f32 = rng.gen_range(0.0..2.0 * PI); + let offset_z = Vec3::new( + phi.sin() * theta.cos(), + phi.sin() * theta.sin(), + phi.cos(), + ); + let random_ori = offset_z * m * Vec3::new(-1.0, -1.0, 1.0); + Particle::new_directed( + beam.properties.duration, + time, + ParticleMode::CultistFlame, + pos, + pos + random_ori * range, + ) + }, + ); + }, + beam::FrontendSpecifier::Ink => { + let mut rng = thread_rng(); + let (from, to) = (Vec3::::unit_z(), *ori.look_dir()); + let m = Mat3::::rotation_from_to_3d(from, to); + self.particles.resize_with( + self.particles.len() + usize::from(beam_tick_count) / 15, + || { + let phi: f32 = rng.gen_range(0.0..beam.properties.angle); + let theta: f32 = rng.gen_range(0.0..2.0 * PI); + let offset_z = Vec3::new( + phi.sin() * theta.cos(), + phi.sin() * theta.sin(), + phi.cos(), + ); + let random_ori = offset_z * m * Vec3::new(-1.0, -1.0, 1.0); + Particle::new_directed( + beam.properties.duration, + time, + ParticleMode::Ink, + pos, + pos + random_ori * range, + ) + }, + ); + }, beam::FrontendSpecifier::Steam => { let mut rng = thread_rng(); let (from, to) = (Vec3::::unit_z(), *ori.look_dir()); @@ -1096,6 +1147,17 @@ impl ParticleMgr { }, ); }, + beam::FrontendSpecifier::Lightning => { + self.particles.resize_with(self.particles.len() + 2, || { + Particle::new_directed( + beam.properties.duration, + time, + ParticleMode::Lightning, + pos, + pos + *ori.look_dir() * range, + ) + }) + }, beam::FrontendSpecifier::Frost => { let mut rng = thread_rng(); let (from, to) = (Vec3::::unit_z(), *ori.look_dir()); @@ -1943,6 +2005,41 @@ impl ParticleMgr { } } }, + FrontendSpecifier::Lightning => { + // 1 particle per unit length of arc + let particles_per_length = arc_length as usize; + let dtheta = radians / particles_per_length as f32; + // Scales number of desired heartbeats from speed - thicker arc = higher speed = + // lower duration = more particles + let heartbeats = self + .scheduler + .heartbeats(Duration::from_secs_f32(1.0 / speed)); + + // Reserves capacity for new particles + let new_particle_count = particles_per_length * heartbeats as usize; + self.particles.reserve(new_particle_count); + + for i in 0..particles_per_length { + let angle = dtheta * i as f32; + let direction = Vec3::new(angle.cos(), angle.sin(), 0.0); + for j in 0..heartbeats { + // Sub tick dt + let dt = (j as f32 / heartbeats as f32) * dt; + let distance = distance + speed * dt; + let pos1 = pos + distance * direction - Vec3::unit_z(); + let pos2 = pos1 + (Vec3::unit_z() + direction) * 3.0; + let time = time + dt as f64; + + self.particles.push(Particle::new_directed( + Duration::from_secs_f32(0.5), + time, + ParticleMode::Lightning, + pos1, + pos2, + )); + } + } + }, FrontendSpecifier::Steam => { // 1 particle per unit length of arc let particles_per_length = arc_length as usize; @@ -1978,7 +2075,77 @@ impl ParticleMgr { } } }, - FrontendSpecifier::IceSpikes => { + FrontendSpecifier::Poison => { + // 1 particle per unit length of arc + let particles_per_length = arc_length as usize; + let dtheta = radians / particles_per_length as f32; + // Scales number of desired heartbeats from speed - thicker arc = higher speed = + // lower duration = more particles + let heartbeats = self + .scheduler + .heartbeats(Duration::from_secs_f32(1.0 / speed)); + + // Reserves capacity for new particles + let new_particle_count = particles_per_length * heartbeats as usize; + self.particles.reserve(new_particle_count); + + for i in 0..particles_per_length { + let angle = dtheta * i as f32; + let direction = Vec3::new(angle.cos(), angle.sin(), 0.0); + for j in 0..heartbeats { + // Sub tick dt + let dt = (j as f32 / heartbeats as f32) * dt; + let distance = distance + speed * dt; + let pos1 = pos + distance * direction - Vec3::unit_z(); + let pos2 = pos1 + (Vec3::unit_z() + direction) * 3.0; + let time = time + dt as f64; + + self.particles.push(Particle::new_directed( + Duration::from_secs_f32(0.5), + time, + ParticleMode::CultistFlame, + pos1, + pos2, + )); + } + } + }, + FrontendSpecifier::Ink => { + // 1 particle per unit length of arc + let particles_per_length = arc_length as usize; + let dtheta = radians / particles_per_length as f32; + // Scales number of desired heartbeats from speed - thicker arc = higher speed = + // lower duration = more particles + let heartbeats = self + .scheduler + .heartbeats(Duration::from_secs_f32(1.0 / speed)); + + // Reserves capacity for new particles + let new_particle_count = particles_per_length * heartbeats as usize; + self.particles.reserve(new_particle_count); + + for i in 0..particles_per_length { + let angle = dtheta * i as f32; + let direction = Vec3::new(angle.cos(), angle.sin(), 0.0); + for j in 0..heartbeats { + // Sub tick dt + let dt = (j as f32 / heartbeats as f32) * dt; + let distance = distance + speed * dt; + let pos1 = pos + distance * direction - Vec3::unit_z(); + let pos2 = pos1 + (Vec3::unit_z() + direction) * 3.0; + let time = time + dt as f64; + + self.particles.push(Particle::new_directed( + Duration::from_secs_f32(0.5), + time, + ParticleMode::Ink, + pos1, + pos2, + )); + } + } + }, + FrontendSpecifier::IceSpikes | FrontendSpecifier::Ice => { // 1 / 3 the size of terrain voxel let scale = 1.0 / 3.0; let scaled_distance = distance / scale;